From dd885ce55928f3666747ab65d2064cde35a2632a Mon Sep 17 00:00:00 2001 From: Ray Miller Date: Sun, 26 Jan 2025 14:02:19 +0000 Subject: [PATCH] Tidy up the AWS CLI interceptor example. --- examples/install-aws-cli.scm | 53 +++++++-------------------- examples/interceptor.scm | 7 +++- modules/ordo/interceptor.scm | 15 ++++++-- modules/ordo/interceptor/command.scm | 22 +++++++++++ modules/ordo/interceptor/download.scm | 22 +++++++++++ modules/ordo/interceptor/unzip.scm | 16 ++++++++ 6 files changed, 90 insertions(+), 45 deletions(-) create mode 100644 modules/ordo/interceptor/command.scm create mode 100644 modules/ordo/interceptor/download.scm create mode 100644 modules/ordo/interceptor/unzip.scm diff --git a/examples/install-aws-cli.scm b/examples/install-aws-cli.scm index 58df289..8ced506 100644 --- a/examples/install-aws-cli.scm +++ b/examples/install-aws-cli.scm @@ -8,50 +8,25 @@ (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)))) + (ordo interceptor download) + (ordo interceptor unzip) + (ordo interceptor command)) +;; This example shows that a function can act a bit like an ansible role by +;; returning a list of interceptors to be added to the caller's interceptor +;; chain. (The list will be flattened to construct the final chain.) (define* (install-aws-cli #:key (url "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip") update? install-dir bin-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)) + (download "download-aws-cli" #:url url #:target-dir (var aws-cli-tmp) #:register 'aws-cli-zipfile) + (unzip "extract-aws-cli" #:file-name (var aws-cli-zipfile) #:target-dir (var 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")))) + (list + (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") + #:check? #t)))) (playbook #:name "Test Playbook" diff --git a/examples/interceptor.scm b/examples/interceptor.scm index d01ec6f..92018a2 100644 --- a/examples/interceptor.scm +++ b/examples/interceptor.scm @@ -7,6 +7,7 @@ (ordo interceptor create-tmp-dir) (ordo interceptor stat-file) (ordo interceptor user-info) + (ordo interceptor command) (ordo interceptor debug)) (playbook @@ -22,10 +23,12 @@ (install-file "install-hello" #:path (let-vars (tmp-dir) (file-name-join* tmp-dir "hello.txt")) - #:content (let-vars (file-content) file-content) + #:content (var file-content) #:register 'hello) (stat-file "stat-hello" - #:path (let-vars (hello) hello) + #:path (var hello) #:register 'hello-stat) + (command "list-tmp-dir" (list "ls" "-l" (var tmp-dir) #:check? #t) #:register 'dir-list) + (command "list-root-dir" (list "ls" "-l" "/root" #:check? #f) #:register 'root-list) (debug-vars))))) diff --git a/modules/ordo/interceptor.scm b/modules/ordo/interceptor.scm index af3a4ec..18cbdd6 100644 --- a/modules/ordo/interceptor.scm +++ b/modules/ordo/interceptor.scm @@ -20,7 +20,9 @@ var-set! var-delete! let-vars + var expand-vars + delayed-var-ref? terminate-when execute)) @@ -83,13 +85,18 @@ expr exprs ...))))) +(define-syntax var + (syntax-rules () + ((var var-name) + (let-vars (var-name) var-name)))) + +(define (delayed-var-ref? v) + (and (procedure? v) (procedure-property v 'delayed-var-ref?))) + (define-syntax expand-vars (syntax-rules () ((expand-vars ctx v ...) - (values (if (and (procedure? v) (procedure-property v 'delayed-var-ref?)) - (v ctx) - v) - ...)))) + (values (if (delayed-var-ref? v) (v ctx) v) ...)))) (define-record-type (make-interceptor name enter leave error) diff --git a/modules/ordo/interceptor/command.scm b/modules/ordo/interceptor/command.scm new file mode 100644 index 0000000..9199c82 --- /dev/null +++ b/modules/ordo/interceptor/command.scm @@ -0,0 +1,22 @@ +(define-module (ordo interceptor command) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-145) + #:use-module (ordo interceptor) + #:use-module (ordo connection) + #:use-module (ordo util flatten) + #:export (command)) + +(define* (command name prog-and-args #:key register) + (assume (string? name) "interceptor name should be a string" name) + (assume (list? prog-and-args) "prog-and-args should be a list" prog-and-args) + (assume (or (not register) (symbol? register)) "register should be a symbol" register) + (interceptor + name + #:enter (lambda (ctx) + (let ((prog-and-args (map (lambda (v) (expand-vars ctx v)) (flatten prog-and-args)))) + (pk prog-and-args) + (call-with-values + (lambda () (apply run (context-connection ctx) prog-and-args)) + (lambda result + (when register + (var-set! ctx register result)))))))) diff --git a/modules/ordo/interceptor/download.scm b/modules/ordo/interceptor/download.scm new file mode 100644 index 0000000..579963f --- /dev/null +++ b/modules/ordo/interceptor/download.scm @@ -0,0 +1,22 @@ +(define-module (ordo interceptor download) + #:use-module (ice-9 filesystem) + #:use-module (srfi srfi-71) + #:use-module (srfi srfi-145) + #:use-module (ordo interceptor) + #:use-module (ordo connection) + #:export (download)) + +(define* (download name #:key url target-dir register) + (assume (string? name) "interceptor name should be a string" name) + (assume (or (string? url) (delayed-var-ref? url)) "url is required and should be a string" url) + (assume (or (not register) (symbol? register)) "register should be a symbol" 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))))) diff --git a/modules/ordo/interceptor/unzip.scm b/modules/ordo/interceptor/unzip.scm new file mode 100644 index 0000000..d6acf61 --- /dev/null +++ b/modules/ordo/interceptor/unzip.scm @@ -0,0 +1,16 @@ +(define-module (ordo interceptor unzip) + #:use-module (srfi srfi-71) + #:use-module (srfi srfi-145) + #:use-module (ordo interceptor) + #:use-module (ordo connection) + #:export (unzip)) + +(define* (unzip name #:key file-name target-dir) + (assume (string? name) "interceptor name is required and should be a string" name) + (assume (or (string? file-name) (delayed-var-ref? file-name)) "file-name is required and should be a string" file-name) + (assume (or (string? target-dir) (delayed-var-ref? target-dir)) "target-dir is required and should be a string" 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)))))