openvstorage / framework

The Framework is a set of components and tools which brings the user an interface (GUI / API) to setup, extend and manage an Open vStorage platform.
Other
27 stars 23 forks source link

DTL logic wrongly detects a manual DTL configuration as "disabled" #956

Closed khenderick closed 7 years ago

khenderick commented 7 years ago

DTL logic wrongly detects a manual DTL configuration as "disabled". It also can't cope well with volumes not existing in the volumedriver.

khenderick commented 7 years ago
                try:
                    current_dtl_config = vdisk.storagedriver_client.get_dtl_config(volume_id)
                    current_dtl_config_mode = vdisk.storagedriver_client.get_dtl_config_mode(volume_id)
                except RuntimeError as rte:

Raises an ObjectNotFoundException which should also be catched.

khenderick commented 7 years ago
        dtl_enabled = dtl_config_mode == StorageDriverClient.VOLDRV_DTL_AUTOMATIC_MODE
        if dtl_enabled is False:
            dtl_mode = StorageDriverClient.FRAMEWORK_DTL_NO_SYNC

Also check whether the host equals ''

kvanhijf commented 7 years ago

openvstorage-2.7.3-rev.4047.aa8ef29

kvanhijf commented 7 years ago

@QA: Set up a vPool with DTL enabled (Synchronously or Asynchronously), deploy some vDisks and verify through logging that DTL is set up correctly (ovs-workers.log) Also check the GUI and hover the DTL tooltip

Then overrule the dtl_config_mode flag and the host in the volumedriver config from ovs.extensions.storageserver.storagedriver import StorageDriverConfiguration from ovs.extensions.generic.sshclient import SSHClient from ovs.dal.lists.vpoollist import VPoolList vpool = VPoolList.get_vpools()[0] conf = StorageDriverConfiguration('storagedriver', vpool.guid, vpool.storagedrivers[0].storagedriver_id) conf.load() conf.configure_filesystem({'fs_dtl_config_mode': StorageDriverClient.VOLDRV_DTL_MANUAL_MODE, 'fs_dtl_host': }) conf.save(SSHClient(, 'root'), reload_config=True)

Retry creating vDisks and validate their DTL, everything should still work and the specified dtl_host in the config should NOT be respected

JeffreyDevloo commented 7 years ago

Steps

Test code

This code will all configurations and will verify the dtls

# Copyright (C) 2016 iNuron NV
#
# This file is part of Open vStorage Open Source Edition (OSE),
# as available from
#
#      http://www.openvstorage.org and
#      http://www.openvstorage.com.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License v3 (GNU AGPLv3)
# as published by the Free Software Foundation, in version 3 as it comes
# in the LICENSE.txt file of the Open vStorage OSE distribution.
#
# Open vStorage is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY of any kind.
from ci.helpers.api import OVSClient
from ovs.extensions.storageserver.storagedriver import StorageDriverConfiguration
from ovs.extensions.generic.sshclient import SSHClient
from ovs.dal.lists.vpoollist import VPoolList
from ovs.extensions.storageserver.storagedriver import StorageDriverClient
from ovs.dal.hybrids.vdisk import VDisk
from ci.helpers.vpool import VPoolHelper
from ci.helpers.storagerouter import StoragerouterHelper

class DTLTest(object):

    @staticmethod
    def test():
        vpool = 'myvpool01'
        api = OVSClient('10.100.199.151', 'admin', 'admin')
        modes = [StorageDriverClient.VOLDRV_DTL_MANUAL_MODE, StorageDriverClient.VOLDRV_DTL_AUTOMATIC_MODE]
        hosts = ['10.100.199.151', '10.100.199.152', '10.100.199.153', '']
        testresults = {}
        for mode in modes:
            for host in hosts:
                DTLTest.change_configuration(vpool, mode, host)
                vdisk_guid = DTLTest.create_vdisk('vdisk{0}{1}'.format(mode, host), vpool, 10485760, '10.100.199.151', api)
                testresults[DTLTest.check_dtl(vdisk_guid)] = 1 if DTLTest.check_dtl(vdisk_guid) not in testresults else testresults[DTLTest.check_dtl(vdisk_guid)] + 1
        print testresults
    @staticmethod
    def create_vdisk(vdisk_name, vpool_name, size, storagerouter_ip, api, timeout=30):
        """
        Create a new vDisk on a certain vPool/storagerouter

        :param vdisk_name: location of a vdisk on a vpool
                           (e.g. /mnt/vpool/test.raw = test.raw, /mnt/vpool/volumes/test.raw = volumes/test.raw )
        :type vdisk_name: str
        :param vpool_name: name of a existing vpool
        :type vpool_name: str
        :param size: size of the new vdisk in BYTES (e.g 10737418240 = 10G)
        :type size: int
        :param storagerouter_ip: ip address of a existing storagerouter
        :type storagerouter_ip: str
        :param api: specify a valid api connection to the setup
        :type api: ci.helpers.api.OVSClient
        :param timeout: time to wait for the task to complete
        :type timeout: int
        :param vpool_name: name of a existing vpool
        :type vpool_name: str
        :return: if success
        :rtype: bool
        """
        vpool_guid = VPoolHelper.get_vpool_by_name(vpool_name).guid
        storagerouter_guid = StoragerouterHelper.get_storagerouter_by_ip(storagerouter_ip).guid

        # remove .raw or .vmdk if is present
        if '.raw' in vdisk_name or '.vmdk' in vdisk_name:
            official_vdisk_name = vdisk_name.split('.')[0]
        else:
            official_vdisk_name = vdisk_name

        data = {"name": official_vdisk_name,
                "size": int(size),
                "vpool_guid": vpool_guid,
                "storagerouter_guid": storagerouter_guid}

        task_guid = api.post(
            api='/vdisks/',
            data=data
        )
        task_result = api.wait_for_task(task_id=task_guid, timeout=timeout)

        if not task_result[0]:
            error_msg = "Creating vdisk `{0}` on vPool `{1}` on storagerouter `{2}` has failed with error {3}".format(
                vdisk_name, vpool_name, storagerouter_ip, task_result[1])
            print (error_msg)
            raise RuntimeError(error_msg)
        else:
            print (
                "Creating vdisk `{0}` on vPool `{1}` on storagerouter `{2}` should have succeeded"
                .format(vdisk_name, vpool_name, storagerouter_ip))
        return task_result[1]

    @staticmethod
    def check_dtl(vdisk_guid):
        vdisk = VDisk(vdisk_guid)
        # Check dtl
        dtl_status = vdisk.dtl_status
        if dtl_status == "ok_standalone":
            print ("Vdisk {0}'s DTL is disabled because of a single node cluster".format(vdisk.name))
            return "ok_standalone"
        elif dtl_status == "ok_sync":
            print ("Vdisk {0}'s DTL is enabled and running.".format(vdisk.name))
            return "ok_sync"
        elif dtl_status == "degraded":
            print ("Vdisk {0}'s DTL is degraded.".format(vdisk.name))
            return "degraded"
        elif dtl_status == "catchup" or dtl_status == "catch_up":
            print ("Vdisk {0}'s DTL is enabled but still syncing.".format(vdisk.name))
            return "catchup"
        else:
            print ("Vdisk {0}'s DTL has an unknown status: {1}.".format(vdisk.name, dtl_status))
            return "other"

    @staticmethod
    def change_configuration(vpool_name, mode ,host):
        vpool = VPoolHelper.get_vpool_by_name(vpool_name)
        conf = StorageDriverConfiguration('storagedriver', vpool.guid, vpool.storagedrivers[0].storagedriver_id)
        conf.load()
        conf.configure_filesystem(fs_dtl_config_mode=mode, fs_dtl_host=host)
        conf.save(SSHClient('10.100.199.151', 'root'), reload_config=True)

if __name__ == "__main__":
    DTLTest.test()

Output

Got the following result dict:

{'ok_sync': 8}

Test result

All disks that were made had an OK DTL Test passed.

Packages