new package watch-outputs and example of its use
This commit is contained in:
parent
2f82e0dab8
commit
d79a941504
@ -177,6 +177,17 @@ in rec {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
services.restart-on-change = longrun {
|
||||||
|
name = "wlan0-restart-on-change";
|
||||||
|
run = ''
|
||||||
|
${pkgs.watch-outputs}/bin/watch-outputs -r wlan0.link.hostapd ${config.services.secrets} wpa_passphrase
|
||||||
|
'';
|
||||||
|
dependencies = [
|
||||||
|
config.services.hostap-liminix
|
||||||
|
config.services.hostap-liminix5
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
services.bootstrap-dhcpc = svc.network.dhcp.client.build {
|
services.bootstrap-dhcpc = svc.network.dhcp.client.build {
|
||||||
interface = config.services.wwan;
|
interface = config.services.wwan;
|
||||||
dependencies = [ config.services.hostname ];
|
dependencies = [ config.services.hostname ];
|
||||||
|
@ -114,6 +114,7 @@ in {
|
|||||||
tufted = callPackage ./tufted { };
|
tufted = callPackage ./tufted { };
|
||||||
uevent-watch = callPackage ./uevent-watch { };
|
uevent-watch = callPackage ./uevent-watch { };
|
||||||
usb-modeswitch = callPackage ./usb-modeswitch { };
|
usb-modeswitch = callPackage ./usb-modeswitch { };
|
||||||
|
watch-outputs = callPackage ./watch-outputs { };
|
||||||
writeAshScript = callPackage ./write-ash-script { };
|
writeAshScript = callPackage ./write-ash-script { };
|
||||||
writeAshScriptBin = callPackage ./write-ash-script/bin.nix { };
|
writeAshScriptBin = callPackage ./write-ash-script/bin.nix { };
|
||||||
writeFennel = callPackage ./write-fennel { };
|
writeFennel = callPackage ./write-fennel { };
|
||||||
|
3
pkgs/watch-outputs/Makefile
Normal file
3
pkgs/watch-outputs/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
check:
|
||||||
|
./output-template '{{' '}}' < example.ini > output
|
||||||
|
diff -u output example.ini.expected
|
35
pkgs/watch-outputs/default.nix
Normal file
35
pkgs/watch-outputs/default.nix
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
fetchurl,
|
||||||
|
writeFennel,
|
||||||
|
fennel,
|
||||||
|
runCommand,
|
||||||
|
lua,
|
||||||
|
anoia,
|
||||||
|
linotify,
|
||||||
|
lualinux,
|
||||||
|
stdenv
|
||||||
|
}:
|
||||||
|
let name = "watch-outputs";
|
||||||
|
in stdenv.mkDerivation {
|
||||||
|
inherit name;
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
buildInputs = [lua];
|
||||||
|
# doCheck = true;
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
cp -p ${writeFennel name {
|
||||||
|
packages = [
|
||||||
|
anoia
|
||||||
|
lualinux
|
||||||
|
linotify
|
||||||
|
fennel
|
||||||
|
] ;
|
||||||
|
mainFunction = "run";
|
||||||
|
} ./watch-outputs.fnl } ${name}
|
||||||
|
'';
|
||||||
|
# checkPhase = "make check";
|
||||||
|
installPhase = ''
|
||||||
|
install -D ${name} $out/bin/${name}
|
||||||
|
'';
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
a11
|
@ -0,0 +1 @@
|
|||||||
|
a33
|
@ -0,0 +1 @@
|
|||||||
|
a55
|
@ -0,0 +1 @@
|
|||||||
|
a66
|
@ -0,0 +1 @@
|
|||||||
|
000000
|
1
pkgs/watch-outputs/example-service/.outputs/colours/blue
Normal file
1
pkgs/watch-outputs/example-service/.outputs/colours/blue
Normal file
@ -0,0 +1 @@
|
|||||||
|
0000ff
|
@ -0,0 +1 @@
|
|||||||
|
00ff00
|
1
pkgs/watch-outputs/example-service/.outputs/colours/red
Normal file
1
pkgs/watch-outputs/example-service/.outputs/colours/red
Normal file
@ -0,0 +1 @@
|
|||||||
|
ff0000
|
1
pkgs/watch-outputs/example-service/.outputs/name
Normal file
1
pkgs/watch-outputs/example-service/.outputs/name
Normal file
@ -0,0 +1 @@
|
|||||||
|
eth1
|
3
pkgs/watch-outputs/example.ini
Normal file
3
pkgs/watch-outputs/example.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
wpa_passphrase={{ output("./example-service","colours/black") }}
|
||||||
|
think = {{ string.format("%q", output("./example-service","colours/blue")) }}
|
||||||
|
argonaut = {{ json_quote "hello\ngoodbye\tnext\027" }}
|
3
pkgs/watch-outputs/example.ini.expected
Normal file
3
pkgs/watch-outputs/example.ini.expected
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
wpa_passphrase=000000
|
||||||
|
think = "0000ff"
|
||||||
|
argonaut = "hello\ngoodbye\tnext\u001B"
|
44
pkgs/watch-outputs/output-template.fnl
Normal file
44
pkgs/watch-outputs/output-template.fnl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
(local svc (require :anoia.svc))
|
||||||
|
|
||||||
|
(fn json-escape [s]
|
||||||
|
;; All Unicode characters may be placed within the quotation marks,
|
||||||
|
;; except for the characters that MUST be escaped:
|
||||||
|
;; quotation mark, reverse solidus, and the control characters (U+0000
|
||||||
|
;; through U+001F). (RFC 8259)
|
||||||
|
(-> s
|
||||||
|
(string.gsub
|
||||||
|
"[\"\b\f\n\r\t]" {
|
||||||
|
"\b" "\\b"
|
||||||
|
"\"" "\\\""
|
||||||
|
"\f" "\\f"
|
||||||
|
"\n" "\\n"
|
||||||
|
"\r" "\\r"
|
||||||
|
"\t" "\\t"
|
||||||
|
})
|
||||||
|
(string.gsub
|
||||||
|
"([\x00-\x1b])"
|
||||||
|
(fn [x] (string.format "\\u%04X" (string.byte x))))))
|
||||||
|
|
||||||
|
|
||||||
|
(fn substitute [text opening closing]
|
||||||
|
(let [delim (.. opening "(.-)" closing)
|
||||||
|
myenv {
|
||||||
|
: string
|
||||||
|
:output
|
||||||
|
(fn [service-path path]
|
||||||
|
(let [s (assert (svc.open (.. service-path "/.outputs")))]
|
||||||
|
(s:output path)))
|
||||||
|
:lua_quote #(string.format "%q" %1)
|
||||||
|
:json_quote (fn [x] (.. "\"" (json-escape x) "\""))
|
||||||
|
}]
|
||||||
|
(string.gsub text delim
|
||||||
|
(fn [x]
|
||||||
|
(assert ((load (.. "return " x) x :t myenv))
|
||||||
|
(string.format "missing value for %q" x))))))
|
||||||
|
|
||||||
|
(fn run []
|
||||||
|
(let [[opening closing] arg
|
||||||
|
out (substitute (: (io.input) :read "*a") opening closing)]
|
||||||
|
(io.write out)))
|
||||||
|
|
||||||
|
{ : run }
|
63
pkgs/watch-outputs/watch-outputs.fnl
Normal file
63
pkgs/watch-outputs/watch-outputs.fnl
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
(local { : system : assoc : split : table= } (require :anoia))
|
||||||
|
(local svc (require :anoia.svc))
|
||||||
|
(local { : view } (require :fennel))
|
||||||
|
(local { : kill } (require :lualinux))
|
||||||
|
|
||||||
|
(fn split-paths [paths]
|
||||||
|
(icollect [_ path (ipairs paths)]
|
||||||
|
(split "/" path)))
|
||||||
|
|
||||||
|
(fn parse-args [args]
|
||||||
|
(match args
|
||||||
|
["-r" service & rest] (assoc (parse-args rest)
|
||||||
|
:controlled-service service
|
||||||
|
:action :restart)
|
||||||
|
["-R" service & rest] (assoc (parse-args rest)
|
||||||
|
:controlled-service service
|
||||||
|
:action :restart-all)
|
||||||
|
["-s" signal service & rest] (assoc (parse-args rest)
|
||||||
|
:controlled-service service
|
||||||
|
:action [:signal signal])
|
||||||
|
[watched-service & paths] { : watched-service
|
||||||
|
:paths (split-paths paths)
|
||||||
|
}))
|
||||||
|
|
||||||
|
(fn dig [tree path]
|
||||||
|
(match path
|
||||||
|
[el & more] (dig (. tree el) more)
|
||||||
|
[el] (. tree el)
|
||||||
|
[] tree))
|
||||||
|
|
||||||
|
(fn changed? [paths old-tree new-tree]
|
||||||
|
(accumulate [changed? false
|
||||||
|
_ path (ipairs paths)]
|
||||||
|
(or changed? (not (table= (dig old-tree path) (dig new-tree path))))))
|
||||||
|
|
||||||
|
|
||||||
|
(fn do-action [action service]
|
||||||
|
(case action
|
||||||
|
:restart (system "s6-svc -r /run/service/%s" service)
|
||||||
|
:restart-all (system "s6-rc -b -d %q; s6-rc-up-tree %q" service service)
|
||||||
|
[:signal n] (system "s6-svc -s %d /run/service/%s" n service)))
|
||||||
|
|
||||||
|
(fn run []
|
||||||
|
(let [{
|
||||||
|
: controlled-service
|
||||||
|
: action
|
||||||
|
: watched-service
|
||||||
|
: paths } (parse-args arg)
|
||||||
|
dir (.. watched-service "/.outputs")
|
||||||
|
_ (print :service-dir dir)
|
||||||
|
service (assert (svc.open dir))]
|
||||||
|
(print "watching " watched-service)
|
||||||
|
(accumulate [tree (service:output ".")
|
||||||
|
v (service:events)]
|
||||||
|
(let [new-tree (service:output ".")]
|
||||||
|
(print :was (view tree) :now (view new-tree))
|
||||||
|
(when (changed? paths tree new-tree)
|
||||||
|
(print "watched path event:" action controlled-service)
|
||||||
|
(do-action action controlled-service))
|
||||||
|
new-tree))))
|
||||||
|
|
||||||
|
|
||||||
|
{ : run }
|
Loading…
Reference in New Issue
Block a user