Skip to content

Conversation

@EstAK
Copy link
Collaborator

@EstAK EstAK commented Oct 28, 2025

Features

  • Users managed through a UserManager
  • User context manager to "safely" run commands on the behalf of a user
  • Usage example : scala_container.py

Motivation

Instead of trusting the user to correctly scope where a user should be enable : encapsulate it. No need to use constructs like anymore :

def foo_builder():
    builder = PartialDockerBuilder()
    builder.root ()
    # some stuff
    builder.user()

now, you can use

def foo_builder(user_manager):
    builder = PartialDockerBuilder()
    builder.user_manager = user_manager
    with builder.as_root() as root_builder:
        # some stuff

at the end of the context manager you are ensured to return to the user that was used before entering it :

def foo_builder(user_manager): 
    builder = PartialDockerBuilder()
    builder.user_manager = user_manager
    with builder.as_user(username="user") as user_builder:
        # some stuff 
        with user_builder.as_root() as root_builder:
            # some stuff as root
       # some stuff as "user"again

EstAK added 2 commits October 28, 2025 18:20
Signed-off-by: Esteban Aguililla Klein <esteban.aguililla.klein.pro@outlook.com>
Signed-off-by: Esteban Aguililla Klein <esteban.aguililla.klein.pro@outlook.com>
@apaolillo apaolillo self-requested a review December 11, 2025 18:38
Copy link
Owner

@apaolillo apaolillo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @EstAK . It is a valuable feature. However, my overall feeling is that this PR does too many changes at once. It should probably split the user manager from the context manager, and the scala example could also come later (you may do a smaller example to validate the changes). Also is this change breaking the API? We can further discuss this.

tailored specifically for Docker environments.
"""

from __future__ import annotations
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

"""

def __init__(
self, partial_docker_builder: PartialDockerBuilder, on_behalf: str, return_to: str
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self, partial_docker_builder: PartialDockerBuilder, on_behalf: str, return_to: str
self, partial_docker_builder: PartialDockerBuilder, on_behalf: str, return_to: str,

and apply format (style.sh)

"""
A class that implements a user context manager where within said context, all actions will be
done on behalf of a chosen user.
"""
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be nested?

self.partial_docker_builder.user(name=self.on_behalf)
return self.partial_docker_builder

def __exit__(self, exc_type, exc_value, traceback):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def __exit__(self, exc_type, exc_value, traceback):
def __exit__(self, exc_type, exc_value, traceback) -> None:


def manage_user(self, username: str) -> None:
"""
Manages the user `username` through the `UserManager`
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what does that mean.

"""
if not name:
name = "${USER_NAME}" # fallback user
elif check and (name not in self.managed_users):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure why this check is necessary

partial_docker_builder._build_commands.append(StrDockerBuildCommand(cmd))

def as_user(
self, partial_docker_builder: PartialDockerBuilder, username: str
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self, partial_docker_builder: PartialDockerBuilder, username: str
self, partial_docker_builder: PartialDockerBuilder, username: str,

return_to: str = self.current_user
self.current_user = username

return UserContext(partial_docker_builder, on_behalf=self.current_user, return_to=return_to)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return UserContext(partial_docker_builder, on_behalf=self.current_user, return_to=return_to)
return UserContext(partial_docker_builder, on_behalf=self.current_user, return_to=return_to,)

Initializes a PartialDockerBuilder with an empty list of build commands.
"""
self._build_commands: List[DockerBuildCommand] = []
self.user_manager: UserManager | None = None
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this means we maintain in the builder all the users that were created?

command = " && \\\n ".join(commands)
self.run(command=command)

def user(self, name: str = "") -> None:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to keep the feature as before as well. Sometimes you don't want to return you just want a one way USER change.

@apaolillo apaolillo marked this pull request as draft December 12, 2025 15:49
@apaolillo
Copy link
Owner

as discussed: we split into more incremental feature set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants