Example #1
0
    def test_attach_wait_for_sync(self, mrapi):
        """Test wait_for_sync when attaching volume to instance.

        """
        volume = mfactory.VolumeFactory()
        vm = volume.machine
        # Test Started VM
        vm.operstate = "STARTED"
        vm.save()
        mrapi().ModifyInstance.return_value = 1
        for sync in [True, False]:
            with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync):
                jobid = backend.attach_volume(vm, volume)
                self.assertEqual(jobid, 1)
                name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]
                self.assertEqual(kwargs['wait_for_sync'], sync)

        # Test Stopped VM. We do not pass wait_for_sync.
        vm.operstate = "STOPPED"
        vm.save()
        mrapi().ModifyInstance.return_value = 1
        for sync in [True, False]:
            with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync):
                jobid = backend.attach_volume(vm, volume)
                self.assertEqual(jobid, 1)
                name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]
                self.assertFalse('wait_for_sync' in kwargs)
Example #2
0
    def test_attach_wait_for_sync(self, mrapi):
        """Test wait_for_sync when attaching volume to instance.

        """
        volume = mfactory.VolumeFactory()
        vm = volume.machine
        # Test Started VM
        vm.operstate = "STARTED"
        vm.save()
        mrapi().ModifyInstance.return_value = 1
        for sync in [True, False]:
            with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync):
                jobid = backend.attach_volume(vm, volume)
                self.assertEqual(jobid, 1)
                name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]
                self.assertEqual(kwargs['wait_for_sync'], sync)

        # Test Stopped VM. We do not pass wait_for_sync.
        vm.operstate = "STOPPED"
        vm.save()
        mrapi().ModifyInstance.return_value = 1
        for sync in [True, False]:
            with override_settings(settings, GANETI_DISKS_WAIT_FOR_SYNC=sync):
                jobid = backend.attach_volume(vm, volume)
                self.assertEqual(jobid, 1)
                name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]
                self.assertFalse('wait_for_sync' in kwargs)
Example #3
0
    def test_attach_volume_type_specs(self, mrapi):
        """Test volume type spces propagation when attaching a
           volume to an instance
        """
        vlmt = mfactory.VolumeTypeFactory(disk_template='ext_archipelago')
        # Generate 4 specs. 2 prefixed with GNT_EXTP_VOLTYPESPEC_PREFIX
        # and 2 with an other prefix that should be omitted
        volume_type_specs = [
            mfactory.VolumeTypeSpecsFactory(volume_type=vlmt,
                                            key='%sbar' %
                                            GNT_EXTP_VOLTYPESPEC_PREFIX),
            mfactory.VolumeTypeSpecsFactory(volume_type=vlmt,
                                            key='%sfoo' %
                                            GNT_EXTP_VOLTYPESPEC_PREFIX),
            mfactory.VolumeTypeSpecsFactory(volume_type=vlmt,
                                            key='other-prefx-baz'),
            mfactory.VolumeTypeSpecsFactory(volume_type=vlmt,
                                            key='another-prefix-biz'),
        ]

        gnt_prefixed_specs = filter(
            lambda s: s.key.startswith(GNT_EXTP_VOLTYPESPEC_PREFIX),
            volume_type_specs)
        volume = mfactory.VolumeFactory(volume_type=vlmt, size=1)
        vm = volume.machine
        osettings = {
            "GANETI_DISK_PROVIDER_KWARGS": {
                "archipelago": {
                    "foo": "mpaz",
                    "lala": "lolo"
                }
            }
        }

        with override_settings(settings, **osettings):
            mrapi().ModifyInstance.return_value = 1
            jobid = backend.attach_volume(vm, volume)
            self.assertEqual(jobid, 1)
            name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]

            disk_kwargs = {
                "provider": "archipelago",
                "name": vm.volumes.all()[0].backend_volume_uuid,
                "reuse_data": 'False',
                "foo": "mpaz",
                "lala": "lolo",
                "size": 1024
            }
            disk_kwargs.update({
                spec.key[len(GNT_EXTP_VOLTYPESPEC_PREFIX):]: spec.value
                for spec in gnt_prefixed_specs
            })

        # Should be "disks": [('add', '-1', {disk_kwargs}), ]
        disk = kwargs["disks"][0]
        self.assertEqual(disk[0], 'add')
        self.assertEqual(disk[1], '-1')
        self.assertEqual(disk[2], disk_kwargs)
Example #4
0
    def test_attach_volume_type_specs(self, mrapi):
        """Test volume type spces propagation when attaching a
           volume to an instance
        """
        vlmt = mfactory.VolumeTypeFactory(disk_template='ext_archipelago')
        # Generate 4 specs. 2 prefixed with GNT_EXTP_VOLTYPESPEC_PREFIX
        # and 2 with an other prefix that should be omitted
        volume_type_specs = [
            mfactory.VolumeTypeSpecsFactory(
                volume_type=vlmt, key='%sbar' % GNT_EXTP_VOLTYPESPEC_PREFIX),
            mfactory.VolumeTypeSpecsFactory(
                volume_type=vlmt, key='%sfoo' % GNT_EXTP_VOLTYPESPEC_PREFIX),
            mfactory.VolumeTypeSpecsFactory(
                volume_type=vlmt, key='other-prefx-baz'),
            mfactory.VolumeTypeSpecsFactory(
                volume_type=vlmt, key='another-prefix-biz'),
        ]

        gnt_prefixed_specs = filter(lambda s: s.key.startswith(
            GNT_EXTP_VOLTYPESPEC_PREFIX), volume_type_specs)
        volume = mfactory.VolumeFactory(volume_type=vlmt, size=1)
        vm = volume.machine
        osettings = {
            "GANETI_DISK_PROVIDER_KWARGS": {
                "archipelago": {
                    "foo": "mpaz",
                    "lala": "lolo"
                }
            }
        }

        with override_settings(settings, **osettings):
            mrapi().ModifyInstance.return_value = 1
            jobid = backend.attach_volume(vm, volume)
            self.assertEqual(jobid, 1)
            name, args, kwargs = mrapi().ModifyInstance.mock_calls[-1]

            disk_kwargs = {"provider": "archipelago",
                           "name": vm.volumes.all()[0].backend_volume_uuid,
                           "reuse_data": 'False',
                           "foo": "mpaz",
                           "lala": "lolo",
                           "size": 1024}
            disk_kwargs.update({spec.key[len(GNT_EXTP_VOLTYPESPEC_PREFIX):]:
                                spec.value
                                for spec in gnt_prefixed_specs})

        # Should be "disks": [('add', '-1', {disk_kwargs}), ]
        disk = kwargs["disks"][0]
        self.assertEqual(disk[0], 'add')
        self.assertEqual(disk[1], '-1')
        self.assertEqual(disk[2], disk_kwargs)
Example #5
0
def _attach_volume(vm, volume):
    """Attach a Volume to a VM and update the Volume's status."""
    jobid = backend.attach_volume(vm, volume)
    log.info("Attached volume '%s' to server '%s'. JobID: '%s'", volume.id,
             volume.machine_id, jobid)
    volume.backendjobid = jobid
    volume.machine = vm
    if volume.status == "AVAILABLE":
        volume.status = "ATTACHING"
    else:
        volume.status = "CREATING"
    volume.save()
    return jobid
Example #6
0
def _attach_volume(vm, volume):
    """Attach a Volume to a VM and update the Volume's status."""
    jobid = backend.attach_volume(vm, volume)
    log.info("Attached volume '%s' to server '%s'. JobID: '%s'", volume.id,
             volume.machine_id, jobid)
    volume.backendjobid = jobid
    volume.machine = vm
    if volume.status == "AVAILABLE":
        volume.status = "ATTACHING"
    else:
        volume.status = "CREATING"
    volume.save()
    return jobid
Example #7
0
def attach_volume(vm, volume, atomic_context):
    """Attach a volume to a server.

    The volume must be in 'AVAILABLE' status in order to be attached. Also,
    number of the volumes that are attached to the server must remain less
    than 'GANETI_MAX_DISKS_PER_INSTANCE' setting. This function will send
    the corresponding job to Ganeti backend and update the status of the
    volume to 'ATTACHING'.

    """
    # Check volume state
    if volume.status not in ["AVAILABLE", "CREATING"]:
        raise faults.BadRequest("Cannot attach volume while volume is in"
                                " '%s' status." % volume.status)
    elif volume.status == "AVAILABLE":
        util.assert_detachable_volume_type(volume.volume_type)

    # Check that disk templates are the same
    if volume.volume_type.template != vm.flavor.volume_type.template:
        msg = ("Volume and server must have the same volume template. Volume"
               " has volume template'%s' while server has '%s'" %
               (volume.volume_type.template, vm.flavor.volume_type.template))
        raise faults.BadRequest(msg)

    # Check maximum disk per instance hard limit
    vm_volumes_num = vm.volumes.filter(deleted=False).count()
    if vm_volumes_num == settings.GANETI_MAX_DISKS_PER_INSTANCE:
        raise faults.BadRequest("Maximum volumes per server limit reached")

    if volume.status == "CREATING":
        action_fields = {"disks": [("add", volume, {})]}
    else:
        action_fields = None

    with commands.ServerCommand("ATTACH_VOLUME",
                                vm,
                                atomic_context=atomic_context,
                                action_fields=action_fields):
        util.assign_volume_to_server(vm, volume)
        jobid = backend.attach_volume(vm, volume)
        vm.record_job(jobid)
        log.info("Attached volume '%s' to server '%s'. JobID: '%s'", volume.id,
                 volume.machine_id, jobid)
        volume.backendjobid = jobid
        volume.machine = vm
        if volume.status == "AVAILABLE":
            volume.status = "ATTACHING"
        else:
            volume.status = "CREATING"
        volume.save()
Example #8
0
def attach_volume(vm, volume, atomic_context):
    """Attach a volume to a server.

    The volume must be in 'AVAILABLE' status in order to be attached. Also,
    number of the volumes that are attached to the server must remain less
    than 'GANETI_MAX_DISKS_PER_INSTANCE' setting. This function will send
    the corresponding job to Ganeti backend and update the status of the
    volume to 'ATTACHING'.

    """
    # Check volume state
    if volume.status not in ["AVAILABLE", "CREATING"]:
        raise faults.BadRequest("Cannot attach volume while volume is in"
                                " '%s' status." % volume.status)
    elif volume.status == "AVAILABLE":
        util.assert_detachable_volume_type(volume.volume_type)

    # Check that disk templates are the same
    if volume.volume_type.template != vm.flavor.volume_type.template:
        msg = ("Volume and server must have the same volume template. Volume"
               " has volume template'%s' while server has '%s'"
               % (volume.volume_type.template, vm.flavor.volume_type.template))
        raise faults.BadRequest(msg)

    # Check maximum disk per instance hard limit
    vm_volumes_num = vm.volumes.filter(deleted=False).count()
    if vm_volumes_num == settings.GANETI_MAX_DISKS_PER_INSTANCE:
        raise faults.BadRequest("Maximum volumes per server limit reached")

    if volume.status == "CREATING":
        action_fields = {"disks": [("add", volume, {})]}
    else:
        action_fields = None

    with commands.ServerCommand("ATTACH_VOLUME", vm,
                                atomic_context=atomic_context,
                                action_fields=action_fields):
        util.assign_volume_to_server(vm, volume)
        jobid = backend.attach_volume(vm, volume)
        vm.record_job(jobid)
        log.info("Attached volume '%s' to server '%s'. JobID: '%s'", volume.id,
                 volume.machine_id, jobid)
        volume.backendjobid = jobid
        volume.machine = vm
        if volume.status == "AVAILABLE":
            volume.status = "ATTACHING"
        else:
            volume.status = "CREATING"
        volume.save()