aboutsummaryrefslogtreecommitdiff
path: root/src/property/chroot.lisp
blob: c516c0dd083caa207c9aa3720a85d2ebe2240652 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
;;; Consfigurator -- Lisp declarative configuration management system

;;; Copyright (C) 2021  Sean Whitton <spwhitton@spwhitton.name>

;;; This file is free software; you can redistribute it and/or modify
;;; it under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3, or (at your option)
;;; any later version.

;;; This file is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.

;;; You should have received a copy of the GNU General Public License
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(in-package :consfigurator.property.chroot)
(named-readtables:in-readtable :consfigurator)

(defprop %debootstrapped :posix (root host &rest options)
  "Bootstrap The Universal Operating System into ROOT using debootstrap(1)."
  (:check
   (declare (ignore options host))
   ;; check whether a previous debootstrap failed partway through
   (if (test "-d" (merge-pathnames "debootstrap/"
                                   (ensure-directory-pathname root)))
       (progn (mrun "rm" "-rf" root) nil)
       (test "-d" root)))
  (:apply
   (let* ((os (car (getf (hostattrs host) :os)))
          (args (list (if (os:supports-arch-p (get-hostattrs-car :os)
                                              (os:linux-architecture os))
                          "debootstrap" "qemu-debootstrap")
                      (plist-to-cmd-args options)
                      (strcat "--arch=" (os:debian-architecture os))
                      (os:debian-suite os)
                      root)))
     (when-let ((proxy (get-hostattrs-car :apt.proxy)))
       (setq args (list* :env (list :http_proxy proxy) args)))
     (when-let ((mirror (get-hostattrs-car :apt.mirror)))
       (nconcf args (list mirror)))
     (apply #'run args))))

(defpropspec %os-bootstrapper-installed :posix (host)
  (:desc (declare (ignore host)) "OS bootstrapper installed")
  `(os:host-etypecase ,host
     (debian
      (os:etypecase
        (debianlike (apt:installed "debootstrap"))))))

(defpropspec %os-bootstrapped :posix (options root host)
  "Bootstrap OS into ROOT, e.g. with debootstrap(1)."
  ;; evaluate HOST once; can't use ONCE-ONLY because gensyms not serialisable
  ;; for sending to remote Lisp images
  (:desc (declare (ignore options root host)) "OS bootstrapped")
  (let ((host host))
    `(os:host-etypecase ,host
       (debian (%debootstrapped ,root ,host ,@options)))))

(defun make-child-host-for-chroot-deploy (propspec)
  "Return a preprocessed child host with properties as specified by PROPSPEC,
additionally set up such that deploying the host will not start up any
services."
  (preprocess-host
   (make-child-host
    :propspec (make-propspec
               :systems (propspec-systems propspec)
               :propspec `(service:without-starting-services
                              ,(propspec-props propspec))))))

(defproplist os-bootstrapped :lisp
    (options root properties
             &aux (host (make-child-host-for-chroot-deploy properties)))
  "Bootstrap an OS into ROOT and apply PROPERTIES.
OPTIONS is a plist of values to pass to the OS-specific bootstrapping property."
  (:desc (declare (ignore options properties))
         #?"Built chroot @ ${root}")
  (%os-bootstrapper-installed host)
  (%os-bootstrapped options root host)
  (deploys `((:chroot :into ,root)) host))