Esempio n. 1
0
    def test_ibm_storage_block_device_api__get_blockdevicevolume_by_vol(
            self, multipathing_mock):

        multipathing_mock.return_value = True
        vol_info = VolInfo('f_{}_{}'.format(UUID1_STR, UUID1_SLUG),
                           int(GiB(16).to_Byte().value),
                           1111,
                           UUID1_STR)
        blockdevicevolume = BlockDeviceVolume(
            blockdevice_id=unicode(UUID1_STR),
            size=int(GiB(16).to_Byte().value),
            attached_to=u'fake_host',
            dataset_id=UUID(UUID1_STR),
        )

        self.mock_client.get_vol_mapping = MagicMock(return_value='fake_host')
        driver_obj = driver.IBMStorageBlockDeviceAPI(
            UUID(FAKE_CLUSTER_ID), self.mock_client, DRIVER_BASIC_CONF)
        driver_obj._is_cluster_volume = MagicMock(return_value=False)
        with self.assertRaises(UnknownVolume):
            driver_obj._get_blockdevicevolume_by_vol(vol_info)

        driver_obj._is_cluster_volume = MagicMock(return_value=True)
        self.assertEqual(blockdevicevolume,
                         driver_obj._get_blockdevicevolume_by_vol(vol_info))
 def allocation_unit(self):
     """
     Return allocation unit
     """
     logging.debug("vSphere allocation unit: " +
                   str(int(GiB(4).to_Byte().value)))
     return int(GiB(4).to_Byte().value)
Esempio n. 3
0
def configured_cluster_for_nodes(reactor, certificates, nodes, dataset_backend,
                                 dataset_backend_configuration):
    """
    Get a ``Cluster`` with Flocker services running on the right nodes.

    :param reactor: The reactor.
    :param Certificates certificates: The certificates to install on the
        cluster.
    :param nodes: The ``ManagedNode``s on which to operate.
    :param NamedConstant dataset_backend: The ``DatasetBackend`` constant
        representing the dataset backend that the nodes will be configured to
        use when they are "started".
    :param dict dataset_backend_configuration: The backend-specific
        configuration the nodes will be given for their dataset backend.

    :returns: A ``Deferred`` which fires with ``Cluster`` when it is
        configured.
    """
    default_volume_size = GiB(1)
    if dataset_backend_configuration.get('auth_plugin') == 'rackspace':
        default_volume_size = GiB(100)

    cluster = Cluster(all_nodes=pvector(nodes),
                      control_node=nodes[0],
                      agent_nodes=nodes,
                      dataset_backend=dataset_backend,
                      default_volume_size=int(
                          default_volume_size.to_Byte().value),
                      certificates=certificates)

    configuring = perform(
        make_dispatcher(reactor),
        configure_cluster(cluster, dataset_backend_configuration))
    configuring.addCallback(lambda ignored: cluster)
    return configuring
class HedvigBlockDeviceAPIInterfaceTests(
        make_iblockdeviceapi_tests(
            blockdevice_api_factory=(
                lambda test_case: GetTestHedvigStorage(test_case)),
            minimum_allocatable_size=int(GiB(8).to_Byte().value),
            device_allocation_unit=int(GiB(8).to_Byte().value),
            unknown_blockdevice_id_factory=lambda test: unicode(uuid4()))):
    """
 def allocation_unit(self):
     """
     Return allocation unit
     """
     logger.debug('Setting minimum allocation unit to Multiplies of 1GiB')
     logger.debug("Reduxio System allocation unit: " +
                  str(int(GiB(1).to_Byte().value)))
     return int(GiB(1).to_Byte().value)
Esempio n. 6
0
def configured_cluster_for_nodes(
    reactor, certificates, nodes, dataset_backend,
    dataset_backend_configuration, dataset_backend_config_file
):
    """
    Get a ``Cluster`` with Flocker services running on the right nodes.

    :param reactor: The reactor.
    :param Certificates certificates: The certificates to install on the
        cluster.
    :param nodes: The ``ManagedNode``s on which to operate.
    :param NamedConstant dataset_backend: The ``DatasetBackend`` constant
        representing the dataset backend that the nodes will be configured to
        use when they are "started".
    :param dict dataset_backend_configuration: The backend-specific
        configuration the nodes will be given for their dataset backend.
    :param FilePath dataset_backend_config_file: A FilePath that has the
        dataset_backend info stored.

    :returns: A ``Deferred`` which fires with ``Cluster`` when it is
        configured.
    """
    # XXX: There is duplication between the values here and those in
    # f.node.agents.test.blockdevicefactory.MINIMUM_ALLOCATABLE_SIZES. We want
    # the default volume size to be greater than or equal to the minimum
    # allocatable size.
    #
    # Ideally, the minimum allocatable size (and perhaps the default volume
    # size) would be something known by an object that represents the dataset
    # backend. Unfortunately:
    #  1. There is no such object
    #  2. There is existing confusion in the code around 'openstack' and
    #     'rackspace'
    #
    # Here, we special-case Rackspace (presumably) because it has a minimum
    # allocatable size that is different from other Openstack backends.
    #
    # FLOC-2584 also discusses this.
    default_volume_size = GiB(1)
    if dataset_backend_configuration.get('auth_plugin') == 'rackspace':
        default_volume_size = GiB(100)

    cluster = Cluster(
        all_nodes=pvector(nodes),
        control_node=nodes[0],
        agent_nodes=nodes,
        dataset_backend=dataset_backend,
        default_volume_size=int(default_volume_size.to_Byte().value),
        certificates=certificates,
        dataset_backend_config_file=dataset_backend_config_file
    )

    configuring = perform(
        make_dispatcher(reactor),
        configure_cluster(cluster, dataset_backend_configuration)
    )
    configuring.addCallback(lambda ignored: cluster)
    return configuring
class EMCScaleIOBlockDeviceAPIInterfaceTests(
        make_iblockdeviceapi_tests(
            blockdevice_api_factory=(
                lambda test_case: emcsioblockdeviceapi_for_test(
                    uuid4(), test_case)),
            minimum_allocatable_size=int(GiB(8).to_Byte().value),
            device_allocation_unit=int(GiB(8).to_Byte().value),
            unknown_blockdevice_id_factory=lambda test: unicode(uuid4()))):
    """
Esempio n. 8
0
class AzureStorageBlockDeviceAPIInterfaceTests(
        make_iblockdeviceapi_tests(
            blockdevice_api_factory=(
                lambda test_case: azureblockdeviceasyncapi_for_test(test_case)
            ),
            minimum_allocatable_size=int(GiB(1).to_Byte().value),
            device_allocation_unit=int(GiB(1).to_Byte().value),
            unknown_blockdevice_id_factory=lambda test: unicode(uuid4()))):
    """
Esempio n. 9
0
class EMCUnityBlockAPIInterfaceTests(
        test_blockdevice.make_iblockdeviceapi_tests(
            blockdevice_api_factory=(
                lambda test_case: emcblockdeviceapi_for_test(
                    # XXX A hack to work around the LUN name length limit. We
                    # need a better way to store the cluster_id.
                    unicode(uuid4()).split('-')[0],
                    test_case)),
            minimum_allocatable_size=int(GiB(8).to_Byte().value),
            device_allocation_unit=int(GiB(8).to_Byte().value),
            unknown_blockdevice_id_factory=lambda test: unicode(uuid4()))):
    """
Esempio n. 10
0
    def test_ibm_storage_block_device_api__create_volume(
            self, multipathing_mock):
        size = int(GiB(16).to_Byte().value)
        multipathing_mock.return_value = True
        mock_vol_obj = MagicMock
        mock_vol_obj.id = 'vol-id-11111'
        mock_vol_obj.size = size
        mock_vol_obj.name = 'volfack'
        mock_vol_obj.wwn = '11111111111'

        self.mock_client.list_volumes = MagicMock(
            return_value=[mock_vol_obj])
        self.mock_client.create_volume = MagicMock
        self.mock_client.handle_default_pool = MagicMock
        self.mock_client.handle_default_profile = MagicMock(
            return_value='fakepool')
        self.mock_client.con_info = CONF_INFO_MOCK

        driver_obj = driver.IBMStorageBlockDeviceAPI(
            UUID1, self.mock_client, DRIVER_BASIC_CONF)
        bdv = driver_obj.create_volume(UUID(UUID1_STR), size)

        expacted_blockdevicevolume = BlockDeviceVolume(
            blockdevice_id=unicode(mock_vol_obj.wwn),
            size=size,
            attached_to=None,
            dataset_id=UUID(UUID1_STR),
        )
        self.assertEqual(bdv, expacted_blockdevicevolume)
    def allocation_unit(self):
        """
        1GiB is the minimum allocation unit for azure disks
        return int: 1 GiB
        """

        return int(GiB(1).to_Byte().value)
Esempio n. 12
0
File: gce.py Progetto: teazj/flocker
    def create_volume_with_profile(self, dataset_id, size, profile_name):
        blockdevice_id = _dataset_id_to_blockdevice_id(dataset_id)
        size = Byte(size)
        profile_type = MandatoryProfiles.lookupByValue(profile_name).name
        gce_disk_type = GCEStorageProfiles.lookupByName(profile_type).value
        try:
            self._operations.create_disk(
                name=blockdevice_id,
                size=size,
                description=self._disk_resource_description(),
                gce_disk_type=gce_disk_type
            )
        except HttpError as e:
            if e.resp.status == 409:
                msg = ("A dataset named {} already exists in this GCE "
                       "project.".format(dataset_id))
                raise GCEVolumeException(msg)
            else:
                raise

        disk = self._operations.get_disk_details(blockdevice_id)
        return BlockDeviceVolume(
            blockdevice_id=blockdevice_id,
            size=int(GiB(int(disk['sizeGb'])).to_Byte()),
            attached_to=_extract_attached_to(disk),
            dataset_id=_blockdevice_id_to_dataset_id(blockdevice_id),
        )
Esempio n. 13
0
    def from_options(cls, reactor, options):
        """
        Create a cluster container deployment object from the
        options given through command line.

        :param reactor: reactor
        :param options: ``ContainerOptions`` container the parsed
            options given to the script.
        """
        try:
            image = DockerImage(repository=options['image'])
            max_size = int(GiB(options['max-size']).to_Byte().value)
            mountpoint = unicode(options['mountpoint'])
            control_node_address = options['control-node']
            timeout = options['wait']
        except Exception as e:
            sys.stderr.write("%s: %s\n" % ("Missing or wrong arguments", e))
            sys.stderr.write(e.args[0])
            sys.stderr.write('\n\n')
            sys.stderr.write(options.getSynopsis())
            sys.stderr.write('\n')
            sys.stderr.write(options.getUsage())
            raise SystemExit(1)

        certificates_path = FilePath(options['cert-directory'])
        cluster_cert = certificates_path.child(b"cluster.crt")
        user_cert = certificates_path.child(b"user.crt")
        user_key = certificates_path.child(b"user.key")

        # Initialise client
        client = FlockerClient(reactor, control_node_address, REST_API_PORT,
                               cluster_cert, user_cert, user_key)

        return cls(reactor, image, max_size, mountpoint, control_node_address,
                   timeout, cluster_cert, user_cert, user_key, client)
Esempio n. 14
0
    def test_ibm_storage_block_device_api__get_device_path(
            self, ospathexist, multipathing_mock, check_output_mock):
        multipathing_mock.return_value = True
        ospathexist.return_value = True
        check_output_mock.return_value = test_host_actions.MULTIPATH_OUTPUT2

        blockdevicevolume = BlockDeviceVolume(
            blockdevice_id=unicode(test_host_actions.MULTIPATH_OUTPUT_WWN2),
            size=int(GiB(16).to_Byte().value),
            attached_to=u'fakehost',
            dataset_id=UUID(UUID1_STR),
        )
        driver_obj = driver.IBMStorageBlockDeviceAPI(
            UUID1, self.mock_client, DRIVER_BASIC_CONF)

        class VolInfoFake(object):
            name = 'fake_volname'
        driver_obj._get_volume_object = MagicMock(return_value=VolInfoFake())
        driver_obj._get_blockdevicevolume_by_vol = MagicMock(
            return_value=blockdevicevolume)
        self.mock_client.backend_type = 'XIV'

        self.mock_client.list_volumes = MagicMock(return_value=[FAKERList])

        dpath = driver_obj.get_device_path(blockdevicevolume.blockdevice_id)
        self.assertEqual(
            dpath,
            FilePath('{}/{}'.format(
                PREFIX_DEVICE_PATH,
                test_host_actions.WWN_PREFIX +
                test_host_actions.MULTIPATH_OUTPUT_WWN2,
            )))
Esempio n. 15
0
 def allocation_unit(self):
     """
     8GiB is the minimum allocation unit described by the ScaelIO Guide
     https://community.emc.com/docs/DOC-43968 for ScaleIO v1.31
     return int: 8 GiB
     """
     return int(GiB(8).to_Byte().value)
Esempio n. 16
0
    def _test_sized_vol_container(self, cluster, node):
        """
        Create a volume with a size, then create a
        container that can use that volume and run lsbk to test
        its size. An http server inside the container uses lsblk to
        return the size of the volume when path is not "/is_http".

        :param cluster: flocker cluster
        :param node: node the contianer and volume will be on.
        """
        client = get_docker_client(cluster, node.public_address)
        volume_name = random_name(self)
        size = integers(min_value=75, max_value=100).example()
        expression = volume_expression.example()
        size_opt = "".join(str(size)) + expression
        size_bytes = int(GiB(size).to_Byte().value)
        self._create_volume(client,
                            volume_name,
                            driver_opts={'size': size_opt})
        http_port = 8080

        container_identifier = self.run_python_container(
            cluster,
            node.public_address, {
                "host_config":
                client.create_host_config(
                    binds=["{}:/sizedvoldata".format(volume_name)],
                    port_bindings={http_port: 0},
                    restart_policy={"Name": "always"},
                    privileged=True),
                "ports": [http_port]
            },
            SCRIPTS.child(b"lsblkhttp.py"), [u"/sizedvoldata"],
            client=client)
        host_port = extract_external_port(
            client,
            container_identifier,
            http_port,
        )

        d = assert_http_server(self,
                               node.public_address,
                               host_port,
                               expected_response=str(size_bytes))

        def _get_datasets(unused_arg):
            return cluster.client.list_datasets_configuration()

        d.addCallback(_get_datasets)

        def _verify_volume_metadata_size(datasets):
            dataset = next(d for d in datasets
                           if d.metadata.get(u'name') == volume_name)
            self.assertEqual(int(dataset.metadata.get(u'maximum_size')),
                             size_bytes)

        d.addCallback(_verify_volume_metadata_size)

        return d
    def vmax_round_allocation(in_bytes):
        """
        Returns a size in bytes that is on a clean cylinder boundary.
        :param in_bytes: input size in bytes
        :return:
        """
        if in_bytes < int(GiB(1).to_Byte().value):
            in_bytes = int(GiB(1).to_Byte().value)

        boundary = int(KiB(1920).to_Byte().value)
        remainder = in_bytes % boundary
        if remainder == 0:
            round_up = in_bytes
        else:
            round_up = in_bytes + boundary - remainder

        return round_up
Esempio n. 18
0
class EBSProfiledBlockDeviceAPIInterfaceTests(
        make_iprofiledblockdeviceapi_tests(
            profiled_blockdevice_api_factory=ebsblockdeviceapi_for_test,
            dataset_size=GiB(4).to_Byte().value)):
    """
    Interface adherence tests for ``IProfiledBlockDeviceAPI``.
    """
    pass
Esempio n. 19
0
    def allocation_unit(self):
        """
        Can only allocate PDs in GiB units.

        Documentation claims `GB` but experimentally this was determined to
        actually be `GiB`.
        """
        return int(GiB(1).to_Byte().value)
Esempio n. 20
0
def test_sbatch_arguments_unsupported_provided():
    params = AllocationParameters(nodes=1,
                                  cores=2,
                                  walltime=Walltime(minutes=10),
                                  memory_per_node=GiB(1))
    params.all['Provided Unsupported Param'] = 12
    with pytest.raises(ValueError):
        SbatchArguments(params=params)
Esempio n. 21
0
 def setUp(self):
     super(AttachVolumeAndWaitTests, self).setUp()
     self.volume = BlockDeviceVolume(
         dataset_id=uuid4(),
         blockdevice_id=u"opaque storage backend id",
         size=int(GiB(100).to_Byte()),
     )
     self.compute_id = u"opaque compute backend id"
def vmax_allocation_unit(size_in_gb):
    """
    Round size to next greatest allocation unit
    :param size_in_gb: size in GigaBytes
    :return:
    Size in bytes
    """
    return EMCVmaxBlockDeviceAPI.vmax_round_allocation(
        int(GiB(size_in_gb).to_Byte().value))
Esempio n. 23
0
class EMCUnityProfiledBlockAPIInterfaceTests(
        test_blockdevice.make_iprofiledblockdeviceapi_tests(
            profiled_blockdevice_api_factory=(
                lambda test_case: emcblockdeviceapi_for_test(
                    # XXX A hack to work around the LUN name length limit. We
                    # need a better way to store the cluster_id.
                    unicode(uuid4()).split('-')[0],
                    test_case)),
            dataset_size=int(GiB(8).to_Byte().value))):
    """
Esempio n. 24
0
    def test_parsenum_size(self, expr, size):
        """
        Send different forms of size expressions
        to ``parse_num``, we expect G(Gigabyte) size results.

        :param expr str: A string representing the size expression
        :param size int: A string representing the volume size
        """
        expected_size = int(GiB(size).to_Byte())
        return self.assertEqual(expected_size,
                                int(parse_num(str(size) + expr).to_Byte()))
    def attach_volume(self, blockdevice_id, attach_to):
        """
        Attach ``blockdevice_id`` to ``host``.
        :param unicode blockdevice_id: The unique identifier for the block
            device being attached.
        :param unicode attach_to: An identifier like the one returned by the
            ``compute_instance_id`` method indicating the node to which to
            attach the volume.
        :raises UnknownVolume: If the supplied ``blockdevice_id`` does not
            exist.
        :raises AlreadyAttachedVolume: If the supplied ``blockdevice_id`` is
            already attached.
        :returns: A ``BlockDeviceVolume`` with a ``host`` attribute set to
            ``host``.
        """

        log_info('Attempting to attach ' + str(blockdevice_id)
                 + ' to ' + str(attach_to))

        _vmstate_lock.acquire()
        try:
            # Make sure disk is present.  Also, need the disk size is needed.
            disks = self._manager.list_disks()
            target_disk = None
            for disk in disks:
                if disk.name == blockdevice_id:
                    target_disk = disk
                    break
            if target_disk is None:
                raise UnknownVolume(blockdevice_id)

            (disk, vmname, lun) = self._get_disk_vmname_lun(blockdevice_id)
            if vmname is not None:
                if unicode(vmname) != self.compute_instance_id():
                    raise AlreadyAttachedVolume(blockdevice_id)
                else:
                    return self._blockdevicevolume_from_azure_volume(
                        blockdevice_id,
                        target_disk.properties.content_length,
                        attach_to)

            self._manager.attach_disk(
                str(attach_to),
                target_disk.name,
                int(GiB(bytes=target_disk.properties.content_length)))
        finally:
            _vmstate_lock.release()

        log_info('disk attached')

        return self._blockdevicevolume_from_azure_volume(
            blockdevice_id,
            target_disk.properties.content_length,
            attach_to)
Esempio n. 26
0
    def allocation_unit(self):
        """
        1GiB is the minimum allocation unit described by the OpenStack
        Cinder API documentation.
         * http://developer.openstack.org/api-ref-blockstorage-v2.html#createVolume # noqa

        Some Cinder storage drivers may actually allocate more than
        this, but as long as the requested size is a multiple of this
        unit, the Cinder API will always report the size that was
        requested.
        """
        return int(GiB(1).to_Byte().value)
Esempio n. 27
0
def get_minimum_allocatable_size():
    """
    Return the minimum supported volume size, in bytes, defined as an
    environment variable or 1GiB if the variable is not set.

    :returns: An ``int`` minimum_allocatable_size in bytes.
    """
    return int(
        environ.get(
            'FLOCKER_FUNCTIONAL_TEST_MINIMUM_ALLOCATABLE_SIZE',
            GiB(1).to_Byte().value,
        ))
Esempio n. 28
0
def test_sbatch_arguments_create():
    params = AllocationParameters(nodes=1,
                                  cores=2,
                                  memory_per_node=GiB(1),
                                  walltime=Walltime(minutes=10))

    sbatch_args = SbatchArguments(params=params)

    assert sbatch_args.native_args == {}
    assert sbatch_args.args == {'--nodes': '1',
                                '--cpus-per-task': '2',
                                '--mem': '1048576K',
                                '--time': '0-00:10:00'}
Esempio n. 29
0
def test_allocation_parameters_create():
    """Tests construction of allocation parameters."""
    params = AllocationParameters(nodes=1,
                                  cores=2,
                                  memory_per_node=GiB(1),
                                  walltime=Walltime(minutes=10),
                                  native_args={
                                      '--abc': None,
                                      '--def': '80'
                                  })

    assert params.all == {
        'nodes': 1,
        'cores': 2,
        'memory_per_node': GiB(1),
        'walltime': Walltime(minutes=10)
    }
    assert params.nodes == 1
    assert params.cores == 2
    assert params.memory_per_node == GiB(1)
    assert params.walltime == Walltime(minutes=10)
    assert params.native_args == {'--abc': None, '--def': '80'}
Esempio n. 30
0
def _blockdevicevolume_from_ebs_volume(ebs_volume):
    """
    Helper function to convert Volume information from
    EBS format to Flocker block device format.

    :param boto.ec2.volume ebs_volume: Volume in EC2 format.

    :return: Input volume in BlockDeviceVolume format.
    """
    return BlockDeviceVolume(blockdevice_id=unicode(ebs_volume.id),
                             size=int(GiB(ebs_volume.size).to_Byte().value),
                             attached_to=ebs_volume.attach_data.instance_id,
                             dataset_id=UUID(
                                 ebs_volume.tags[DATASET_ID_LABEL]))