Basic playbook functionality
This commit is contained in:
parent
3685369de5
commit
38f08e8ce4
8 changed files with 237 additions and 33 deletions
19
examples/inventory.scm
Normal file
19
examples/inventory.scm
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
(use-modules (ordo connection)
|
||||||
|
(ordo inventory))
|
||||||
|
|
||||||
|
(list
|
||||||
|
(host #:name "localhost"
|
||||||
|
#:connection (local-connection)
|
||||||
|
#:tags '(#:linux #:guix))
|
||||||
|
|
||||||
|
(host #:name "limiting-factor"
|
||||||
|
#:connection (ssh-connection "limiting-factor" #:user "core")
|
||||||
|
#:tags '(#:linux #:coreos))
|
||||||
|
|
||||||
|
(host #:name "screw-loose"
|
||||||
|
#:connection (ssh-connection "screw-loose" #:user "core")
|
||||||
|
#:tags '(#:linux #:coreos))
|
||||||
|
|
||||||
|
(host #:name "control-surface"
|
||||||
|
#:connection (ssh-connection "control-surface")
|
||||||
|
#:tags '(#:linux #:debian)))
|
8
examples/playbook.scm
Normal file
8
examples/playbook.scm
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
(use-modules (ordo playbook))
|
||||||
|
|
||||||
|
(playbook
|
||||||
|
#:name "Example playbook"
|
||||||
|
#:vars '((foo . 1) (bar . "baz"))
|
||||||
|
#:plays (list
|
||||||
|
(play #:name "Example play"
|
||||||
|
#:host "localhost")))
|
|
@ -1,8 +1,12 @@
|
||||||
(define-module (ordo cli run)
|
(define-module (ordo cli run)
|
||||||
#:use-module (config)
|
#:use-module (config)
|
||||||
#:use-module (config api)
|
#:use-module (config api)
|
||||||
|
#:use-module (ice-9 filesystem)
|
||||||
|
#:use-module (ordo inventory)
|
||||||
#:use-module (ordo logger)
|
#:use-module (ordo logger)
|
||||||
|
#:use-module (ordo playbook)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
#:export (config handler))
|
#:export (config handler))
|
||||||
|
|
||||||
(define (valid-tags? x)
|
(define (valid-tags? x)
|
||||||
|
@ -21,9 +25,9 @@
|
||||||
(list
|
(list
|
||||||
(setting
|
(setting
|
||||||
(name 'inventory)
|
(name 'inventory)
|
||||||
(default "inventory.scm")
|
(default "/dev/null")
|
||||||
(example "examples/inventory.scm")
|
(example "examples/inventory.scm")
|
||||||
(handler identity)
|
(handler (cut expand-file-name <> #f #t))
|
||||||
(test file-exists?)
|
(test file-exists?)
|
||||||
(synopsis "Inventory file"))
|
(synopsis "Inventory file"))
|
||||||
(switch
|
(switch
|
||||||
|
@ -37,12 +41,11 @@
|
||||||
(list
|
(list
|
||||||
(argument
|
(argument
|
||||||
(name 'playbook)
|
(name 'playbook)
|
||||||
(handler identity)
|
(handler (cut expand-file-name <> #f #t))
|
||||||
(test file-exists?))))
|
(test file-exists?))))
|
||||||
(synopsis "Run a playbook")))
|
(synopsis "Run a playbook")))
|
||||||
|
|
||||||
(define (handler options)
|
(define (handler options)
|
||||||
(let ((inventory (option-ref options 'inventory))
|
(let ((inventory (load-inventory (option-ref options 'inventory)))
|
||||||
(playbook (option-ref options '(playbook))))
|
(playbook (load-playbook (option-ref options '(playbook)))))
|
||||||
(log-msg 'INFO "Running playbook " playbook " with inventory " inventory)
|
(run-playbook playbook inventory)))
|
||||||
))
|
|
||||||
|
|
|
@ -23,23 +23,25 @@
|
||||||
(define (local-connection)
|
(define (local-connection)
|
||||||
(make <local-connection>))
|
(make <local-connection>))
|
||||||
|
|
||||||
(define* (ssh-connection user host #:key (password #f) (identity #f) (authenticate-server? #t))
|
(define* (ssh-connection host #:key (user (getlogin)) (password #f) (identity #f) (authenticate-server? #t))
|
||||||
(make <ssh-connection> #:user user #:host host #:password password
|
(make <ssh-connection> #:user user #:host host #:password password
|
||||||
#:identity identity #:authenticate-server? authenticate-server?))
|
#:identity identity #:authenticate-server? authenticate-server?))
|
||||||
|
|
||||||
(define* (call-with-connection conn proc #:key sudo? sudo-user sudo-password)
|
(define* (call-with-connection conn proc #:key sudo? sudo-user sudo-password)
|
||||||
(when (and sudo? (not (is-a? conn <sudo-connection>)))
|
(let ((conn (deep-clone conn)))
|
||||||
(raise-exception
|
(when sudo?
|
||||||
(make-exception
|
(unless (is-a? conn <sudo-connection>)
|
||||||
(make-programming-error)
|
(raise-exception
|
||||||
(make-exception-with-message (format #f "connection ~a does not support sudo" conn)))))
|
(make-exception
|
||||||
(set! (become? conn) sudo?)
|
(make-programming-error)
|
||||||
(set! (become-user conn) sudo-user)
|
(make-exception-with-message (format #f "connection ~a does not support sudo" conn)))))
|
||||||
(set! (become-password conn) sudo-password)
|
(set! (become? conn) sudo?)
|
||||||
(dynamic-wind
|
(set! (become-user conn) sudo-user)
|
||||||
(lambda () (setup conn))
|
(set! (become-password conn) sudo-password))
|
||||||
(lambda () (proc conn))
|
(dynamic-wind
|
||||||
(lambda () (teardown conn))))
|
(lambda () (setup conn))
|
||||||
|
(lambda () (proc conn))
|
||||||
|
(lambda () (teardown conn)))))
|
||||||
|
|
||||||
(define (run conn prog . args)
|
(define (run conn prog . args)
|
||||||
(let* ((args options (break keyword? args))
|
(let* ((args options (break keyword? args))
|
||||||
|
|
49
ordo/context.scm
Normal file
49
ordo/context.scm
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
(define-module (ordo context)
|
||||||
|
#:use-module (srfi srfi-69))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Inventory
|
||||||
|
;;
|
||||||
|
(define-public *inventory* (make-parameter #f))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Playbook vars
|
||||||
|
;;
|
||||||
|
(define-public *playbook-vars* (make-parameter #f))
|
||||||
|
|
||||||
|
(define-public (playbook-var-ref key)
|
||||||
|
(hash-table-ref (*playbook-vars*) key))
|
||||||
|
|
||||||
|
(define-public (playbook-var-ref/default key default)
|
||||||
|
(hash-table-ref/default (*playbook-vars*) key default))
|
||||||
|
|
||||||
|
(define-public (playbook-var-set! key value)
|
||||||
|
(hash-table-set! (*playbook-vars*) key value))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Play vars
|
||||||
|
;;
|
||||||
|
(define-public *play-vars* (make-parameter #f))
|
||||||
|
|
||||||
|
(define-public (play-var-ref key)
|
||||||
|
(hash-table-ref (*play-vars*) key))
|
||||||
|
|
||||||
|
(define-public (play-var-ref/default key default)
|
||||||
|
(hash-table-ref/default (*play-vars*) key default))
|
||||||
|
|
||||||
|
(define-public (play-var-set! key value)
|
||||||
|
(hash-table-set! (*play-vars*) key value))
|
||||||
|
|
||||||
|
;;
|
||||||
|
;; Host vars
|
||||||
|
;;
|
||||||
|
(define-public *host-vars* (make-parameter #f))
|
||||||
|
|
||||||
|
(define-public (host-var-ref key)
|
||||||
|
(hash-table-ref (*host-vars*) key))
|
||||||
|
|
||||||
|
(define-public (host-var-ref/default key default)
|
||||||
|
(hash-table-ref/default (*host-vars*) key default))
|
||||||
|
|
||||||
|
(define-public (host-var-set! key value)
|
||||||
|
(hash-table-set! (*host-vars*) key value))
|
|
@ -1,25 +1,37 @@
|
||||||
(define-module (ordo inventory)
|
(define-module (ordo inventory)
|
||||||
|
#:use-module (ice-9 eval-string)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (ice-9 textual-ports)
|
||||||
#:use-module (srfi srfi-9)
|
#:use-module (oop goops)
|
||||||
#:use-module ((ordo connection) #:select (local-connection))
|
#:use-module ((ordo connection) #:select (local-connection))
|
||||||
|
#:use-module (ordo logger)
|
||||||
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-69)
|
||||||
#:export (host
|
#:export (host
|
||||||
host?
|
host?
|
||||||
host-name
|
host-name
|
||||||
host-connection
|
host-connection
|
||||||
host-tags
|
host-tags
|
||||||
add-host!
|
host-vars
|
||||||
resolve-hosts))
|
resolve-hosts
|
||||||
|
load-inventory))
|
||||||
|
|
||||||
(define-record-type <host>
|
(define-class <host> ()
|
||||||
(make-host name connection tags)
|
(name #:init-keyword #:name #:getter host-name)
|
||||||
host?
|
(connection #:init-keyword #:connection #:getter host-connection)
|
||||||
(name host-name)
|
(tags #:init-keyword #:tags #:getter host-tags #:init-form (list))
|
||||||
(connection host-connection)
|
(vars #:init-keyword #:vars #:getter host-vars #:init-form (list)))
|
||||||
(tags host-tags))
|
|
||||||
|
|
||||||
(define (host name connection . tags)
|
(define-method (initialize (object <host>) initargs)
|
||||||
(make-host name connection tags))
|
(next-method)
|
||||||
|
(slot-set! object 'vars (alist->hash-table (slot-ref object 'vars)))
|
||||||
|
object)
|
||||||
|
|
||||||
|
(define (host . args)
|
||||||
|
(apply make <host> args))
|
||||||
|
|
||||||
|
(define (host? x)
|
||||||
|
(is-a? x <host>))
|
||||||
|
|
||||||
(define (tagged-every? wanted-tags)
|
(define (tagged-every? wanted-tags)
|
||||||
(lambda (h)
|
(lambda (h)
|
||||||
|
@ -36,9 +48,18 @@
|
||||||
(define (resolve-hosts inventory expr)
|
(define (resolve-hosts inventory expr)
|
||||||
(match expr
|
(match expr
|
||||||
("localhost" (list (or (find (named? "localhost") inventory)
|
("localhost" (list (or (find (named? "localhost") inventory)
|
||||||
(make-host "localhost" (local-connection) '()))))
|
(make <host> #:name "localhost" #:connection (local-connection)))))
|
||||||
((? string? hostname) (filter (named? hostname) inventory))
|
((? string? hostname) (filter (named? hostname) inventory))
|
||||||
('all inventory)
|
('all inventory)
|
||||||
(('tagged tag) (filter (tagged-every? (list tag)) inventory))
|
(('tagged tag) (filter (tagged-every? (list tag)) inventory))
|
||||||
(('tagged/every tag . tags) (filter (tagged-every? (cons tag tags)) inventory))
|
(('tagged/every tag . tags) (filter (tagged-every? (cons tag tags)) inventory))
|
||||||
(('tagged/any tag . tags) (filter (tagged-any? (cons tag tags)) inventory))))
|
(('tagged/any tag . tags) (filter (tagged-any? (cons tag tags)) inventory))))
|
||||||
|
|
||||||
|
(define (load-inventory filename)
|
||||||
|
(log-msg 'INFO "Loading inventory " filename)
|
||||||
|
(let* ((inventory (eval-string (call-with-input-file filename get-string-all)
|
||||||
|
#:file filename))
|
||||||
|
(inventory (if (list? inventory) inventory '())))
|
||||||
|
(when (null? inventory)
|
||||||
|
(log-msg 'NOTICE "Inventory is empty, only localhost will be available"))
|
||||||
|
inventory))
|
||||||
|
|
57
ordo/play.scm
Normal file
57
ordo/play.scm
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
(define-module (ordo play)
|
||||||
|
#:use-module (oop goops)
|
||||||
|
#:use-module (ordo connection)
|
||||||
|
#:use-module (ordo context)
|
||||||
|
#:use-module (ordo inventory)
|
||||||
|
#:use-module (ordo logger)
|
||||||
|
#:use-module (ordo util flatten)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
|
#:use-module (srfi srfi-69)
|
||||||
|
#:export (play
|
||||||
|
play?
|
||||||
|
play-host
|
||||||
|
play-sudo?
|
||||||
|
play-sudo-user
|
||||||
|
play-sudo-password
|
||||||
|
play-vars
|
||||||
|
play-actions
|
||||||
|
play-handlers
|
||||||
|
run-play))
|
||||||
|
|
||||||
|
(define-class <play> ()
|
||||||
|
(name #:init-keyword #:name #:getter play-name)
|
||||||
|
(host #:init-keyword #:host #:getter play-host)
|
||||||
|
(sudo? #:init-keyword #:sudo? #:getter play-sudo? #:init-value #f)
|
||||||
|
(sudo-user #:init-keyword #:sudo-user #:getter play-sudo-user #:init-value #f)
|
||||||
|
(sudo-password #:init-keyword #:sudo-password #:getter play-sudo-password #:init-value #f)
|
||||||
|
(vars #:init-keyword #:vars #:getter play-vars #:init-form (list))
|
||||||
|
(actions #:init-keyword #:actions #:getter play-actions #:init-form (list))
|
||||||
|
(handlers #:init-keyword #:handlers #:getter play-handlers #:init-form (list)))
|
||||||
|
|
||||||
|
(define-method (initialize (object <play>) initargs)
|
||||||
|
(next-method)
|
||||||
|
(slot-set! object 'vars (alist->hash-table (slot-ref object 'vars)))
|
||||||
|
object)
|
||||||
|
|
||||||
|
(define (play . args)
|
||||||
|
(apply make <play> args))
|
||||||
|
|
||||||
|
(define (run-play p)
|
||||||
|
(log-msg 'NOTICE "Running play: " (play-name p))
|
||||||
|
(parameterize ((*play-vars* (play-vars p)))
|
||||||
|
(let ((hosts (resolve-hosts (*inventory*) (play-host p))))
|
||||||
|
(if (null? hosts)
|
||||||
|
(log-msg 'WARN "No hosts matched: " (play-host p))
|
||||||
|
(for-each (lambda (h) (run-host-play p h)) hosts)))))
|
||||||
|
|
||||||
|
(define (run-host-play p h)
|
||||||
|
(log-msg 'NOTICE "Running play: " (play-name p) " on host: " (host-name h))
|
||||||
|
(parameterize ((*host-vars* (host-vars h)))
|
||||||
|
(call-with-connection
|
||||||
|
(host-connection h)
|
||||||
|
(lambda (conn)
|
||||||
|
#f
|
||||||
|
)
|
||||||
|
#:sudo? (play-sudo? p)
|
||||||
|
#:sudo-user (play-sudo-user p)
|
||||||
|
#:sudo-password (play-sudo-password p))))
|
45
ordo/playbook.scm
Normal file
45
ordo/playbook.scm
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
(define-module (ordo playbook)
|
||||||
|
#:use-module (ice-9 eval-string)
|
||||||
|
#:use-module (ice-9 textual-ports)
|
||||||
|
#:use-module (oop goops)
|
||||||
|
#:use-module (ordo context)
|
||||||
|
#:use-module (ordo logger)
|
||||||
|
#:use-module (ordo play)
|
||||||
|
#:use-module (srfi srfi-26)
|
||||||
|
#:use-module (srfi srfi-69)
|
||||||
|
#:export (<playbook>
|
||||||
|
playbook
|
||||||
|
playbook?
|
||||||
|
playbook-name
|
||||||
|
playbook-vars
|
||||||
|
playbook-plays
|
||||||
|
load-playbook
|
||||||
|
run-playbook)
|
||||||
|
#:re-export (play))
|
||||||
|
|
||||||
|
(define-class <playbook> ()
|
||||||
|
(name #:init-keyword #:name #:getter playbook-name)
|
||||||
|
(vars #:init-keyword #:vars #:getter playbook-vars)
|
||||||
|
(plays #:init-keyword #:plays #:getter playbook-plays))
|
||||||
|
|
||||||
|
(define-method (initialize (object <playbook>) initargs)
|
||||||
|
(next-method)
|
||||||
|
(slot-set! object 'vars (alist->hash-table (slot-ref object 'vars)))
|
||||||
|
object)
|
||||||
|
|
||||||
|
(define (playbook . args)
|
||||||
|
(apply make <playbook> args))
|
||||||
|
|
||||||
|
(define (playbook? p)
|
||||||
|
(is-a? p <playbook>))
|
||||||
|
|
||||||
|
(define (load-playbook filename)
|
||||||
|
(log-msg 'INFO "Loading playbook " filename)
|
||||||
|
(eval-string (call-with-input-file filename get-string-all)
|
||||||
|
#:file filename))
|
||||||
|
|
||||||
|
(define (run-playbook pb inventory)
|
||||||
|
(log-msg 'NOTICE "Running playbook: " (playbook-name pb))
|
||||||
|
(parameterize ((*inventory* inventory)
|
||||||
|
(*playbook-vars* (playbook-vars pb)))
|
||||||
|
(for-each run-play (playbook-plays pb))))
|
Loading…
Add table
Add a link
Reference in a new issue