]> git.scottworley.com Git - auto-upgrade-with-pinch/blob - upgrade-config.nix
e9962ebbee18662ac1fd902ffd71e3f466cc7c92
[auto-upgrade-with-pinch] / upgrade-config.nix
1 { upgradeConfig, lib ? (import <nixpkgs> { }).lib, }:
2 with lib;
3 evalModules {
4 modules = upgradeConfig ++ [{
5 options = {
6
7 enable = mkOption {
8 type = types.bool;
9 default = false;
10 description = ''
11 Whether to periodically upgrade NixOS to the latest version.
12 Presumes that /etc/nixos is a git repo with a remote and
13 contains a pinch file called "channels".
14 '';
15 };
16
17 dates = mkOption {
18 default = "04:40";
19 type = types.str;
20 description = ''
21 Specification (in the format described by
22 <citerefentry><refentrytitle>systemd.time</refentrytitle>
23 <manvolnum>7</manvolnum></citerefentry>) of the time at
24 which the update will occur.
25 '';
26 };
27
28 repos = mkOption {
29 description = ''
30 Git repositories to pull before running pinch. These are maintained
31 as git checkouts at specified places in the filesystem with specified
32 ownership rather than kept read-only in the nix store so that humans
33 can use them both as points of intervention in the automation and to
34 author and push changes back up.
35 '';
36 type = types.attrsOf (types.submodule {
37 options = {
38 url = mkOption {
39 description = "Remote git repo.";
40 type = types.str;
41 };
42 remoteName = mkOption {
43 description = ''Name of the git remote. Customarily "origin".'';
44 type = types.str;
45 default = "origin";
46 };
47 onRemoteURLMismatch = mkOption {
48 description = ''
49 What to do if the remote URL in the git repo doesn't match the
50 URL configured here.
51 '';
52 type = types.enum [ "update" "abort" ];
53 default = "update";
54 };
55 onBranchMismatch = mkOption {
56 description = ''
57 What to do if a different branch is currently checked out.
58
59 (Changes from <literal>remoteBranch</literal> are only ever
60 merged into <literal>localBranch</literal>, so if a different
61 branch is checked out, no remote changes will be merged.)
62 '';
63 type = types.enum [ "continue" "abort" ];
64 default = "continue";
65 };
66 user = mkOption {
67 description = "User as which to run 'git fetch'";
68 type = types.str;
69 };
70 localBranch = mkOption {
71 description = "";
72 type = types.str;
73 default = "master";
74 };
75 remoteBranch = mkOption {
76 type = types.str;
77 default = "master";
78 };
79 requireSignature = mkOption {
80 type = types.bool;
81 default = true;
82 description = ''
83 Only pull when the tip of the remote ref is signed by a key
84 specifed in <literal>signingKeys</literal>.
85 '';
86 };
87 signingKeys = mkOption {
88 type = types.listOf types.path;
89 description = ''
90 Files containing GPG keys that are authorized to sign updates.
91 Updates are only merged if the commit at the tip of the remote
92 ref is signed with one of these keys.
93 '';
94 };
95 };
96 });
97 example = {
98 "/etc/nixos" = {
99 url = "https://github.com/chkno/auto-upgrade-demo-nixos";
100 user = "root";
101 signingKeys = [ ./admins.asc ];
102 };
103 "/home/alice/.config/nixpkgs" = {
104 url = "https://github.com/chkno/auto-upgrade-demo-user-nixpkgs";
105 user = "alice";
106 signingKeys = [ ./admins.asc ./alice.asc ];
107 };
108 };
109 };
110
111 pinchFiles = mkOption {
112 description = ''
113 Pinch files to use for channel updates. Typically these are inside
114 <literal>repos</literal>' paths.
115 '';
116 type = types.listOf types.path;
117 example = [ "/etc/nixos/channels" ];
118 };
119
120 userEnvironments = mkOption {
121 description = ''
122 User environments to update as part of an upgrade run.
123 '';
124 type = types.attrsOf (types.submodule {
125 options = {
126 package = mkOption {
127 type = types.str;
128 default = "userPackages";
129 description = ''
130 The name of the single package that will be updated. You'll
131 want to create an 'entire user environment' package as shown in
132 https://nixos.wiki/wiki/FAQ#How_can_I_manage_software_with_nix-env_like_with_configuration.nix.3F
133 '';
134 };
135 otherPackagesAction = mkOption {
136 type = types.enum [ "remove" "keep" "abort" ];
137 default = "remove";
138 description = ''
139 What to do with packages other than <literal>package</literal>.
140
141 THIS DEFAULTS TO "remove", WHICH IS POTENTIALLY SOMEWHAT
142 DESTRUCTIVE! This is the default because it is the recommended
143 setting -- This module recommends managing your environment
144 through your one entire-environment <literal>package</literal>.
145 This keeps your environment declarative and ensures that all
146 packages receive regular updates.
147 '';
148 # It seems like "upgrade" ought to be another choice here, powered
149 # by "nix-env --upgrade". But when I tried this, it didn't work.
150 };
151 };
152 });
153 example = { alice = { }; };
154 };
155 };
156 }];
157 }