[systemd-devel] Best practice for prepopulating the CacheDirectory of dynamic users

Antoine Pietri antoine.pietri1 at gmail.com
Tue Feb 27 13:37:33 UTC 2018


Hi!

To experiment with systemd dynamic users, I started working on a
wrapper around a program that builds user packages (Archlinux makepkg)
and that refuses to be launched as root (for very good reasons). The
idea is that the wrapper just calls:

systemd-run --pipe \
  -p DynamicUser=yes \
  -p CacheDirectory=mywrapper \
  -p WorkingDirectory=/var/cache/mywrapper/build/repo \
  makepkg

However, to be able to run makepkg, its cache directory has to be
pre-populated with a clone of the package to build. So, from my
wrapper, I just did:

  os.makedirs(os.path.dirname(build_dir), exist_ok=True)
  shutil.copytree(repo_path, build_dir)

to copy the content of the repo to the build directory. But it fails with:

  run-u63.service: Failed to set up special execution directory in
/var/cache: File exists

This makes sense, because of the symbolic link shenanigans to
/var/cache/private that systemd uses to keep the filesystem readonly.
So, now I'm wondering what would be the best practice to prepopulate
this directory:

- My current workaround is to shell-out to `systemd-run -p
DynamicUser=yes ...` first to do a mkdir -p, then for a cp -R. This
solution requires a lot of boilerplate from the Python wrapper and
takes more time for no good reason, so I think it's not ideal.

- I believe another solution would be to modify /var/cache/private
directly, but I'm not sure it's a good practice to do so because I
don't know if this path is reliable or just an implementation detail.
Plus, it requires a weird special case compared to when I don't run
makepkg with systemd-run, as I have to insert something in the middle
of the copy destination path.

- Maybe there's something else I'm missing that would allow me to do
this more cleanly?

Thanks,

-- 
Antoine Pietri


More information about the systemd-devel mailing list