Create systemd top-level drop-in - nixos

Systemd supports top-level drop-ins which can be applied to all systemd services or units of a particular type. This is super useful if you want to, for example, have an email sent anytime a systemd service enters a failure state.
Essentially, you have to create a file at /etc/systemd/system/service.d/onfailure.conf and the contents of that file will get applied as a drop-in to all systemd services.
Here's a detailed explanation for how this works in systemd:
https://trstringer.com/systemd-top-level-drop-in/
How would I go about doing this in NixOS?

I ended up finding a direct answer to this problem over on the NixOS discourse forums:
https://discourse.nixos.org/t/how-to-use-toplevel-overrides-for-systemd/12501

Related

Golang os.Create permission denied

I'm trying to create a log file on linux /var/log directory, but got permission denied. Any best practices without having to change the ownership of the directory?
f, _ := os.Create("/var/log/go_server.log")
defer f.Close()
log.SetOutput(f)
What you have there is a standard UNIX permissions issue. Given the special nature of that directory, you've got three options:
Change the permissions of that directory to be more promiscuous. Bad idea, as it opens up a nasty can of worms security-wise.
Run the go program using sysV, upstart, or systemd such that the program runs with a user with permissions there (usually root). Better because only one process gets the upgrade and you get nice start/stop/monitor routines and rudimentary self-healing with upstart or systemd. Indeed, you may want to explore using one of those if you're not already.
Use go's built-in interface to syslog and configure your local syslogd to save its logs to that file. Best, because you're just sending logs to a socket and letting the service deal with it for you.
Note also that systemd can save your stdout/err to files if you configure it right and you can then browse with journalctl. Indeed, leaving your program to stupidly print diags to stdout/err and not forking itself is the smartest thing to do now that systemd does all that stuff for you (that way, you can focus on what your program does and not reinventing the wheel wrt daemonization and logging).
For all the grief systemd gets, it's actually pretty good at this use case.

How can a program detect if it is running as a systemd daemon?

Is there any way to detect in a program that it is run by systemd as a daemon?
systemd API
sd_booted()
is used to detected if the whole system is booted by systemd, but says nothing about the program itself.
Thanks
Get the parent process id and see whether that process is systemd.
Starting from systemd v232, an environment variable INVOCATION_ID is given to all processes started as (part of) a service unit. This is a nice trait from systemd and not any other service manager, so it can be used as a convenient way to detect systemd, but not necessarily reliable.
Personally I use this to disable timestamp in logging as systemd journal already does that.
You could set a magic environment variable in the daemon's service file and look for this variable.

Programmatically start systemd service or test if service running

I need to start a service and (later) detect if it running from within a C++ program. Is there a simpler approach than invoking systemctl with suitable arguments and parsing the output?
The source of the service is entirely under my control. (Currently it is written in bash, but a C++ wrapper is entirely possible.)
(I've had a brief look at DBus - it is clearly very powerful, but fails the "simpler" test.)
The source of the service is entirely under my control. (Currently it is written in bash, but C++ is entirely possible.)
The code is for an embedded device running a variant of Debian Jessie. Portability is not a major concern (but obviously the answer will be more useful to others if it is portable).
Most programs are written with the other way in mind (even in pre-systemd days).
Typical services (those having and started with a single server process) are writing their PID (as an ASCII number on a single line) in some /var/run/foobar.pid file at their startup. If you adopt such a convention in your service, you can read that file using fscanf then check that the process is running with kill(pid, 0); (of course, you cannot be certain that it is the same service, but it probably would be).
I have right now more than 20 files matching /var/run/*.pid, notably /var/run/sshd.pid & /var/run/atd.pid
So, assuming you can improve the code of your service FooBar (if that functionality is not there), change its code to write its pid into /var/run/foobar.pid; this is a documented convention.
If you can change the service, you might have it providing some ping or nop functionality; so you would add to it some RPC facility which justs check that the service is running (and could also give some additional information, like the version of the program, etc.). Most existing Linux services have such feature.
Why not flip the problem around? No parsing would be needed.
ttm.update.service will do the following.
systemctl stop ttm.service
systemctl disable ttm.service
#do you update here
#if the service configs changed do
systemctl daemon-reload
systemctl enable ttm.service
systemctl start ttm.service
ttm.service would never have to worry about the updater, it just runs and do it's job.

How can I tell Puppet to stop a service on shutdown without keeping it running?

Context:
On a linux (RedHat family) system, I have an init-script-based service that is started/stopped manually most of the time, and in general is only run in response to specific, uncommon situations. The init scripts are thin wrappers around code that I do not have control over.
If the service is killed without running the stop action on its init script, it is aborted uncleanly and leaves the system in a broken state that requires manual intervention to fix.
When the systems running the service shut down, they kill it uncleanly. I can register the service with chkconfig such that it gets shut down via the init script when the host shuts down; this solves the problem on a per-host basis.
Question:
I would like to automate the configuration of this service to stop-at-shutdown via Puppet.
How can I tell Puppet to register a service with chkconfig such that the service will be stopped via the init script when the system shuts down, but will not otherwise be managed by Puppet?
What I've Tried:
I made a hokey exec statement in Puppet that calls chkconfig directly, but that feels inelegant (and will probably break in some way I haven't thought of).
I played around with the noop flag to the service type in Puppet, but it didn't seem to have the desired effect.
Puppet does not have any built-in support for configuring which runlevels a service runs in, nor any built-in, generalized support for chkconfig. Ordinarily it is a service-installation responsibility to register the service with chkconfig; services that are installed from the system RPMs are registered that way.
Furthermore, chkconfig recognizes structured comments at the top of initscripts to determine which runlevels the service will run in by default, according to LSB convention. A proper initscript need only be registered with chkconfig to have the default runlevels set -- in particular, for it to be set to be stopped in runlevels 0 and 6, which is what you're after.
If you're rolling your own initscripts and deploying them manually or directly via Puppet (as opposed to packaging them up and installing them via Yum) then your best bet is probably to build a defined type that manages the initscript and its registration. You do not need and probably do not want a Service resource for it, but a File resource to put the proper file in place and an Exec resource to handle registration sounds about right.

How do I disable SELinux for a subprocess launched from Apache?

My Apache module launches a helper subprocess which does, for example, but not limited by, the following things:
It sets up a socket so that it can communicate with Apache.
Reads and writes files in a temporary location that is deleted when Apache exits. These files are used e.g. for storing large amounts of data received over the network, in case that data does not comfortably fit in RAM.
It spawns user-specified executables. Similar to CGI. Each of these spawned processes are run as their own dedicated user.
The helper subprocess is launched as root so that it can manage file ownerships and permissions and can spawn more processes as specific users.
Some users of my module run on systems with SELinux installed, e.g. RedHat-based distros. SELinux usually interferes with my module. Until now I've been telling people to disable SELinux system-wide because I can't figure out how to write a proper policy for my software. Documentation is very scattered, complex and usually only targets system administrators, not software developers.
As a step into the right direction, I want to implement minimal support for SELinux. I'm looking for a way to launch my helper subprocess without any SELinux constraints without disabling SELinux system-wide. Is there a way to do that, and if so, how?
Well... you could write a rule that transitions your domain to unconfined_t, but then you'd piss off quite a few sysadmins. Best to write yourself a new domain that inherits from httpd_t and also adds the appropriate contexts for access.

Resources