def ValidateImageUrl(image_url, services):
    """Check the user-provided image URL.

  Ensures that:
  - it is consistent with the services being deployed (there must be exactly
    one)
  - it is an image in a supported Docker registry

  Args:
    image_url: str, the URL of the image to deploy provided by the user
    services: list, the services to deploy

  Raises:
    MultiDeployError: if image_url is provided and more than one service is
      being deployed
    docker.UnsupportedRegistryError: if image_url is provided and does not point
      to one of the supported registries
  """
    # Validate the image url if provided, and ensure there is a single service
    # being deployed.
    if image_url is None:
        return
    if len(services) != 1:
        raise exceptions.MultiDeployError()
    for registry in constants.ALL_SUPPORTED_REGISTRIES:
        if image_url.startswith(registry):
            return
    raise docker.UnsupportedRegistryError(image_url)
Exemple #2
0
def GetDeployables(args, stager, path_matchers, appyaml=None):
    """Given a list of args, infer the deployable services and configs.

  Given a deploy command, e.g. `gcloud app deploy ./dir other/service.yaml
  cron.yaml WEB-INF/appengine-web.xml`, the deployables can be on multiple
  forms. This method pre-processes and infers yaml descriptors from the
  various formats accepted. The rules are as following:

  This function is a context manager, and should be used in conjunction with
  the `with` keyword.

  1. If `args` is an empty list, add the current directory to it.
  2. For each arg:
    - If arg refers to a config file, add it to the configs set.
    - Else match the arg against the path matchers. The first match will win.
      The match will be added to the services set. Matchers may run staging.

  Args:
    args: List[str], positional args as given on the command-line.
    stager: staging.Stager, stager that will be invoked on sources that have
        entries in the stager's registry.
    path_matchers: List[Function], list of functions on the form
        fn(path, stager) ordered by descending precedence, where fn returns
        a Service or None if no match.
    appyaml: str or None, the app.yaml location to used for deployment.

  Raises:
    FileNotFoundError: One or more argument does not point to an existing file
        or directory.
    UnknownSourceError: Could not infer a config or service from an arg.
    DuplicateConfigError: Two or more config files have the same type.
    DuplicateServiceError: Two or more services have the same service id.

  Returns:
    Tuple[List[Service], List[ConfigYamlInfo]], lists of deployable services
    and configs.
  """
    if not args:
        args = ['.']
    paths = [os.path.abspath(arg) for arg in args]
    configs = Configs()
    services = Services()
    if appyaml:
        if len(paths) > 1:
            raise exceptions.MultiDeployError()
        if not os.path.exists(os.path.abspath(appyaml)):
            raise exceptions.FileNotFoundError(
                'File {0} referenced by --appyaml '
                'does not exist.'.format(appyaml))
        if not os.path.exists(paths[0]):
            raise exceptions.FileNotFoundError(paths[0])

    for path in paths:
        if not os.path.exists(path):
            raise exceptions.FileNotFoundError(path)
        config = yaml_parsing.ConfigYamlInfo.FromFile(path)
        if config:
            configs.Add(config)
            continue
        service = Service.FromPath(path, stager, path_matchers, appyaml)
        if service:
            services.Add(service)
            continue
        raise exceptions.UnknownSourceError(path)
    return services.GetAll(), configs.GetAll()