Exemple #1
0
    def test_detach(self, mrapi):
        """Test the detach functionality."""
        # Fail to detach a non-detachable volume
        vol = mf.VolumeFactory(volume_type=self.file_vt,
                               machine=self.file_vm,
                               userid=self.userid,
                               status="IN_USE")
        message = "Volume type '{}' is not detachable".format(
            self.file_vt.disk_template)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach a volume that has never been attached to any server
        vol = mf.VolumeFactory(userid=self.userid,
                               volume_type=self.archip_vt,
                               machine=None)
        message = "Volume is already detached"
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach a volume that is not in use
        vol = mf.VolumeFactory(userid=self.userid, volume_type=self.archip_vt)
        vol.machine = self.archip_vm
        vol.status = "CREATING"
        vol.save()
        message = "Cannot detach volume while volume is in '{}' status".format(
            vol.status)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach the root volume of a vm
        vol.status = "IN_USE"
        vol.index = 0
        vol.save()
        message = "Cannot detach the root volume of server {}.".format(
            self.archip_vm)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Detach a volume from a server
        vol.userid = self.userid
        vol.index = 1
        vol.save()
        mrapi().ModifyInstance.return_value = 42
        with mocked_quotaholder() as m:
            volumes.detach(vol.id, self.credentials)
        # Assert that the VM has just one volume, the volume has an appropriate
        # status and that no commission was sent.
        self.assertEqual(self.archip_vm.volumes.all().count(), 1)
        vol = Volume.objects.get(pk=vol.id)
        self.assertEqual(vol.status, "DETACHING")
        self.assertNoCommission(m)
        # Assert that Ganeti was instructed to keep the disks and that the
        # ModifyInstance command corresponds to the target volume and server.
        gnt_args = self.get_ganeti_args(mrapi)
        self.assertIn("keep_disks", gnt_args)
        disk_args = self.get_ganeti_disk_args(mrapi)
        self.assertEqual(disk_args[0], "remove")
        self.assertEqual(disk_args[1], vol.backend_volume_uuid)
        self.assertEqual(disk_args[2], {})
Exemple #2
0
    def test_detach(self, mrapi):
        """Test the detach functionality."""
        # Fail to detach a non-detachable volume
        vol = mf.VolumeFactory(volume_type=self.file_vt, machine=self.file_vm,
                               userid=self.userid, status="IN_USE")
        message = "Volume type '{}' is not detachable".format(
            self.file_vt.disk_template)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach a volume that has never been attached to any server
        vol = mf.VolumeFactory(userid=self.userid, volume_type=self.archip_vt,
                               machine=None)
        message = "Volume is already detached"
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach a volume that is not in use
        vol = mf.VolumeFactory(userid=self.userid, volume_type=self.archip_vt)
        vol.machine = self.archip_vm
        vol.status = "CREATING"
        vol.save()
        message = "Cannot detach volume while volume is in '{}' status".format(
            vol.status)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Fail to detach the root volume of a vm
        vol.status = "IN_USE"
        vol.index = 0
        vol.save()
        message = "Cannot detach the root volume of server {}.".format(
            self.archip_vm)
        with self.assertRaisesMessage(faults.BadRequest, message):
            volumes.detach(vol.id, self.credentials)

        # Detach a volume from a server
        vol.userid = self.userid
        vol.index = 1
        vol.save()
        mrapi().ModifyInstance.return_value = 42
        with mocked_quotaholder() as m:
            volumes.detach(vol.id, self.credentials)
        # Assert that the VM has just one volume, the volume has an appropriate
        # status and that no commission was sent.
        self.assertEqual(self.archip_vm.volumes.all().count(), 1)
        vol = Volume.objects.get(pk=vol.id)
        self.assertEqual(vol.status, "DETACHING")
        self.assertNoCommission(m)
        # Assert that Ganeti was instructed to keep the disks and that the
        # ModifyInstance command corresponds to the target volume and server.
        gnt_args = self.get_ganeti_args(mrapi)
        self.assertIn("keep_disks", gnt_args)
        disk_args = self.get_ganeti_disk_args(mrapi)
        self.assertEqual(disk_args[0], "remove")
        self.assertEqual(disk_args[1], vol.backend_volume_uuid)
        self.assertEqual(disk_args[2], {})
    def handle(self, *args, **options):
        if not args:
            raise CommandError("Please provide a volume ID")

        force = options['force']
        message = "volumes" if len(args) > 1 else "volume"
        self.confirm_detachment(force, message, args)

        for volume_id in args:
            self.stdout.write("\n")
            try:
                volume = volumes.detach(volume_id)

                wait = parse_bool(options["wait"])
                if volume.machine is not None:
                    volume.machine.task_job_id = volume.backendjobid
                    common.wait_server_task(volume.machine, wait,
                                            stdout=self.stdout)
                else:
                    self.stdout.write("Successfully detached volume %s\n"
                                      % volume)
            except CommandError as e:
                self.stdout.write("Error -- %s\n" % e.message)
Exemple #4
0
    def handle(self, *args, **options):
        if not args:
            raise CommandError("Please provide a volume ID")

        force = options['force']
        message = "volumes" if len(args) > 1 else "volume"
        self.confirm_detachment(force, message, args)

        for volume_id in args:
            self.stdout.write("\n")
            try:
                volume = volumes.detach(volume_id)

                wait = parse_bool(options["wait"])
                if volume.machine is not None:
                    volume.machine.task_job_id = volume.backendjobid
                    common.wait_server_task(volume.machine, wait,
                                            stdout=self.stdout)
                else:
                    self.stdout.write("Successfully detached volume %s\n"
                                      % volume)
            except CommandError as e:
                self.stdout.write("Error -- %s\n" % e.message)