commit f164f19d954cf41c763272db913850dbb12251ee
parent dd4ab41f6ac4f76bca1d8132e9eb456f0e3f0818
Author: Daniel Barlow <dan@telent.net>
Date: Wed, 6 Mar 2024 23:18:28 +0000
service starts and stops
Diffstat:
2 files changed, 111 insertions(+), 31 deletions(-)
diff --git a/pkgs/ifwait/ifwait.fnl b/pkgs/ifwait/ifwait.fnl
@@ -1,9 +1,8 @@
(local nl (require :anoia.nl))
+(local { : assoc : system } (require :anoia))
; (local { : view} (require :fennel))
-(local { : assoc : system } (require :anoia))
-
(fn parse-args [args]
(match args
["-v" & rest] (assoc (parse-args rest) :verbose true)
@@ -31,9 +30,19 @@
_
{})]
- (. got params.expecting)))
+ (not (not (. got params.expecting)))))
+
+(var up :unknown)
+(fn toggle-service [service wanted?]
+ (when (not (= up wanted?))
+ (set up
+ (if wanted?
+ (pcall system (.. "s6-rc -u change " service))
+ (not (pcall system (.. "s6-rc -d change " service)))))
+ ))
(fn run [args event-fn]
+ (set up :unknown)
(let [parameters
(assert (parse-args args)
(.. "Usage: ifwait [-v] ifname [present|up|running]"))]
@@ -41,9 +50,13 @@
(print (.. "ifwait: waiting for "
parameters.link " to be " parameters.expecting)))
- (each [e (event-fn)
- &until (event-matches? parameters e)]
- true)))
+ (if parameters.service
+ (each [e (event-fn)]
+ (if (= e.name parameters.link)
+ (toggle-service parameters.service (event-matches? parameters e))))
+ (each [e (event-fn)
+ &until (event-matches? parameters e)]
+ true))))
(when (not (= (. arg 0) "test"))
(run arg #(nl.events {:link true})))
diff --git a/pkgs/ifwait/test-ifwait.fnl b/pkgs/ifwait/test-ifwait.fnl
@@ -4,6 +4,14 @@
(var fake-system (fn [s] (print "executing " s)))
(tset anoia :system #(fake-system $1))
+(macro expect= [actual expected]
+ `(let [ve# (view ,expected)
+ va# (view ,actual)]
+ (when (not (= ve# va#))
+ (assert false
+ (.. "\nexpected " ve# "\ngot " va#)
+ ))))
+
(fn event-generator [events]
(coroutine.wrap
(fn []
@@ -19,34 +27,93 @@
(local ifwait (require :ifwait))
(let [gen (event-generator (file-events "events-fixture"))]
- (ifwait.run ["-v" "dummy0" "up"] #gen)
+ (ifwait.run ["dummy0" "up"] #gen)
(match (pcall gen)
(true _) true
(false msg) (error "didn't detect dummy0 up event")))
-(var succeeded? false)
+(var upsies [])
(set fake-system
(fn [s]
- (print "exec" s)
- (if (s:match "addmember") (set succeeded? true))))
-
-(let [events
- [{:event "newlink"
- :hwaddr "b6:7d:5c:38:89:1d"
- :index 21
- :mtu 1500
- :name "dummy0"
- :running "no"
- :stamp 857161382
- :up "no"}
- {:event "newlink"
- :hwaddr "52:f0:46:da:0c:0c"
- :index 22
- :mtu 1500
- :name "dummy0"
- :running "no"
- :stamp 857161383
- :up "yes"}]
- gen (event-generator events)]
- (ifwait.run ["-v" "-s" "addmember" "dummy0" "up"] #gen)
- (assert succeeded?))
+ (if (s:match "-u change addmember")
+ (table.insert upsies :u)
+ (s:match "-d change addmember")
+ (table.insert upsies :d))))
+
+(fn newlink [name up running]
+ {:event "newlink"
+ :hwaddr "b6:7d:5c:38:89:1d"
+ :index (string.unpack ">i2" name)
+ :mtu 1500
+ : name
+ : running
+ :stamp 857161382
+ : up })
+
+"when it gets events that don't match the interface, nothing happens"
+
+(let [gen (-> [(newlink "eth1" "no" "no")] event-generator)]
+ (set upsies [])
+ (ifwait.run [ "-s" "addmember" "dummy0" "up"] #gen)
+ (expect= upsies []))
+
+"when it gets an event that should start the service, the service starts"
+
+(let [gen (->
+ [(newlink "dummy0" "no" "no")
+ (newlink "dummy0" "yes" "no")
+ (newlink "eth1" "no" "no")]
+ event-generator)]
+ (set upsies [])
+ (ifwait.run ["-s" "addmember" "dummy0" "up"] #gen)
+ (expect= upsies [:d :u]))
+
+"when it gets an event that should stop the service, the service stops"
+
+(let [gen (->
+ [(newlink "dummy0" "no" "no")
+ (newlink "dummy0" "yes" "no")
+ (newlink "dummy0" "no" "no")
+ ]
+ event-generator)]
+ (set upsies [])
+ (ifwait.run ["-s" "addmember" "dummy0" "up"] #gen)
+ (expect= upsies [:d :u :d]))
+
+"it does not call s6-rc again if the service is already in required state"
+
+(let [gen (->
+ [(newlink "dummy0" "no" "no")
+ (newlink "dummy0" "yes" "no")
+ (newlink "dummy0" "yes" "yes")
+ (newlink "dummy0" "yes" "yes")
+ (newlink "dummy0" "yes" "no")
+ (newlink "dummy0" "no" "no")
+ ]
+ event-generator)]
+ (set upsies [])
+ (ifwait.run ["-s" "addmember" "dummy0" "up"] #gen)
+ (expect= upsies [:d :u :d]))
+
+"it handles an error return from s6-rc"
+
+(set fake-system
+ (fn [s]
+ (if (s:match "-u change addmember")
+ (table.insert upsies :u)
+ (s:match "-d change addmember")
+ (table.insert upsies :d))
+ (error "false")
+ ))
+
+(let [gen (->
+ [(newlink "dummy0" "yes" "no")
+ (newlink "dummy0" "yes" "yes")
+ (newlink "dummy0" "yes" "yes")
+ (newlink "dummy0" "yes" "no")
+ (newlink "dummy0" "no" "no")
+ ]
+ event-generator)]
+ (set upsies [])
+ (ifwait.run ["-s" "addmember" "dummy0" "up"] #gen)
+ (expect= upsies [:u :u :u :u]))