all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ricardo Wurmus <rekado@elephly.net>
To: "Thompson, David" <dthompson2@worcester.edu>
Cc: "Yasuaki Kudo" <yasu@yasuaki.com>, Phil <phil@beadling.co.uk>,
	"Ludovic Courtès" <ludo@gnu.org>,
	"Benjamin Slade" <beoram@gmail.com>,
	"Olivier Dion" <olivier.dion@polymtl.ca>,
	help-guix <help-guix@gnu.org>
Subject: Re: Enterprise Guix Hosting?
Date: Wed, 31 Aug 2022 08:33:25 +0200	[thread overview]
Message-ID: <878rn4syql.fsf@elephly.net> (raw)
In-Reply-To: <CAJ=RwfbO7cVg3i=ha51=HmdE9ZWWGc-H-kP9kNkVLcSGo5qBaQ@mail.gmail.com>


"Thompson, David" <dthompson2@worcester.edu> writes:

>> Using a shared /gnu/store as a big cache for all containers can be a
>> real asset.  We can learn lessons from the HPC experience here.
>
> What might have a positive impact is if Guix had an answer to 'docker
> compose'.  Most of the pieces are there already.  Such a tool could be
> combined with 'guix shell' so you could get all the tools needed for
> local development *and* automatically start any necessary daemons,
> like database servers, in isolated containers.

Yes, this would be useful.

Another thing that seems to be missing is a way to supervise and manage
running containers.  I use a shepherd instance for this with
container-specific actions like this:

(define %ip
  (let ((loc #f))
    (lambda ()
      "Return the absolute file name of the ip command."
      (or loc
          (let ((value (which "ip")))
            (set! loc value)
            value)))))

(define (launch container-id script)
   (herd "root" "eval"
         (format #false
           "~s"
           `(begin
              (use-modules (srfi srfi-2)
                           (ice-9 popen)
                           (ice-9 rdelim)
                           (ice-9 match))
              (define (guix-container id script)
                (make <service>
                  #:provides (list
                              (string->symbol (string-append "guix-container-" id)))
                  #:docstring "Run a Guix System container"
                  #:start
                  ;; TODO: Using /bin/sh -c is ugly, but
                  ;; without it the container would be stuck in the early boot process.
                  (make-forkexec-constructor
                   `("/bin/sh" "-c" (string-join (list "exec" script ,@args) #\space)))
                  #:stop (make-kill-destructor)
                  #:actions
                  (make-actions
                   (pid
                    "Show the PID of the system container."
                    (lambda (running)
                      (let ((pid (call-with-input-file
                                     (format #false "/proc/~a/task/~a/children"
                                             running running)
                                   read)))
                        (display (match pid
                                   ((? eof-object?) "")
                                   (_ pid))))))
                   (ip
                    "Show the IP address of the system container."
                    (lambda (running)
                      (let* ((pid (number->string
                                   (call-with-input-file
                                       (format #false "/proc/~a/task/~a/children"
                                               running running)
                                     read)))
                             (ns (format #false "guix-~a" pid))
                             (ip ,(%ip))
                             (address
                              (catch #true
                                (lambda ()
                                  (let* ((pipe (open-pipe* OPEN_READ
                                                           ip "netns" "exec" ns
                                                           "ip" "-o" "-4"
                                                           "-family" "inet"
                                                           "addr" "show"
                                                           "dev" (format #false "ceth-~a" pid)))
                                         (output (read-line pipe)))
                                    (match (string-tokenize output)
                                      ((number if "inet" ip . rest) ip)
                                      (_ ""))))
                                (lambda _ ""))))
                        (display address))))
                   (up
                    "Connect network for the system container."
                    (lambda (running)
                      (let* ((pid (number->string
                                   (call-with-input-file
                                       (format #false "/proc/~a/task/~a/children"
                                               running running)
                                     read)))
                             (ns (format #false "guix-~a" pid))
                             (host (format #false "veth-~a" pid))
                             (client (format #false "ceth-~a" pid))
                             (ip ,(%ip))
                             (sys (lambda args
                                    (or (zero? (apply system* args))
                                        (error args)))))
                        ;; Make existing network namespace available to ip netns
                        (sys ip "netns" "attach" ns pid)

                        ;; Create veth pair and move the client side into the container.
                        (sys ip "link" "add" host "type" "veth" "peer" "name" client)
                        (sys ip "link" "set" host "up")
                        (sys ip "link" "set" client "netns" ns)

                        ;; Attach host side to host bridge
                        (sys ip "link" "set" host "master" "br0")

                        ;; Bring up interface in container
                        (sys ip "netns" "exec" ns "ip" "link" "set" "lo" "up")
                        (sys ip "netns" "exec" ns "ip" "link" "set" client "up"))))
                   (down
                    "Disconnect network for the system container."
                    (lambda (running)
                      (let* ((pid (number->string
                                   (call-with-input-file
                                       (format #false "/proc/~a/task/~a/children"
                                               running running)
                                     read)))
                             (ns (format #false "guix-~a" pid))
                             (host (format #false "veth-~a" pid))
                             (ip ,(%ip))
                             (sys (lambda args
                                    (or (zero? (apply system* args))
                                        (error args)))))
                        (sys ip "netns" "delete" ns)
                        (sys ip "link" "delete" host))))
                   (netstat
                    (lambda (running)
                      (and-let* ((pid (number->string
                                       (call-with-input-file
                                           (format #false "/proc/~a/task/~a/children"
                                                   running running)
                                         read)))
                                 (template (lambda (what)
                                             (format #false "/sys/class/net/veth-~a/statistics/~a_bytes" pid what)))
                                 (rx (call-with-input-file (template "rx") read))
                                 (tx (call-with-input-file (template "tx") read)))
                        (format #true "receive:~a transmit:~a" rx tx)))))))
              (let ((service (guix-container ,vm-id ,script)))
                (register-services service)
                (start service))))))


-- 
Ricardo


  reply	other threads:[~2022-08-31  6:40 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-29 23:23 Enterprise Guix Hosting? Yasuaki Kudo
2022-07-30 14:36 ` Olivier Dion via
2022-07-30 16:20   ` Phil
2022-07-30 23:18     ` Yasuaki Kudo
2022-07-31  0:42       ` Benjamin Slade
2022-07-31 11:01         ` Phil
2022-08-09 20:37           ` Ludovic Courtès
2022-08-09 22:24             ` Yasuaki Kudo
2022-08-14  9:53             ` Phil
2022-08-14 22:03               ` Yasuaki Kudo
2022-08-15 20:50                 ` Phil
2022-08-25 18:37                   ` Olivier Dion via
2022-08-26  6:40                     ` Yasuaki Kudo
2022-10-12  9:55                     ` Ade Malsasa Akbar
2022-10-12 10:18                       ` Olivier Dion via
2022-08-26  7:24                 ` Ricardo Wurmus
2022-08-31  1:42                   ` Thompson, David
2022-08-31  6:33                     ` Ricardo Wurmus [this message]
2022-08-31 10:46                       ` [EXT] " Thompson, David
2022-08-31 11:42                         ` Olivier Dion via
2022-08-31 12:54                           ` Thompson, David
2022-09-05 19:38                         ` [EXT] " Ludovic Courtès
2023-01-23 15:34                           ` declarative containers (was Re: [EXT] Re: Enterprise Guix Hosting?) Giovanni Biscuolo
2023-01-23 16:48                             ` Przemysław Kamiński
2023-01-23 17:59                               ` Wojtek Kosior via
2022-09-05 19:42               ` Enterprise Guix Hosting? Ludovic Courtès
2022-10-07 11:03               ` zimoun
2022-10-08 16:23                 ` Phil
2022-10-10  7:58                   ` zimoun
2022-10-10 10:30                     ` (
2022-10-10 10:49                       ` zimoun
2022-10-10 19:35                     ` Phil

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=878rn4syql.fsf@elephly.net \
    --to=rekado@elephly.net \
    --cc=beoram@gmail.com \
    --cc=dthompson2@worcester.edu \
    --cc=help-guix@gnu.org \
    --cc=ludo@gnu.org \
    --cc=olivier.dion@polymtl.ca \
    --cc=phil@beadling.co.uk \
    --cc=yasu@yasuaki.com \
    /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.