Commit | Line | Data |
---|---|---|
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 | |
52 | environment. MAPPINGS is a list of <file-system-mapping> to realize in the | |
53 | containerized 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. | |
77 | MAPPINGS is a list of <file-system> objects that specify the files/directories | |
78 | that 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)))))) |