22
33load ("//helm/private:json_extractor.bzl" , "json_extractor" )
44
5- ImagePushRepositoryInfo = provider (
6- doc = "Repository and image information for a given oci_push or image_push target" ,
5+ ImageRepositoryInfo = provider (
6+ doc = "Repository and image information for a given rules_oci or rules_img image target" ,
77 fields = {
88 "manifest_file" : "File (optional): The manifest JSON file for rules_img images" ,
99 "oci_layout" : "File (optional): The OCI layout directory for rules_oci images (contains index.json)" ,
10- "remote_tags_file" : "File (optional): The file containing remote tags (one per line) used for the push target" ,
11- "repository_file" : "File: The file containing the repository path for the push target" ,
10+ "remote_tags_file" : "File (optional): The file containing remote tags (one per line) used for the target" ,
11+ "repository_file" : "File: The file containing the repository path for the target" ,
1212 },
1313)
1414
15- def _image_push_repository_aspect_img (target , ctx ):
15+ def _image_repository_aspect_img_pull (target , ctx ):
16+ repository_file = None
17+ remote_tags_file = None
18+ manifest_file = None
19+
20+ if hasattr (ctx .rule .attr , "digest" ) and ctx .rule .attr .digest :
21+ digest = ctx .rule .attr .digest
22+
23+ if not hasattr (ctx .rule .attr , "data" ) or not ctx .rule .attr .data :
24+ fail ("image_pull target {} must have a `data` attribute" .format (target .label ))
25+
26+ data = ctx .rule .attr .data
27+
28+ if not digest in data or not data [digest ]:
29+ fail ("manifest file not found in `data` of image_pull target {}" .format (target .label ))
30+
31+ manifest_file = ctx .actions .declare_file ("{}.rules_helm.pull_manifest.txt" .format (target .label .name ))
32+ ctx .actions .write (
33+ output = manifest_file ,
34+ content = data [digest ],
35+ )
36+ else :
37+ fail ("image_pull target {} must have a `digest` attribute" .format (target .label ))
38+
39+ registry = None
40+
41+ # The primary registry from which to pull the image
42+ if hasattr (ctx .rule .attr , "registry" ) and ctx .rule .attr .registry :
43+ registry = ctx .rule .attr .registry
44+
45+ # Additional registries can be provided. When rules_img pulls the image,
46+ # these are tried in order, before the primary registry. To emulate this
47+ # behaviour, if the list is set, the first element will be used as the
48+ # registry to pull from
49+ if hasattr (ctx .rule .attr , "registries" ) and ctx .rule .attr .registries :
50+ registries = ctx .rule .attr .registries
51+ if len (registries ) > 0 :
52+ registry = registries [0 ]
53+
54+ if registry == None :
55+ fail ("image_pull target {} must have either a `registry` or `registries` attribute" .format (target .label ))
56+
57+ repository = None
58+ if hasattr (ctx .rule .attr , "repository" ) and ctx .rule .attr .repository :
59+ repository = ctx .rule .attr .repository
60+ else :
61+ fail ("image_pull target {} must have a `repository` attribute" .format (target .label ))
62+
63+ registry_clean = registry .replace ("https://" , "" ).replace ("http://" , "" )
64+ repository_file = ctx .actions .declare_file ("{}.rules_helm.repository.txt" .format (target .label .name ))
65+ ctx .actions .write (
66+ output = repository_file ,
67+ content = "{}/{}" .format (registry_clean , repository ),
68+ )
69+
70+ if hasattr (ctx .rule .attr , "tag" ) and ctx .rule .attr .tag :
71+ remote_tags_file = ctx .actions .declare_file ("{}.rules_helm.tags.txt" .format (target .label .name ))
72+ ctx .actions .write (
73+ output = remote_tags_file ,
74+ content = ctx .rule .attr .tag ,
75+ )
76+
77+ return [ImageRepositoryInfo (
78+ repository_file = repository_file ,
79+ manifest_file = manifest_file ,
80+ oci_layout = None ,
81+ remote_tags_file = remote_tags_file ,
82+ )]
83+
84+ def _image_repository_aspect_img_push (target , ctx ):
1685 repository_file = None
1786 remote_tags_file = None
1887 manifest_file = None
@@ -118,14 +187,14 @@ def _image_push_repository_aspect_img(target, ctx):
118187 # it
119188 remote_tags_file = ctx .rule .file .tag_file
120189
121- return [ImagePushRepositoryInfo (
190+ return [ImageRepositoryInfo (
122191 repository_file = repository_file ,
123192 manifest_file = manifest_file ,
124193 oci_layout = None ,
125194 remote_tags_file = remote_tags_file ,
126195 )]
127196
128- def _image_push_repository_aspect_oci (target , ctx ):
197+ def _image_repository_aspect_oci_push (target , ctx ):
129198 repository_file = None
130199 remote_tags_file = None
131200
@@ -148,27 +217,30 @@ def _image_push_repository_aspect_oci(target, ctx):
148217 if not hasattr (ctx .rule .file , "image" ):
149218 fail ("oci_push target {} must have an `image` attribute" .format (target .label ))
150219
151- return [ImagePushRepositoryInfo (
220+ return [ImageRepositoryInfo (
152221 repository_file = repository_file ,
153222 oci_layout = ctx .rule .file .image ,
154223 manifest_file = None ,
155224 remote_tags_file = remote_tags_file ,
156225 )]
157226
158- def _image_push_repository_aspect_impl (target , ctx ):
227+ def _image_repository_aspect_impl (target , ctx ):
228+ if ctx .rule .kind == "image_import" :
229+ return _image_repository_aspect_img_pull (target , ctx )
230+
159231 if ctx .rule .kind == "image_push" or hasattr (ctx .rule .attr , "registry" ):
160- return _image_push_repository_aspect_img (target , ctx )
232+ return _image_repository_aspect_img_push (target , ctx )
161233
162- return _image_push_repository_aspect_oci (target , ctx )
234+ return _image_repository_aspect_oci_push (target , ctx )
163235
164236# This aspect exists because rules_oci and rules_img don't provide a provider
165237# that cleanly publishes this information but for the helm rules, it's
166238# absolutely necessary that an image's repository and digest are knowable.
167239# If rules_oci/rules_img decide to define their own provider for this (which they should)
168240# then this should be deleted in favor of that.
169- image_push_repository_aspect = aspect (
170- doc = "Provides the repository and image_root for a given oci_push or image_push target" ,
171- implementation = _image_push_repository_aspect_impl ,
241+ image_repository_aspect = aspect (
242+ doc = "Provides the repository and image_root for a given oci_{push,pull} or image_{push-pull} target" ,
243+ implementation = _image_repository_aspect_impl ,
172244 attrs = {
173245 "_json_extractor" : attr .label (
174246 doc = "Tool for extracting data from json files" ,
0 commit comments