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")
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
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
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)
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
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)
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
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)