
    m                     H   S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKrSSK	J
r
  SSK	Jr  SSKJr  SS	KJr  SS
KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKrSSKrSSKrSSKr\" SSSSS\R8                  " S5      \R8                  " S5      \R8                  " S5      S\R8                  " S5      1
5      r\" \S1-  5      r " S S\R>                  5      r  " S S\R>                  5      r! " S S\R>                  5      r" " S S \R>                  5      r# " S! S"\#5      r$ " S# S$\#5      r% " S% S&\R>                  5      r& " S' S(\RN                  5      r(S) r)\RT                  S* 5       r+ " S+ S,\,5      r- " S- S.\,5      r. " S/ S0\,5      r/ " S1 S2\,5      r0S4S3 jr1g)5a2  Library code to support App Engine Flex runtime builders.

The App Engine Flex platform runs a user's application that has been packaged
into a docker image. At the lowest level, the user provides us with a source
directory complete with Dockerfile, which we build into an image and deploy.
To make development easier, Google provides blessed language runtimes that the
user can extend in their Dockerfile to get a working base image for their
application. To further make development easier, we do not require users to
author their own Dockerfiles for "canonical" applications for each of the
Silver Languages.

In order for this to be possible, preprocessing must be done prior to the
Docker build to inspect the user's source code and automatically generate a
Dockerfile.

Flex runtime builders are a per-runtime pipeline that covers the full journey
from source directory to docker image. They are stored as templated .yaml files
representing CloudBuild Build messages. These .yaml files contain a series of
CloudBuild build steps. Additionally, the runtime root stores a `runtimes.yaml`
file which contains a list of runtime names and mappings to the corresponding
builder yaml files.

Such a builder will look something like this (note that <angle_brackets> denote
values to be filled in by the builder author, and $DOLLAR_SIGNS denote a
literal part of the template to be substituted at runtime):

    steps:
    - name: 'gcr.io/google_appengine/python-builder:<version>'
      env: ['GAE_APPLICATION_YAML_PATH=${_GAE_APPLICATION_YAML_PATH}']
    - name: 'gcr.io/cloud-builders/docker:<docker_image_version>'
      args: ['build', '-t', '$_OUTPUT_IMAGE', '.']
    images: ['$_OUTPUT_IMAGE']

To test this out in the context of a real deployment, do something like the
following (ls/grep steps just for illustrating where files are):

    $ ls /tmp/runtime-root
    runtimes.yaml python-v1.yaml
    $ cat /tmp/runtime-root/runtimes.yaml
    schema_version: 1
    runtimes:
      python:
        target:
          file: python-v1.yaml
    $ gcloud config set app/use_runtime_builders true
    $ gcloud config set app/runtime_builders_root file:///tmp/runtime-root
    $ cd $MY_APP_DIR
    $ grep 'runtime' app.yaml
    runtime: python
    $ grep 'env' app.yaml
    env: flex
    $ gcloud beta app deploy

A (possibly) easier way of achieving the same thing if you don't have a
runtime_builders_root set up for development yet:

   $ cd $MY_APP_DIR
   $ export _OUTPUT_IMAGE=gcr.io/$PROJECT/appengine/placeholder
   $ gcloud container builds submit \
       --config=<(envsubst < /path/to/cloudbuild.yaml) .
   $ gcloud app deploy --image-url=$_OUTPUT_IMAGE

Or (even easier) use a 'custom' runtime:

    $ cd $MY_APP_DIR
    $ ls
    cloudbuild.yaml app.yaml
    $ rm -f Dockerfile
    $ grep 'runtime' app.yaml
    runtime: custom
    $ gcloud beta app deploy
    )absolute_import)division)unicode_literalsN)cloudbuild_util)config)storage_api)storage_util)
exceptions)log)
properties)yaml
aspnetcorephpnodejsrubyjavaz(python|python-.+)$z(go|go1\..+)$z^gs://ztest-gaztest-re-[ab]z	test-betac                       \ rS rSrSrSrg)FileReadError{   z.Error indicating a file read operation failed. N__name__
__module____qualname____firstlineno____doc____static_attributes__r       2lib/googlecloudsdk/api_lib/app/runtime_builders.pyr   r   {   s    6r   r   c                       \ rS rSrSrSrg)ManifestError   z9Error indicating a problem parsing or using the manifest.r   Nr   r   r   r   r!   r!          Ar   r!   c                       \ rS rSrSrSrg)ExperimentsError   zBError indicating a problem parsing or using the experiment config.r   Nr   r   r   r   r%   r%      s    Jr   r%   c                       \ rS rSrSrSrg)CloudBuildLoadError   zHError indicating an issue loading the runtime Cloud Build specification.r   Nr   r   r   r   r(   r(      s    Pr   r(   c                       \ rS rSrSrSrg)CloudBuildFileNotFound   z,Error indicating a missing Cloud Build file.r   Nr   r   r   r   r+   r+      s    4r   r+   c                   ,   ^  \ rS rSrSrU 4S jrSrU =r$ )InvalidRuntimeBuilderURI   zGError indicating that the runtime builder URI format wasn't recognized.c                 J   > [         [        U ]  SR                  U5      5        g )Nz[{}] is not a valid runtime builder URI. Please set the app/runtime_builders_root property to a URI with either the Google Cloud Storage (`gs://`) or local file (`file://`) protocol.)superr.   __init__format)selfuri	__class__s     r   r2   !InvalidRuntimeBuilderURI.__init__   s#    	
"D2	 F3K	!r   r   )r   r   r   r   r   r2   r   __classcell__)r6   s   @r   r.   r.      s    O! !r   r.   c                       \ rS rSrSrSrg)BuilderResolveError   z9Error indicating that a build file could not be resolved.r   Nr   r   r   r   r:   r:      r#   r   r:   c                   :    \ rS rSrSrSrSrSrSrS r	S r
S	 rS
rg)RuntimeBuilderStrategy   z-Enum indicating when to use runtime builders.            c                     X R                   L a  [        $ X R                  L a  [        $ [	        SR                  U 5      5      e)a   Return the allowlist of runtimes for this strategy.

The allowlist is kept as a constant within this module.

Returns:
  list of str, the names of runtimes that are allowed for this strategy.

Raises:
  ValueError: if this strategy is not allowlist-based.
z5RuntimeBuilderStrategy {} is not an allowed strategy.)ALLOWLIST_GA_ALLOWLISTED_RUNTIMES_GAALLOWLIST_BETA_ALLOWLISTED_RUNTIMES_BETA
ValueErrorr3   r4   s    r   _GetAllowlist$RuntimeBuilderStrategy._GetAllowlist   sE        %%	$$	$''
?FFtLN Nr   c                     U R                  5        H  n UR                  U5      (       a    gM     g! [         a    X:X  a     g M6  f = f)NTF)rJ   matchAttributeError)r4   runtimeallowlisted_runtimes      r   
_IsAllowed!RuntimeBuilderStrategy._IsAllowed   sX    #113$$W-- .  4   ) *s   2AAc                 (   US:X  a(  X R                   U R                  U R                  4;   a  U$ X R                   L a  gX R                  L d  X R                  L a  U R                  U5      $ X R                  L a  g[        SR                  U 5      5      e)ak  Returns True if runtime should use runtime builders under this strategy.

For the most part, this is obvious: the ALWAYS strategy returns True, the
ALLOWLIST_${TRACK} strategies return True if the given runtime is in the
list of _ALLOWLISTED_RUNTIMES_${TRACK}, and the NEVER strategy returns
False.

However, in the case of 'custom' runtimes, things get tricky: if the
strategy *is not* NEVER, we return True only if there is no `Dockerfile` in
the current directory (this method assumes that there is *either* a
`Dockerfile` or a `cloudbuild.yaml` file), since one needs to get generated
by the Cloud Build.

Args:
  runtime: str, the runtime being built.
  needs_dockerfile: bool, whether the Dockerfile in the source directory is
    absent.

Returns:
  bool, whether to use the runtime builders.
Raises:
  ValueError: if an unrecognized runtime_builder_strategy is given
customTFz&Invalid runtime builder strategy [{}].)ALWAYSrF   rD   rQ   NEVERrH   r3   )r4   rO   needs_dockerfiles      r   ShouldUseRuntimeBuilders/RuntimeBuilderStrategy.ShouldUseRuntimeBuilders   s    6 (t(,(;(;(,(9(9(;  ; {{	$$	$0A0A(A__W%%		?FFtLMMr   r   N)r   r   r   r   r   rV   rF   rD   rU   rJ   rQ   rX   r   r   r   r   r=   r=      s*    5
%.,&N$'Nr   r=   c                  l    SR                  U  Vs/ s H  oR                  S5      PM     sn5      $ s  snf )z:Join parts of a gs:// Cloud Storage or local file:// path./)joinstrip)argsargs     r   _Joinr`      s+     
T2Tc99S>T2	332s   1c              #     #     U R                  S5      (       aU  [        R                  " [        R                  R
                  R                  R                  U 5      5       nUv   SSS5        gU R                  S5      (       ag  [        R                  " 5       n[        R                  R                  U 5      n[        R                  " UR                  U5      5       nUv   SSS5        g[        U 5      e! , (       d  f       g= f! , (       d  f       g= f! [        R                  R
                  R                  R                   [        R                  R
                  R                  R"                  [$        R&                  4 a9  n[(        R*                  " SSS9  [-        [        R.                  " U5      5      eSnAff = f7f)a  Read a file/object (local file:// or gs:// Cloud Storage path).

>>> with _Read('gs://builder/object.txt') as f:
...   assert f.read() == 'foo'
>>> with _Read('file:///path/to/object.txt') as f:
...   assert f.read() == 'bar'

Args:
  uri: str, the path to the file/object to read. Must begin with 'file://' or
    'gs://'

Yields:
  a file-like context manager.

Raises:
  FileReadError: If opening or reading the file failed.
  InvalidRuntimeBuilderPath: If the path is invalid (doesn't begin with an
      appropriate prefix).
zfile://Ngs:// Texc_info)
startswith
contextlibclosingsixmovesurllibrequesturlopenr   StorageClientr	   ObjectReferenceFromUrl
ReadObjectr.   error	HTTPErrorURLErrorcalliope_exceptionsBadFileExceptionr   debugr   	text_type)r5   reqstorage_clientobject_fes         r   _Readr~      s=    **
~~i  cii..66>>sCD	 ED		 	 "002n,,44S9gn77@AQ BA %S)) ED
 BA ))


 
 
*
*CII,<,<,B,B,K,K

.
.
0 *IIb4 
a(
))*s   GAD !C7&D .G/A/D D#D +G,D 7
DD GD 
DD GD A/G4F<<GGc                   :    \ rS rSrSrS
S jrS rS rS rS r	S	r
g)BuilderReferencei  z6A reference to a specific cloudbuild.yaml file to use.Nc                 (    Xl         X l        X0l        g)aQ  Constructs a BuilderReference.

Args:
  runtime: str, The runtime this builder corresponds to.
  build_file_uri: str, The full URI of the build configuration or None if
    this runtime existed but no longer can be built (deprecated).
  deprecation_message: str, A message to print when using this builder or
    None if not deprecated.
NrO   build_file_urideprecation_message)r4   rO   r   r   s       r   r2   BuilderReference.__init__  s     L(2r   c                 <   U R                   (       d"  [        SR                  U R                  S95      e[        R
                  " 5       n[        U R                   5       n[        R                  " X2US9nSSS5        WR                  c  UR                  5       Ul	        UR                  R                  R                  UR                  l        UR                   H  nSnSnUR                   HH  nUR!                  S5      n	["        R$                  " S['        U	5      -   5        SU	;   a  S	nS
U	;   d  MF  S	nMJ     U(       d  UR                  R)                  S5        U(       a  M  SU;   d  M  UR                  R)                  S5        M     U$ ! , (       d  f       GN= f)a  Loads the Cloud Build configuration file for this builder reference.

Args:
  params: dict, a dictionary of values to be substituted in to the
    Cloud Build configuration template corresponding to this runtime
    version.

Returns:
  Build message, the parsed and parameterized Cloud Build configuration
    file.

Raises:
  CloudBuildLoadError: If the Cloud Build configuration file is unknown.
  FileReadError: If reading the configuration file fails.
  InvalidRuntimeBuilderPath: If the path of the configuration file is
    invalid.
z:There is no build file associated with runtime [{runtime}]rO   )messagesparamsNF=zEnv var in build step: GAE_APPLICATION_YAML_PATHTGOOGLE_RUNTIME_VERSIONz7GAE_APPLICATION_YAML_PATH=${_GAE_APPLICATION_YAML_PATH}_GOOGLE_RUNTIME_VERSIONz1GOOGLE_RUNTIME_VERSION=${_GOOGLE_RUNTIME_VERSION})r   r(   r3   rO   r   GetMessagesModuler~   cloudbuild_configLoadCloudbuildConfigFromStreamoptionsBuildOptions!SubstitutionOptionValueValuesEnumALLOW_LOOSEsubstitutionOptionstepsenvsplitr   rw   strappend)
r4   r   r   databuildstephas_yaml_pathhas_runtime_versionr   partss
             r   LoadCloudBuildBuilderReference.LoadCloudBuild(  sO   $ 
F6$,,6') ) 002H	t""	#t>>
&2e 
$ }}++-em77CC 
MM$m!#		#		+c%j89&%/-#u, $
  E	G  %>&%HKL  L- 
$	#s   F
Fc                 h    U R                   (       a!  [        R                  " U R                   5        gg)zFWarns that this runtime is deprecated (if it has been marked as such).N)r   r   warningrI   s    r   WarnIfDeprecated!BuilderReference.WarnIfDeprecatedW  s"    	kk$**+  r   c                     U R                   UR                   :H  =(       a9    U R                  UR                  :H  =(       a    U R                  UR                  :H  $ Nr   r4   others     r   __eq__BuilderReference.__eq__\  sL    LLEMM) B5#7#77B$$(A(AACr   c                 .    U R                  U5      (       + $ r   )r   r   s     r   __ne__BuilderReference.__ne__a  s    {{5!!!r   )r   r   rO   r   )r   r   r   r   r   r2   r   r   r   r   r   r   r   r   r   r     s     >3-^,
C
"r   r   c                   >    \ rS rSrSrSr\S 5       rS rS r	S r
Srg	)
Manifestie  a  Loads and parses a runtimes.yaml manifest.

To resolve a builder configuration file to use, a given runtime name is
looked up in this manifest. For each runtime, it either points to a
configuration file directly, or to another runtime. If it points to a runtime,
resolution continues until a configuration file is reached.

The following is the proto-ish spec for the yaml schema of the mainfest:

# Used to determine if this client can parse this manifest. If the number is
# less than or equal to the version this client knows about, it is compatible.
int schema_version; # Required

# The registry of all the runtimes that this manifest defines. The key of the
# map is the runtime name that appears in app.yaml.
<string, Runtime> runtimes {

  # Determines which builder this runtime points to.
  Target target {

    oneof {
      # A path relative to the manifest's location of the builder spec to use.
      string file;

      # Another runtime registered in this file that should be resolved and
      # used for this runtime.
      string runtime;
    }
  }

  # Specifies deprecation information about this runtime.
  Deprecation deprecation {

    # A message to be displayed to the user on use of this runtime.
    string message;
  }
}
r?   c                     [         R                  " SU5        [        U5       n[        R                  " X!S9nSSS5        U " UW5      $ ! , (       d  f       N= f)zLoads a manifest from a gs:// or file:// path.

Args:
  uri: str, A gs:// or file:// URI

Returns:
  Manifest, the loaded manifest.
z#Loading runtimes manifest from [%s]	file_hintN)r   rw   r~   r   load)clsr5   r|   r   s       r   LoadFromURIManifest.LoadFromURI  sC     II3S9	sqYYq(d 
sD> 
s   A		
Ac                    Xl         X l        U R                  R                  SS5      nUc  [        SR	                  U5      5      eU[
        R                  :  a'  [        SR	                  [
        R                  US95      eg)0Use LoadFromFile, not this constructor directly.schema_versionNz+Unable to parse the runtimes manifest: [{}]zUnable to parse the runtimes manifest. Your client supports schema version [{supported}] but requires [{required}]. Please update your SDK to a later version.	supportedrequired)_uri_datagetr!   r3   r   SCHEMA_VERSIONr4   r5   r   required_versions       r   r2   Manifest.__init__  s    IJzz~~&6=
7
>
>s
CE E(111$$*FX5L5L4D %+ %FG G 2r   c                 h    [        U R                  R                  S0 5      R                  5       5      $ )zSGet all registered runtimes in the manifest.

Returns:
  [str], The runtime names.
runtimes)listr   r   keysrI   s    r   RuntimesManifest.Runtimes  s'     

z2.33566r   c                 *   U R                   R                  S0 5      nUnU1n UR                  US5      nU(       d"  [        R                  " SX0R                  5        gUR                  S0 5      R                  SS5      nU(       aI  [        R                  " SX65        Xd;   a  [        SR                  US95      eUR                  U5        UnM  UR                  S	0 5      R                  S
S5      nUR                  S0 5      R                  SS5      nU(       aV  [        [        R                  R                  U R                  5      U5      n	[        R                  " SX95        [        X9U5      $ [        R                  " SU5        [        USU5      $ )a  Gets the associated reference for the given runtime.

Args:
  runtime: str, The name of the runtime.

Returns:
  BuilderReference, The reference pointed to by the manifest, or None if the
  runtime is not registered.

Raises:
  ManifestError: if a problem occurred parsing the manifest.
r   Nz'Runtime [%s] not found in manifest [%s]targetrO   z!Runtime [%s] is an alias for [%s]zSA circular dependency was found while resolving the builder for runtime [{runtime}]r   deprecationmessagefilez1Resolved runtime [%s] as build configuration [%s]z0Resolved runtime [%s] has no build configuration)r   r   r   rw   r   r!   r3   addr`   ospathdirnamer   )
r4   rO   r   current_runtimeseenruntime_defnew_runtimedeprecation_msg
build_filefull_build_uris
             r   GetBuilderReferenceManifest.GetBuilderReference  sa    zz~~j"-HOD
LL$7k		;!99	.OOHb155iFk			5!	0$$*F7F$;= = 	%#r:>>y$Oo??8R044VTBj	rwwtyy9:F		E!	3_> 	> 
iiB!ot_EEr   r   r   N)r   r   r   r   r   r   classmethodr   r2   r   r   r   r   r   r   r   r   e  s2    %L . G74Fr   r   c                   J    \ rS rSrSrSrSrSr\S 5       r	S r
S rSS	 jrS
rg)Experimentsi  ak  Runtime experiment configs as read from a gs:// or a file:// source.

The experiment config file follows the following protoish schema:

# Used to determine if this client can parse this manifest. If the number is
# less than or equal to the version this client knows about, it is compatible.
int schema_version; # Required

# Map of experiments and their rollout percentage.
# The key is the name of the experiment, the value is an integer between 0
# and 100 representing the rollout percentage
# In case no experiments are defined, an empty 'experiments:' section needs to
# be present.
<String, Number> experiments
r?   zexperiments.yamltrigger_build_server_sidec                    [        XR                  5      n[        R                  " SU5         [	        U5       n[
        R                  " X2S9nSSS5        U " UW5      $ ! , (       d  f       N= f! [         a  n[        SR                  X%5      5      eSnAf[
        R                   a  n[        SR                  X%5      5      eSnAff = f)zLoads a runtime experiment config from a gs:// or file:// path.

Args:
  dir_uri: str, A gs:// or file:// URI pointing to a folder that contains
    the file called Experiments.CONFIG_FILE

Returns:
  Experiments, the loaded runtime experiments config.
z,Loading runtimes experiment config from [%s]r   Nz>Unable to read the runtimes experiment config: [{}], error: {})r`   CONFIG_FILEr   rw   r~   r   r   r   r%   r3   YAMLParseError)r   dir_urir5   r|   r   r}   s         r   r   Experiments.LoadFromURI  s     
)CII<cB:yy* d^ :  
J6#>   
J6#> s:   A0 AA0 
A-)A0 0
C
:BC
+CC
c                    Xl         X l        U R                  R                  SS5      nUc  [        SR	                  U5      5      eU[
        R                  :  a'  [        SR	                  [        R                  US95      eg)r   r   NzXUnable to parse the runtimes experiment config due to missing schema_version field: [{}]zUnable to parse the runtimes experiments config. Your client supports schema version [{supported}] but requires [{required}]. Please update your SDK to a newer version.r   )r   r   r   r%   r3   r   r   r   r   s       r   r2   Experiments.__init__  s    IJzz~~&6=''-vc{4 4 +44477=v //:J 8> 8LM M 5r   c                 8    U R                   R                  S5      $ )zqGet all experiments and their rollout percentage.

Returns:
  dict[str,int] Experiments and their rollout state.
experiments)r   r   rI   s    r   r   Experiments.Experiments)  s     ::>>-((r   c                 d     U R                   R                  S5      U   $ ! [         a    Us $ f = f)zGet the rollout percentage of an experiment or return 'default'.

Args:
  experiment: the name of the experiment
  default: the value to return if the experiment was not found

Returns:
  int the percent of the experiment
r   )r   r   KeyError)r4   
experimentdefaults      r   GetExperimentPercentWithDefault+Experiments.GetExperimentPercentWithDefault1  s3    ZZ^^M*:66 ns     //r   N)r   )r   r   r   r   r   r   r   TRIGGER_BUILD_SERVER_SIDEr   r   r2   r   r   r   r   r   r   r   r     s;     ."+9 2M )r   r   c                   T    \ rS rSrSrSrSrSr SS jrS r	S r
S	 rS
 rS rS rSrg)ResolveriA  zResolves the location of a builder configuration for a runtime.

There are several possible locations that builder configuration can be found
for a given runtime, and they are checked in order. Check GetBuilderReference
for the locations checked.
zruntimes.yamlzruntimes_buildpacks.yamlzcloudbuild.yamlc                 `   Xl         [        R                  R                  U5      U l        X0l        [        R                  R                  R                  R                  SS9U l        X@l        [        R                  " SU R                  5        [        R                  " SU R                  5        g)a  Instantiates a resolver.

Args:
  runtime: str, The name of the runtime to be resolved.
  source_dir: str, The local path of the source code being deployed.
  legacy_runtime_version: str, The value from runtime_config.runtime_version
    in app.yaml. This is only used in legacy mode.
  use_flex_with_buildpacks: bool, if true, use the build-image and
  run-image built through buildpacks.

Returns:
  Resolver, The instantiated resolver.
T)r   z#Using use_flex_with_buildpacks [%s]zUsing runtime builder root [%s]N)rO   r   r   abspath
source_dirlegacy_runtime_versionr   VALUESappruntime_builders_rootGetbuild_file_rootuse_flex_with_buildpacksr   rw   )r4   rO   r   r   r   s        r   r2   Resolver.__init__O  s     Lggooj1DO"8%,,00FFJJ K D$<!II3++-II/1E1EFr   c                    U R                  5       =(       d>    U R                  5       =(       d'    U R                  5       =(       d    U R                  5       nU(       d"  [	        SR                  U R                  S95      eU$ )zResolve the builder reference.

Returns:
  BuilderReference, The reference to the builder configuration.

Raises:
  BuilderResolveError: if this fails to resolve a builder.
z4Unable to resolve a builder for runtime: [{runtime}]r   )_GetReferenceCustom_GetReferencePinned_GetReferenceFromManifest_GetReferenceFromLegacyr:   r3   rO   )r4   builder_defs     r   r   Resolver.GetBuilderReferenceh  sw     	  " 	'  "	'&&(	' 	$$&	  
@6$,,6') ) r   c           
      "   U R                   S:X  a  [        R                  " S[        R                  5        [        U R                   [        SU R                  R                  SS5      R                  S5      -   [        R                  5      5      $ g)a  Tries to resolve the reference for runtime: custom.

If the user has an app.yaml with runtime: custom we will look in the root
of their source directory for a custom build pipeline named cloudbuild.yaml.

This should only be called if there is *not* a Dockerfile in the source
root since that means they just want to build and deploy that Docker image.

Returns:
  BuilderReference or None
rT   z5Using local cloud build file [%s] for custom runtime.zfile:///\r[   N)
rO   r   rw   r   CLOUDBUILD_FILEr   r`   r   replacer]   rI   s    r   r  Resolver._GetReferenceCustom~  su     ||x	iiG((*
,,

T__44T3?EEcJJ((*+ + r   c                     U R                   R                  S5      (       aA  [        R                  " SU R                   5        [	        U R                   U R                   5      $ g)aN  Tries to resolve the reference for when a runtime is pinned.

Usually a runtime is looked up in the manifest and resolved to a
configuration file. The user does have the option of 'pinning' their build
to a specific configuration by specifying the absolute path to a builder
in the runtime field.

Returns:
  BuilderReference or None
rb   z#Using pinned cloud build file [%s].N)rO   rf   r   rw   r   rI   s    r   r  Resolver._GetReferencePinned  sD     ||w''	ii5t||DdllDLL99r   c                 j   U R                   (       a  [        R                  O[        R                  n[	        U R
                  U5      n[        R                  " SU5         [        R                  U5      nUR                  U R                  5      $ ! [         a    [        R                  " SSS9   gf = f)a  Tries to resolve the reference by looking up the runtime in the manifest.

Calculate the location of the manifest based on the builder root and load
that data. Then try to resolve a reference based on the contents of the
manifest.

Returns:
  BuilderReference or None
zUsing manifest_uri [%s]rc   Trd   N)r   r   BUILDPACKS_MANIFEST_NAMEMANIFEST_NAMEr`   r   r   rw   r   r   r   rO   r   )r4   manifest_file_namemanifest_urimanifests       r   r  "Resolver._GetReferenceFromManifest  s     (( 	))## 
 --/ABLII'6%%l3h))$,,77 	iiT"s    /B B21B2c                 :   U R                   (       a  U R                  U R                   5      $ [        R                  " SU R                  5        U R                  S-   n[        U R                  U5      n [        U5       nUR                  5       R                  5       R                  5       nSSS5        [        R                  " SWU R                  5        U R                  U5      $ ! , (       d  f       NA= f! [         a    [        R                  " SSS9   gf = f)aF  Tries to resolve the reference by the legacy resolution process.

TODO(b/37542861): This can be removed after all runtimes have been migrated
to publish their builders in the manifest instead of <runtime>.version
files.

If the runtime is not found in the manifest, use legacy resolution. If the
app.yaml contains a runtime_config.runtime_version, this loads the file from
'<runtime>-<version>.yaml' in the runtime builders root. Otherwise, it
checks '<runtime>.version' to get the default version, and loads the
configuration for that version.

Returns:
  BuilderReference or None
z0Fetching version for runtime [%s] in legacy modez.versionNrc   Trd   z2Using version [%s] for runtime [%s] in legacy mode)r   "_GetReferenceFromLegacyWithVersionr   rw   rO   r`   r   r~   readdecoder]   r   )r4   version_file_nameversion_file_urir|   versions        r   r   Resolver._GetReferenceFromLegacy  s      ""44

%
%' ' II@$,,Oz1T113DE!"a&&(//#))+ # IIBt||%227;; #" 	iiT"s0   4C8 ?-C',C8 '
C51C8 5C8 8DDc                     SR                  U R                  U/5      S-   n[        U R                  U5      n[        R
                  " SU5        [        U R                  U5      $ )zGets the name of configuration file to use for legacy mode.

Args:
  version: str, The pinned version of the configuration file.

Returns:
  BuilderReference
-z.yamlz7Calculated builder definition using legacy version [%s])r\   rO   r`   r   r   rw   r   )r4   r  	file_namefile_uris       r   r  +Resolver._GetReferenceFromLegacyWithVersion  sU     $,,01G;IT))95HIIGDLL(33r   )r   r   rO   r   r   NF)r   r   r   r   r   r  r  r
  r2   r   r  r  r  r  r  r   r   r   r   r   r   A  sC     "-7%/ ).G2,* 4"<H4r   r   c                     U R                   R                  nU(       a  UR                  SS5      OSn[        U R                  XU5      nUR                  5       $ )a_  Constructs a BuilderReference from a ServiceYamlInfo.

Args:
  service: ServiceYamlInfo, The parsed service config.
  source_dir: str, the source containing the application directory to build.
  use_flex_with_buildpacks: bool, if true, use the build-image and
    run-image built through buildpacks.

Returns:
  RuntimeBuilderVersion for the service.
runtime_versionN)parsedruntime_configr   r   rO   r   )servicer   r   r'  legacy_versionresolvers         r   FromServiceInfor+    sU     >>00.% #&&'8$?+/ gooz.0(		%	%	''r   r#  )2r   
__future__r   r   r   rg   enumr   re!googlecloudsdk.api_lib.cloudbuildr   r   r   googlecloudsdk.api_lib.storager   r	   googlecloudsdk.callioper
   ru   googlecloudsdk.corer   r   r   ri   six.moves.urllib.errorsix.moves.urllib.parsesix.moves.urllib.request	frozensetcompilerE   rG   Errorr   r!   r%   r(   r+   r.   r:   Enumr=   r`   contextmanagerr~   objectr   r   r   r   r+  r   r   r   <module>r<     s  GR '  '   	 	 = I 6 7 E * # * $ 
    %5(FFZZ&'ZZ !ZZ

>*	,-  'M 
7J$$ 7BJ$$ BKz'' KQ*** Q50 5!2 !B*** BJNTYY JNZ4 "* "*JK"v K"\CFv CFLS& Slm4v m4`(r   