Beispiel #1
0
  def Run(self, args):
    super(Scp, self).Run(args)

    file_specs = []

    # Parses the positional arguments.
    for arg in args.sources + [args.destination]:
      if ssh_utils.IsScpLocalPath(arg):
        file_specs.append(LocalFile(arg))
      else:
        user_host, file_path = arg.split(':', 1)
        user_host_parts = user_host.split('@', 1)
        if len(user_host_parts) == 1:
          user = ssh_utils.GetDefaultSshUsername(warn_on_account_user=True)
          instance = user_host_parts[0]
        else:
          user, instance = user_host_parts
        file_specs.append(RemoteFile(user, instance, file_path))

    logging.debug('Normalized arguments: %s', file_specs)

    # Validates the positional arguments.
    # TODO(b/21515495): Look into relaxing these conditions.
    sources = file_specs[:-1]
    destination = file_specs[-1]
    if isinstance(destination, LocalFile):
      for source in sources:
        if isinstance(source, LocalFile):
          raise exceptions.ToolException(
              'All sources must be remote files when the destination '
              'is local.')

    else:  # RemoteFile
      for source in sources:
        if isinstance(source, RemoteFile):
          raise exceptions.ToolException(
              'All sources must be local files when the destination '
              'is remote.')

    instances = set()
    for file_spec in file_specs:
      if isinstance(file_spec, RemoteFile):
        instances.add(file_spec.instance_name)

    if len(instances) > 1:
      raise exceptions.ToolException(
          'Copies must involve exactly one virtual machine instance; '
          'your invocation refers to [{0}] instances: [{1}].'.format(
              len(instances), ', '.join(sorted(instances))))

    instance_ref = self.CreateZonalReference(instances.pop(), args.zone)
    instance = self.GetInstance(instance_ref)
    external_ip_address = ssh_utils.GetExternalIPAddress(instance)

    # Builds the scp command.
    scp_args = [self.scp_executable]
    if not args.plain:
      scp_args.extend(self.GetDefaultFlags())

    # apply args
    if args.quiet:
      scp_args.append('-q')
    if args.port:
      scp_args.extend(['-P', args.port])
    if args.recurse:
      scp_args.append('-r')
    if args.compress:
      scp_args.append('-C')
    if args.scp_flag:
      scp_args.extend(args.scp_flag)

    for file_spec in file_specs:
      if isinstance(file_spec, LocalFile):
        scp_args.append(file_spec.file_path)

      else:
        scp_args.append('{0}:{1}'.format(
            ssh_utils.UserHost(file_spec.user, external_ip_address),
            file_spec.file_path))

    self.ActuallyRun(args, scp_args, user, instance)
Beispiel #2
0
    def Run(self, args):
        super(CopyFiles, self).Run(args)

        file_specs = []

        # Parses the positional arguments.
        for arg in args.sources + [args.destination]:
            if ssh_utils.IsScpLocalPath(arg):
                file_specs.append(LocalFile(arg))
            else:
                user_host, file_path = arg.split(':', 1)
                user_host_parts = user_host.split('@', 1)
                if len(user_host_parts) == 1:
                    user = ssh_utils.GetDefaultSshUsername(
                        warn_on_account_user=True)
                    source_instance = user_host_parts[0]
                else:
                    user, source_instance = user_host_parts
                file_specs.append(RemoteFile(user, source_instance, file_path))

        log.debug('Normalized arguments: %s', file_specs)

        # Validates the positional arguments.
        # TODO(user): Look into relaxing these conditions.
        sources = file_specs[:-1]
        destination = file_specs[-1]
        if isinstance(destination, LocalFile):
            for source in sources:
                if isinstance(source, LocalFile):
                    raise exceptions.ToolException(
                        'All sources must be remote files when the destination '
                        'is local.')

        else:  # RemoteFile
            for source in sources:
                if isinstance(source, RemoteFile):
                    raise exceptions.ToolException(
                        'All sources must be local files when the destination '
                        'is remote.')

        destination_instances = set()
        for file_spec in file_specs:
            if isinstance(file_spec, RemoteFile):
                destination_instances.add(file_spec.instance_name)

        if len(destination_instances) > 1:
            raise exceptions.ToolException(
                'Copies must involve exactly one virtual machine instance; '
                'your invocation refers to [{0}] instances: [{1}].'.format(
                    len(destination_instances),
                    ', '.join(sorted(destination_instances))))

        source_instance_ref = instance_flags.SSH_INSTANCE_RESOLVER.ResolveResources(
            [source_instance],
            flags.ScopeEnum.ZONE,
            args.zone,
            self.resources,
            scope_lister=flags.GetDefaultScopeLister(self.compute_client,
                                                     self.project))[0]
        source_instance = self.GetInstance(source_instance_ref)
        external_ip_address = ssh_utils.GetExternalIPAddress(source_instance)

        # Builds the scp command.
        scp_args = [self.scp_executable]
        if not args.plain:
            scp_args.extend(self.GetDefaultFlags())
            scp_args.extend(self.GetHostKeyArgs(args, source_instance))
            scp_args.append('-r')

        for file_spec in file_specs:
            if isinstance(file_spec, LocalFile):
                scp_args.append(file_spec.file_path)

            else:
                scp_args.append('{0}:{1}'.format(
                    ssh_utils.UserHost(file_spec.user, external_ip_address),
                    file_spec.file_path))

        self.ActuallyRun(args, scp_args, user, source_instance,
                         source_instance_ref.project)