services: Add 'system-service-type'.
[jackhill/guix/guix.git] / gnu / system / linux-container.scm
CommitLineData
239db054
DT
1;;; GNU Guix --- Functional package management for GNU
2;;; Copyright © 2015 David Thompson <davet@gnu.org>
3;;;
4;;; This file is part of GNU Guix.
5;;;
6;;; GNU Guix is free software; you can redistribute it and/or modify it
7;;; under the terms of the GNU General Public License as published by
8;;; the Free Software Foundation; either version 3 of the License, or (at
9;;; your option) any later version.
10;;;
11;;; GNU Guix is distributed in the hope that it will be useful, but
12;;; WITHOUT ANY WARRANTY; without even the implied warranty of
13;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14;;; GNU General Public License for more details.
15;;;
16;;; You should have received a copy of the GNU General Public License
17;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
18
19(define-module (gnu system linux-container)
20 #:use-module (ice-9 match)
21 #:use-module (srfi srfi-1)
22 #:use-module (guix config)
23 #:use-module (guix store)
24 #:use-module (guix gexp)
25 #:use-module (guix derivations)
26 #:use-module (guix monads)
27 #:use-module (gnu build linux-container)
8e5999e0 28 #:use-module (gnu services)
239db054
DT
29 #:use-module (gnu system)
30 #:use-module (gnu system file-systems)
31 #:export (mapping->file-system
32 system-container
33 containerized-operating-system
34 container-script))
35
36(define (mapping->file-system mapping)
37 "Return a file system that realizes MAPPING."
38 (match mapping
39 (($ <file-system-mapping> source target writable?)
40 (file-system
41 (mount-point target)
42 (device source)
43 (type "none")
44 (flags (if writable?
45 '(bind-mount)
46 '(bind-mount read-only)))
47 (check? #f)
48 (create-mount-point? #t)))))
49
239db054
DT
50(define (containerized-operating-system os mappings)
51 "Return an operating system based on OS for use in a Linux container
52environment. MAPPINGS is a list of <file-system-mapping> to realize in the
53containerized OS."
54 (define user-file-systems
55 (remove (lambda (fs)
56 (let ((target (file-system-mount-point fs))
57 (source (file-system-device fs)))
58 (or (string=? target (%store-prefix))
59 (string=? target "/")
60 (string-prefix? "/dev/" source)
61 (string-prefix? "/dev" target)
62 (string-prefix? "/sys" target))))
63 (operating-system-file-systems os)))
64
65 (define (mapping->fs fs)
66 (file-system (inherit (mapping->file-system fs))
67 (needed-for-boot? #t)))
68
69 (operating-system (inherit os)
70 (swap-devices '()) ; disable swap
71 (file-systems (append (map mapping->fs (cons %store-mapping mappings))
72 %container-file-systems
73 user-file-systems))))
74
75(define* (container-script os #:key (mappings '()))
76 "Return a derivation of a script that runs OS as a Linux container.
77MAPPINGS is a list of <file-system> objects that specify the files/directories
78that will be shared with the host system."
79 (let* ((os (containerized-operating-system os mappings))
80 (file-systems (filter file-system-needed-for-boot?
81 (operating-system-file-systems os)))
82 (specs (map file-system->spec file-systems)))
83
d62e201c
LC
84 (mlet* %store-monad ((os-drv (operating-system-derivation
85 os
86 #:container? #t)))
239db054
DT
87
88 (define script
89 #~(begin
90 (use-modules (gnu build linux-container)
91 (guix build utils))
92
93 (call-with-container '#$specs
94 (lambda ()
95 (setenv "HOME" "/root")
96 (setenv "TMPDIR" "/tmp")
97 (setenv "GUIX_NEW_SYSTEM" #$os-drv)
98 (for-each mkdir-p '("/run" "/bin" "/etc" "/home" "/var"))
1c8a81b1
DT
99 (primitive-load (string-append #$os-drv "/boot")))
100 ;; A range of 65536 uid/gids is used to cover 16 bits worth of
101 ;; users and groups, which is sufficient for most cases.
102 ;;
103 ;; See: http://www.freedesktop.org/software/systemd/man/systemd-nspawn.html#--private-users=
104 #:host-uids 65536)))
239db054
DT
105
106 (gexp->script "run-container" script
107 #:modules '((ice-9 match)
108 (srfi srfi-98)
109 (guix config)
110 (guix utils)
111 (guix build utils)
112 (guix build syscalls)
113 (gnu build file-systems)
114 (gnu build linux-container))))))