[systemd-devel] Best practice for prepopulating the CacheDirectory of dynamic users
aleivag
aleivag at gmail.com
Wed Feb 28 16:13:36 UTC 2018
Hi Antoine:
2 disclosure before reading this:
1) i'm not part of systemd-devel team, and
2) this is also a shameless plug because i'm talking about a lib i created.
with that out of the way, here is my advice/solution.
do everything in python and use `pystemd` (pip install pystemd, just have
libsystemd installed and you should be fine), and also ditch the
cachedirectory in favor of PrivateTmp, that is always new when you start
your unit, and always goes away with your unit.
pystemd is apython wrapper around a few libsystemd-dev, and it has a nice
module name pystemd.run, here is a example
import sys
import pystemd.run
pscript = """
import os
import shutil
print(shutil.copytree('/var/cache/dnf', '/tmp/dnf'))
print(os.listdir('/tmp/dnf'))
"""
pystemd.run(
['/usr/bin/python3', '-c', pscript],
stdout=sys.stdout, stderr=sys.stderr, wait=True,
env={'PYTHONUSERBASE': '/dev/null'},
extra={'DynamicUser': True, 'PrivateTmp': True},
)
this would output: something like
/tmp/dnf
['last_makecache', '.gpgkeyschecked.yum', 'rawhide-2d95c80a1fa0a67d',
'google-chrome-filenames.solvx', 'tempfiles.json',
'rawhide-filenames.solvx', 'google-chrome.solv', 'expired_repos.json',
'rawhide.solv', 'packages.db', 'google-chrome-eb0d6f10ccbdafba']
so my recommendation, create a custom script with your build process and
call it using pystemd.run. Now, you could also use systemd-run to run your
script, but then it would not have been a shameless plug, right?
hope it helps
Alvaro Leiva
On Wed, Feb 28, 2018 at 7:03 AM, Antoine Pietri <antoine.pietri1 at gmail.com>
wrote:
> On Tue, Feb 27, 2018 at 2:37 PM, Antoine Pietri
> <antoine.pietri1 at gmail.com> wrote:
> > - 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?
>
> We came up with a third option, which looks a bit weird at first but
> should work:
>
> 1) systemd-run -P \
> -p DynamicUser=yes \
> -p CacheDirectory=mywrapper \
> sh -c read
>
> 2) do the file operations in the Python code
> 3) send a "\n" or just kill() the systemd-run process when the setup is
> done.
>
> I am still not satisfied with any of the three options, so I would
> love to know what you think would be best. :-)
>
> --
> Antoine Pietri
>
> On Tue, Feb 27, 2018 at 2:37 PM, Antoine Pietri
> <antoine.pietri1 at gmail.com> wrote:
> > 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
>
>
>
> --
> Antoine Pietri
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/systemd-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20180228/e72fecda/attachment.html>
More information about the systemd-devel
mailing list