1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- ;; (Programming against the v1.38 interface of docker engine.)
- (use-modules (web client)
- (web uri)
- (json)
- (ice-9 iconv))
- (define* (connect-to-docker-socket #:key (socket-path "/var/run/docker.sock"))
- (let ([docker-sock-addr (make-socket-address AF_UNIX socket-path)]
- [docker-sock (socket PF_UNIX SOCK_STREAM 0)])
- ;; socket options:
- ;; https://www.gnu.org/software/libc/manual/html_node/Socket_002dLevel-Options.html
- (setsockopt docker-sock SOL_SOCKET SO_REUSEADDR 1)
- ;; usage of connect:
- ;; https://www.gnu.org/software/guile/manual/html_node/Network-Sockets-and-Communication.html#Network-Sockets-and-Communication
- ;; server side would use `bind`, `accept` and `listen`.
- ;; client side uses `connect` and `close`.
- (connect docker-sock docker-sock-addr)
- docker-sock))
- (define (conditionally-make-alist-of names vals)
- (cond [(null? names) '()]
- [(car vals)
- (cons (cons (car names) (car vals))
- (conditionally-make-alist-of (cdr names) (cdr vals)))]
- [else (conditionally-make-alist-of (cdr names) (cdr vals))]))
- (define (alist-to-query-params alist)
- (string-join (map (lambda (assoc)
- (string-append (car assoc) "=" (cdr assoc)))
- alist)
- "&"))
- (define (make-complete-api-url api-route query-params-as-string)
- (string-append api-route "?" query-params-as-string))
- (define (scm-json->uri-encoded-string scm-json)
- "The argument scm-json is the Scheme representation of guile-json
- for JSON."
- (uri-encode (scm->json-string scm-json)))
- (define* (/containers/json dock-sock #:key (limit #f) (filters #f) (all #f) (size #f))
- (define (build-api-url)
- (display
- (simple-format #f
- "URL-ENCODED FILTERS: ~s\n"
- (scm-json->uri-encoded-string filters)))
- (let* ([filters-url-encoded
- (scm-json->uri-encoded-string filters)]
- [query-params
- (alist-to-query-params
- (conditionally-make-alist-of
- '("limit" "filters" "all" "size")
- (list limit filters-url-encoded all size)))])
- (string-append "/containers/json" "?" query-params)))
- (call-with-values
- (lambda ()
- (http-get (build-api-url)
- #:port dock-sock
- ;; dockerd uses HTTP 1.1 it seems.
- ;; other values will result in: "Bad Request: unsupported protocol version"
- #:version '(1 . 1)
- #:keep-alive? #f
- ;; Apparently the `host` header must be specified.
- ;; The `host` header in this case is ("localhost" . #f).
- ;; The `host` header contains domain and port
- #:headers '((host . ("localhost" . #f))
- #;(content-type . "application/x-www-form-urlencoded"))
- #:decode-body? #t
- #:streaming? #f))
- (lambda (response response-text)
- (display
- (simple-format #f
- "RESPONSE TEXT: ~s"
- (bytevector->string response-text "utf-8")))
- (let ([resp-text-as-string (bytevector->string response-text "utf-8")])
- (cons response resp-text-as-string)))))
- (let ([dock-sock (connect-to-docker-socket)])
- (let ([resp-and-resp-text
- (/containers/json dock-sock
- #:all "true"
- #:filters '(("name" . #("db"))
- ("status" . #("running" "exited"))))])
- (display resp-and-resp-text)
- (newline)))
|