liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

odhcp6-script.fnl (2938B)


      1 (local { : split : merge : hash : base64url } (require :anoia))
      2 (local { : mktree : rmtree } (require :anoia.fs))
      3 
      4 (local state-directory (assert (os.getenv "SERVICE_STATE")))
      5 (mktree state-directory)
      6 
      7 (fn write-value [name value]
      8   (let [path (.. state-directory "/" name)]
      9     (with-open [fout (io.open path :w)]
     10       (when value (fout:write value)))))
     11 
     12 (fn write-value-from-env [name]
     13   (write-value name (os.getenv (string.upper name))))
     14 
     15 (fn parse-address [str]
     16   (fn parse-extra [s]
     17     (let [out {}]
     18       (each [name val (string.gmatch s ",(.-)=([^,]+)")]
     19         (tset out name val))
     20       out))
     21   (let [(address len preferred valid extra)
     22         (string.match str "(.-)/(%d+),(%d+),(%d+)(.*)$")]
     23     (merge {: address : len : preferred : valid} (parse-extra extra))))
     24 
     25 (fn write-addresses [prefix addresses]
     26   (each [_ a (ipairs (split " " addresses))]
     27     (let [address (parse-address a)
     28           suffix (base64url (string.pack "n" (hash a)))
     29           ;; keydir should be a function of all the address
     30           ;; attributes: we want it to change whenever anything changes
     31           ;; so that clients can see which addresses are new without
     32           ;; deep table comparisons
     33           keydir (..
     34                   prefix
     35                   (-> address.address
     36                       (: :gsub "::$" "")
     37                       (: :gsub ":" "-"))
     38                   "_"
     39                   suffix)]
     40       (mktree (.. state-directory "/" keydir))
     41       (each [k v (pairs address)]
     42         (write-value (.. keydir "/" k) v)))))
     43 
     44 ;; we remove state before updating to ensure that consumers don't get
     45 ;; a half-updated snapshot
     46 (os.remove (.. state-directory "/state"))
     47 
     48 ;; remove parsed addresses/prefixes from any previous run
     49 (rmtree (.. state-directory "/prefix"))
     50 (rmtree (.. state-directory "/address"))
     51 
     52 (let [wanted
     53       [
     54        :addresses
     55        :aftr
     56        :cer
     57        :domains
     58        :lw406
     59        :mape
     60        :mapt
     61        :ntp_fqdn
     62        :ntp_ip
     63        :option_1
     64        :option_2
     65        :option_3
     66        :option_4
     67        :option_5
     68        :passthru
     69        :prefixes
     70        :ra_addresses
     71        :ra_dns
     72        :ra_domains
     73        :ra_hoplimit
     74        :ra_mtu
     75        :ra_reachable
     76        :ra_retransmit
     77        :ra_routes
     78        :rdnss
     79        :server
     80        :sip_domain
     81        :sip_ip
     82        :sntp_ip
     83        :sntp_fqdn
     84        ]]
     85   (each [_ n (ipairs wanted)]
     86     (write-value-from-env n))
     87 
     88   (match (os.getenv :ADDRESSES) s (write-addresses "address/" s))
     89   (match (os.getenv :PREFIXES) s (write-addresses "prefix/" s)))
     90 
     91 (let [[ifname state] arg
     92       ready (match state
     93               "started" false
     94               "unbound" false
     95               "stopped" false
     96               _ true)]
     97   (write-value ".lock" (tostring (os.time)))
     98   (write-value "ifname" ifname)
     99   (write-value "state" state)
    100   (os.remove (.. state-directory "/.lock"))
    101   (when ready
    102     (with-open [fd (io.open "/proc/self/fd/10" :w)] (fd:write "\n"))))