Beispiel #1
0
def get_image(image_id, user_id):
    if image_id:
        try:
            return util.get_image_dict(image_id, user_id)
        except faults.ItemNotFound:
            raise CommandError("Image with ID %s not found."
                               " Use snf-manage image-list to find"
                               " out available image IDs." % image_id)
    else:
        raise CommandError("image-id is mandatory")
Beispiel #2
0
def get_image(image_id, user_id):
    if image_id:
        try:
            return util.get_image_dict(image_id, user_id)
        except faults.ItemNotFound:
            raise CommandError("Image with ID %s not found."
                               " Use snf-manage image-list to find"
                               " out available image IDs." % image_id)
    else:
        raise CommandError("image-id is mandatory")
Beispiel #3
0
def create_server(request):
    # Normal Response Code: 202
    # Error Response Codes: computeFault (400, 500),
    #                       serviceUnavailable (503),
    #                       unauthorized (401),
    #                       badMediaType(415),
    #                       itemNotFound (404),
    #                       badRequest (400),
    #                       serverCapacityUnavailable (503),
    #                       overLimit (413)
    req = utils.get_request_dict(request)
    user_id = request.user_uniq
    log.info('create_server user: %s request: %s', user_id, req)

    try:
        server = req['server']
        name = server['name']
        metadata = server.get('metadata', {})
        assert isinstance(metadata, dict)
        image_id = server['imageRef']
        flavor_id = server['flavorRef']
        personality = server.get('personality', [])
        assert isinstance(personality, list)
        networks = server.get("networks")
        if networks is not None:
            assert isinstance(networks, list)
    except (KeyError, AssertionError):
        raise faults.BadRequest("Malformed request")

    # Verify that personalities are well-formed
    util.verify_personality(personality)
    # Get image information
    image = util.get_image_dict(image_id, user_id)
    # Get flavor (ensure it is active)
    flavor = util.get_flavor(flavor_id, include_deleted=False)
    if not flavor.allow_create:
        msg = ("It is not allowed to create a server from flavor with id '%d',"
               " see 'allow_create' flavor attribute")
        raise faults.Forbidden(msg % flavor.id)
    # Generate password
    password = util.random_password()

    vm = servers.create(user_id, name, password, flavor, image,
                        metadata=metadata, personality=personality,
                        networks=networks)

    server = vm_to_dict(vm, detail=True)
    server['status'] = 'BUILD'
    server['adminPass'] = password

    response = render_server(request, server, status=202)

    return response
Beispiel #4
0
def create_server(request):
    # Normal Response Code: 202
    # Error Response Codes: computeFault (400, 500),
    #                       serviceUnavailable (503),
    #                       unauthorized (401),
    #                       badMediaType(415),
    #                       itemNotFound (404),
    #                       badRequest (400),
    #                       serverCapacityUnavailable (503),
    #                       overLimit (413)
    req = utils.get_request_dict(request)
    log.info('create_server %s', req)
    user_id = request.user_uniq

    try:
        server = req['server']
        name = server['name']
        metadata = server.get('metadata', {})
        assert isinstance(metadata, dict)
        image_id = server['imageRef']
        flavor_id = server['flavorRef']
        personality = server.get('personality', [])
        assert isinstance(personality, list)
    except (KeyError, AssertionError):
        raise faults.BadRequest("Malformed request")

    # Verify that personalities are well-formed
    util.verify_personality(personality)
    # Get image information
    image = util.get_image_dict(image_id, user_id)
    # Get flavor (ensure it is active)
    flavor = util.get_flavor(flavor_id, include_deleted=False)
    # Generate password
    password = util.random_password()

    vm = do_create_server(user_id,
                          name,
                          password,
                          flavor,
                          image,
                          metadata=metadata,
                          personality=personality)

    server = vm_to_dict(vm, detail=True)
    server['status'] = 'BUILD'
    server['adminPass'] = password

    response = render_server(request, server, status=202)

    return response
Beispiel #5
0
def create_server(request):
    # Normal Response Code: 202
    # Error Response Codes: computeFault (400, 500),
    #                       serviceUnavailable (503),
    #                       unauthorized (401),
    #                       badMediaType(415),
    #                       itemNotFound (404),
    #                       badRequest (400),
    #                       serverCapacityUnavailable (503),
    #                       overLimit (413)
    req = utils.get_request_dict(request)
    log.info('create_server %s', req)
    user_id = request.user_uniq

    try:
        server = req['server']
        name = server['name']
        metadata = server.get('metadata', {})
        assert isinstance(metadata, dict)
        image_id = server['imageRef']
        flavor_id = server['flavorRef']
        personality = server.get('personality', [])
        assert isinstance(personality, list)
    except (KeyError, AssertionError):
        raise faults.BadRequest("Malformed request")

    # Verify that personalities are well-formed
    util.verify_personality(personality)
    # Get image information
    image = util.get_image_dict(image_id, user_id)
    # Get flavor (ensure it is active)
    flavor = util.get_flavor(flavor_id, include_deleted=False)
    # Generate password
    password = util.random_password()

    vm = do_create_server(user_id, name, password, flavor, image,
                          metadata=metadata, personality=personality)

    server = vm_to_dict(vm, detail=True)
    server['status'] = 'BUILD'
    server['adminPass'] = password

    response = render_server(request, server, status=202)

    return response
Beispiel #6
0
def get_image(user_id, image_id, exception=faults.ItemNotFound):
    try:
        return get_image_dict(image_id, user_id)
    except faults.ItemNotFound:
        raise exception("Image %s not found" % image_id)
Beispiel #7
0
def get_image(user_id, image_id, exception=faults.ItemNotFound):
    try:
        return get_image_dict(image_id, user_id)
    except faults.ItemNotFound:
        raise exception("Image %s not found" % image_id)
Beispiel #8
0
def create(userid,
           name,
           password,
           flavor,
           image_id,
           metadata={},
           personality=[],
           networks=None,
           use_backend=None,
           project=None,
           volumes=None):

    utils.check_name_length(name, VirtualMachine.VIRTUAL_MACHINE_NAME_LENGTH,
                            "Server name is too long")

    # Get the image, if any, that is used for the first volume
    vol_image_id = None
    if volumes:
        vol = volumes[0]
        if vol["source_type"] in ["image", "snapshot"]:
            vol_image_id = vol["source_uuid"]

    # Check conflict between server's and volume's image
    if image_id and vol_image_id and image_id != vol_image_id:
        raise faults.BadRequest("The specified server's image is different"
                                " from the the source of the first volume.")
    elif vol_image_id and not image_id:
        image_id = vol_image_id
    elif not image_id:
        raise faults.BadRequest("You need to specify either an image or a"
                                " block device mapping.")

    if len(metadata) > settings.CYCLADES_VM_MAX_METADATA:
        raise faults.BadRequest("Virtual Machines cannot have more than %s "
                                "metadata items" %
                                settings.CYCLADES_VM_MAX_METADATA)
    # Get image info
    image = util.get_image_dict(image_id, userid)

    if not volumes:
        # If no volumes are specified, we automatically create a volume with
        # the size of the flavor and filled with the specified image.
        volumes = [{
            "source_type": "image",
            "source_uuid": image_id,
            "size": flavor.disk,
            "delete_on_termination": True
        }]
    assert (len(volumes) > 0), "Cannot create server without volumes"

    if volumes[0]["source_type"] == "blank":
        raise faults.BadRequest("Root volume cannot be blank")

    try:
        is_system = (image["owner"] == settings.SYSTEM_IMAGES_OWNER)
        img, created = Image.objects.get_or_create(uuid=image["id"],
                                                   version=image["version"])
        if created:
            img.owner = image["owner"]
            img.name = image["name"]
            img.location = image["location"]
            img.mapfile = image["mapfile"]
            img.is_public = image["is_public"]
            img.is_snapshot = image["is_snapshot"]
            img.is_system = is_system
            img.os = image["metadata"].get("OS", "unknown")
            img.osfamily = image["metadata"].get("OSFAMILY", "unknown")
            img.save()
    except Exception as e:
        # Image info is not critical. Continue if it fails for any reason
        log.warning("Failed to store image info: %s", e)

    if use_backend is None:
        # Allocate server to a Ganeti backend
        use_backend = allocate_new_server(userid, flavor)

    # Create the ports for the server
    ports = create_instance_ports(userid, networks)

    if project is None:
        project = userid

    # We must save the VM instance now, so that it gets a valid
    # vm.backend_vm_id.
    vm = VirtualMachine.objects.create(name=name,
                                       backend=use_backend,
                                       userid=userid,
                                       project=project,
                                       imageid=image["id"],
                                       image_version=image["version"],
                                       flavor=flavor,
                                       operstate="BUILD")
    log.info("Created entry in DB for VM '%s'", vm)

    # Associate the ports with the server
    for index, port in enumerate(ports):
        associate_port_with_machine(port, vm)
        port.index = index
        port.save()

    # Create instance volumes
    server_vtype = flavor.volume_type
    server_volumes = []
    for index, vol_info in enumerate(volumes):
        if vol_info["source_type"] == "volume":
            uuid = vol_info["source_uuid"]
            v = get_volume(userid,
                           uuid,
                           for_update=True,
                           non_deleted=True,
                           exception=faults.BadRequest)
            if v.volume_type_id != server_vtype.id:
                msg = ("Volume '%s' has type '%s' while flavor's volume type"
                       " is '%s'" % (v.id, v.volume_type_id, server_vtype.id))
                raise faults.BadRequest(msg)
            if v.status != "AVAILABLE":
                raise faults.BadRequest("Cannot use volume while it is in %s"
                                        " status" % v.status)
            v.delete_on_termination = vol_info["delete_on_termination"]
            v.machine = vm
            v.index = index
            v.save()
        else:
            v = _create_volume(server=vm,
                               user_id=userid,
                               volume_type=server_vtype,
                               project=project,
                               index=index,
                               **vol_info)
        server_volumes.append(v)

    # Create instance metadata
    for key, val in metadata.items():
        utils.check_name_length(key, VirtualMachineMetadata.KEY_LENGTH,
                                "Metadata key is too long")
        utils.check_name_length(val, VirtualMachineMetadata.VALUE_LENGTH,
                                "Metadata value is too long")
        VirtualMachineMetadata.objects.create(meta_key=key,
                                              meta_value=val,
                                              vm=vm)

    # Create the server in Ganeti.
    vm = create_server(vm, ports, server_volumes, flavor, image, personality,
                       password)

    return vm
Beispiel #9
0
def create(credentials,
           name,
           password,
           flavor,
           image_id,
           metadata={},
           personality=[],
           networks=None,
           use_backend=None,
           project=None,
           volumes=None,
           helper=False,
           user_data="",
           shared_to_project=False,
           key_names=None):

    userid = credentials.userid
    utils.check_name_length(name, VirtualMachine.VIRTUAL_MACHINE_NAME_LENGTH,
                            "Server name is too long")

    # Get the image, if any, that is used for the first volume
    vol_image_id = None
    if volumes:
        vol = volumes[0]
        if vol["source_type"] in ["image", "snapshot"]:
            vol_image_id = vol["source_uuid"]

    # Check conflict between server's and volume's image
    if image_id and vol_image_id and image_id != vol_image_id:
        raise faults.BadRequest("The specified server's image is different"
                                " from the the source of the first volume.")
    elif vol_image_id and not image_id:
        image_id = vol_image_id
    elif not image_id:
        raise faults.BadRequest("You need to specify either an image or a"
                                " block device mapping.")

    if len(metadata) > settings.CYCLADES_VM_MAX_METADATA:
        raise faults.BadRequest("Virtual Machines cannot have more than %s "
                                "metadata items" %
                                settings.CYCLADES_VM_MAX_METADATA)
    # Get image info
    image = util.get_image_dict(image_id, userid)

    if not volumes:
        # If no volumes are specified, we automatically create a volume with
        # the size of the flavor and filled with the specified image.
        volumes = [{
            "source_type": "image",
            "source_uuid": image_id,
            "size": flavor.disk,
            "delete_on_termination": True
        }]
    assert (len(volumes) > 0), "Cannot create server without volumes"

    if volumes[0]["source_type"] == "blank":
        raise faults.BadRequest("Root volume cannot be blank")

    try:
        is_system = (image["owner"] == settings.SYSTEM_IMAGES_OWNER)
        img, created = Image.objects.get_or_create(uuid=image["id"],
                                                   version=image["version"])
        if created:
            img.owner = image["owner"]
            img.name = image["name"]
            img.location = image["location"]
            img.mapfile = image["mapfile"]
            img.is_public = image["is_public"]
            img.is_snapshot = image["is_snapshot"]
            img.is_system = is_system
            img.os = image["metadata"].get("OS", "unknown")
            img.osfamily = image["metadata"].get("OSFAMILY", "unknown")
            img.save()

    except Exception as e:
        # Image info is not critical. Continue if it fails for any reason
        log.warning("Failed to store image info: %s", e)

    if project is None:
        project = userid

    if use_backend is None:
        # Allocate server to a Ganeti backend
        use_backend = allocate_new_server(userid, project, flavor)

    if key_names is None:
        key_names = []

    auth_keys = '\n'.join(
        [util.get_keypair(key_name, userid).content for key_name in key_names])

    vm_id, port_ids, volume_ids, origin_sizes = _db_create_server(
        credentials, name, flavor, image, metadata, networks, use_backend,
        project, volumes, helper, shared_to_project, key_names)

    return _create_server(vm_id, port_ids, volume_ids, flavor, image,
                          personality, user_data, password, auth_keys,
                          origin_sizes)
Beispiel #10
0
def create(userid, name, password, flavor, image_id, metadata={},
           personality=[], networks=None, use_backend=None, project=None,
           volumes=None, helper=False, user_projects=None,
           shared_to_project=False):

    utils.check_name_length(name, VirtualMachine.VIRTUAL_MACHINE_NAME_LENGTH,
                            "Server name is too long")

    # Get the image, if any, that is used for the first volume
    vol_image_id = None
    if volumes:
        vol = volumes[0]
        if vol["source_type"] in ["image", "snapshot"]:
            vol_image_id = vol["source_uuid"]

    # Check conflict between server's and volume's image
    if image_id and vol_image_id and image_id != vol_image_id:
        raise faults.BadRequest("The specified server's image is different"
                                " from the the source of the first volume.")
    elif vol_image_id and not image_id:
        image_id = vol_image_id
    elif not image_id:
        raise faults.BadRequest("You need to specify either an image or a"
                                " block device mapping.")

    if len(metadata) > settings.CYCLADES_VM_MAX_METADATA:
        raise faults.BadRequest("Virtual Machines cannot have more than %s "
                                "metadata items" %
                                settings.CYCLADES_VM_MAX_METADATA)
    # Get image info
    image = util.get_image_dict(image_id, userid)

    if not volumes:
        # If no volumes are specified, we automatically create a volume with
        # the size of the flavor and filled with the specified image.
        volumes = [{"source_type": "image",
                    "source_uuid": image_id,
                    "size": flavor.disk,
                    "delete_on_termination": True}]
    assert(len(volumes) > 0), "Cannot create server without volumes"

    if volumes[0]["source_type"] == "blank":
        raise faults.BadRequest("Root volume cannot be blank")

    try:
        is_system = (image["owner"] == settings.SYSTEM_IMAGES_OWNER)
        img, created = Image.objects.get_or_create(uuid=image["id"],
                                                   version=image["version"])
        if created:
            img.owner = image["owner"]
            img.name = image["name"]
            img.location = image["location"]
            img.mapfile = image["mapfile"]
            img.is_public = image["is_public"]
            img.is_snapshot = image["is_snapshot"]
            img.is_system = is_system
            img.os = image["metadata"].get("OS", "unknown")
            img.osfamily = image["metadata"].get("OSFAMILY", "unknown")
            img.save()
    except Exception as e:
        # Image info is not critical. Continue if it fails for any reason
        log.warning("Failed to store image info: %s", e)

    if use_backend is None:
        # Allocate server to a Ganeti backend
        use_backend = allocate_new_server(userid, flavor)

    # Create the ports for the server
    ports = create_instance_ports(userid, user_projects, networks)

    if project is None:
        project = userid

    # We must save the VM instance now, so that it gets a valid
    # vm.backend_vm_id.
    vm = VirtualMachine.objects.create(name=name,
                                       backend=use_backend,
                                       userid=userid,
                                       project=project,
                                       shared_to_project=shared_to_project,
                                       imageid=image["id"],
                                       image_version=image["version"],
                                       flavor=flavor,
                                       operstate="BUILD",
                                       helper=helper)
    log.info("Created entry in DB for VM '%s'", vm)

    # Associate the ports with the server
    for index, port in enumerate(ports):
        associate_port_with_machine(port, vm)
        port.index = index
        port.save()

    # Create instance volumes
    server_vtype = flavor.volume_type
    server_volumes = []
    for index, vol_info in enumerate(volumes):
        if vol_info["source_type"] == "volume":
            uuid = vol_info["source_uuid"]
            v = get_volume(userid, user_projects, uuid, for_update=True,
                           non_deleted=True, exception=faults.BadRequest)
            if v.volume_type_id != server_vtype.id:
                msg = ("Volume '%s' has type '%s' while flavor's volume type"
                       " is '%s'" % (v.id, v.volume_type_id, server_vtype.id))
                raise faults.BadRequest(msg)
            if v.status != "AVAILABLE":
                raise faults.BadRequest("Cannot use volume while it is in %s"
                                        " status" % v.status)
            v.delete_on_termination = vol_info["delete_on_termination"]
        else:
            v = _create_volume(user_id=userid, volume_type=server_vtype,
                               project=project, index=index,
                               shared_to_project=shared_to_project,
                               **vol_info)
        assign_volume_to_server(vm, v, index=index)
        server_volumes.append(v)

    # Create instance metadata
    for key, val in metadata.items():
        utils.check_name_length(key, VirtualMachineMetadata.KEY_LENGTH,
                                "Metadata key is too long")
        utils.check_name_length(val, VirtualMachineMetadata.VALUE_LENGTH,
                                "Metadata value is too long")
        VirtualMachineMetadata.objects.create(
            meta_key=key,
            meta_value=val,
            vm=vm)

    # Create the server in Ganeti.
    vm = create_server(vm, ports, server_volumes, flavor, image, personality,
                       password)

    return vm
Beispiel #11
0
def create(credentials, name, password, flavor, image_id, metadata={},
           personality=[], networks=None, use_backend=None, project=None,
           volumes=None, helper=False, user_data="",
           shared_to_project=False, key_names=None):

    userid = credentials.userid
    utils.check_name_length(name, VirtualMachine.VIRTUAL_MACHINE_NAME_LENGTH,
                            "Server name is too long")

    # Get the image, if any, that is used for the first volume
    vol_image_id = None
    if volumes:
        vol = volumes[0]
        if vol["source_type"] in ["image", "snapshot"]:
            vol_image_id = vol["source_uuid"]

    # Check conflict between server's and volume's image
    if image_id and vol_image_id and image_id != vol_image_id:
        raise faults.BadRequest("The specified server's image is different"
                                " from the the source of the first volume.")
    elif vol_image_id and not image_id:
        image_id = vol_image_id
    elif not image_id:
        raise faults.BadRequest("You need to specify either an image or a"
                                " block device mapping.")

    if len(metadata) > settings.CYCLADES_VM_MAX_METADATA:
        raise faults.BadRequest("Virtual Machines cannot have more than %s "
                                "metadata items" %
                                settings.CYCLADES_VM_MAX_METADATA)
    # Get image info
    image = util.get_image_dict(image_id, userid)

    if not volumes:
        # If no volumes are specified, we automatically create a volume with
        # the size of the flavor and filled with the specified image.
        volumes = [{"source_type": "image",
                    "source_uuid": image_id,
                    "size": flavor.disk,
                    "delete_on_termination": True}]
    assert(len(volumes) > 0), "Cannot create server without volumes"

    if volumes[0]["source_type"] == "blank":
        raise faults.BadRequest("Root volume cannot be blank")

    try:
        is_system = (image["owner"] == settings.SYSTEM_IMAGES_OWNER)
        img, created = Image.objects.get_or_create(uuid=image["id"],
                                                   version=image["version"])
        if created:
            img.owner = image["owner"]
            img.name = image["name"]
            img.location = image["location"]
            img.mapfile = image["mapfile"]
            img.is_public = image["is_public"]
            img.is_snapshot = image["is_snapshot"]
            img.is_system = is_system
            img.os = image["metadata"].get("OS", "unknown")
            img.osfamily = image["metadata"].get("OSFAMILY", "unknown")
            img.save()

    except Exception as e:
        # Image info is not critical. Continue if it fails for any reason
        log.warning("Failed to store image info: %s", e)

    if project is None:
        project = userid

    if use_backend is None:
        # Allocate server to a Ganeti backend
        use_backend = allocate_new_server(userid, project, flavor)

    if key_names is None:
        key_names = []

    auth_keys = '\n'.join([
        util.get_keypair(key_name, userid).content for key_name in key_names
    ])


    vm_id, port_ids, volume_ids, origin_sizes = _db_create_server(
        credentials, name, flavor, image, metadata, networks, use_backend,
        project, volumes, helper, shared_to_project,
        key_names)

    return _create_server(vm_id, port_ids, volume_ids, flavor, image,
                          personality, user_data, password, auth_keys,
                          origin_sizes)