I’m trying to use a webhook server on NixOS. It’s an HTTP endpoint handler. You define an endpoint and when there’s GET or POST request arrives to this endpoint, webhook executes command(or script). I created systemd service, which has to run webhook as a service. Here’s a configuration:
{ pkgs, ... }:
{
environment.etc."webhook.conf".text = ''
[
{
"id": "update",
"execute-command": "/var/webhook/update.sh",
"command-working-directory": "/tmp"
},
{
"id": "rollback",
"execute-command": "nixos-rebuild switch --rollback",
"command-working-directory": "/tmp"
},
]
'';
users.users.webhook = {
isNormalUser = true;
};
systemd.services.webhook = {
enable = true;
serviceConfig = {
User = "webhook";
ExecStart = "${pkgs.webhook}/bin/webhook -hooks /etc/webhook.conf -secure -cert /var/lib/acme/example.com/fullchain.pem -key /var/lib/acme/example.com/key.pem -verbose";
};
};
}
But when I trigger the command execution, webhook fails to execute any command I ask it because “command not found”
● webhook.service
Loaded: loaded (/nix/store/7gc38iaqm789xgw741ha5ry6mvfs0zza-unit-webhook.service/webhook.service; linked; vendor preset: enabled)
Active: active (running) since Thu 2020-09-24 12:16:18 UTC; 11min ago
Main PID: 30867 (webhook)
IP: 1.4K in, 5.0K out
Tasks: 5 (limit: 1166)
Memory: 8.4M
CPU: 42ms
CGroup: /system.slice/webhook.service
└─30867 /nix/store/a3513plsphspb0fa55yyhznkbk2fv4mr-webhook-2.6.8-bin/bin/webhook -hooks /etc/webhook.conf -secure -cert /var/lib/acme/ilchub.net/fullchain.pem -key /var/lib/acme/ilchub.net/key.pem -ve>
Sep 24 12:16:18 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:18 serving hooks on https://0.0.0.0:9000/hooks/{id}
Sep 24 12:16:18 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:18 os signal watcher ready
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] incoming HTTP request from 93.77.150.2:49634
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] update got matched
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] update hook triggered successfully
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 200 | 1.238232ms | example.com:9000 | GET /hooks/update
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] executing /var/webhook/update.sh (/var/webhook/update.sh) with arguments ["/var/webhook/update.sh"] and environment [] using /tmp as c>
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] command output: /var/webhook/update.sh: line 3: nixos-rebuild: command not found
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] error occurred: exit status 127
Sep 24 12:16:35 ilchub webhook[30867]: [webhook] 2020/09/24 12:16:35 [5c4246] finished handling update
Here’s a content of /var/webhook/update.sh
#!/run/current-system/sw/bin/bash
nixos-rebuild switch --upgrade
So, I’m wondering, how to make this script, running in the shell with all commands available
lewo
September 24, 2020, 1:42pm
2
You have to replace nixos-rebuild
with something such as ${config.system.build.nixos-rebuild}/bin/nixos-rebuild
. You can look at the auto-upgrade module .
Also, instead of writing -hooks /etc/webhook.conf
you should write something such as -hooks ${myWebhookFile}
(where myWebhookFile = pkgs.writeText "filename" "file content"
), otherwise, nixos-rebuild won’t be able to restart your service on configuration file changes. You could also use the “writers” to create scripts on the fly
I followed your advice and rewritten my webhook.nix, this way:
{ pkgs, config, ... }:
{
nixpkgs.overlays = [(self: super: {
updateScript = pkgs.writeScriptBin "updateScript" ''
#!${pkgs.stdenv.shell}
${config.system.build.nixos-rebuild}/bin/nixos-rebuild --upgrade
'';
})];
environment.etc."webhook.conf".text = ''
[
{
"id": "update",
"execute-command": "${pkgs.updateScript}/bin/updateScript",
"command-working-directory": "/tmp"
},
{
"id": "rollback",
"execute-command": "nixos-rebuild switch --rollback",
"command-working-directory": "/tmp"
},
]
'';
users.users.webhook = {
isNormalUser = false;
};
systemd.services.webhook = {
enable = true;
serviceConfig = {
User = "webhook";
ExecStart = "${pkgs.webhook}/bin/webhook -hooks /etc/webhook.conf -secure -cert /var/lib/acme/example.com/fullchain.pem -key /var/lib/acme/example.com/key.pem -verbose";
};
};
}
but the problem seems to be in the nixos-rebuild script, itself
● webhook.service
Loaded: loaded (/nix/store/7gc38iaqm789xgw741ha5ry6mvfs0zza-unit-webhook.service/webhook.service; linked; vendor preset: enabled)
Active: active (running) since Thu 2020-09-24 14:13:00 UTC; 14s ago
Main PID: 32647 (webhook)
IP: 1.5K in, 3.6K out
Tasks: 6 (limit: 1166)
Memory: 1.8M
CPU: 42ms
CGroup: /system.slice/webhook.service
└─32647 /nix/store/a3513plsphspb0fa55yyhznkbk2fv4mr-webhook-2.6.8-bin/bin/webhook -hooks /etc/webhook.conf -secure -cert /var/lib/acme/example.com/fullchain.pem -key /var/lib/acme/example.com/key.pem -ve>
Sep 24 14:13:00 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:00 serving hooks on https://0.0.0.0:9000/hooks/{id}
Sep 24 14:13:00 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:00 os signal watcher ready
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] incoming HTTP request from 93.77.150.2:52462
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] update got matched
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] update hook triggered successfully
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 200 | 1.622591ms | example.com:9000 | GET /hooks/update
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] executing /nix/store/8whbihdvcz7k84rm0qip1nclzq9zpw89-updateScript/bin/updateScript (/nix/store/8whbihdvcz7k84rm0qip1nclzq9zpw89-updat>
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] command output: /nix/store/85vha2v87a5gbqdy1kvwh4c11h1av0rg-nixos-rebuild/bin/nixos-rebuild: line 11: exec: man: not found
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] error occurred: exit status 127
Sep 24 14:13:13 ilchub webhook[32647]: [webhook] 2020/09/24 14:13:13 [faa855] finished handling update
nixos-rebuild calls other binaries directly, instead of using Nixpkg variables
Then a systemd unit can define it’s path:
systemd.services.<name>.path
where you could put the different packages your service may require
Could you, please, provide more detailed usage examples of this option?
Yeah. Seems like a plan. But I tried adding nix-channel command, this way:
systemd.services.webhook = {
path = with pkgs; [
man
nix-channel
];
enable = true;
serviceConfig = {
User = "webhook";
ExecStart = "${pkgs.webhook}/bin/webhook -hooks /etc/webhook.conf -secure -cert /var/lib/acme/ilchub.net/fullchain.pem -key /var/lib/acme/ilchub.net/key.pem -verbose";
};
and got configuration switch error:
building Nix...
building the system configuration...
error: undefined variable 'nix-channel' at /etc/nixos/webhook.nix:31:7
(use '--show-trace' to show detailed location information)
How do I include this package?
twoolie
September 25, 2020, 5:05am
8
try config.nix.package.out
instead of nix-channel
1 Like
What about source
command? I thought it would work without adding it to systemd path, but it doesn’t. So I added source
, but it says error: undefined variable 'source'
How to use it in systemd services?