diff --git a/ansible_bender/api.py b/ansible_bender/api.py index d816ac4..1eac791 100644 --- a/ansible_bender/api.py +++ b/ansible_bender/api.py @@ -121,7 +121,7 @@ def build(self, build): set_finish_time=True) b.log_lines = output # commit the final image and apply all metadata - b.final_layer_id = builder.commit(build.target_image) + b.final_layer_id = builder.commit(build.target_image, final_image=True) if not b.is_layering_on(): self.record_progress(b, None, b.final_layer_id) diff --git a/ansible_bender/builders/buildah_builder.py b/ansible_bender/builders/buildah_builder.py index 2fee9f6..efd9136 100644 --- a/ansible_bender/builders/buildah_builder.py +++ b/ansible_bender/builders/buildah_builder.py @@ -166,6 +166,7 @@ def create(self): # let's apply configuration before execing the playbook, except for user configure_buildah_container( self.ansible_host, working_dir=self.build.metadata.working_dir, + user=self.build.build_user, env_vars=self.build.metadata.env_vars, ports=self.build.metadata.ports, labels=self.build.metadata.labels, # labels are not applied when they are configured @@ -192,11 +193,16 @@ def swap_working_container(self): self.clean() self.create() - def commit(self, image_name, print_output=True): + def commit(self, image_name, print_output=True, final_image=False): + if final_image: + user=self.build.metadata.user + else: + user=self.build.build_user + if self.build.metadata.user or self.build.metadata.cmd or self.build.metadata.volumes: # change user if needed configure_buildah_container( - self.ansible_host, user=self.build.metadata.user, + self.ansible_host, user=user, cmd=self.build.metadata.cmd, volumes=self.build.metadata.volumes, ) diff --git a/ansible_bender/cli.py b/ansible_bender/cli.py index 1f74232..c47b3ae 100644 --- a/ansible_bender/cli.py +++ b/ansible_bender/cli.py @@ -105,6 +105,10 @@ def _do_build_interface(self): "should be specified as '/host/dir:/container/dir'", nargs="*" ) + self.build_parser.add_argument( + "--build-user", + help="the container gets invoked with this user during build" + ) self.build_parser.add_argument( "-w", "--workdir", help="path to an implicit working directory in the container" diff --git a/ansible_bender/conf.py b/ansible_bender/conf.py index 501585a..6e765df 100644 --- a/ansible_bender/conf.py +++ b/ansible_bender/conf.py @@ -118,6 +118,7 @@ def __init__(self): self.build_id = None # PK, should be set by database self.playbook_path = None self.build_volumes = [] # volumes for the build container + self.build_user = None self.metadata = None # Image metadata self.state = BuildState.NEW self.build_start_time = None @@ -144,6 +145,7 @@ def to_dict(self): "build_id": self.build_id, "playbook_path": self.playbook_path, "build_volumes": self.build_volumes, + "build_user": self.build_user, "metadata": self.metadata.to_dict(), "state": self.state.value, "build_start_time": self.build_start_time.strftime(TIMESTAMP_FORMAT) @@ -171,6 +173,7 @@ def to_dict(self): def update_from_configuration(self, data): """ update current object with data provided from Ansible vars """ self.build_volumes += graceful_get(data, "working_container", "volumes", default=[]) + self.build_user = graceful_get(data, "working_container", "user") self.base_image = graceful_get(data, "base_image") self.target_image = graceful_get(data, "target_image", "name") # self.builder_name = None @@ -187,6 +190,7 @@ def from_json(cls, j): b.build_id = j["build_id"] b.playbook_path = j.get("playbook_path", None) b.build_volumes = j["build_volumes"] + b.build_user = j["build_user"] b.metadata = ImageMetadata.from_json(j["metadata"]) b.state = BuildState(j["state"]) b.build_start_time = None diff --git a/docs/configuration.md b/docs/configuration.md index 9066c08..0ea57de 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -36,6 +36,7 @@ only from the first play. All the plays will end up in a single container image. | Key name | type | description | |----------------------|-----------------|----------------------------------------------------------------------| | `volumes` | list of strings | volumes mappings for the working container (`HOST:CONTAINER:PARAMS`) | +| `user` | string | UID or username to invoke the container during build (run ansible) | #### `target_image` @@ -113,6 +114,7 @@ optional arguments: mount selected directory inside the container during build, should be specified as '/host/dir:/container/dir' + --build-user USER the container gets invoked with this user during build -w WORKDIR, --workdir WORKDIR path to an implicit working directory in the container -l [LABELS [LABELS ...]], --label [LABELS [LABELS ...]]