예제 #1
0
 def create(self, request, *args, **kwargs):
     serializer = self.get_serializer(data=request.data)
     serializer.is_valid(raise_exception=True)
     if not validate_cloud_objects_limit():
         raise APIBadRequest(_('Licence cloud objects limit reached. Please check your license.'))
     try:
         os_image_api = Images(api_session=self.os_admin_api.session)
         image = os_image_api.create(owner=self.os_admin_api.project_id, **serializer.validated_data)
     except Exception as e:
         LOG.error(e)
         handle(self.request, message='Unable to create the image')
     else:
         headers = self.get_success_headers(serializer.data)
         data = serializer.data
         data['id'] = image.id
         reseller_resources = user_reseller_resources(self.request.user)
         if reseller_resources:
             Image.objects.update_or_create(
                 defaults={
                     'reseller_resources': reseller_resources,
                     'min_disk': serializer.validated_data.get('min_disk', 0),
                     'min_ram': serializer.validated_data.get('min_ram', 0),
                     'region': serializer.validated_data.get('region')
                 },
                 id=image.id,
             )
         return Response(data, status=status.HTTP_201_CREATED, headers=headers)
예제 #2
0
def create_instance_from_iso_task(volume_id,
                                  project_id,
                                  project_domain_id,
                                  region_name,
                                  name,
                                  image,
                                  flavor,
                                  nics,
                                  block_device_mapping_v2,
                                  block_device_mapping,
                                  user_data,
                                  admin_pass=None,
                                  key_name=None,
                                  key_content=None,
                                  **create_args):
    boot_image_id = image
    identity_admin_api = IdentityAdminApi()

    # wait for image
    if not wait_for(
            lambda: Image.objects.filter(id=boot_image_id).first().status ==
            OpenStackImageStatus.ACTIVE, 600):
        raise InstanceTaskException(_('Upload image failed '))
    region = OpenstackRegion.objects.get(id=region_name)
    boot_image_model = Image.objects.get(id=boot_image_id)
    unique_name = '{}'.format(uuid4())
    os_image_api = Images(api_session=identity_admin_api.session)

    # copy properties starting with hw_ to new image
    extra_properties = {}
    prefixes = getattr(settings, 'OPENSTACK_CREATE_FROM_ISO_PROPERTY_PREFIXES',
                       [])
    for property_name in boot_image_model.properties:  # type: str
        for prefix in prefixes:
            if property_name.startswith(prefix):
                extra_properties[property_name] = boot_image_model.properties[
                    property_name]

    owner = project_id if project_id else identity_admin_api.project_id
    disk_format = getattr(settings, 'OPENSTACK_CREATE_FROM_ISO_IMAGE_TYPE',
                          'raw')

    try:
        new_image = os_image_api.create(
            owner=owner,
            name=unique_name,
            min_disk=1,
            min_ram=1,
            container_format='bare',
            disk_format=disk_format,
            visibility='community',
            protected=False,
            architecture=boot_image_model.architecture,
            os_distro=boot_image_model.os_distro,
            os_version=boot_image_model.os_version,
            region=region,
            hypervisor_type=boot_image_model.hypervisor_type,
            file=None,
            url=None,
            source=None,
            properties=extra_properties,
        )
    except Exception as e:
        del e  # unused
        LOG.exception(
            'Create instance failed. (owner: {}, disk_format: {}, extra_properties: {}'
            .format(owner, disk_format, extra_properties))
        return None
    else:
        try:
            if disk_format == 'qcow2':
                upload_empty_qcow2_image(new_image.id,
                                         region_name=region_name,
                                         disk_size_in_bytes=1)
            else:
                upload_zero_filled_image(new_image.id,
                                         region_name=region_name,
                                         length_in_bytes=1)
        except Exception as e:
            LOG.exception(
                'Failed to create temporary image when booting from iso: {}'.
                format(e))
            try:
                db_image = Image.objects.get(id=new_image.id)
                os_image_api.get(image=db_image).delete()
            except Exception as e:
                LOG.exception('Failed to delete image: {}'.format(e))
            return None

        instance_id = create_instance_task(
            volume_id=volume_id,
            project_id=project_id,
            project_domain_id=project_domain_id,
            region_name=region_name,
            name=name,
            image=new_image.id,
            flavor=flavor,
            admin_pass=admin_pass,
            nics=nics,
            key_name=key_name,
            key_content=key_content,
            block_device_mapping_v2=block_device_mapping_v2,
            user_data=user_data,
            block_device_mapping=block_device_mapping,
            **create_args,
        )

        activity_helper.add_current_activity_params(object_id=instance_id)

        if not wait_for(
                lambda: ModelInstance.objects.filter(id=instance_id).first(),
                max_time=300):
            raise InstanceTaskException(_('Failed to create instance'))
        if not wait_for(lambda: ModelInstance.objects.filter(id=instance_id).
                        first().status == 'active',
                        max_time=300):
            raise InstanceTaskException(_('Failed to create instance'))
        if not wait_for(lambda: not ModelInstance.objects.filter(
                id=instance_id).first().task_state,
                        max_time=300):
            raise InstanceTaskException(_('Failed to create instance'))

        try:
            db_image = Image.objects.get(id=new_image.id)
            os_image_api.get(image=db_image).delete()
        except Exception as e:
            LOG.exception('Failed to delete image: {}'.format(e))

        instance_model = ModelInstance.objects.get(id=instance_id)
        instance_model.booted_from_iso = True
        instance_model.save()
        instance_api = Instance.with_admin_session(instance=instance_model)
        instance_api.rescue(image=boot_image_id)

        signal_boot_from_iso.delay(instance_id=instance_id,
                                   is_new_instance=True)

        return instance_id