[systemd-devel] Best way to limit per-user system-wide units
Samuel Williams
space.ship.traveller at gmail.com
Tue Dec 13 22:17:08 UTC 2016
Reindl, thanks for your continued help.
> what *exact* problem are you trying to solve - don#t come with the solution
> "doing that as systemd-unit" - explain the problem what you are trying to
> solve not the solution you think is good!
Okay, our website deployment process is something like this.
Developers (or ci) have a password-less (ssh key only) account on the
server (either production or development).
- They push code into a repository on the production server using git.
They are a member of the group of the .git directory (usually http),
the code is pushed as the website user/group so that all users can do
it without borking up the permissions on files.
- The git repository runs a post-receive hook as that user (e.g. "bob"
or "ci"). It performs several tasks as that user, but the primary
task, once the source code is checked out and updated, is to deploy
any changes.
- The way this works, is that `rake deploy` is run in the web
directory. This task does quite a bit of stuff, including updating
foreman tasks.
- Foreman can generate tasks in lots of different ways, but we prefer
systemd units. We essentially run `sudo systemctl stop
$website.target`, `foreman export ...` and then `sudo systemctl start
$website.target`.
Exact foreman command: sh("bundle", "exec", "foreman", "export",
"systemd", SYSTEMD_UNIT_PATH, "-a", DATABASE_NAME, "-u",
`whoami`.chomp!)
sudo is set up to allow developers to do pretty much anything without
a password, while the website user is locked down pretty tightly.
Ideally, we don't expose root via the ability to arbitrarily load
systemd tasks.
For me, the ideal solution would be something like a per-user global
systemd unit directory. In theory, systemd would run units in that
directory locked down to that specific user. But, being in the global
context, would allow tasks to depend on each other. If it was kept in
a separate directory, it would simplify deployment and changes.
The next best solution as far as I can see, is to use systemd --user.
But this has a number of downsides - firstly out of the box it doesn't
work with a sudo environment:
Logged in as a dev user:
% systemd-run --user sleep 10
Running as unit: run-r341b245b4e324a2fa9aec1c272d8abea.service
% sudo -u http !!
sudo -u http systemd-run --user sleep 10
Failed to create bus connection: No such file or directory
% su -c "sudo -u http systemd-run --user sleep 10" - http
Password:
su: Authentication failure
Secondly, I've got concerns about how reliable this is in terms of
tasks that need to start at boot, and might have dependencies on
system-level tasks. How does `loginctl enable-linger http` work and is
it reliable?
Thanks for any insight, ideas, or suggestions you might have to
improve this process.
Kind regards
Samuel
More information about the systemd-devel
mailing list