diff --git a/examples/install-aws-cli.scm b/examples/install-aws-cli.scm index 15ea839..58df289 100644 --- a/examples/install-aws-cli.scm +++ b/examples/install-aws-cli.scm @@ -1,28 +1,66 @@ (use-modules (ice-9 filesystem) - (ordo)) + (srfi srfi-71) + (ordo playbook) + (ordo play) + (ordo interceptor) + (ordo connection) + (ordo interceptor create-tmp-dir) + (ordo interceptor require-commands) + (ordo interceptor user-info) + (ordo util flatten)) + +;; TODO: this should be in (ordo interceptor download) and it needs arg validation +(define* (download name #:key url target-dir register) + (interceptor + name + #:enter (lambda (ctx) + (let* ((url target-dir (expand-vars ctx url target-dir)) + (file-name (file-name-join* target-dir (file-basename url)))) + (run (context-connection ctx) "wget" "-O" file-name url #:check? #t) + (when register + (var-set! ctx register file-name)))) + #:leave (lambda (ctx) (when register (var-delete! ctx register))) + #:error (lambda (ctx) (when register (var-delete! ctx register))))) + +;; TODO: this should be in (ordo interceptor unzip) and it needs arg validation +(define* (unzip name #:key file-name target-dir) + (interceptor + name + #:enter (lambda (ctx) + (let ((file-name target-dir (expand-vars ctx file-name target-dir))) + (run (context-connection ctx) "unzip" file-name "-d" target-dir #:check? #t))))) + +;; TODO: this should be in (ordo interceptor command) +;; Maybe it could expose more of the run functionality? +(define (command name prog . args) + (interceptor + name + #:enter (lambda (ctx) + (run (context-connection ctx) + (expand-vars ctx prog) + (map (lambda (a) (expand-vars ctx a)) (flatten args)) + #:check? #t)))) (define* (install-aws-cli #:key (url "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip") update? install-dir bin-dir) - (let* ((conn (current-connection)) - (tmp-dir (run conn "mktemp" "-d" #:return car #:check? #t))) - (dynamic-wind - (const #t) - (lambda () - (let ((zipfile (file-name-join* tmp-dir (file-basename url)))) - (run conn "wget" "-O" zipfile url #:check? #t) - (run conn "unzip" zipfile "-d" tmp-dir #:check? #t) - (run conn (file-name-join* tmp-dir "aws" "install") - (when install-dir `("-i" ,install-dir)) - (when bin-dir `("-b" ,bin-dir)) - (when update? "-u") - #:check? #t))) - (lambda () - (run conn "rm" "-rf" tmp-dir))))) + (list (require-commands "wget" "unzip") + (create-tmp-dir #:register 'aws-cli-tmp) + (download "download-aws-cli" #:url url #:target-dir (let-vars (aws-cli-tmp) aws-cli-tmp) #:register 'aws-cli-zipfile) + (unzip "extract-aws-cli" #:file-name (let-vars (aws-cli-zipfile) aws-cli-zipfile) #:target-dir (let-vars (aws-cli-tmp) aws-cli-tmp)) + (command "run-aws-cli-installer" + (let-vars (aws-cli-tmp) (file-name-join* aws-cli-tmp "aws" "install")) + (when install-dir `("-i" ,install-dir)) + (when bin-dir `("-b" ,bin-dir)) + (when update? "-u")))) -(playbook "Test Playbook" - (play "Test play" - #:host "localhost" - (task - (install-aws-cli #:update? #t - #:install-dir (file-name-join* ($ #:fact.home-dir) ".local" "aws-cli") - #:bin-dir (file-name-join* ($ #:fact.home-dir) ".local" "bin"))))) +(playbook + #:name "Test Playbook" + #:plays (list + (play + #:name "Install AWS CLI" + #:host "localhost" + #:interceptors (list + (user-info) + (install-aws-cli #:update? #t + #:install-dir (let-vars (user-info) (file-name-join* (assoc-ref user-info #:home-dir) ".local" "aws-cli")) + #:bin-dir (let-vars (user-info) (file-name-join* (assoc-ref user-info #:home-dir) ".local" "bin"))))))) diff --git a/modules/ordo/interceptor/require-commands.scm b/modules/ordo/interceptor/require-commands.scm new file mode 100644 index 0000000..f31586c --- /dev/null +++ b/modules/ordo/interceptor/require-commands.scm @@ -0,0 +1,28 @@ +(define-module (ordo interceptor require-commands) + #:use-module (ice-9 exceptions) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-71) + #:use-module (srfi srfi-145) + #:use-module (ordo interceptor) + #:use-module (ordo connection) + #:export (require-commands)) + +(define-exception-type &missing-command-error &external-error + make-missing-command-error + missing-command-error? + (command-name missing-command-error-command-name)) + +(define (require-commands . commands) + (assume (every string? commands) "commands should be strings" commands) + (interceptor + (string-append "require-commands " (string-join commands ",")) + #:enter (lambda (ctx) + (for-each (lambda (cmd) + (let ((out rc (run (context-connection ctx) "which" cmd))) + (unless (zero? rc) + (if (string-contains (car out) (format #f "which: no ~a in" cmd)) + (raise-exception (make-missing-command-error cmd)) + (raise-exception (make-exception + (make-external-error) + (make-exception-with-message (string-append "error running which: " (car out))))))))) + commands))))