Skip to content

Instantly share code, notes, and snippets.

@jarppe
Created October 18, 2021 08:03
Show Gist options
  • Save jarppe/edca8f5bcc78c033da7c7aff6d76bcd6 to your computer and use it in GitHub Desktop.
Save jarppe/edca8f5bcc78c033da7c7aff6d76bcd6 to your computer and use it in GitHub Desktop.
Babashka script to shutdown idle host
#!/usr/local/bin/bb
(require '[clojure.java.shell :as sh]
'[clojure.string :as str])
(import '(java.util.concurrent TimeUnit)
'(java.time ZoneId ZonedDateTime)
'(java.time.format DateTimeFormatter))
(def check-interval (.toMillis TimeUnit/MINUTES 5))
(def max-idle-time (.toMillis TimeUnit/HOURS 3))
(def log
(let [zone (ZoneId/of "Europe/Helsinki")
formatter (DateTimeFormatter/ofPattern "yyyy-MM-dd HH:mm:ss")]
(fn [& args]
(apply println (-> (ZonedDateTime/now zone)
(.format formatter)
(str " -")
(cons args))))))
(defn active-session-count []
(let [{:keys [exit out err]} (sh/sh "w" "-hs")]
(when (not= exit 0)
(log "FAIL: can't exec w\n" err)
(System/exit 1))
(->> out
(str/split-lines)
(remove str/blank?)
(count))))
(defn shutdown! []
(log "Max idle time reached, system shutdown initiated")
(sh/sh "/usr/sbin/shutdown" "-h" "now"))
(loop [idle-since nil]
(let [now (System/currentTimeMillis)
session-count (active-session-count)
idle-time (if idle-since
(- now idle-since))
time-left (if idle-time
(- max-idle-time idle-time))]
(if (and time-left (neg? time-left))
(shutdown!)
(do (log (str session-count " active sessions"
(if time-left
(str ", " (.toSeconds TimeUnit/MILLISECONDS time-left) " seconds until shutdown")
"")))
(Thread/sleep check-interval)
(recur (if (zero? session-count)
(or idle-since now)))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment