about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/system/boot/systemd/sysupdate.nix
blob: b1914a9c4e76709aad5fee312998d235f80d19ef (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
{ config, lib, pkgs, utils, ... }:

let
  cfg = config.systemd.sysupdate;

  format = pkgs.formats.ini { };

  definitionsDirectory = utils.systemdUtils.lib.definitions
    "sysupdate.d"
    format
    cfg.transfers;
in
{
  options.systemd.sysupdate = {

    enable = lib.mkEnableOption (lib.mdDoc "systemd-sysupdate") // {
      description = lib.mdDoc ''
        Atomically update the host OS, container images, portable service
        images or other sources.

        If enabled, updates are triggered in regular intervals via a
        `systemd.timer` unit.

        Please see
        <https://www.freedesktop.org/software/systemd/man/systemd-sysupdate.html>
        for more details.
      '';
    };

    timerConfig = utils.systemdUtils.unitOptions.timerOptions.options.timerConfig // {
      default = { };
      description = lib.mdDoc ''
        The timer configuration for performing the update.

        By default, the upstream configuration is used:
        <https://github.com/systemd/systemd/blob/main/units/systemd-sysupdate.timer>
      '';
    };

    reboot = {
      enable = lib.mkEnableOption (lib.mdDoc "automatically rebooting after an update") // {
        description = lib.mdDoc ''
          Whether to automatically reboot after an update.

          If set to `true`, the system will automatically reboot via a
          `systemd.timer` unit but only after a new version was installed.

          This uses a unit completely separate from the one performing the
          update because it is typically advisable to download updates
          regularly while the system is up, but delay reboots until the
          appropriate time (i.e. typically at night).

          Set this to `false` if you do not want to reboot after an update. This
          is useful when you update a container image or another source where
          rebooting is not necessary in order to finalize the update.
        '';
      };

      timerConfig = utils.systemdUtils.unitOptions.timerOptions.options.timerConfig // {
        default = { };
        description = lib.mdDoc ''
          The timer configuration for rebooting after an update.

          By default, the upstream configuration is used:
          <https://github.com/systemd/systemd/blob/main/units/systemd-sysupdate-reboot.timer>
        '';
      };
    };

    transfers = lib.mkOption {
      type = with lib.types; attrsOf format.type;
      default = { };
      example = {
        "10-uki.conf" = {
          Transfer = {
            ProtectVersion = "%A";
          };

          Source = {
            Type = "url-file";
            Path = "https://download.example.com/";
            MatchPattern = "nixos_@v.efi.xz";
          };

          Target = {
            Type = "regular-file";
            Path = "/EFI/Linux";
            PathRelativeTo = "boot";
            MatchPattern = ''
              nixos_@v+@l-@d.efi"; \
              nixos_@v+@l.efi \
              nixos_@v.efi
            '';
            Mode = "0444";
            TriesLeft = 3;
            TriesDone = 0;
            InstancesMax = 2;
          };
        };
      };
      description = lib.mdDoc ''
        Specify transfers as a set of the names of the transfer files as the
        key and the configuration as its value. The configuration can use all
        upstream options. See
        <https://www.freedesktop.org/software/systemd/man/sysupdate.d.html>
        for all available options.
      '';
    };

  };

  config = lib.mkIf cfg.enable {

    systemd.additionalUpstreamSystemUnits = [
      "systemd-sysupdate.service"
      "systemd-sysupdate.timer"
      "systemd-sysupdate-reboot.service"
      "systemd-sysupdate-reboot.timer"
    ];

    systemd.timers = {
      "systemd-sysupdate" = {
        wantedBy = [ "timers.target" ];
        timerConfig = cfg.timerConfig;
      };
      "systemd-sysupdate-reboot" = lib.mkIf cfg.reboot.enable {
        wantedBy = [ "timers.target" ];
        timerConfig = cfg.reboot.timerConfig;
      };
    };

    environment.etc."sysupdate.d".source = definitionsDirectory;
  };

  meta.maintainers = with lib.maintainers; [ nikstur ];
}