Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NixOS's systemd abstraction doesn't work with systemd template units #135557

Closed
grahamc opened this issue Aug 24, 2021 · 12 comments
Closed

NixOS's systemd abstraction doesn't work with systemd template units #135557

grahamc opened this issue Aug 24, 2021 · 12 comments
Labels
0.kind: bug 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: nixos

Comments

@grahamc
Copy link
Member

grahamc commented Aug 24, 2021

Describe the bug

A clear and concise description of what the bug is.

Steps To Reproduce

Steps to reproduce the behavior:

Create a template unit, like:

{
  systemd.services."foo@" = {
    scriptArgs = "%i";
    script = ''
      echo "$1"
    '';
  };

  systemd.services."foo@example" = {};
}

Expected behavior

Starting foo@example should run the foo@example template service.

Actual behavior

Starting a template unit which is not defined by NixOS works fine:

# systemctl start foo@bar
# journalctl -fu foo@bar
-- Journal begins at Wed 2021-08-11 22:25:17 EDT. --
Aug 24 10:01:35 scruffy systemd[1]: Started foo@bar.service.
Aug 24 10:01:35 scruffy foo_-start[3297689]: bar
Aug 24 10:01:35 scruffy systemd[1]: foo@bar.service: Succeeded.

However, starting the foo@example service, defined by NixOS fails:

# systemctl status foo@example
● foo@example.service
     Loaded: bad-setting (Reason: Unit foo@example.service has a bad unit file setting.)
     Active: inactive (dead)

Aug 24 10:01:41 scruffy systemd[1]: foo@example.service: Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing.

Notify maintainers

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

  • system: "x86_64-linux"
  • host os: Linux 5.10.52, NixOS, 21.11.20210810.6f6ade6 (Porcupine)
  • multi-user?: yes
  • sandbox: yes
  • version: nix-env (Nix) 2.4pre20210813_d581129
  • nixpkgs: /nix/var/nix/profiles/per-user/root/channels/nixos

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
# a list of nixos modules affected by the problem
module:
@grahamc
Copy link
Member Author

grahamc commented Aug 24, 2021

Further, I added another service like:

{
  systemd.services."several-foos" = {
      requires = [ "foo@fizz" "foo@buzz" ]; 
      wantedBy = [ "default.target" ];
      script = ''
      
      '';
 }

and several-foos starts but foo@fizz and foo@buzz do not get started.

@vcunat
Copy link
Member

vcunat commented Aug 24, 2021

I've been successfully generating a target. Re-tested now on 21.05:

{
    systemd.targets.kresd = { # configure units started by default
      wantedBy = [ "multi-user.target" ];
      wants = [ "kres-cache-gc.service" ]
        ++ map (i: "kresd@${toString i}.service") (range 1 cfg.instances);
    };
 }

@grahamc
Copy link
Member Author

grahamc commented Aug 24, 2021

Is the kresd@.service unit file provided by kresd the package, or by a NixOS service?

@vcunat
Copy link
Member

vcunat commented Aug 24, 2021

Provided by package and modified by service.

@grahamc
Copy link
Member Author

grahamc commented Aug 24, 2021

I think the issue is unique to units which are created totally by the module system.

@vcunat
Copy link
Member

vcunat commented Aug 24, 2021

As a workaround you should be able to define a pseudo-package that defines the service (i.e. creates the unit file "manually").

@rnhmjoj
Copy link
Contributor

rnhmjoj commented Aug 25, 2021

Duplicate of #80933?

@pennae
Copy link
Contributor

pennae commented Oct 5, 2021

using instances of systemd services create by the module system in OnFailure= clauses does work on recent nixos-unstable (c21ba4f), as does the snippet from #135557 (comment) after suffixing .service to each required unit.

this does feel like it's behaving correctly: referencing templated units with parameters elsewhere invokes them as expected, and defining them through the module system defines them as though they hadn't existed before. maybe we should have a systemd.dropIn.<name> to explicitly configure overrides?

@roberth
Copy link
Member

roberth commented Jan 9, 2022

I think we should first model Exec* correctly before we revise are replace .script. #154123

@stale stale bot added the 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md label Jul 10, 2022
@ck3d
Copy link
Contributor

ck3d commented Oct 28, 2022

PR #186314 is now merged into master, which fixes this issue. A working example:

{
  systemd.services."foo@" = {
    scriptArgs = "%i";
    script = ''
      echo "$1"
    '';
  };

  systemd.services."foo@example" = {
    overrideStrategy = "asDropin";
  };
}

@con-f-use
Copy link
Contributor

con-f-use commented Jul 13, 2024

I don't think that example works anymore and we might be looking at a regression here. As in if I copy&paste this the foo@example job is not started on system boot but rather displayed in systemctl status foo@example.service as dead. The corresponding service file does not have an exec line or anything other than environment definitions:

$ cat /etc/systemd/system/foo@example.service.d/overrides.conf 
[Unit]

[Service]
Environment="LOCALE_ARCHIVE=/nix/store/9dij3pl4dkdxmxhasjw1pa9hzqv4rjlp-glibc-locales-2.39-52/lib/locale/locale-archive"
Environment="PATH=/nix/store/ysqx2xfzygv2rxl7nxnw48276z5ckppn-coreutils-9.5/bin:/nix/store/36rvynxwln7iz0qq3k1v3r1mna8bma8s-fi"
Environment="TZDIR=/nix/store/jyh52p2cxrjn8r4ywdv2am5pjkj1xcqa-tzdata-2024a/share/zoneinfo"

Reproduction:
image

# build with: nix-build <this file>
# then run: result/bin/run-nixos-vm
let
  configuration = 
    { pkgs, lib, config, ... }:
    {
      systemd.services."foo@" = {
        scriptArgs = "%i";
        script = ''
          echo "$1"
        '';
      };

      systemd.services."foo@example" = {
        overrideStrategy = "asDropin";
      };

      services.getty.autologinUser = "root";

      system.stateVersion = config.system.nixos.release;

      virtualisation.vmVariant = {
        virtualisation = {
          qemu.options = [ "-vga virtio" ];
          diskImage = null; # "./nixos.qcow2";
          mountHostNixStore = true;
          writableStoreUseTmpfs = false;
        };
      };

      boot.loader.grub.device = "nodev";
      fileSystems."/" = { };
    }
  ;

  commit = "a046c1202e11b62cbede5385ba64908feb7bfac4";
  source = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/${commit}.tar.gz";
  };
in
(import "${source}/nixos/lib/eval-config.nix" {
  system = "x86_64-linux";
  modules = [ configuration ];
}).config.virtualisation.vmVariant.system.build.vm

@ck3d @grahamc

@ck3d
Copy link
Contributor

ck3d commented Jul 28, 2024

The override.conf should not have an exec setting, the the template service defines exec. Also the status dead looks as expected.
I see no degradation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug 2.status: stale https://github.com/NixOS/nixpkgs/blob/master/.github/STALE-BOT.md 6.topic: nixos
Projects
None yet
Development

No branches or pull requests

7 participants