Exemplo n.º 1
0
    def _DetermineImageFromArgs(self, args):
        """Gets the image to use for the build, given the user args.

    Args:
      args: argsparse object from the DeployGKE command.

    Returns:
      Full image string representation.
    """
        if args.tag:
            if (properties.VALUES.builds.check_tag.GetBool()
                    and 'gcr.io/' not in args.tag):
                raise c_exceptions.InvalidArgumentException(
                    '--tag',
                    'Tag value must be in the gcr.io/* or *.gcr.io/* namespace.'
                )
            return args.tag

        elif args.image:
            if (properties.VALUES.builds.check_tag.GetBool()
                    and 'gcr.io/' not in args.image):
                raise c_exceptions.InvalidArgumentException(
                    '--image',
                    'Image value must be in the gcr.io/* or *.gcr.io/* namespace.'
                )
            return args.image

        else:  # Default tag
            if args.app_name:
                default_name = args.app_name
            elif os.path.isdir(
                    args.source):  # I.e., the source is not a tarball
                default_name = os.path.basename(os.path.abspath(args.source))
            else:
                raise c_exceptions.OneOfArgumentsRequiredException(
                    ['--app-name', '--tag'],
                    'Cannot resolve default container image. Provide an app name with '
                    '--app-name to use as the container image, or provide a full '
                    'tag using --tag.')

            if args.app_version:
                default_tag = args.app_version
            elif git.IsGithubRepository(
                    args.source) and not git.HasPendingChanges(args.source):
                default_tag = git.GetGitHeadRevision(args.source)
                if not default_tag:
                    raise c_exceptions.OneOfArgumentsRequiredException(
                        ['--app-version', '--tag'],
                        'Cannot resolve default container tag using the Git commit SHA. '
                        'Provide an app version with --app-version to use as the '
                        'container tag, or provide a full tag using --tag.')
            else:
                raise c_exceptions.OneOfArgumentsRequiredException(
                    ['--app-version', '--tag'],
                    'Cannot resolve default container tag. '
                    'Provide an app version with --app-version to use as the '
                    'container tag, or provide a full tag using --tag.')

            return 'gcr.io/$PROJECT_ID/{name}:{tag}'.format(name=default_name,
                                                            tag=default_tag)
Exemplo n.º 2
0
  def _DetermineImageFromArgs(self, args):
    """Gets the image to use for the build, given the user args.

    Args:
      args: argsparse object from the DeployGKE command.

    Returns:
      Full image string representation.
    """
    if args.tag_default:
      if args.app_name:
        default_name = args.app_name
      elif os.path.isdir(args.source):
        default_name = os.path.basename(os.path.abspath(args.source))
      else:
        raise c_exceptions.InvalidArgumentException(
            '--tag-default',
            'No default container image name available. Provide an '
            'app name with --app-name, or provide a valid --tag.')

      if args.app_version:
        default_tag = args.app_version
      elif git.IsGithubRepository(
          args.source) and not git.HasPendingChanges(args.source):
        default_tag = git.GetGitHeadRevision(args.source)
        if not default_tag:
          raise c_exceptions.InvalidArgumentException(
              '--tag-default',
              'No default tag available, no commit sha at HEAD of source '
              'repository available for tag. Provide an app version '
              'with --app-version, or provide a valid --tag.')
      else:
        raise c_exceptions.InvalidArgumentException(
            '--tag-default',
            'No default container image tag available. Provide an app '
            'version with --app-version, or provide a valid --tag.')

      return 'gcr.io/$PROJECT_ID/{name}:{tag}'.format(
          name=default_name, tag=default_tag)

    if args.tag:
      if (properties.VALUES.builds.check_tag.GetBool() and
          'gcr.io/' not in args.tag):
        raise c_exceptions.InvalidArgumentException(
            '--tag',
            'Tag value must be in the gcr.io/* or *.gcr.io/* namespace.')
      return args.tag

    if args.image:
      if (properties.VALUES.builds.check_tag.GetBool() and
          'gcr.io/' not in args.image):
        raise c_exceptions.InvalidArgumentException(
            '--image',
            'Image value must be in the gcr.io/* or *.gcr.io/* namespace.')
      return args.image
Exemplo n.º 3
0
    def Run(self, args):
        """This is what gets called when the user runs this command.

    Args:
      args: an argparse namespace. All the arguments that were provided to this
        command invocation.

    Returns:
      Some value that we want to have printed later.

    Raises:
      FailedDeployException: If the build is completed and not 'SUCCESS'.
    """

        if not args.source and not args.no_source:
            raise c_exceptions.InvalidArgumentException(
                '--no-source', 'To omit source, use the --no-source flag.')

        if args.no_source:
            if args.tag:
                raise c_exceptions.RequiredArgumentException(
                    'SOURCE', 'Source is required to build container image.')
            if args.config:
                raise c_exceptions.RequiredArgumentException(
                    'SOURCE',
                    'Source is required when specifying --config because it is a '
                    'relative path in the source directory.')

        do_build_and_push = args.image is None
        if not do_build_and_push and not args.config:
            args.no_source = True

        image = self._DetermineImageFromArgs(args)

        # Determine app_name
        if args.app_name:
            app_name = args.app_name
        else:
            app_name = self._ImageName(image)

        # Determine app_version
        app_version = None
        image_has_tag = '@' not in image and ':' in image
        if args.app_version:
            app_version = args.app_version
        elif image_has_tag:
            app_version = image.split(':')[-1]  # Set version to tag
        elif args.source:
            if git.IsGithubRepository(
                    args.source) and not git.HasPendingChanges(args.source):
                commit_sha = git.GetGitHeadRevision(args.source)
                if commit_sha:
                    app_version = commit_sha

        # Validate expose
        if args.expose and args.expose < 0:
            raise c_exceptions.InvalidArgumentException(
                '--expose', 'port number is invalid')

        # Determine gcs_staging_dir_bucket and gcs_staging_dir_object
        if args.gcs_staging_dir is None:
            gcs_staging_dir_bucket = staging_bucket_util.GetDefaultStagingBucket(
            )
            gcs_staging_dir_object = 'deploy'
        else:
            try:
                gcs_staging_dir_ref = resources.REGISTRY.Parse(
                    args.gcs_staging_dir, collection='storage.objects')
                gcs_staging_dir_object = gcs_staging_dir_ref.object
            except resources.WrongResourceCollectionException:
                gcs_staging_dir_ref = resources.REGISTRY.Parse(
                    args.gcs_staging_dir, collection='storage.buckets')
                gcs_staging_dir_object = None
            gcs_staging_dir_bucket = gcs_staging_dir_ref.bucket

        gcs_client = storage_api.StorageClient()
        try:
            gcs_client.CreateBucketIfNotExists(
                gcs_staging_dir_bucket,
                check_ownership=args.gcs_staging_dir is None)
        except storage_api.BucketInWrongProjectError:
            # If we're using the default bucket but it already exists in a different
            # project, then it could belong to a malicious attacker (b/33046325).
            raise c_exceptions.RequiredArgumentException(
                '--gcs-staging-dir',
                'A bucket with name {} already exists and is owned by '
                'another project. Specify a bucket using '
                '--gcs-staging-dir.'.format(gcs_staging_dir_bucket))

        if gcs_staging_dir_object:
            gcs_config_staging_path = '{}/{}/config'.format(
                gcs_staging_dir_bucket, gcs_staging_dir_object)
        else:
            gcs_config_staging_path = gcs_staging_dir_bucket

        if not args.no_source:
            staged_source = self._StageSource(args.source,
                                              gcs_staging_dir_bucket,
                                              gcs_staging_dir_object)
        else:
            staged_source = None

        messages = cloudbuild_util.GetMessagesModule()
        build_config = build_util.CreateBuild(
            messages,
            build_timeout=properties.VALUES.builds.timeout.Get(),
            build_and_push=do_build_and_push,
            staged_source=staged_source,
            image=image,
            dockerfile_path='Dockerfile',
            app_name=app_name,
            app_version=app_version,
            config_path=args.config,
            namespace=args.namespace,
            expose_port=args.expose,
            gcs_config_staging_path=gcs_config_staging_path,
            cluster=args.cluster,
            location=args.location,
            build_tags=([] if not args.app_name else [args.app_name]))

        client = cloudbuild_util.GetClientInstance()
        self._SubmitBuild(client, messages, build_config,
                          gcs_config_staging_path, args.config is None,
                          args.async_)