(in-package #:nekod.docker) (defun create-container (sock spec) "Create a container from a nekod:container-spec. Returns container ID." (let* ((json-body (nekod:container-spec->json spec)) (path (format nil "/containers/create?name=~a" (nekod:container-spec-name spec)))) (multiple-value-bind (status body) (docker-post sock path json-body) (if (= status 201) (progn (format t "Container created: ~a~%" (nekod:container-spec-name spec)) body) (error 'nekod:docker-api-error :message (format nil "Create failed: ~a" body) :status-code status :endpoint path))))) (defun start-container (sock id) "Start a container by ID or name." (multiple-value-bind (status body) (docker-post sock (format nil "/containers/~a/start" id)) (if (member status '(204 304)) (progn (format t "Started: ~a~%" id) t) (error 'nekod:docker-api-error :message body :status-code status :endpoint (format nil "/containers/~a/start" id))))) (defun stop-container (sock id &optional (timeout 10)) "Stop a container gracefully." (multiple-value-bind (status body) (docker-post sock (format nil "/containers/~a/stop?t=~a" id timeout)) (if (member status '(204 304)) (progn (format t "Stopped: ~a~%" id) t) (error 'nekod:docker-api-error :message body :status-code status :endpoint (format nil "/containers/~a/stop" id))))) (defun kill-container (sock id &optional (signal "SIGKILL")) "Kill a container immediately." (docker-post sock (format nil "/containers/~a/kill?signal=~a" id signal))) (defun list-containers (sock &optional (all t)) "List containers. all=t includes stopped containers." (multiple-value-bind (status body) (docker-get sock (format nil "/containers/json?all=~a" (if all 1 0))) (if (= status 200) body (error 'nekod:docker-api-error :message body :status-code status :endpoint "/containers/json"))))