-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodule.nix
More file actions
122 lines (107 loc) · 4.5 KB
/
module.nix
File metadata and controls
122 lines (107 loc) · 4.5 KB
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
{ config, lib, pkgs, ... }:
let
inherit (builtins) attrValues toFile;
inherit (lib) escapeShellArg mkEnableOption mkOption mkIf;
cfg = config.flake-programdb;
# Parses aws listing xml
hredParseNext = "nextmarker @.textContent";
hredParseKeys = "contents key @.textContent";
# Selects the release corresponding to a given rev, or fails with at least some kind of error message
jqSrc = toFile "select-rev.jq" ''
def prefixof(str): . as $prefix | str | startswith($prefix);
map(select(split(".") | last | prefixof($rev))) |
if length == 1 then
.[0]
else
error("Git revision must have exactly one match among the channel releases. Matches for revision \($rev): \(.)")
end
'';
# Downloads programs.sqlite from the release of the selected channel
# with the same rev as our nixpkgs input, if not already downloaded.
downloadDatabase = pkgs.resholve.writeScript "download-programs-database" {
interpreter = "${pkgs.bash}/bin/bash";
inputs = attrValues {
inherit (pkgs) coreutils curl hred jq xz gnutar sqlite;
};
execer = [ "cannot:${pkgs.hred}/bin/hred" ]; # Remove this line once 25.11 has been out for a while. See https://github.com/NixOS/nixpkgs/pull/419679
} ''
set -e -o pipefail
aws_depaginate() {
exec {fd}>&1
next="$(curl -fsSL "$1" | tee /proc/self/fd/$fd | hred ${escapeShellArg hredParseNext} -cr)"
while [ -n "$next" ]; do
next="$(curl -fsSL "$1&marker=$next" | tee /proc/self/fd/$fd | hred ${escapeShellArg hredParseNext} -cr)"
done
}
dbdir="$1"
channel="$2"
rev="$3"
# Quit if we already have a database for the right rev
[ -e "$dbdir/programs.sqlite" ] && [ -e "$dbdir/programs.rev" ] && [ "$(< "$dbdir/programs.rev")" == "$rev" ] && exit 0
# Ensure we'll keep trying until we succeed
rm -f "$dbdir/programs.rev"
# Get the channel prefix used by the release infra
redirect_url="$(curl -fsSw '%{redirect_url}' "https://channels.nixos.org/$channel")"
current_release="''${redirect_url#https://releases.nixos.org/}"
channel_prefix="''${current_release%/*}"
# Parse the list of channel releases for our channel and find the one with our nixpkgs rev
aws_url="https://nix-releases.s3.amazonaws.com/?delimiter=/&prefix=$channel_prefix/"
correct_release="$(aws_depaginate "$aws_url" | hred ${escapeShellArg hredParseKeys} | jq -rf ${jqSrc} --arg rev "$rev")"
# Download nixexprs.tar.xz and extract programs.sqlite in stream
nixexprs_url="https://releases.nixos.org/$correct_release/nixexprs.tar.xz"
curl -fsSL "$nixexprs_url" | xz -d | tar -xO --wildcards '*/programs.sqlite' > "$dbdir/programs.sqlite.part"
# Check that what we downloaded at least looks like a valid sqlite3 database
test_result="$(sqlite3 -readonly "$dbdir/programs.sqlite.part" 'PRAGMA integrity_check')"
[ "$test_result" == "ok" ]
# Overwrite previous download
mv -Tf "$dbdir/programs.sqlite.part" "$dbdir/programs.sqlite"
echo "$rev" > "$dbdir/programs.rev"
'';
in
{
options.flake-programdb = {
enable = mkEnableOption "downloading the command-not-found database";
dbDir = mkOption {
type = lib.types.path;
default = "/var/cache/programdb";
};
channel = mkOption {
type = lib.types.str;
default = "nixos-" + config.system.nixos.release;
defaultText = ''"nixos-" + config.system.nixos.release'';
};
rev = mkOption {
type = lib.types.nullOr lib.types.str;
default = config.system.nixos.revision;
defaultText = "config.system.nixos.revision";
};
};
config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.rev != null;
message = "flake-programdb.rev cannot be null. Autodetection of nixpkgs rev most likely failed. Set the option yourself to indicate your nixpkgs rev.";
}
];
programs.command-not-found.enable = true;
programs.command-not-found.dbPath = "${cfg.dbDir}/programs.sqlite";
systemd.tmpfiles.settings.flake-programdb.${cfg.dbDir} = {
d = {
user = "root";
group = "root";
mode = "0755";
};
};
systemd.services.flake-programdb = {
description = "program database download for command-not-found";
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
serviceConfig = {
Type = "oneshot";
ExecStart = "${downloadDatabase} ${cfg.dbDir} ${cfg.channel} ${cfg.rev}";
RemainAfterExit = true;
};
};
};
}