-
Notifications
You must be signed in to change notification settings - Fork 694
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement container_layer rule. #279
implement container_layer rule. #279
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will also want to document this in README.md
, and probably create {docker,oci}_layer
aliases.
testdata/BUILD
Outdated
container_image( | ||
name = "files_in_layer_with_files_base", | ||
base = ":files_base", | ||
container_layers = [":files_in_layer"], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this kwarg
should just be layers
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand this. :files_base
is the base (which is a bunch of file), and layers
is the files on top of that. Am I wrong?
container/image_test.py
Outdated
@@ -66,6 +66,14 @@ def test_files_with_file_base(self): | |||
self.assertEqual(2, len(img.fs_layers())) | |||
self.assertTopLayerContains(img, ['.', './bar']) | |||
|
|||
def test_files_with_file_base(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You didn't rename this test, so it collides with the name above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the catch. Done.
container/image_test.py
Outdated
@@ -83,6 +91,17 @@ def test_tar_with_tar_base(self): | |||
'./asdf', './usr', './usr/bin', | |||
'./usr/bin/miraclegrow']) | |||
|
|||
def test_tar_with_tar_base(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing rename
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
container/layer.bzl
Outdated
_join_path = "join", | ||
) | ||
|
||
def magic_path(ctx, f): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we're using this in lang_image
anymore. Can you double check, and if I'm right make it private again (leading _
) and strip the comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. It is not used in lang_image
as you said.
container/layer.bzl
Outdated
diff_id=diff_id, | ||
env=env)] | ||
|
||
_layer_attrs = dict({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this and container_image
share a definition for their common attributes? I'd expect it defined here and loaded/used there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, if possible I think I'd like us to change container_image
to a macro that creates a container_layer
and just assembles it. That may be a more involved change, but I think it definitely results in the best separation of concerns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't handle this comments yet, since I am still not sure about how to change container_image
to a macro.
There are still some attrs which are container_image
only, e.g. legacy_run_behavior
, labels
etc., which are not in container_layer
rule. Also how to deal with the backward compatibility of the existing usage of container_image
rule?
So how about 1) I re-use all the container_layer
attrs and 2) re-use the container_layer
impl for the related attrs, but still keep container_image
as a rule?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok with punting on this for now, but I'd still like the rules to head this general direction to avoid repeating logic. This is the motivation for some of my comments like _image_config
.
The idea is that container_image
would still be a rule, but likely _container_image
, and container_image
becomes a macro that wraps container_layer
and _container_image
.
container/layer.bzl
Outdated
debs=debs, tars=tars) | ||
# Generate the zipped filesystem layer, and its sha256 (aka blob sum) | ||
zipped_layer, blob_sum = zip_layer(ctx, unzipped_layer) | ||
# Returns constituent parts of the Container layer as provider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worth elaborating on why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Added doc explaining why we use provider.
container/image.bzl
Outdated
@@ -342,6 +298,7 @@ _attrs = dict({ | |||
), | |||
"label_file_strings": attr.string_list(), | |||
"empty_files": attr.string_list(), | |||
"container_layers": attr.label_list(providers = [LayerInfo]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said elsewhere, I'd prefer just layers
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Emm... this is tricky since layers
is also used in lang_image
rule, which extends the attrs from container_image
rule.
So if we want to keep layers
in container_image
rule, we need to change the layers
in lang_image
to something else.
Do you have some suggestions for me?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a problem. lang_image
wraps dep_layer
and app_layer
rules which extend the container_image
rule. I don't believe layers
is passed through.
container/image.bzl
Outdated
zipped_layers = parent_parts.get("zipped_layer", []) + _getLayerInfo(layers, "zipped_layer") + [zipped_layer] | ||
shas = parent_parts.get("blobsum", []) + _getLayerInfo(layers, "blob_sum") + [blob_sum] | ||
unzipped_layers = parent_parts.get("unzipped_layer", []) + _getLayerInfo(layers, "unzipped_layer") + [unzipped_layer] | ||
layer_diff_ids = _getLayerInfo(layers, "diff_id") + [diff_id] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You are inconsistent about whether this portion is hoisted (like this one) or a nested expression. IMO pick one and keep these lines more consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry that I didn't quite get the the meaning of "hoisted".
Do you mean I should use all nested expression e.g. list comprehension in this case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By hoisted I mean:
foo = _getLayerInfo(...)
bar = parent_parts.get(...) + foo
vs:
bar = parent_parts.get(...) + _getLayerInfo(...)
container/image.bzl
Outdated
|
||
# Get and merge environment variables | ||
env = {} | ||
[env.update(layer[LayerInfo].env) for layer in layers] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't work, it doesn't properly evaluate read-modify-write environment variables like PATH
.
I believe that for this to work properly, we actually want N calls to _image_config(...)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like _image_config will deal with more things than envvars.
I wrote a skylark function _evalute_merge_env
to handle envvar here properly. And I have unit test to cover the read-modify-write case like PATH
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like _image_config will deal with more things than envvars.
That's fine, so just pass env vars :)
I wrote a skylark function _evalute_merge_env to handle envvar here properly
I'd rather not fork this logic across two places. I'd definitely prefer we use _image_config
iteratively.
3cc42c5
to
681c385
Compare
* each container_layer rule will create its own tar files. * container_image rule was refactored so that it can composed by multiple container_layers via such new attr. Tested: - new unit tests in image_test.py
- fix unit tests'name - have _evalute_merge_env to properly expand envvar - magic_path -> _magic_path to make it private - add comments for provider usage - create alias docker_layer / oci_layer
- also changes attrs in lang_image to avoid name conflict
* also remove entrypoint / cmd from container_layer rule since they are not used in the container_image
681c385
to
4597293
Compare
Hi Matt, I have done more refactor of this PR, including:
Could you take another review of this PR? Many thanks, |
container/flatten.bzl
Outdated
"//container:layers.bzl", | ||
"//skylib:path.bzl", | ||
_get_runfile_path = "runfile", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this used? trying to understand the diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I was not familiar with the PR previously and I rebased my change instead of merging master. So this was unrelated change somehow got in.
Fixed right now.
container/image.bzl
Outdated
@@ -216,9 +161,25 @@ def _repository_name(ctx): | |||
# the v2 registry specification. | |||
return _join_path(ctx.attr.repository, ctx.label.package) | |||
|
|||
def _evalute_merge_env(env, new_env): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: evaluAte
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed as this function was deleted.
container/image.bzl
Outdated
for k, v in new_env.items(): | ||
elems = [] | ||
for e in v.split(":"): | ||
if e.startswith("$") and e[1:] in env.keys(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't handle a:$PATH:b
or ${PATH}:a:b
.
I'd really rather see this go away in favor of _image_config
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PATH
is also not the environment variable that supports read-modify-write, so splitting on :
is also insufficient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Now use //container:create_image_config to generate config layer by layer so the envvars can be handled correctly.
@@ -286,7 +286,7 @@ def _war_app_layer_impl(ctx): | |||
"""Appends the app layer with all remaining runfiles.""" | |||
|
|||
available = depset() | |||
for jar in ctx.attr.layers: | |||
for jar in ctx.attr.jar_layers: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, we do have layers. This rename is better because these are an implementation detail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack.
@philwo No CI is running for this repo, what's up? |
@mattmoor I've setup post-/presubmit checks for this repo now. The presubmit for this PR will run when a new commit is pushed to it. I also sent you an invite to Buildkite - please accept it. You'll need to verify PRs from external contributors to make sure that they're safe to run on CI. :) Let me know if you have any questions or if it doesn't work. |
- remove unnecessary imports in flatten.bzl - use //container:create_image_config to generate config layer by layer so the envvars can be handled correctly.
All comments addressed, please help review again. As for the re-use
Yes, currently I just use Many Thanks! |
container/image.bzl
Outdated
# Get the config for the base layer | ||
config_file = _get_base_config(ctx) | ||
# Generate the new config layer by layer, using the attributes specified and the diff_id | ||
for i in range(len(layers)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for i, layer in enumerate(layers):
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Many thanks for the review and approval!!
Fixed. Let me know if you encounter any issues. |
* implement container_layer rule. * add document for container_layer rule
multiple container_layers via such new attr.
Tested: