Example #1
0
    def test_create_standalone_accept_serial_ex(self, mrapi):
        """Create a volume, send commission and crash when accepting serial."""
        with patch("synnefo.quotas.accept_serial") as m:
            m.side_effect = MurphysLaw
            with mocked_quotaholder() as mqh:
                volumes.create(**self.kwargs)

        # Assert that the transaction was commited and that the commission was
        # sent and accepted, albeit locally.
        vol = Volume.objects.get(name=self.volume_name)
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
        self.assertEqual(vol.serial.accept, True)
Example #2
0
    def test_create_standalone_accept_serial_ex(self, mrapi):
        """Create a volume, send commission and crash when accepting serial."""
        with patch("synnefo.quotas.accept_serial") as m:
            m.side_effect = MurphysLaw
            with mocked_quotaholder() as mqh:
                volumes.create(**self.kwargs)

        # Assert that the transaction was commited and that the commission was
        # sent and accepted, albeit locally.
        vol = Volume.objects.get(name=self.volume_name)
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
        self.assertEqual(vol.serial.accept, True)
Example #3
0
    def test_create_and_attach_ex(self, mrapi):
        """Create a volume and crash when attaching it to a VM."""
        self.kwargs["server_id"] = self.archip_vm.id
        mrapi().ModifyInstance.return_value = 42
        with patch("synnefo.logic.backend.attach_volume") as m:
            m.side_effect = MurphysLaw
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)
        del self.kwargs["server_id"]

        # Assert that the commission was sent.
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
Example #4
0
    def test_create_standalone_create_common_ex(self, mrapi):
        """Create volume and crash right after that."""
        def mock_create_common(*args, **kwargs):
            create_common(*args, **kwargs)
            raise MurphysLaw

        with patch.object(volumes, "create_common") as m:
            m.side_effect = mock_create_common
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that no commission was sent
        self.assertNoCommission(mqh)
Example #5
0
    def test_create_standalone_create_common_ex(self, mrapi):
        """Create volume and crash right after that."""
        def mock_create_common(*args, **kwargs):
            create_common(*args, **kwargs)
            raise MurphysLaw

        with patch.object(volumes, "create_common") as m:
            m.side_effect = mock_create_common
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that no commission was sent
        self.assertNoCommission(mqh)
Example #6
0
    def test_create_and_attach_ex(self, mrapi):
        """Create a volume and crash when attaching it to a VM."""
        self.kwargs["server_id"] = self.archip_vm.id
        mrapi().ModifyInstance.return_value = 42
        with patch("synnefo.logic.backend.attach_volume") as m:
            m.side_effect = MurphysLaw
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)
        del self.kwargs["server_id"]

        # Assert that the commission was sent.
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
Example #7
0
    def test_create_standalone_handle_resource_commission_ex(self, mrapi):
        """Create a volume, send commission and crash right after that."""
        def mock_handle_resource_commission(*args, **kwargs):
            handle_resource_commission(*args, **kwargs)
            raise MurphysLaw

        with patch("synnefo.quotas.handle_resource_commission") as m:
            m.side_effect = mock_handle_resource_commission
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that the commission was sent.
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
Example #8
0
    def test_create_standalone_handle_resource_commission_ex(self, mrapi):
        """Create a volume, send commission and crash right after that."""
        def mock_handle_resource_commission(*args, **kwargs):
            handle_resource_commission(*args, **kwargs)
            raise MurphysLaw

        with patch("synnefo.quotas.handle_resource_commission") as m:
            m.side_effect = mock_handle_resource_commission
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that the commission was sent.
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(mqh, expected_commission)
Example #9
0
    def test_create_standalone_create_common_ex(self, mrapi):
        """Create volume and crash right after that."""
        def mock_create_common(*args, **kwargs):
            create_common(*args, **kwargs)
            raise MurphysLaw

        with patch.object(volumes, "create_common") as m:
            m.side_effect = mock_create_common
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that the transaction was rollbacked and that no commission was
        # sent
        with self.assertRaises(Volume.DoesNotExist):
            Volume.objects.get(name=self.volume_name)
        self.assertNoCommission(mqh)
Example #10
0
    def test_create_standalone_create_common_ex(self, mrapi):
        """Create volume and crash right after that."""
        def mock_create_common(*args, **kwargs):
            create_common(*args, **kwargs)
            raise MurphysLaw

        with patch.object(volumes, "create_common") as m:
            m.side_effect = mock_create_common
            with self.assertRaises(MurphysLaw):
                with mocked_quotaholder() as mqh:
                    volumes.create(**self.kwargs)

        # Assert that the transaction was rollbacked and that no commission was
        # sent
        with self.assertRaises(Volume.DoesNotExist):
            Volume.objects.get(name=self.volume_name)
        self.assertNoCommission(mqh)
Example #11
0
    def test_create_standalone(self, mrapi):
        """Test if standalone volumes are created properly."""
        kwargs = self.create_kwargs(volume_type_id=self.archip_vt.id,
                                    server_id=None)
        with mocked_quotaholder() as m:
            vol = volumes.create(**kwargs)
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(m, expected_commission)
        self.assertAcceptedSerial(m, vol.serial)

        self.common_volume_checks(vol)
        self.assertEqual(vol.machine, None)
        self.assertEqual(vol.volume_type, self.archip_vt)
        self.assertEqual(vol.status, "AVAILABLE")
        self.assertEqual(vol.index, None)
Example #12
0
    def test_create_standalone(self, mrapi):
        """Test if standalone volumes are created properly."""
        kwargs = self.create_kwargs(volume_type_id=self.archip_vt.id,
                                    server_id=None)
        with mocked_quotaholder() as m:
            vol = volumes.create(**kwargs)
        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(m, expected_commission)
        self.assertAcceptedSerial(m, vol.serial)

        self.common_volume_checks(vol)
        self.assertEqual(vol.machine, None)
        self.assertEqual(vol.volume_type, self.archip_vt)
        self.assertEqual(vol.status, "AVAILABLE")
        self.assertEqual(vol.index, None)
Example #13
0
    def test_create(self, mrapi):
        # No server id
        kwargs = deepcopy(self.kwargs)
        kwargs["server_id"] = None
        self.assertRaises(faults.BadRequest,
                          volumes.create,
                          **kwargs)

        # Invalid server
        vm = mf.VirtualMachineFactory(userid="other_user")
        kwargs["server_id"] = vm.id
        self.assertRaises(faults.BadRequest,
                          volumes.create,
                          **kwargs)

        # Invalid size
        kwargs = deepcopy(self.kwargs)
        max_size = settings.CYCLADES_VOLUME_MAX_SIZE
        kwargs["size"] = max_size + 1
        self.assertRaises(faults.BadRequest,
                          volumes.create,
                          **kwargs)

        # Create server without source!
        mrapi().ModifyInstance.return_value = 42
        with mocked_quotaholder():
            vol = volumes.create(**self.kwargs)

        self.assertEqual(vol.size, self.size)
        self.assertEqual(vol.userid, self.userid)
        self.assertEqual(vol.name, None)
        self.assertEqual(vol.description, None)
        self.assertEqual(vol.source_snapshot_id, None)
        self.assertEqual(vol.source, None)
        self.assertEqual(vol.origin, None)
        self.assertEqual(vol.source_volume_id, None)
        self.assertEqual(vol.source_image_id, None)
        self.assertEqual(vol.machine, self.vm)
        self.assertEqual(vol.volume_type, self.vm.flavor.volume_type)

        name, args, kwargs = mrapi().ModifyInstance.mock_calls[0]
        self.assertEqual(kwargs["instance"], self.vm.backend_vm_id)
        disk_info = kwargs["disks"][0][2]
        self.assertEqual(disk_info["size"], self.size << 10)
        self.assertEqual(disk_info["name"], vol.backend_volume_uuid)
        self.assertFalse("origin" in disk_info)
Example #14
0
    def test_create_from_snapshot(self, mimage, mrapi):
        # Wrong source
        mimage().__enter__().get_snapshot.side_effect = faults.ItemNotFound
        kwargs = self.create_kwargs(server_id=self.archip_vm.id,
                                    source_snapshot_id=421)
        self.assertRaises(faults.BadRequest, volumes.create, **kwargs)

        mimage().__enter__().get_snapshot.side_effect = None
        mimage().__enter__().get_snapshot.return_value = {
            'location': 'pithos://foo',
            'mapfile': 'snf-snapshot-43',
            'id': 12,
            'name': "test_image",
            'version': 42,
            'size': 1242,
            'disk_format': 'diskdump',
            'status': 'AVAILABLE',
            'properties': {
                'source_volume': 42
            }
        }

        mrapi().ModifyInstance.return_value = 42
        kwargs = self.create_kwargs(source_snapshot_id=12,
                                    server_id=self.archip_vm.id)
        with mocked_quotaholder():
            vol = volumes.create(**kwargs)

        self.assertEqual(vol.size, self.size)
        self.assertEqual(vol.userid, self.userid)
        self.assertEqual(vol.name, None)
        self.assertEqual(vol.description, None)
        self.assertEqual(int(vol.source_snapshot_id), 12)
        self.assertEqual(vol.source_volume_id, None)
        self.assertEqual(vol.source_image_id, None)
        self.assertEqual(vol.origin, "snf-snapshot-43")

        name, args, kwargs = mrapi().ModifyInstance.mock_calls[0]
        self.assertEqual(kwargs["instance"], self.archip_vm.backend_vm_id)
        disk_info = kwargs["disks"][0][2]
        self.assertEqual(disk_info["size"], self.size << 10)
        self.assertEqual(disk_info["name"], vol.backend_volume_uuid)
        self.assertEqual(disk_info["origin"], "snf-snapshot-43")
Example #15
0
    def create_and_attach(self, mrapi, vm):
        """Common tests for create and attach operation."""
        kwargs = self.create_kwargs(server_id=vm.id)
        mrapi().ModifyInstance.return_value = 42
        with mocked_quotaholder() as m:
            vol = volumes.create(**kwargs)

        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(m, expected_commission)
        self.common_volume_checks(vol)
        self.assertEqual(vol.machine, vm)
        self.assertEqual(vol.volume_type, vm.flavor.volume_type)
        self.assertEqual(vol.index, 0)

        gnt_args = self.get_ganeti_args(mrapi)
        self.assertEqual(gnt_args["instance"], vm.backend_vm_id)
        disk_info = self.get_ganeti_disk_args(mrapi)[2]
        self.assertEqual(disk_info["size"], self.size << 10)
        self.assertEqual(disk_info["name"], vol.backend_volume_uuid)
        self.assertFalse("origin" in disk_info)
Example #16
0
    def create_and_attach(self, mrapi, vm):
        """Common tests for create and attach operation."""
        kwargs = self.create_kwargs(server_id=vm.id)
        mrapi().ModifyInstance.return_value = 42
        with mocked_quotaholder() as m:
            vol = volumes.create(**kwargs)

        expected_commission = {(self.userid, "cyclades.disk"): self.size << 30}
        self.assertCommissionEqual(m, expected_commission)
        self.common_volume_checks(vol)
        self.assertEqual(vol.machine, vm)
        self.assertEqual(vol.volume_type, vm.flavor.volume_type)
        self.assertEqual(vol.index, 0)

        gnt_args = self.get_ganeti_args(mrapi)
        self.assertEqual(gnt_args["instance"], vm.backend_vm_id)
        disk_info = self.get_ganeti_disk_args(mrapi)[2]
        self.assertEqual(disk_info["size"], self.size << 10)
        self.assertEqual(disk_info["name"], vol.backend_volume_uuid)
        self.assertFalse("origin" in disk_info)
Example #17
0
    def test_create_from_snapshot(self, mimage, mrapi):
        # Wrong source
        mimage().__enter__().get_snapshot.side_effect = faults.ItemNotFound
        kwargs = self.create_kwargs(server_id=self.archip_vm.id,
                                    source_snapshot_id=421)
        self.assertRaises(faults.BadRequest, volumes.create, **kwargs)

        mimage().__enter__().get_snapshot.side_effect = None
        mimage().__enter__().get_snapshot.return_value = {
            'location': 'pithos://foo',
            'mapfile': 'snf-snapshot-43',
            'id': 12,
            'name': "test_image",
            'version': 42,
            'size': 1242,
            'disk_format': 'diskdump',
            'status': 'AVAILABLE',
            'properties': {'source_volume': 42}}

        mrapi().ModifyInstance.return_value = 42
        kwargs = self.create_kwargs(source_snapshot_id=12,
                                    server_id=self.archip_vm.id)
        with mocked_quotaholder():
            vol = volumes.create(**kwargs)

        self.assertEqual(vol.size, self.size)
        self.assertEqual(vol.userid, self.userid)
        self.assertEqual(vol.name, None)
        self.assertEqual(vol.description, None)
        self.assertEqual(int(vol.source_snapshot_id), 12)
        self.assertEqual(vol.source_volume_id, None)
        self.assertEqual(vol.source_image_id, None)
        self.assertEqual(vol.origin, "snf-snapshot-43")

        name, args, kwargs = mrapi().ModifyInstance.mock_calls[0]
        self.assertEqual(kwargs["instance"], self.archip_vm.backend_vm_id)
        disk_info = kwargs["disks"][0][2]
        self.assertEqual(disk_info["size"], self.size << 10)
        self.assertEqual(disk_info["name"], vol.backend_volume_uuid)
        self.assertEqual(disk_info["origin"], "snf-snapshot-43")
Example #18
0
    def test_create_bad_volume_types(self, mrapi):
        """Various tests for the create action regarding volume types."""
        # No volume type
        kwargs = self.create_kwargs(server_id=None)
        with self.assertRaises(faults.BadRequest):
            volumes.create(**kwargs)

        # Conflicting volume types (ext_archipelago != file)
        conflict_msg = "Cannot create a volume with template '{}' to a " \
                       "server with volume template '{}'".format(
                            self.archip_vt.template, self.file_vt.template)
        kwargs = self.create_kwargs(volume_type_id=self.archip_vt.id,
                                    server_id=self.file_vm.id)
        with self.assertRaisesMessage(faults.BadRequest, conflict_msg):
            volumes.create(**kwargs)

        # Non-detachable volume type
        non_detachable_msg = "Volume type 'file' is not detachable"
        kwargs = self.create_kwargs(volume_type_id=self.file_vt.id,
                                    server_id=None)
        with self.assertRaisesMessage(faults.BadRequest, non_detachable_msg):
            volumes.create(**kwargs)
Example #19
0
    def test_create_bad_volume_types(self, mrapi):
        """Various tests for the create action regarding volume types."""
        # No volume type
        kwargs = self.create_kwargs(server_id=None)
        with self.assertRaises(faults.BadRequest):
            volumes.create(**kwargs)

        # Conflicting volume types (ext_archipelago != file)
        conflict_msg = "Cannot create a volume with template '{}' to a " \
                       "server with volume template '{}'".format(
                            self.archip_vt.template, self.file_vt.template)
        kwargs = self.create_kwargs(volume_type_id=self.archip_vt.id,
                                    server_id=self.file_vm.id)
        with self.assertRaisesMessage(faults.BadRequest, conflict_msg):
            volumes.create(**kwargs)

        # Non-detachable volume type
        non_detachable_msg = "Volume type 'file' is not detachable"
        kwargs = self.create_kwargs(volume_type_id=self.file_vt.id,
                                    server_id=None)
        with self.assertRaisesMessage(faults.BadRequest, non_detachable_msg):
            volumes.create(**kwargs)
Example #20
0
def create_volume(request):
    """Create a new Volume."""

    req = utils.get_json_body(request)
    credentials = request.credentials
    user_id = credentials.userid

    log.debug("User: %s, Action: create_volume, Request: %s",
              user_id, req)

    vol_dict = utils.get_attribute(req, "volume", attr_type=dict,
                                   required=True)
    name = utils.get_attribute(vol_dict, "display_name",
                               attr_type=basestring, required=True)

    # Get and validate 'size' parameter
    size = utils.get_attribute(vol_dict, "size",
                               attr_type=(basestring, int), required=True)
    try:
        size = int(size)
        if size <= 0:
            raise ValueError
    except (TypeError, ValueError):
        raise faults.BadRequest("Volume 'size' needs to be a positive integer"
                                " value. '%s' cannot be accepted." % size)

    project = vol_dict.get("project")
    if project is None:
        project = user_id
    shared_to_project= vol_dict.get("shared_to_project", False)

    # Optional parameters
    volume_type_id = utils.get_attribute(vol_dict, "volume_type",
                                         attr_type=(basestring, int),
                                         required=False)
    description = utils.get_attribute(vol_dict, "display_description",
                                      attr_type=basestring, required=False,
                                      default="")
    metadata = utils.get_attribute(vol_dict, "metadata", attr_type=dict,
                                   required=False, default={})

    # Id of the volume to clone from
    source_volume_id = utils.get_attribute(vol_dict, "source_volid",
                                           required=False)

    # Id of the snapshot to create the volume from
    source_snapshot_id = utils.get_attribute(vol_dict, "snapshot_id",
                                             required=False)

    snapshots_enabled = util.snapshots_enabled_for_user(request.user)
    if source_snapshot_id and not snapshots_enabled:
        raise faults.NotImplemented("Making a clone from a snapshot is not"
                                    " implemented")

    # Reference to an Image stored in Glance
    source_image_id = utils.get_attribute(vol_dict, "imageRef", required=False)

    # Get server ID to attach the volume.
    server_id = utils.get_attribute(vol_dict, "server_id", required=False)

    # Create the volume
    volume = volumes.create(credentials, size=size, name=name,
                            source_volume_id=source_volume_id,
                            source_snapshot_id=source_snapshot_id,
                            source_image_id=source_image_id,
                            volume_type_id=volume_type_id,
                            description=description,
                            metadata=metadata,
                            server_id=server_id, project_id=project,
                            shared_to_project=shared_to_project)

    log.info("User %s created volume %s attached to server %s, shared: %s",
             user_id, volume.id, server_id, shared_to_project)

    # Render response
    data = json.dumps(dict(volume=volume_to_dict(volume, detail=False)))
    return HttpResponse(data, status=202)
Example #21
0
    def handle(self, *args, **options):
        if args:
            raise CommandError("Command doesn't accept any arguments")

        size = options.get("size")
        user_id = options.get("user_id")
        project_id = options.get("project")
        server_id = options.get("server_id")
        volume_type_id = options.get("volume_type_id")
        wait = parse_bool(options["wait"])
        credentials = Credentials(user_id)

        display_name = options.get("name", "")
        display_description = options.get("description", "")

        if size is None:
            raise CommandError("Please specify the size of the volume")

        if server_id:
            vm = common.get_resource("server", server_id)
            if project_id is None:
                project_id = vm.project

        if user_id is None and server_id is None:
            raise CommandError("Please specify the id of a user or a server")
        elif user_id is None and server_id is not None:
            user_id = vm.userid

        if volume_type_id is not None:
            vtype = common.get_resource("volume-type", volume_type_id)
        elif server_id:
            vtype = vm.flavor.volume_type
        else:
            raise CommandError("Please specify the id of the volume type")

        # At this point, user_id, vtype must have been provided or extracted by
        # the server. The project_id is optional and will default to the user's
        # project.

        source_image_id = source_volume_id = source_snapshot_id = None
        source = options.get("source")
        if source is not None:
            try:
                source_type, source_uuid = source.split(":", 1)
            except (ValueError, TypeError):
                raise CommandError("Invalid '--source' option. Value must be"
                                   " of the form <source_type>:<source_uuid>")
            if source_type == "image":
                source_image_id = source_uuid
            elif source_type == "snapshot":
                source_snapshot_id = source_uuid
            else:
                raise CommandError("Unknown volume source type '%s'"
                                   % source_type)

        volume = volumes.create(credentials, size, server_id,
                                name=display_name,
                                description=display_description,
                                source_image_id=source_image_id,
                                source_snapshot_id=source_snapshot_id,
                                source_volume_id=source_volume_id,
                                volume_type_id=vtype.id, metadata={},
                                project_id=project_id)

        self.stdout.write("Created volume '%s' in DB:\n" % volume.id)

        pprint.pprint_volume(volume, stdout=self.stdout)
        self.stdout.write("\n")
        if volume.machine is not None:
            volume.machine.task_job_id = volume.backendjobid
            common.wait_server_task(volume.machine, wait, stdout=self.stdout)
Example #22
0
    def handle(self, *args, **options):
        if args:
            raise CommandError("Command doesn't accept any arguments")

        size = options.get("size")
        user_id = options.get("user_id")
        project_id = options.get("project")
        server_id = options.get("server_id")
        volume_type_id = options.get("volume_type_id")
        wait = parse_bool(options["wait"])

        display_name = options.get("name", "")
        display_description = options.get("description", "")

        if size is None:
            raise CommandError("Please specify the size of the volume")

        if server_id is None:
            raise CommandError("Please specify the server to attach the"
                               " volume.")

        vm = common.get_resource("server", server_id, for_update=True)

        if user_id is None:
            user_id = vm.userid

        if volume_type_id is not None:
            vtype = common.get_resource("volume-type", volume_type_id)
        else:
            vtype = vm.flavor.volume_type

        if project_id is None:
            project_id = vm.project

        source_image_id = source_volume_id = source_snapshot_id = None
        source = options.get("source")
        if source is not None:
            try:
                source_type, source_uuid = source.split(":", 1)
            except (ValueError, TypeError):
                raise CommandError("Invalid '--source' option. Value must be"
                                   " of the form <source_type>:<source_uuid>")
            if source_type == "image":
                source_image_id = source_uuid
            elif source_type == "snapshot":
                source_snapshot_id = source_uuid
            else:
                raise CommandError("Unknown volume source type '%s'" %
                                   source_type)

        volume = volumes.create(user_id,
                                size,
                                server_id,
                                name=display_name,
                                description=display_description,
                                source_image_id=source_image_id,
                                source_snapshot_id=source_snapshot_id,
                                source_volume_id=source_volume_id,
                                volume_type_id=vtype.id,
                                metadata={},
                                project=project_id)

        self.stdout.write("Created volume '%s' in DB:\n" % volume.id)

        pprint.pprint_volume(volume, stdout=self.stdout)
        self.stdout.write("\n")
        if volume.machine is not None:
            volume.machine.task_job_id = volume.backendjobid
            common.wait_server_task(volume.machine, wait, stdout=self.stdout)
Example #23
0
    def handle(self, *args, **options):
        if args:
            raise CommandError("Command doesn't accept any arguments")

        size = options.get("size")
        user_id = options.get("user_id")
        project_id = options.get("project")
        server_id = options.get("server_id")
        volume_type_id = options.get("volume_type_id")
        wait = parse_bool(options["wait"])
        credentials = Credentials(user_id)

        display_name = options.get("name", "")
        display_description = options.get("description", "")

        if size is None:
            raise CommandError("Please specify the size of the volume")

        if server_id:
            vm = common.get_resource("server", server_id)
            if project_id is None:
                project_id = vm.project

        if user_id is None and server_id is None:
            raise CommandError("Please specify the id of a user or a server")
        elif user_id is None and server_id is not None:
            user_id = vm.userid

        if volume_type_id is not None:
            vtype = common.get_resource("volume-type", volume_type_id)
        elif server_id:
            vtype = vm.flavor.volume_type
        else:
            raise CommandError("Please specify the id of the volume type")

        # At this point, user_id, vtype must have been provided or extracted by
        # the server. The project_id is optional and will default to the user's
        # project.

        source_image_id = source_volume_id = source_snapshot_id = None
        source = options.get("source")
        if source is not None:
            try:
                source_type, source_uuid = source.split(":", 1)
            except (ValueError, TypeError):
                raise CommandError("Invalid '--source' option. Value must be"
                                   " of the form <source_type>:<source_uuid>")
            if source_type == "image":
                source_image_id = source_uuid
            elif source_type == "snapshot":
                source_snapshot_id = source_uuid
            else:
                raise CommandError("Unknown volume source type '%s'" %
                                   source_type)

        volume = volumes.create(credentials,
                                size,
                                server_id,
                                name=display_name,
                                description=display_description,
                                source_image_id=source_image_id,
                                source_snapshot_id=source_snapshot_id,
                                source_volume_id=source_volume_id,
                                volume_type_id=vtype.id,
                                metadata={},
                                project_id=project_id)

        self.stdout.write("Created volume '%s' in DB:\n" % volume.id)

        pprint.pprint_volume(volume, stdout=self.stdout)
        self.stdout.write("\n")
        if volume.machine is not None:
            volume.machine.task_job_id = volume.backendjobid
            common.wait_server_task(volume.machine, wait, stdout=self.stdout)
Example #24
0
def create_volume(request):
    """Create a new Volume."""

    req = utils.get_json_body(request)
    log.debug("create_volume %s", req)
    user_id = request.user_uniq

    vol_dict = utils.get_attribute(req,
                                   "volume",
                                   attr_type=dict,
                                   required=True)
    name = utils.get_attribute(vol_dict,
                               "display_name",
                               attr_type=basestring,
                               required=True)

    # Get and validate 'size' parameter
    size = utils.get_attribute(vol_dict,
                               "size",
                               attr_type=(basestring, int),
                               required=True)
    try:
        size = int(size)
        if size <= 0:
            raise ValueError
    except (TypeError, ValueError):
        raise faults.BadRequest("Volume 'size' needs to be a positive integer"
                                " value. '%s' cannot be accepted." % size)

    project = vol_dict.get("project")
    if project is None:
        project = user_id

    # Optional parameters
    volume_type_id = utils.get_attribute(vol_dict,
                                         "volume_type",
                                         attr_type=(basestring, int),
                                         required=False)
    description = utils.get_attribute(vol_dict,
                                      "display_description",
                                      attr_type=basestring,
                                      required=False,
                                      default="")
    metadata = utils.get_attribute(vol_dict,
                                   "metadata",
                                   attr_type=dict,
                                   required=False,
                                   default={})

    # Id of the volume to clone from
    source_volume_id = utils.get_attribute(vol_dict,
                                           "source_volid",
                                           required=False)

    # Id of the snapshot to create the volume from
    source_snapshot_id = utils.get_attribute(vol_dict,
                                             "snapshot_id",
                                             required=False)
    if source_snapshot_id and not settings.CYCLADES_SNAPSHOTS_ENABLED:
        raise faults.NotImplemented("Making a clone from a snapshot is not"
                                    " implemented")

    # Reference to an Image stored in Glance
    source_image_id = utils.get_attribute(vol_dict, "imageRef", required=False)

    # Get server ID to attach the volume. Since we currently do not supported
    # detached volumes, server_id attribute is mandatory.
    server_id = utils.get_attribute(vol_dict, "server_id", required=True)

    # Create the volume
    volume = volumes.create(user_id=user_id,
                            size=size,
                            name=name,
                            source_volume_id=source_volume_id,
                            source_snapshot_id=source_snapshot_id,
                            source_image_id=source_image_id,
                            volume_type_id=volume_type_id,
                            description=description,
                            metadata=metadata,
                            server_id=server_id,
                            project=project)

    # Render response
    data = json.dumps(dict(volume=volume_to_dict(volume, detail=False)))
    return HttpResponse(data, status=202)
Example #25
0
def create_volume(request):
    """Create a new Volume."""

    req = utils.get_json_body(request)
    log.debug("create_volume %s", req)
    user_id = request.user_uniq

    vol_dict = utils.get_attribute(req, "volume", attr_type=dict,
                                   required=True)
    name = utils.get_attribute(vol_dict, "display_name",
                               attr_type=basestring, required=True)

    # Get and validate 'size' parameter
    size = utils.get_attribute(vol_dict, "size",
                               attr_type=(basestring, int), required=True)
    try:
        size = int(size)
        if size <= 0:
            raise ValueError
    except (TypeError, ValueError):
        raise faults.BadRequest("Volume 'size' needs to be a positive integer"
                                " value. '%s' cannot be accepted." % size)

    project = vol_dict.get("project")
    if project is None:
        project = user_id

    # Optional parameters
    volume_type_id = utils.get_attribute(vol_dict, "volume_type",
                                         attr_type=(basestring, int),
                                         required=False)
    description = utils.get_attribute(vol_dict, "display_description",
                                      attr_type=basestring, required=False,
                                      default="")
    metadata = utils.get_attribute(vol_dict, "metadata", attr_type=dict,
                                   required=False, default={})

    # Id of the volume to clone from
    source_volume_id = utils.get_attribute(vol_dict, "source_volid",
                                           required=False)

    # Id of the snapshot to create the volume from
    source_snapshot_id = utils.get_attribute(vol_dict, "snapshot_id",
                                             required=False)
    if source_snapshot_id and not settings.CYCLADES_SNAPSHOTS_ENABLED:
        raise faults.NotImplemented("Making a clone from a snapshot is not"
                                    " implemented")

    # Reference to an Image stored in Glance
    source_image_id = utils.get_attribute(vol_dict, "imageRef", required=False)

    # Get server ID to attach the volume. Since we currently do not supported
    # detached volumes, server_id attribute is mandatory.
    server_id = utils.get_attribute(vol_dict, "server_id", required=True)

    # Create the volume
    volume = volumes.create(user_id=user_id, size=size, name=name,
                            source_volume_id=source_volume_id,
                            source_snapshot_id=source_snapshot_id,
                            source_image_id=source_image_id,
                            volume_type_id=volume_type_id,
                            description=description,
                            metadata=metadata,
                            server_id=server_id, project=project)

    # Render response
    data = json.dumps(dict(volume=volume_to_dict(volume, detail=False)))
    return HttpResponse(data, status=202)
Example #26
0
def create_volume(request):
    """Create a new Volume."""

    req = utils.get_json_body(request)
    user_id = request.user_uniq

    log.debug("User: %s, Action: create_volume, Request: %s", user_id, req)

    vol_dict = utils.get_attribute(req,
                                   "volume",
                                   attr_type=dict,
                                   required=True)
    name = utils.get_attribute(vol_dict,
                               "display_name",
                               attr_type=basestring,
                               required=True)

    # Get and validate 'size' parameter
    size = utils.get_attribute(vol_dict,
                               "size",
                               attr_type=(basestring, int),
                               required=True)
    try:
        size = int(size)
        if size <= 0:
            raise ValueError
    except (TypeError, ValueError):
        raise faults.BadRequest("Volume 'size' needs to be a positive integer"
                                " value. '%s' cannot be accepted." % size)

    project = vol_dict.get("project")
    if project is None:
        project = user_id
    shared_to_project = vol_dict.get("shared_to_project", False)

    # Optional parameters
    volume_type_id = utils.get_attribute(vol_dict,
                                         "volume_type",
                                         attr_type=(basestring, int),
                                         required=False)
    description = utils.get_attribute(vol_dict,
                                      "display_description",
                                      attr_type=basestring,
                                      required=False,
                                      default="")
    metadata = utils.get_attribute(vol_dict,
                                   "metadata",
                                   attr_type=dict,
                                   required=False,
                                   default={})

    # Id of the volume to clone from
    source_volume_id = utils.get_attribute(vol_dict,
                                           "source_volid",
                                           required=False)

    # Id of the snapshot to create the volume from
    source_snapshot_id = utils.get_attribute(vol_dict,
                                             "snapshot_id",
                                             required=False)

    snapshots_enabled = util.snapshots_enabled_for_user(request.user)
    if source_snapshot_id and not snapshots_enabled:
        raise faults.NotImplemented("Making a clone from a snapshot is not"
                                    " implemented")

    # Reference to an Image stored in Glance
    source_image_id = utils.get_attribute(vol_dict, "imageRef", required=False)

    # Get server ID to attach the volume.
    server_id = utils.get_attribute(vol_dict, "server_id", required=False)

    server = None
    if server_id:
        try:
            server = get_vm(server_id,
                            user_id,
                            request.user_projects,
                            for_update=True,
                            non_deleted=True)
        except faults.ItemNotFound:
            raise faults.BadRequest("Server %s not found" % server_id)

    # Create the volume
    volume = volumes.create(user_id=user_id,
                            size=size,
                            name=name,
                            source_volume_id=source_volume_id,
                            source_snapshot_id=source_snapshot_id,
                            source_image_id=source_image_id,
                            volume_type_id=volume_type_id,
                            description=description,
                            metadata=metadata,
                            server=server,
                            project_id=project,
                            shared_to_project=shared_to_project)

    server_id = server.id if server else None
    log.info("User %s created volume %s attached to server %s, shared: %s",
             user_id, volume.id, server_id, shared_to_project)

    # Render response
    data = json.dumps(dict(volume=volume_to_dict(volume, detail=False)))
    return HttpResponse(data, status=202)
Example #27
0
    def handle(self, *args, **options):
        if args:
            raise CommandError("Command doesn't accept any arguments")

        size = options.get("size")
        user_id = options.get("user_id")
        project_id = options.get("project")
        server_id = options.get("server_id")
        volume_type_id = options.get("volume_type_id")
        wait = parse_bool(options["wait"])

        display_name = options.get("name", "")
        display_description = options.get("description", "")

        if size is None:
            raise CommandError("Please specify the size of the volume")

        if server_id is None:
            raise CommandError("Please specify the server to attach the"
                               " volume.")

        vm = common.get_resource("server", server_id, for_update=True)

        if user_id is None:
            user_id = vm.userid

        if volume_type_id is not None:
            vtype = common.get_resource("volume-type", volume_type_id)
        else:
            vtype = vm.flavor.volume_type

        if project_id is None:
            project_id = vm.project

        source_image_id = source_volume_id = source_snapshot_id = None
        source = options.get("source")
        if source is not None:
            try:
                source_type, source_uuid = source.split(":", 1)
            except (ValueError, TypeError):
                raise CommandError("Invalid '--source' option. Value must be"
                                   " of the form <source_type>:<source_uuid>")
            if source_type == "image":
                source_image_id = source_uuid
            elif source_type == "snapshot":
                source_snapshot_id = source_uuid
            else:
                raise CommandError("Unknown volume source type '%s'"
                                   % source_type)

        volume = volumes.create(user_id, size, server_id,
                                name=display_name,
                                description=display_description,
                                source_image_id=source_image_id,
                                source_snapshot_id=source_snapshot_id,
                                source_volume_id=source_volume_id,
                                volume_type_id=vtype.id,
                                metadata={}, project=project_id)

        self.stdout.write("Created volume '%s' in DB:\n" % volume.id)

        pprint.pprint_volume(volume, stdout=self.stdout)
        self.stdout.write("\n")
        if volume.machine is not None:
            volume.machine.task_job_id = volume.backendjobid
            common.wait_server_task(volume.machine, wait, stdout=self.stdout)