Skip to content

Conversation

@dotconfig404
Copy link
Contributor

@dotconfig404 dotconfig404 commented Nov 12, 2025

About

This PR adds support for running the alpine container as a user with arbitrary UID.

Changes

Default user no longer root

The default user is now set to puppet, but can be set to a user with any UID, for example UID 1337: --user 1337. ~~Or back to root: --user root. ~~ EDIT: running as root will require some additional changes due to the runuser instruction in foreground. Not sure right now what needs to be changed, but if this is important I can check it out more closely once I get more time.

The default group is still root.

Group = root on relevant directories

The following directories have changed their group membership to root:

/etc/puppetlabs 
/var/log/puppetlabs 
/var/run/puppetlabs 
/opt/puppetlabs/var 
/opt/puppetlabs/cache 
/opt/puppetlabs/server/data

and their group access is mirroring the user permissions. The setgid bit has been set on these directories and their subdirectories to ensure permission inheritance.

The list of required directories may not be complete and could potentially be appended, but for basic operation they should suffice.

Any volumes should also be given root group and the needed permissions in order for the server to have access to them.

This pattern is the recommended approach to making OpenShift compatible containers:
https://developers.redhat.com/blog/2020/10/26/adapting-docker-and-kubernetes-containers-to-run-on-red-hat-openshift-container-platform
https://docs.redhat.com/en/documentation/openshift_container_platform/3.11/html/creating_images/creating-images-guidelines

30-set-permissions.sh removal

Another change was the removal of 30-set-permissions.sh. This script is not compatible with rootless containers, as it tries to recursively change owner and group to puppet on most of the directories that we just set the root group.

30-ensure-config.sh addition

This runtime script ensures that the default directories that are used for interpolation are the same for the current user and root. it also sets manage_internal_file_permissions to false, which is crucial for keeping the group membership as root

puppet config set vardir /opt/puppetlabs/puppet/cache
puppet config set logdir /var/log/puppetlabs/puppet
puppet config set codedir /etc/puppetlabs/code
puppet config set rundir /var/run/puppetlabs
puppet config set manage_internal_file_permissions false

USER="" in /etc/default/puppetserver

Before running the server the via the foreground, the EUID is compared to the UID of the user that is defined in /etc/default/puppetserver. If it is not the same, a user switch is done before execution.

We want this check to pass and in order to do so we could directly edit the foreground script, or we can set the USER variable to an empty string, as the check uses id -u ${USER} to get the UID, and when id -u` is called with no arguments it will give the UID of the current user.

This is not ideal, but probably stable enough. Maybe we could implement some upstream changes in the future to make this work without resorting to something like that.

Disabling link creation of CA dir in puppetserver setup

When calling puppetserver ca setup a symlink is created from /etc/puppetlabs/puppetserver/ca to $ssldir/ca. This is done for compatibility with puppet 6 in which the cadir still was in $ssldir.

During link creation chown is called, which is incompatible with can't be done without root or the CAP_CHOWN capability.

Therefore I opted to simply comment out the code line that creates starts the link creation via sed and a hardcoded path to the setup.rb script.. This is definitively brittle, maybe you have a better suggestion here?

Perhaps we could also monkey patch this or wrap the setup script otherwise.

Ultimately, I believe this should be fixed upstream. Maybe the support for the "old" cadir location could be dropped anyways, at least in the next major version. There was a bunch of issues in my initial approaches due to this, for example puppetserver ca setup defaults to $HOME/.puppetlabs/etc/puppetserver/ca for the cadir when non-root (which is congruent with all the other non-root paths) but puppet only defaults to that path if it exists, otherwise it will take the system path.

No more hardcoded Paths

The commit cca7655 changes a lot of hardcoded paths to be resolved via puppet config print instead. It may not strictly be necessary, as the paths do not change, but it makes the image more robust for future divergences.

@dotconfig404
Copy link
Contributor Author

I am actively using the main branch which is synced with the feat/nonroot of my fork and in doing so I may discover bugs, just like the one I just fixed in 5c2b008. The commit changes the list of directories that have the root group pattern slightly:

/etc/puppetlabs 
/var/log/puppetlabs 
/var/run/puppetlabs 
/opt/puppetlabs/ 

and ensures the config being used is the same. There was an issue with how puppet discovers the correct paths, somehow puppet config print gives the right paths, but they are not respected via library calls from the server.

Thus I just opted to additionally symlink the non-root directories and the system directories.

RUN ln -sf /etc/puppetlabs ${HOME}/.puppetlabs/etc
RUN ln -sf /opt/puppetlabs ${HOME}/.puppetlabs/opt
RUN ln -sf /var/log/puppetlabs ${HOME}/.puppetlabs/var/log
RUN ln -sf /var/run/puppetlabs ${HOME}/.puppetlabs/var/run

and additionally initialised the puppet.conf with some directories set.

Probably overkill, but it works. :)

Also tested some basic volumes mounting, e.g. cadir or puppet.conf, seems good.

Just have to repeat the general usage instruction of giving root group the necessary permissions on the volumes of course.

@rwaffen
Copy link
Member

rwaffen commented Nov 14, 2025

LGTM

@rwaffen rwaffen added the enhancement New feature or request label Nov 14, 2025
@dotconfig404 dotconfig404 force-pushed the feat/nonroot branch 2 times, most recently from 6547d90 to 0f4638f Compare November 14, 2025 14:29
@rwaffen
Copy link
Member

rwaffen commented Nov 20, 2025

markdown check will be fixed separately from me

@rwaffen rwaffen merged commit 8e9940c into OpenVoxProject:main Nov 20, 2025
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants