From: guix-patches--- via <guix-patches@gnu.org>
To: 58123@debbugs.gnu.org, maximedevos@telenet.be
Subject: [bug#58123]
Date: Sun, 02 Oct 2022 22:38:42 +0200 [thread overview]
Message-ID: <87mtae9d0t.fsf@disroot.org> (raw)
In-Reply-To: <87r0zwr9dv.fsf@disroot.org>
[-- Attachment #1: Type: text/plain, Size: 288 bytes --]
I have applied the changes as you suggested. Thank you for your (as you
said) "superficial comments", they were really helpful! And I am happy
that you made them, as I'm sometimes too happy that I have made a
contribution and I forget that I don't write only for myself, but for
others.
[-- Attachment #2: 0001-Add-docker-container-management-with-shepherd.patch --]
[-- Type: text/x-patch, Size: 13525 bytes --]
---
gnu/services/docker.scm | 240 +++++++++++++++++++++++++++++++++++++---
1 file changed, 222 insertions(+), 18 deletions(-)
diff --git a/gnu/services/docker.scm b/gnu/services/docker.scm
index 741bab5a8c..f3a347981f 100644
--- a/gnu/services/docker.scm
+++ b/gnu/services/docker.scm
@@ -5,6 +5,7 @@
;;; Copyright © 2020 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2020 Jesse Dowell <jessedowell@gmail.com>
;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
+;;; Copyright © 2022 Maya Tomasek <maya.omase@disroot.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -21,7 +22,9 @@
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
-(define-module (gnu services docker)
+(define-module (magi system docker)
+ #:use-module (srfi srfi-1)
+ #:use-module (ice-9 format)
#:use-module (gnu services)
#:use-module (gnu services configuration)
#:use-module (gnu services base)
@@ -36,9 +39,191 @@ (define-module (gnu services docker)
#:use-module (guix packages)
#:export (docker-configuration
+ docker-container
docker-service-type
singularity-service-type))
+(define (pair-of-strings? val)
+ (and (pair? val)
+ (string? (car val))
+ (string? (cdr val))))
+
+(define (list-of-pair-of-strings? val)
+ (list-of pair-of-strings?))
+
+(define-configuration/no-serialization docker-container
+ (name
+ (symbol '())
+ "Name of the docker container. Will be used to denote service to Shepherd and must be unique!
+We recommend, that the name of the container is prefixed with @code{docker-}.")
+ (documentation
+ (string "")
+ "Documentation on the docker container (optional). It will be used for the shepherd service.")
+ (image-name
+ (string #f)
+ "A name of the image that will be used. (Note that the existence of the image
+is not guaranteed by this daemon.)")
+ (volumes
+ (list-of-pair-of-strings '())
+ "A list of volume bindings. In (HOST-PATH CONTAINER-PATH) format.")
+ (ports
+ (list-of-pair-of-strings '())
+ "A list of port bindings. In (HOST-PORT CONTAINER-PORT) or (HOST-PORT CONTAINER-PORT OPTIONS) format.
+For example, both port bindings are valid:
+
+@lisp
+(ports '((\"2222\" \"22\") (\"21\" \"21\" \"tcp\")))
+@end lisp")
+ (environments
+ (list-of-pair-of-strings '())
+ "A list of environment variables, inside the container environment, in (VARIABLE VALUE) format.")
+ (network
+ (string "none")
+ "Network type.
+
+Available types are:
+@table @code
+@c Copied from https://docs.docker.com/network/
+
+@item none
+
+The default option. For this container, disable all networking. Usually used in
+conjunction with a custom network driver. none is not available for swarm services.
+
+@item bridge
+
+Bridge networks are usually used when your applications run in standalone
+containers that need to communicate.
+
+@item host
+
+For standalone containers, remove network isolation between the container and the Docker host,
+and use the host’s networking directly.
+
+@item overlay
+
+Overlay networks connect multiple Docker daemons together and enable swarm services to
+communicate with each other. You can also use overlay networks to facilitate
+communication between a swarm service and a standalone container, or between
+two standalone containers on different Docker daemons. This strategy removes
+the need to do OS-level routing between these containers.
+
+@item ipvlan
+
+IPvlan networks give users total control over both IPv4 and IPv6 addressing.
+The VLAN driver builds on top of that in giving operators complete control of
+layer 2 VLAN tagging and even IPvlan L3 routing for users interested in underlay
+network integration.
+
+@item macvlan
+
+Macvlan networks allow you to assign a MAC address to a container, making it appear
+as a physical device on your network. The Docker daemon routes traffic to containers
+by their MAC addresses. Using the macvlan driver is sometimes the best choice when
+dealing with legacy applications that expect to be directly connected to the physical
+network, rather than routed through the Docker host’s network stack.
+
+@end table")
+ (additional-arguments
+ (list-of-strings '())
+ "Additional arguments to the docker command line interface.")
+ (container-command
+ (list-of-strings '())
+ "Command to send into the container.")
+ (pid-file-timeout
+ (number 5)
+ "If the docker container does not show up in @code{docker ps} as @code{running} in less than pid-file-timeout seconds, the container is considered as failing to start.
+
+Note that some containers take a really long time to start, so you should adjust it accordingly."))
+
+(define (serialize-volumes config)
+ "Serialize list of pairs into flat list of @code{(\"-v\" \"HOST_PATH:CONTAINER_PATH\" ...)}"
+ (append-map
+ (lambda (volume-bind)
+ (list "-v" (apply format #f "~a:~a~^:~a" volume-bind)))
+ (docker-container-volumes config)))
+
+(define (serialize-ports config)
+ "Serialize list of either pairs, or lists into flat list of
+@code{(\"-p\" \"NUMBER:NUMBER\" \"-p\" \"NUMBER:NUMBER/PROTOCOL\" ...)}"
+ (append-map
+ (lambda (port-bind)
+ (list "-p" (apply format #f "~a:~a~^/~a" port-bind)))
+ (docker-container-ports config)))
+
+(define (serialize-environments config)
+ "Serialize list of pairs into flat list of @code{(\"-e\" \"VAR=val\" \"-e\" \"VAR=val\" ...)}."
+ (append-map
+ (lambda (env-bind)
+ (list "-e" (apply format #f "~a=~a" env-bind)))
+ (docker-container-environments config)))
+
+(define (docker-container-startup-script docker-cli container-name cid-file config)
+ "Return a program file, that executes the startup sequence of the @code{docker-container-shepherd-service}."
+ (let* ((image-name (docker-container-image-name config))
+ (volumes (serialize-volumes config))
+ (ports (serialize-ports config))
+ (envs (serialize-environments config))
+ (network (docker-container-network config))
+ (additional-arguments (docker-container-additional-arguments config))
+ (container-command (docker-container-container-command config)))
+ (with-imported-modules
+ '((guix build utils))
+ (program-file
+ (string-append "start-" container-name "-container")
+ #~(let ((docker (string-append #$docker-cli "/bin/docker")))
+ (use-modules (guix build utils))
+ ;; These two commands should fail
+ ;; they are there as a failsafe to
+ ;; prevent contamination from unremoved containers
+ (system* docker "stop" #$container-name)
+ (system* docker "rm" #$container-name)
+ (apply invoke `(,docker
+ "run"
+ ,(string-append "--name=" #$container-name)
+ ;; Automatically remove the container when stopping
+ ;; If you want persistent data, you need to use
+ ;; volume binds or other methods.
+ "--rm"
+ ,(string-append "--network=" #$network)
+ ;; Write to a cid file the container id, this allows
+ ;; for shepherd to manage container even when the process
+ ;; itself gets detached from the container
+ "--cidfile" #$cid-file
+ #$@volumes
+ #$@ports
+ #$@envs
+ #$@additional-arguments
+ ,#$image-name
+ #$@container-command)))))))
+
+(define (docker-container-shepherd-service docker-cli config)
+ "Return a shepherd-service that runs CONTAINER."
+ (let* ((container-name (symbol->string (docker-container-name config)))
+ (cid-file (string-append "/var/run/docker/" container-name ".pid"))
+ (pid-file-timeout (docker-container-pid-file-timeout config)))
+ (shepherd-service
+ (provision (list (docker-container-name config)))
+ (requirement `(dockerd))
+ (documentation (docker-container-documentation config))
+ (start #~(apply make-forkexec-constructor
+ `(,(list #$(docker-container-startup-script docker-cli container-name cid-file config))
+ ;; Watch the cid-file instead of the docker run command, as the daemon can
+ ;; still be running even when the command terminates
+ #:pid-file #$cid-file
+ #:pid-file-timeout #$pid-file-timeout)))
+ (stop #~(lambda _
+ (invoke
+ (string-append #$docker-cli "/bin/docker")
+ "stop"
+ #$container-name)
+ ;; Shepherd expects the stop command to return #f if it succeeds
+ ;; docker stop should always succeed
+ #f)))))
+
+(define (list-of-docker-containers? val)
+ (list-of docker-container?))
+
(define-configuration docker-configuration
(docker
(file-like docker)
@@ -65,8 +250,21 @@ (define-configuration docker-configuration
(environment-variables
(list '())
"Environment variables to set for dockerd")
+ (containers
+ (list-of-docker-containers '())
+ "List of docker containers to run as shepherd services.")
(no-serialization))
+(define (docker-container-shepherd-services config)
+ "Return shepherd services for all containers inside config."
+ (let ((docker-cli (docker-configuration-docker-cli config)))
+ (map
+ (lambda (container)
+ (docker-container-shepherd-service
+ docker-cli
+ container))
+ (docker-configuration-containers config))))
+
(define %docker-accounts
(list (user-group (name "docker") (system? #t))))
@@ -88,20 +286,20 @@ (define (containerd-shepherd-service config)
(debug? (docker-configuration-debug? config))
(containerd (docker-configuration-containerd config)))
(shepherd-service
- (documentation "containerd daemon.")
- (provision '(containerd))
- (start #~(make-forkexec-constructor
- (list (string-append #$package "/bin/containerd")
- #$@(if debug?
- '("--log-level=debug")
- '()))
- ;; For finding containerd-shim binary.
- #:environment-variables
- (list (string-append "PATH=" #$containerd "/bin"))
- #:pid-file "/run/containerd/containerd.pid"
- #:pid-file-timeout 300
- #:log-file "/var/log/containerd.log"))
- (stop #~(make-kill-destructor)))))
+ (documentation "containerd daemon.")
+ (provision '(containerd))
+ (start #~(make-forkexec-constructor
+ (list (string-append #$package "/bin/containerd")
+ #$@(if debug?
+ '("--log-level=debug")
+ '()))
+ ;; For finding containerd-shim binary.
+ #:environment-variables
+ (list (string-append "PATH=" #$containerd "/bin"))
+ #:pid-file "/run/containerd/containerd.pid"
+ #:pid-file-timeout 300
+ #:log-file "/var/log/containerd.log"))
+ (stop #~(make-kill-destructor)))))
(define (docker-shepherd-service config)
(let* ((docker (docker-configuration-docker config))
@@ -148,7 +346,7 @@ (define (docker-shepherd-service config)
(define docker-service-type
(service-type (name 'docker)
(description "Provide capability to run Docker application
-bundles in Docker containers.")
+bundles in Docker containers and optionally wrap those containers in shepherd services.")
(extensions
(list
;; Make sure the 'docker' command is available.
@@ -158,10 +356,16 @@ (define docker-service-type
%docker-activation)
(service-extension shepherd-root-service-type
(lambda (config)
- (list (containerd-shepherd-service config)
- (docker-shepherd-service config))))
+ (cons* (containerd-shepherd-service config)
+ (docker-shepherd-service config)
+ (docker-container-shepherd-services config))))
(service-extension account-service-type
(const %docker-accounts))))
+ (compose concatenate)
+ (extend (lambda (config containers)
+ (docker-configuration
+ (inherit config)
+ (containers (append containers (docker-configuration-containers config))))))
(default-value (docker-configuration))))
\f
--
2.37.3
next prev parent reply other threads:[~2022-10-02 20:45 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-27 17:16 [bug#58123] [PATCH] gnu: services: docker: Add docker-container-service-type guix-patches--- via
2022-09-29 18:31 ` Maxime Devos
2022-09-30 13:40 ` guix-patches--- via
2022-09-30 18:47 ` Maxime Devos
2022-09-30 18:48 ` Maxime Devos
2022-10-02 20:38 ` guix-patches--- via [this message]
2022-10-09 20:31 ` Ludovic Courtès
2022-10-11 18:04 ` guix-patches--- via
2022-10-13 13:05 ` Ludovic Courtès
2022-12-01 15:59 ` Ludovic Courtès
2022-12-15 21:07 ` guix-patches--- via
2023-12-20 21:48 ` Sergey Trofimov
2024-01-08 16:29 ` bug#58123: " Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87mtae9d0t.fsf@disroot.org \
--to=guix-patches@gnu.org \
--cc=58123@debbugs.gnu.org \
--cc=maximedevos@telenet.be \
--cc=maya.tomasek@disroot.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/guix.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.