aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2021-05-04 11:35:38 -0700
committerSean Whitton <spwhitton@spwhitton.name>2021-05-06 12:23:51 -0700
commit2fcbe645d1d11a871cd152aa2ac86f287631ff65 (patch)
tree870589b156e17abe91f09563d60f837336ab9c92
parent9c66f8a7b5863ac19cc3827ed174c1f960361a4b (diff)
downloadconsfigurator-2fcbe645d1d11a871cd152aa2ac86f287631ff65.tar.gz
implement populating /etc/crypttab for LUKS containers
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
-rw-r--r--consfigurator.asd1
-rw-r--r--src/package.lisp12
-rw-r--r--src/property/crypttab.lisp88
-rw-r--r--src/property/installer.lisp18
4 files changed, 109 insertions, 10 deletions
diff --git a/consfigurator.asd b/consfigurator.asd
index 4fea201..f61220d 100644
--- a/consfigurator.asd
+++ b/consfigurator.asd
@@ -37,6 +37,7 @@
(:file "src/property/live-build")
(:file "src/property/disk")
(:file "src/property/fstab")
+ (:file "src/property/crypttab")
(:file "src/property/user")
(:file "src/property/git")
(:file "src/property/gnupg")
diff --git a/src/package.lisp b/src/package.lisp
index f2fca72..c2292f9 100644
--- a/src/package.lisp
+++ b/src/package.lisp
@@ -379,6 +379,7 @@
#:all-subvolumes
#:copy-volume-and-contents
#:require-volumes-data
+ #:device-file
#:physical-disk
#:disk-image
@@ -430,6 +431,14 @@
#:entries-for-volumes
#:entries-for-opened-volumes))
+(defpackage :consfigurator.property.crypttab
+ (:use #:cl #:alexandria #:consfigurator #:consfigurator.property.disk)
+ (:local-nicknames (#:re #:cl-ppcre)
+ (#:os #:consfigurator.property.os)
+ (#:file #:consfigurator.property.file))
+ (:export #:volume->entry
+ #:entries-for-opened-volumes))
+
(defpackage :consfigurator.property.gnupg
(:use #:cl #:consfigurator)
(:export #:public-key-imported))
@@ -469,7 +478,8 @@
(:local-nicknames (#:os #:consfigurator.property.os)
(#:file #:consfigurator.property.file)
(#:chroot #:consfigurator.property.chroot)
- (#:fstab #:consfigurator.property.fstab))
+ (#:fstab #:consfigurator.property.fstab)
+ (#:crypttab #:consfigurator.property.crypttab))
(:export #:chroot-installed-to-volumes))
(defpackage :consfigurator.connection.local
diff --git a/src/property/crypttab.lisp b/src/property/crypttab.lisp
new file mode 100644
index 0000000..a24ac26
--- /dev/null
+++ b/src/property/crypttab.lisp
@@ -0,0 +1,88 @@
+;;; 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.crypttab)
+(named-readtables:in-readtable :consfigurator)
+
+;;;; Methods on volumes to get strings for crypttab
+
+(defun get-lsblk-field (device field)
+ (let ((val (stripln (run "lsblk" "-ndo" field device))))
+ (if (string= val "") nil val)))
+
+(defun get-device-parent (device)
+ (multiple-value-bind (match groups)
+ (re:scan-to-strings #?/^1\s+dependencies\s*:\s*\((\S+)\)$/
+ (run "dmsetup" "deps" "-o" "blkdevname" device))
+ (and match (merge-pathnames (elt groups 0) #P"/dev/"))))
+
+(defmethod ct-target ((volume opened-luks-container))
+ (volume-label volume))
+
+(defmethod ct-source ((volume opened-luks-container))
+ (with-slots (device-file) volume
+ (let ((parent
+ (or (get-device-parent device-file)
+ (failed-change
+ "Could not determine parent device of ~A" device-file))))
+ (if-let ((partuuid (get-lsblk-field parent "PARTUUID")))
+ (strcat "PARTUUID=" partuuid)
+ (if-let ((uuid (get-lsblk-field parent "UUID")))
+ (strcat "UUID=" uuid)
+ (failed-change
+ "Could not determine crypttab source field for ~A" device-file))))))
+
+(defmethod ct-keyfile ((volume opened-luks-container))
+ (if (slot-boundp volume 'crypttab-keyfile)
+ (crypttab-keyfile volume)
+ "none"))
+
+(defmethod ct-options ((volume opened-luks-container))
+ (or (crypttab-options volume) '("none")))
+
+(defmethod volume->entry ((volume opened-luks-container))
+ (format nil "~A ~A ~A ~{~A~^,~}"
+ (ct-target volume) (ct-source volume)
+ (ct-keyfile volume) (ct-options volume)))
+
+
+;;;; Properties
+
+(defprop entries :posix (&rest entries)
+ "Ensure that /etc/crypttab contains each of ENTRIES, using a simple merge
+procedure: existing lines of the crypttab with the same mapped device name as
+any of ENTRIES are updated to match the corresponding members of ENTRIES,
+except that if the second field of the existing entry is not \"none\" and the
+corresponding member of ENTRIES is \"none\" or \"PLACEHOLDER\", use the
+existing field value."
+ (:desc
+ (let ((devices
+ (loop for entry in entries collect (car (split-string entry)))))
+ (format nil "crypttab entr~@P for ~{~A~^, ~}" (length devices) devices)))
+ (:apply (file:update-unix-table #P"/etc/crypttab" 1 0 entries)))
+
+(defprop entries-for-opened-volumes :posix ()
+ "Add or update entries in /etc/crypttab for currently open volumes.
+
+This is used when building disk images and installing operating systems."
+ (:desc "crypttab entries for opened volumes")
+ (:hostattrs (os:required 'os:linux))
+ (:apply
+ (apply #'entries
+ (mapcar #'volume->entry
+ (mapcan (curry #'subvolumes-of-type 'opened-luks-container)
+ (get-connattr :opened-volumes))))))
diff --git a/src/property/installer.lisp b/src/property/installer.lisp
index 80229a6..04bccfb 100644
--- a/src/property/installer.lisp
+++ b/src/property/installer.lisp
@@ -50,14 +50,14 @@ Also update the fstab and crypttab, and try to install a bootloader."
(debianlike
(file:lacks-lines "/etc/fstab"
"# UNCONFIGURED FSTAB FOR BASE SYSTEM")
- ;; This will overwrite any custom mount options, etc., with
- ;; values from VOLUMES. Possibly it would be better to use a
- ;; property which only updates the fs-spec field. However,
- ;; given that VOLUMES ultimately comes from the volumes the
- ;; user has declared for the host, it is unlikely there are
- ;; other properties setting mount options etc. which are in
- ;; conflict with VOLUMES.
- (fstab:entries-for-opened-volumes)))))
- ;; TODO Update /etc/crypttab
+ ;; These will overwrite any custom mount options, etc., with
+ ;; values from VOLUMES. Possibly it would be better to use
+ ;; properties which only update the fs-spec/source fields.
+ ;; However, given that VOLUMES ultimately comes from the
+ ;; volumes the user has declared for the host, it is unlikely
+ ;; there are other properties setting mount options etc. which
+ ;; are in conflict with VOLUMES.
+ (fstab:entries-for-opened-volumes)
+ (crypttab:entries-for-opened-volumes)))))
;; TODO Install bootloader
)))