Nix package manager with CoreOS

I just want to share my nix package manager install butane file. With this you can install any nix package and use it with your coreos.

I just put selinux to permissive mode. If somebody needs to install nix with selinux enabled just write it here and I will share that butane too.

variant: fcos
version: 1.4.0
kernel_arguments:
  should_exist:
    - enforcing=0
systemd:
  units:
    - name: install-nix.service
      enabled: true
      contents: |
        [Unit]
        Description=Install nix package manager
        Requires=nix.mount
        Wants=network-online.target
        After=nix.mount network-online.target
        ConditionPathExists=!/var/lib/%N.stamp

        [Service]
        Type=oneshot
        User=core
        Group=core
        Environment=PATH=/var/home/core/.local/bin:/var/home/core/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
        ExecStart=/bin/sh -c "curl -L https://nixos.org/nix/install | sh"
        ExecStart=+/bin/touch /var/lib/%N.stamp

        [Install]
        WantedBy=multi-user.target
    - name: mkdir-rootfs@.service
      contents: |
        [Unit]
        Description=Enable mount points in / for ostree
        ConditionPathExists=!%f
        DefaultDependencies=no
        Requires=local-fs-pre.target
        After=local-fs-pre.target

        [Service]
        Type=oneshot
        ExecStartPre=chattr -i /
        ExecStart=mkdir -p '%f'
        ExecStopPost=chattr +i /
    - name: nix.mount
      enabled: true
      contents: |
        [Unit]
        Description=Nix Package Manager
        DefaultDependencies=no
        After=mkdir-rootfs@nix.service
        Wants=mkdir-rootfs@nix.service
        Before=sockets.target
        After=ostree-remount.service
        BindsTo=var.mount

        [Mount]
        What=/var/lib/nix
        Where=/nix
        Options=bind
        Type=none

        [Install]
        WantedBy=local-fs.target
storage:
  directories:
    - path: /var/lib/nix
      user:
        name: core
      group:
        name: core
1 Like

For SELinux, I wonder if the mock policy might get you pretty close to covering your bases? Perhaps:

semanage-fcontext -a -e /var/lib/mock /var/lib/nix
semanage-fcontext -a -e /var/lib/mock /nix
semanage fcontext -a -t bin_t "/var/home/core(/.local)?/bin(/.*)?"
restorecon -Rv /var/lib/nix /nix /var/home/core

(I have not tested this and have a very limited understanding of NixOS.)

I end up with this butane for selinux: enforcing

variant: fcos
version: 1.4.0
systemd:
  units:
    - name: rpm-ostree-install-policycoreutils-python-utils.service
      enabled: true
      contents: |
        [Unit]
        Description=Layer policycoreutils-python-utils with rpm-ostree
        Wants=network-online.target
        After=network-online.target
        # We run before `zincati.service` to avoid conflicting rpm-ostree
        # transactions.
        Before=zincati.service
        ConditionPathExists=!/var/lib/%N.stamp

        [Service]
        Type=oneshot
        Restart=on-failure
        RemainAfterExit=yes
        # `--allow-inactive` ensures that rpm-ostree does not return an error
        # if the package is already installed. This is useful if the package is
        # added to the root image in a future Fedora CoreOS release as it will
        # prevent the service from failing.
        ExecStart=/usr/bin/rpm-ostree install --apply-live --allow-inactive policycoreutils-python-utils
        ExecStart=/bin/touch /var/lib/%N.stamp

        [Install]
        WantedBy=multi-user.target
    - name: set-selinux-nix.service
      enabled: true
      contents: |
        [Unit]
        Description=Set /nix directory contexts
        Requires=rpm-ostree-install-policycoreutils-python-utils.service
        Wants=rpm-ostree-install-policycoreutils-python-utils.service
        After=nix.mount rpm-ostree-install-policycoreutils-python-utils.service
        ConditionPathExists=!/var/lib/%N.stamp

        [Service]
        Type=oneshot
        ExecStart=/bin/sh -c "semanage fcontext -a -t etc_t '/nix/store/[^/]+/etc(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t lib_t '/nix/store/[^/]+/lib(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t systemd_unit_file_t '/nix/store/[^/]+/lib/systemd/system(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t man_t '/nix/store/[^/]+/man(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t bin_t '/nix/store/[^/]+/s?bin(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t usr_t '/nix/store/[^/]+/share(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t var_run_t '/nix/var/nix/daemon-socket(/.*)?'"
        ExecStart=/bin/sh -c "semanage fcontext -a -t usr_t '/nix/var/nix/profiles(/per-user/[^/]+)?/[^/]+'"
        ExecStart=/bin/touch /var/lib/%N.stamp

        [Install]
        WantedBy=multi-user.target
    - name: install-nix.service
      enabled: true
      contents: |
        [Unit]
        Description=Install nix package manager
        Requires=nix.mount set-selinux-nix.service
        Wants=network-online.target
        After=nix.mount network-online.target set-selinux-nix.service
        ConditionPathExists=!/var/lib/%N.stamp

        [Service]
        Type=oneshot
        User=core
        Group=core
        Environment=PATH=/var/home/core/.local/bin:/var/home/core/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
        ExecStart=/bin/sh -c "curl -L https://nixos.org/nix/install | sh"
        ExecStart=+/bin/touch /var/lib/%N.stamp

        [Install]
        WantedBy=multi-user.target
    - name: mkdir-rootfs@.service
      contents: |
        [Unit]
        Description=Enable mount points in / for ostree
        ConditionPathExists=!%f
        DefaultDependencies=no
        Requires=local-fs-pre.target
        After=local-fs-pre.target

        [Service]
        Type=oneshot
        ExecStartPre=chattr -i /
        ExecStart=mkdir -p '%f'
        ExecStopPost=chattr +i /
    - name: nix.mount
      enabled: true
      contents: |
        [Unit]
        Description=Nix Package Manager
        DefaultDependencies=no
        After=mkdir-rootfs@nix.service
        Wants=mkdir-rootfs@nix.service
        Before=sockets.target
        After=ostree-remount.service
        BindsTo=var.mount

        [Mount]
        What=/var/lib/nix
        Where=/nix
        Options=bind
        Type=none

        [Install]
        WantedBy=local-fs.target
storage:
  directories:
    - path: /var/lib/nix
      user:
        name: core
      group:
        name: core
1 Like