13

Suppose I use nix-env to install a package that uses SystemD, on a Ubuntu host. What needs to be done to make Ubuntu's SystemD aware of the SystemD modules that come from Nix packages?

Let's try finding the Nix installed .service files, and symlinking them from /lib/systemd/system/, for the Apache Kafka package.

nix-env -i apache-kafka
sudo systemctl start apache-kafka # Failed to start apache-kafka.service: Unit apache-kafka.service not found.
sudo updatedb && locate apache-kafka.service # No dice
locate kafka | grep service # Just a bunch of `.nix` files

Here, I'm guessing the service name based on the service configuration's name in the Nix package definition. I haven't been able to find any documentation describing how and where that config becomes a SystemD service file.

When that didn't work, I started really digging around, on the assumption that somewhere, Nix must have created this service file. But now, I am starting to doubt that it exists. So, are SystemD modules installed by the Nix package manager supposed to work outside of NixOS, and if so, how do we make them work?

5

5 Answers 5

10

On NixOS it is possible to use environment.systemPackages = [ package ]; to install package's systemd units into system. Proof

Units in /nix/store/hash-package/lib/systemd/system are copied to /run/current-system/sw/lib/systemd/system, which is then used by systemd as an extra service dir.

So, if you want to use service units when installing package as root, be sure the path /root/.nix-profile/lib/systemd/system is used by systemd in addition to /etc/systemd/system. Also, be sure the derivation provides the units.

Completely untested, because I'm on NixOS

5

Location of *.service files

As to where the *.service files are located, Eelco Dolstra (main Nix author) recently answered a similar question:

Many packages do in fact provide systemd units, for example:

$ nix-build -A utillinux.bin

$ ls -l ./result-bin/lib/systemd/system/
total 16
-r--r--r-- 2 root root 155 Jan  1  1970 fstrim.service
-r--r--r-- 5 root root 170 Jan  1  1970 fstrim.timer
-r--r--r-- 2 root root 248 Jan  1  1970 uuidd.service
-r--r--r-- 2 root root 185 Jan  1  1970 uuidd.socket

So, depending how you build a derivation (official name for a "Nix package"), the *.service files should be available in resulting $out/lib/systemd/system/ directory. (Where for $out you may need to substitute different values, depending what options you use with nix-build.)

Specifically, when using nix-env -i (as is in your case), you should look into ~/.nix-profile/ as your $out. For example, on one of my machines:

$ ls -l ~/.nix-profile/lib/systemd/system/
total 8
-r--r--r-- 1 akavel akavel 268 sty  1  1970 nix-daemon.service
-r--r--r-- 1 akavel akavel 235 sty  1  1970 nix-daemon.socket

Activating the services in Ubuntu's systemd

As to this part of the question, I'm not sure how to do this at the moment, but I'm interested in configuring something similar as what you describe.

I think the following additional "parts" might be needed:

  • some change in Ubuntu systemd configuration to make it aware of the ~.nixprofile/... directory; (by the way: I believe some special user should be created for this, as those files will be then effectively equivalent to having sudo access)
  • some "activation" script which would run systemctl enable --now $SERVICE on all Nix-provided services;
    • ideally, not all services built by Nix should be auto-enabled, only the ones listed in some additional list, like enabledServices = [ ... ]; or something;
    • ideally, the "activation" script should disable services previously enabled from Nix, but now missing from enabledServices (maybe by checking active services in systemctl loaded from path .../.nix-profile/...?)
    • or maybe above could be done with some intermediary 'nixos-guest.target' thing, plus systemctl daemon-reload ?
2

It sounds like you have two questions:

  1. Where does Nix install files?
  2. Where do systemd files need to located for them to work?

Your nix package is almost certainly a compressed archive format like .zip or a .tar.gz, but with a different extension. You can check the file type by downloading the Nix package, and then using the file tool:

 file ./my-nix-package

Assuming it's using the .zip or .tar.gz format, you can then using the related zip or tar command to list the contents of the package. Usually package contents overlay the file system, so this will confirm for you if there's a .service file in the package and where it might be installed.

Nix might also have packaging command to answer the question "where are all the files that belong to this packakge?".

The answer to your second question is in man systemd.unit. systemd will look for systemd system unit files in the following directories, this this preference order:

   /etc/systemd/system/*
   /run/systemd/system/*
   /lib/systemd/system/*

If Nix is well-behaved, it would have installed systemd files into /lib/systemd/system. If it installed a .service file somewhere else, then you should copy or link it into /etc/systemd/system-- Only package managers should modify the files in /lib/systemd/system.

2
  • Yeah, Nix's directory layout is the polar opposite of what POSIX would consider "well behaved". Amazingly, it actually works out fairly well on top of a classic POSIX system, for the most part. Different goals, different strengths, different problems.
    – Dan Ross
    Mar 5, 2017 at 22:47
  • My plan was to symlink Nix managed files from one of the usual SystemD directories. Something that Nix would not do automatically, because that would defeat the goal of supporting conflicting software package installs; the host system's collection of service files are a form of global / singleton state.
    – Dan Ross
    Mar 5, 2017 at 22:54
2

I think nix-env-installed packages aren't found by systemd even on NixOS – and speaking of system services, I'd consider it a flaw if it were otherwise. (For user services this would make sense but I don't know the status of support.)

1
  • Yes, I did not expect the host SystemD to pick up on Nix installed files, for that reason. What is really throwing me for a loop though, is the fact that Nix doesn't seem to have created service files anywhere - it's like it is using SystemD without having any of SystemD's files kicking around. I suppose I should ask around on IRC or Slack or whatever the local dev community uses.
    – Dan Ross
    Mar 5, 2017 at 22:58
1

Create a file called ~/.config/systemd/user.conf with the following contents (make sure to replace your user-name):

[Manager]
ManagerEnvironment="XDG_DATA_DIRS=/home/your_user/.nix-profile/share:/usr/local/share:/usr/share"

This injects XDG_DATA_DIRS into the environment of the systemd --user process at startup, which makes the Nix systemd unit files discoverable from ~/.nix-profile/share/systemd/user.

See man 5 systemd-user.conf and man 5 systemd.unit for more information.

1
  • as a nice side-effect, this will also allow applications with a .desktop file to show up in the list of applications registered with Gnome (this might not update until you re-login)
    – Josh Bode
    Jun 1 at 22:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .