Beispiel #1
0
def create_server(vm, nics, flavor, image, personality, password):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.
    server_created.send(sender=vm, created_vm_params={
        'img_id': image['backend_id'],
        'img_passwd': password,
        'img_format': str(image['format']),
        'img_personality': json.dumps(personality),
        'img_properties': json.dumps(image['metadata']),
    })
    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s",
             vm.userid, vm, nics, vm.backend, str(jobID))

    return jobID
Beispiel #2
0
def create_server(vm, nics, flavor, image, personality, password):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.
    server_created.send(sender=vm,
                        created_vm_params={
                            'img_id': image['backend_id'],
                            'img_passwd': password,
                            'img_format': str(image['format']),
                            'img_personality': json.dumps(personality),
                            'img_properties': json.dumps(image['metadata']),
                        })
    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s", vm.userid,
             vm, nics, vm.backend, str(jobID))

    return jobID
Beispiel #3
0
def create_server(vm, nics, volumes, flavor, image, personality, password,
                  public_key):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.

    # If the root volume has a provider, then inform snf-image to not fill
    # the volume with data
    image_id = image["pithosmap"]
    root_volume = volumes[0]
    if root_volume.volume_type.provider in settings.GANETI_CLONE_PROVIDERS:
        image_id = "null"

    created_vm_params = {
        'img_id': image_id,
        'img_passwd': password,
        'img_format': str(image['format']),
        'img_personality': json.dumps(personality),
        'img_properties': json.dumps(image['metadata']),
    }

    if public_key is not None:
        created_vm_params['auth_keys'] = public_key

    server_created.send(sender=vm, created_vm_params=created_vm_params)

    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, volumes, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")
        vm.volumes.all().update(status="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s", vm.userid,
             vm, nics, vm.backend, str(jobID))

    return jobID
Beispiel #4
0
def create_server(vm, nics, volumes, flavor, image, personality, password):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.

    # If the root volume has a provider, then inform snf-image to not fill
    # the volume with data
    image_id = image["pithosmap"]
    root_volume = volumes[0]
    if root_volume.volume_type.provider in settings.GANETI_CLONE_PROVIDERS:
        image_id = "null"

    server_created.send(sender=vm, created_vm_params={
        'img_id': image_id,
        'img_passwd': password,
        'img_format': str(image['format']),
        'img_personality': json.dumps(personality),
        'img_properties': json.dumps(image['metadata']),
    })

    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, volumes, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")
        vm.volumes.all().update(status="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s",
             vm.userid, vm, nics, vm.backend, str(jobID))

    return jobID
Beispiel #5
0
def do_create_server(userid, name, password, flavor, image, metadata={},
                     personality=[], network=None, backend=None):
    # Fix flavor for archipelago
    disk_template, provider = util.get_flavor_provider(flavor)
    if provider:
        flavor.disk_template = disk_template
        flavor.disk_provider = provider
        flavor.disk_origin = image['checksum']
        image['backend_id'] = 'null'
    else:
        flavor.disk_provider = None
        flavor.disk_origin = None

    try:
        if backend is None:
            # Allocate backend to host the server.
            backend_allocator = BackendAllocator()
            backend = backend_allocator.allocate(userid, flavor)
            if backend is None:
                log.error("No available backend for VM with flavor %s", flavor)
                raise faults.ServiceUnavailable("No available backends")

        if network is None:
            # Allocate IP from public network
            (network, address) = util.get_public_ip(backend)
        else:
            address = util.get_network_free_address(network)

        # We must save the VM instance now, so that it gets a valid
        # vm.backend_vm_id.
        vm = VirtualMachine.objects.create(
            name=name,
            backend=backend,
            userid=userid,
            imageid=image["id"],
            flavor=flavor,
            action="CREATE")

        log.info("Created entry in DB for VM '%s'", vm)

        # Create VM's public NIC. Do not wait notification form ganeti hooks to
        # create this NIC, because if the hooks never run (e.g. building error)
        # the VM's public IP address will never be released!
        nic = NetworkInterface.objects.create(machine=vm, network=network,
                                              index=0, ipv4=address,
                                              state="BUILDING")

        # Also we must create the VM metadata in the same transaction.
        for key, val in metadata.items():
            VirtualMachineMetadata.objects.create(
                meta_key=key,
                meta_value=val,
                vm=vm)
        # Issue commission to Quotaholder and accept it since at the end of
        # this transaction the VirtualMachine object will be created in the DB.
        # Note: the following call does a commit!
        quotas.issue_and_accept_commission(vm)
    except:
        transaction.rollback()
        raise
    else:
        transaction.commit()

    try:
        vm = VirtualMachine.objects.select_for_update().get(id=vm.id)
        # dispatch server created signal needed to trigger the 'vmapi', which
        # enriches the vm object with the 'config_url' attribute which must be
        # passed to the Ganeti job.
        server_created.send(sender=vm, created_vm_params={
            'img_id': image['backend_id'],
            'img_passwd': password,
            'img_format': str(image['format']),
            'img_personality': json.dumps(personality),
            'img_properties': json.dumps(image['metadata']),
        })

        jobID = create_instance(vm, nic, flavor, image)
        # At this point the job is enqueued in the Ganeti backend
        vm.backendopcode = "OP_INSTANCE_CREATE"
        vm.backendjobid = jobID
        vm.save()
        transaction.commit()
        log.info("User %s created VM %s, NIC %s, Backend %s, JobID %s",
                 userid, vm, nic, backend, str(jobID))
    except:
        # If an exception is raised, then the user will never get the VM id.
        # In order to delete it from DB and release it's resources, we
        # mock a successful OP_INSTANCE_REMOVE job.
        process_op_status(vm=vm,
                          etime=datetime.datetime.now(),
                          jobid=-0,
                          opcode="OP_INSTANCE_REMOVE",
                          status="success",
                          logmsg="Reconciled eventd: VM creation failed.")
        raise

    return vm
Beispiel #6
0
def _create_server(vm_id, port_ids, volume_ids, flavor, image, personality,
                   user_data, password, auth_keys, origin_sizes):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.

    vm = VirtualMachine.objects.select_for_update().get(id=vm_id)
    nics = NetworkInterface.objects.select_for_update().filter(id__in=port_ids)
    volumes = Volume.objects.select_for_update().filter(id__in=volume_ids)

    for v in volumes:
        v.origin_size = origin_sizes.get(v.id)

    # If the root volume has a provider, then inform snf-image to not fill
    # the volume with data
    image_id = image["pithosmap"]
    root_volume = volumes[0]
    if root_volume.volume_type.provider in settings.GANETI_CLONE_PROVIDERS:
        image_id = "null"

    created_vm_params = {
        'img_id': image_id,
        'img_passwd': password,
        'img_format': str(image['format']),
        'img_personality': json.dumps(personality),
        'img_properties': json.dumps(image['metadata']),
    }

    if auth_keys:
        created_vm_params['auth_keys'] = auth_keys

    if user_data:
        created_vm_params['cloud_userdata'] = user_data

    server_created.send(sender=vm, created_vm_params=created_vm_params)

    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, volumes, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")
        vm.volumes.all().update(status="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s", vm.userid,
             vm, nics, vm.backend, str(jobID))

    # store the new task in the VM
    if jobID is not None:
        vm.task = "BUILD"
        vm.task_job_id = jobID
    vm.save()
    return vm
Beispiel #7
0
def do_create_server(userid,
                     name,
                     password,
                     flavor,
                     image,
                     metadata={},
                     personality=[],
                     network=None,
                     backend=None):
    # Fix flavor for archipelago
    disk_template, provider = util.get_flavor_provider(flavor)
    if provider:
        flavor.disk_template = disk_template
        flavor.disk_provider = provider
        flavor.disk_origin = image['checksum']
        image['backend_id'] = 'null'
    else:
        flavor.disk_provider = None
        flavor.disk_origin = None

    try:
        if backend is None:
            # Allocate backend to host the server.
            backend_allocator = BackendAllocator()
            backend = backend_allocator.allocate(userid, flavor)
            if backend is None:
                log.error("No available backend for VM with flavor %s", flavor)
                raise faults.ServiceUnavailable("No available backends")

        if network is None:
            # Allocate IP from public network
            (network, address) = util.get_public_ip(backend)
            nic = {'ip': address, 'network': network.backend_id}
        else:
            address = util.get_network_free_address(network)

        # We must save the VM instance now, so that it gets a valid
        # vm.backend_vm_id.
        vm = VirtualMachine.objects.create(name=name,
                                           backend=backend,
                                           userid=userid,
                                           imageid=image["id"],
                                           flavor=flavor,
                                           action="CREATE")

        # Create VM's public NIC. Do not wait notification form ganeti hooks to
        # create this NIC, because if the hooks never run (e.g. building error)
        # the VM's public IP address will never be released!
        NetworkInterface.objects.create(machine=vm,
                                        network=network,
                                        index=0,
                                        ipv4=address,
                                        state="BUILDING")

        log.info("Created entry in DB for VM '%s'", vm)

        # dispatch server created signal
        server_created.send(sender=vm,
                            created_vm_params={
                                'img_id': image['backend_id'],
                                'img_passwd': password,
                                'img_format': str(image['format']),
                                'img_personality': json.dumps(personality),
                                'img_properties':
                                json.dumps(image['metadata']),
                            })

        # Also we must create the VM metadata in the same transaction.
        for key, val in metadata.items():
            VirtualMachineMetadata.objects.create(meta_key=key,
                                                  meta_value=val,
                                                  vm=vm)
        # Issue commission to Quotaholder and accept it since at the end of
        # this transaction the VirtualMachine object will be created in the DB.
        # Note: the following call does a commit!
        quotas.issue_and_accept_commission(vm)
    except:
        transaction.rollback()
        raise
    else:
        transaction.commit()

    try:
        jobID = create_instance(vm, nic, flavor, image)
        # At this point the job is enqueued in the Ganeti backend
        vm.backendjobid = jobID
        vm.save()
        transaction.commit()
        log.info("User %s created VM %s, NIC %s, Backend %s, JobID %s", userid,
                 vm, nic, backend, str(jobID))
    except GanetiApiError as e:
        log.exception("Can not communicate to backend %s: %s.", backend, e)
        # Failed while enqueuing OP_INSTANCE_CREATE to backend. Restore
        # already reserved quotas by issuing a negative commission
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Can not communicate to backend."
        vm.deleted = True
        vm.save()
        quotas.issue_and_accept_commission(vm, delete=True)
        raise
    except:
        transaction.rollback()
        raise

    return vm
Beispiel #8
0
def _create_server(vm_id, port_ids, volume_ids, flavor, image, personality,
                   user_data, password, auth_keys, origin_sizes):
    # dispatch server created signal needed to trigger the 'vmapi', which
    # enriches the vm object with the 'config_url' attribute which must be
    # passed to the Ganeti job.

    vm = VirtualMachine.objects.select_for_update().get(id=vm_id)
    nics = NetworkInterface.objects.select_for_update().filter(
        id__in=port_ids)
    volumes = Volume.objects.select_for_update().filter(
        id__in=volume_ids)

    for v in volumes:
        v.origin_size = origin_sizes.get(v.id)

    # If the root volume has a provider, then inform snf-image to not fill
    # the volume with data
    image_id = image["pithosmap"]
    root_volume = volumes[0]
    if root_volume.volume_type.provider in settings.GANETI_CLONE_PROVIDERS:
        image_id = "null"

    created_vm_params = {
        'img_id': image_id,
        'img_passwd': password,
        'img_format': str(image['format']),
        'img_personality': json.dumps(personality),
        'img_properties': json.dumps(image['metadata']),
    }

    if auth_keys:
        created_vm_params['auth_keys'] = auth_keys

    if user_data:
        created_vm_params['cloud_userdata'] = user_data

    server_created.send(sender=vm, created_vm_params=created_vm_params)

    # send job to Ganeti
    try:
        jobID = backend.create_instance(vm, nics, volumes, flavor, image)
    except:
        log.exception("Failed create instance '%s'", vm)
        jobID = None
        vm.operstate = "ERROR"
        vm.backendlogmsg = "Failed to send job to Ganeti."
        vm.save()
        vm.nics.all().update(state="ERROR")
        vm.volumes.all().update(status="ERROR")

    # At this point the job is enqueued in the Ganeti backend
    vm.backendopcode = "OP_INSTANCE_CREATE"
    vm.backendjobid = jobID
    vm.save()
    log.info("User %s created VM %s, NICs %s, Backend %s, JobID %s",
             vm.userid, vm, nics, vm.backend, str(jobID))

    # store the new task in the VM
    if jobID is not None:
        vm.task = "BUILD"
        vm.task_job_id = jobID
    vm.save()
    return vm