コード例 #1
0
ファイル: create.py プロジェクト: bopopescu/UCSC
    def CreateRequests(self, args):
        instances_flags.ValidateDiskFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)

        # This feature is only exposed in alpha/beta
        allow_rsa_encrypted = self.ReleaseTrack() in [
            base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
        ]
        self.csek_keys = csek_utils.CsekKeyStore.FromArgs(
            args, allow_rsa_encrypted)

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=self.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        service_accounts = instance_utils.CreateServiceAccountMessages(
            messages=self.messages,
            scopes=([] if args.no_scopes else args.scopes))

        if args.tags:
            tags = self.messages.Tags(items=args.tags)
        else:
            tags = None

        metadata = metadata_utils.ConstructMetadataMessage(
            self.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)

        # If the user already provided an initial Windows password and
        # username through metadata, then there is no need to check
        # whether the image or the boot disk is Windows.

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
            args,
            self.resources,
            scope_lister=flags.GetDefaultScopeLister(self.compute_client,
                                                     self.project))

        # Check if the zone is deprecated or has maintenance coming.
        self.WarnForZonalCreation(instance_refs)

        network_interface_arg = getattr(args, 'network_interface', None)
        if network_interface_arg:
            network_interfaces = instance_utils.CreateNetworkInterfaceMessages(
                resources=self.resources,
                compute_client=self.compute_client,
                network_interface_arg=network_interface_arg,
                instance_refs=instance_refs)
        else:
            network_interfaces = [
                instance_utils.CreateNetworkInterfaceMessage(
                    resources=self.resources,
                    compute_client=self.compute_client,
                    network=args.network,
                    subnet=args.subnet,
                    private_network_ip=args.private_network_ip,
                    no_address=args.no_address,
                    address=args.address,
                    instance_refs=instance_refs)
            ]

        machine_type_uris = instance_utils.CreateMachineTypeUris(
            resources=self.resources,
            compute_client=self.compute_client,
            project=self.project,
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            instance_refs=instance_refs)

        create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk
                                                                  or [])
        if create_boot_disk:
            image_uri, _ = self.ExpandImageFlag(
                image=args.image,
                image_family=args.image_family,
                image_project=args.image_project,
                return_image_resource=False)
        else:
            image_uri = None

        # A list of lists where the element at index i contains a list of
        # disk messages that should be set for the instance at index i.
        disks_messages = []

        # A mapping of zone to boot disk references for all existing boot
        # disks that are being attached.
        # TODO(user): Simplify this once resources.Resource becomes
        # hashable.
        existing_boot_disks = {}

        for instance_ref in instance_refs:
            persistent_disks, boot_disk_ref = (
                instance_utils.CreatePersistentAttachedDiskMessages(
                    self.resources, self.compute_client, self.csek_keys,
                    args.disk or [], instance_ref))
            persistent_create_disks = (
                instance_utils.CreatePersistentCreateDiskMessages(
                    self, self.compute_client, self.resources, self.csek_keys,
                    getattr(args, 'create_disk', []), instance_ref))
            local_ssds = []
            for x in args.local_ssd or []:
                local_ssds.append(
                    instance_utils.CreateLocalSsdMessage(
                        self.resources, self.messages, x.get('device-name'),
                        x.get('interface'), instance_ref.zone))

            if create_boot_disk:
                boot_disk = instance_utils.CreateDefaultBootAttachedDiskMessage(
                    self.compute_client,
                    self.resources,
                    disk_type=args.boot_disk_type,
                    disk_device_name=args.boot_disk_device_name,
                    disk_auto_delete=args.boot_disk_auto_delete,
                    disk_size_gb=boot_disk_size_gb,
                    require_csek_key_create=(args.require_csek_key_create
                                             if self.csek_keys else None),
                    image_uri=image_uri,
                    instance_ref=instance_ref,
                    csek_keys=self.csek_keys)
                persistent_disks = [boot_disk] + persistent_disks
            else:
                existing_boot_disks[boot_disk_ref.zone] = boot_disk_ref
            disks_messages.append(persistent_disks + persistent_create_disks +
                                  local_ssds)

        requests = []
        for instance_ref, machine_type_uri, disks in zip(
                instance_refs, machine_type_uris, disks_messages):
            requests.append(
                self.messages.ComputeInstancesInsertRequest(
                    instance=self.messages.Instance(
                        canIpForward=args.can_ip_forward,
                        disks=disks,
                        description=args.description,
                        machineType=machine_type_uri,
                        metadata=metadata,
                        name=instance_ref.Name(),
                        networkInterfaces=network_interfaces,
                        serviceAccounts=service_accounts,
                        scheduling=scheduling,
                        tags=tags,
                    ),
                    project=self.project,
                    zone=instance_ref.zone))

        return requests
コード例 #2
0
    def Run(self, args):
        instances_flags.ValidateDiskFlags(args,
                                          enable_kms=self._support_kms,
                                          enable_snapshots=True)
        instances_flags.ValidateImageFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)
        instances_flags.ValidateNetworkTierArgs(args)

        if self._support_reservation:
            instances_flags.ValidateReservationAffinityGroup(args)

        holder = base_classes.ComputeApiHolder(self.ReleaseTrack())
        compute_client = holder.client
        resource_parser = holder.resources

        instance_refs = instance_utils.GetInstanceRefs(args, compute_client,
                                                       holder)

        requests = self._CreateRequests(args, instance_refs, compute_client,
                                        resource_parser, holder)

        if not args. async:
            # TODO(b/63664449): Replace this with poller + progress tracker.
            try:
                # Using legacy MakeRequests (which also does polling) here until
                # replaced by api_lib.utils.waiter.
                return compute_client.MakeRequests(requests)
            except exceptions.ToolException as e:
                invalid_machine_type_message_regex = (
                    r'Invalid value for field \'resource.machineType\': .+. '
                    r'Machine type with name \'.+\' does not exist in zone \'.+\'\.'
                )
                if re.search(invalid_machine_type_message_regex,
                             six.text_type(e)):
                    raise exceptions.ToolException(
                        six.text_type(e) +
                        '\nUse `gcloud compute machine-types list --zones` to see the '
                        'available machine  types.')
                raise

        errors_to_collect = []
        responses = compute_client.BatchRequests(requests, errors_to_collect)
        for r in responses:
            err = getattr(r, 'error', None)
            if err:
                errors_to_collect.append(poller.OperationErrors(err.errors))
        if errors_to_collect:
            raise core_exceptions.MultiError(errors_to_collect)

        operation_refs = [
            holder.resources.Parse(r.selfLink) for r in responses
        ]

        for instance_ref, operation_ref in zip(instance_refs, operation_refs):
            log.status.Print(
                'Instance creation in progress for [{}]: {}'.format(
                    instance_ref.instance, operation_ref.SelfLink()))
        log.status.Print(
            'Use [gcloud compute operations describe URI] command '
            'to check the status of the operation(s).')
        if not args.IsSpecified('format'):
            # For async output we need a separate format. Since we already printed in
            # the status messages information about operations there is nothing else
            # needs to be printed.
            args.format = 'disable'
        return responses
コード例 #3
0
    def _CreateRequests(self, args):
        instances_flags.ValidateDiskFlags(args)
        instances_flags.ValidateLocalSsdFlags(args)
        instances_flags.ValidateNicFlags(args)
        instances_flags.ValidateServiceAccountAndScopeArgs(args)
        instances_flags.ValidateAcceleratorArgs(args)

        # This feature is only exposed in alpha/beta
        allow_rsa_encrypted = self.ReleaseTrack() in [
            base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA
        ]
        self.csek_keys = csek_utils.CsekKeyStore.FromArgs(
            args, allow_rsa_encrypted)

        scheduling = instance_utils.CreateSchedulingMessage(
            messages=self.messages,
            maintenance_policy=args.maintenance_policy,
            preemptible=args.preemptible,
            restart_on_failure=args.restart_on_failure)

        if args.tags:
            tags = self.messages.Tags(items=args.tags)
        else:
            tags = None

        metadata = metadata_utils.ConstructMetadataMessage(
            self.messages,
            metadata=args.metadata,
            metadata_from_file=args.metadata_from_file)

        # If the user already provided an initial Windows password and
        # username through metadata, then there is no need to check
        # whether the image or the boot disk is Windows.

        boot_disk_size_gb = utils.BytesToGb(args.boot_disk_size)
        utils.WarnIfDiskSizeIsTooSmall(boot_disk_size_gb, args.boot_disk_type)

        instance_refs = instances_flags.INSTANCES_ARG.ResolveAsResource(
            args,
            self.resources,
            scope_lister=flags.GetDefaultScopeLister(self.compute_client,
                                                     self.project))

        # Check if the zone is deprecated or has maintenance coming.
        zone_resource_fetcher = zone_utils.ZoneResourceFetcher(
            self.compute_client)
        zone_resource_fetcher.WarnForZonalCreation(instance_refs)

        network_interface_arg = getattr(args, 'network_interface', None)
        if network_interface_arg:
            network_interfaces = instance_utils.CreateNetworkInterfaceMessages(
                resources=self.resources,
                compute_client=self.compute_client,
                network_interface_arg=network_interface_arg,
                instance_refs=instance_refs,
                support_network_tier=self._support_network_tier)
        else:
            if self._support_public_dns is True:
                instances_flags.ValidatePublicDnsFlags(args)

            network_tier = getattr(args, 'network_tier', None)

            network_interfaces = [
                instance_utils.CreateNetworkInterfaceMessage(
                    resources=self.resources,
                    compute_client=self.compute_client,
                    network=args.network,
                    subnet=args.subnet,
                    private_network_ip=args.private_network_ip,
                    no_address=args.no_address,
                    address=args.address,
                    instance_refs=instance_refs,
                    network_tier=network_tier,
                    no_public_dns=getattr(args, 'no_public_dns', None),
                    public_dns=getattr(args, 'public_dns', None),
                    no_public_ptr=getattr(args, 'no_public_ptr', None),
                    public_ptr=getattr(args, 'public_ptr', None),
                    no_public_ptr_domain=getattr(args, 'no_public_ptr_domain',
                                                 None),
                    public_ptr_domain=getattr(args, 'public_ptr_domain', None))
            ]

        machine_type_uris = instance_utils.CreateMachineTypeUris(
            resources=self.resources,
            compute_client=self.compute_client,
            project=self.project,
            machine_type=args.machine_type,
            custom_cpu=args.custom_cpu,
            custom_memory=args.custom_memory,
            ext=getattr(args, 'custom_extensions', None),
            instance_refs=instance_refs)

        create_boot_disk = not instance_utils.UseExistingBootDisk(args.disk
                                                                  or [])
        if create_boot_disk:
            image_expander = image_utils.ImageExpander(self.compute_client,
                                                       self.resources)
            image_uri, _ = image_expander.ExpandImageFlag(
                user_project=self.project,
                image=args.image,
                image_family=args.image_family,
                image_project=args.image_project,
                return_image_resource=False)
        else:
            image_uri = None

        # A list of lists where the element at index i contains a list of
        # disk messages that should be set for the instance at index i.
        disks_messages = []

        # A mapping of zone to boot disk references for all existing boot
        # disks that are being attached.
        # TODO(user): Simplify this once resources.Resource becomes
        # hashable.
        existing_boot_disks = {}

        for instance_ref in instance_refs:
            persistent_disks, boot_disk_ref = (
                instance_utils.CreatePersistentAttachedDiskMessages(
                    self.resources, self.compute_client, self.csek_keys,
                    args.disk or [], instance_ref))
            persistent_create_disks = (
                instance_utils.CreatePersistentCreateDiskMessages(
                    self, self.compute_client, self.resources, self.csek_keys,
                    getattr(args, 'create_disk', []), instance_ref))
            local_ssds = []
            for x in args.local_ssd or []:
                local_ssds.append(
                    instance_utils.CreateLocalSsdMessage(
                        self.resources, self.messages, x.get('device-name'),
                        x.get('interface'), instance_ref.zone))

            if create_boot_disk:
                boot_disk = instance_utils.CreateDefaultBootAttachedDiskMessage(
                    self.compute_client,
                    self.resources,
                    disk_type=args.boot_disk_type,
                    disk_device_name=args.boot_disk_device_name,
                    disk_auto_delete=args.boot_disk_auto_delete,
                    disk_size_gb=boot_disk_size_gb,
                    require_csek_key_create=(args.require_csek_key_create
                                             if self.csek_keys else None),
                    image_uri=image_uri,
                    instance_ref=instance_ref,
                    csek_keys=self.csek_keys)
                persistent_disks = [boot_disk] + persistent_disks
            else:
                existing_boot_disks[boot_disk_ref.zone] = boot_disk_ref
            disks_messages.append(persistent_disks + persistent_create_disks +
                                  local_ssds)

        accelerator_args = getattr(args, 'accelerator', None)

        project_to_sa = {}
        requests = []
        for instance_ref, machine_type_uri, disks in zip(
                instance_refs, machine_type_uris, disks_messages):
            if instance_ref.project not in project_to_sa:
                scopes = None
                if not args.no_scopes and not args.scopes:
                    # User didn't provide any input on scopes. If project has no default
                    # service account then we want to create a VM with no scopes
                    request = (self.compute.projects, 'Get',
                               self.messages.ComputeProjectsGetRequest(
                                   project=instance_ref.project))
                    errors = []
                    result = self.compute_client.MakeRequests([request],
                                                              errors)
                    if not errors:
                        if not result[0].defaultServiceAccount:
                            scopes = []
                            log.status.Print(
                                'There is no default service account for project {}. '
                                'Instance {} will not have scopes.'.format(
                                    instance_ref.project, instance_ref.Name))
                if scopes is None:
                    scopes = [] if args.no_scopes else args.scopes

                if args.no_service_account:
                    service_account = None
                else:
                    service_account = args.service_account
                service_accounts = instance_utils.CreateServiceAccountMessages(
                    messages=self.messages,
                    scopes=scopes,
                    service_account=service_account)
                project_to_sa[instance_ref.project] = service_accounts

            instance = self.messages.Instance(
                canIpForward=args.can_ip_forward,
                disks=disks,
                description=args.description,
                machineType=machine_type_uri,
                metadata=metadata,
                name=instance_ref.Name(),
                networkInterfaces=network_interfaces,
                serviceAccounts=project_to_sa[instance_ref.project],
                scheduling=scheduling,
                tags=tags)
            if getattr(args, 'min_cpu_platform', None):
                instance.minCpuPlatform = args.min_cpu_platform
            if accelerator_args:
                accelerator_type_name = accelerator_args['type']
                accelerator_type_ref = self.resources.Parse(
                    accelerator_type_name,
                    collection='compute.acceleratorTypes',
                    params={
                        'project': instance_ref.project,
                        'zone': instance_ref.zone
                    })
                # Accelerator count is default to 1.
                accelerator_count = int(accelerator_args.get('count', 1))
                accelerators = instance_utils.CreateAcceleratorConfigMessages(
                    self.compute_client.messages, accelerator_type_ref,
                    accelerator_count)
                instance.guestAccelerators = accelerators

            request = self.messages.ComputeInstancesInsertRequest(
                instance=instance,
                project=instance_ref.project,
                zone=instance_ref.zone)

            sole_tenancy_host_arg = getattr(args, 'sole_tenancy_host', None)
            if sole_tenancy_host_arg:
                sole_tenancy_host_ref = self.resources.Parse(
                    sole_tenancy_host_arg,
                    collection='compute.hosts',
                    params={'zone': instance_ref.zone})
                request.instance.host = sole_tenancy_host_ref.SelfLink()
            requests.append((self.compute.instances, 'Insert', request))
        return requests