s6-rc-up-tree.fnl (2132B)
1 (local { : opendir : readdir } (require :lualinux)) 2 3 (fn fail [err] 4 (print "ERROR" err) 5 (os.exit 1)) 6 7 (macro with-popen [[handle command] & body] 8 `(let [,handle (assert (io.popen ,command)) 9 val# (do ,(unpack body))] 10 (case (: ,handle :close) 11 ok# val# 12 (nil :exit code#) (fail (.. ,command " exited " code#)) 13 (nil :signal sig#) (fail (.. ,command " killed by " sig#))))) 14 15 (fn popen [command] 16 (with-popen [fh command] (icollect [v (fh:lines)] v))) 17 18 (fn controlled-services [dir] 19 (case (opendir dir) ;; FIXME [nit] doesn't closedir 20 d (collect [filename #(readdir d)] 21 (if (not (string.match filename "^%.")) 22 (values filename filename))) 23 (nil err) (fail (.. "can't open " dir " :" err)))) 24 25 (fn stopped-controlled-services [dir] 26 (let [controlled (controlled-services dir)] 27 (with-popen [h (.. "s6-rc -b -da list")] 28 (collect [s (h:lines)] 29 (if (. controlled s) (values s s)))))) 30 31 (fn dependencies [service] 32 (popen (.. "s6-rc-db all-dependencies " service))) 33 34 (fn reverse-dependencies [service] 35 (popen (.. "s6-rc-db -d all-dependencies " service))) 36 37 (fn start-service [name] 38 (with-popen [h (.. "s6-rc -b -u change " name)] 39 (each [s (h:lines)] 40 (print "s6-rc " name ": " s)))) 41 42 (fn keys [t] 43 (icollect [_ v (pairs t)] v)) 44 45 (fn run [dir] 46 (let [service (. arg 1) 47 blocks (doto 48 (stopped-controlled-services (or dir "/run/services/controlled")) 49 (tset service nil)) 50 rdepends (reverse-dependencies service) 51 starts 52 (icollect [_ s (ipairs rdepends)] 53 (when 54 (accumulate [start true 55 _ dep (ipairs (dependencies s))] 56 (and start (not (. blocks dep)))) 57 s))] 58 (print "s6-rc-up-tree" 59 service 60 "blocks (" (table.concat (keys blocks) ", ") ")" 61 ;; "rdepends (" (table.concat rdepends ", ") ")" 62 "start (" (table.concat starts ", ") ")") 63 (if (> (# starts) 0) 64 (each [_ s (ipairs starts)] 65 (start-service s)) 66 (os.exit 1)))) 67 68 69 { : run }