aboutsummaryrefslogtreecommitdiff
path: root/src/property
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 /src/property
parent9c66f8a7b5863ac19cc3827ed174c1f960361a4b (diff)
downloadconsfigurator-2fcbe645d1d11a871cd152aa2ac86f287631ff65.tar.gz
implement populating /etc/crypttab for LUKS containers
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
Diffstat (limited to 'src/property')
-rw-r--r--src/property/crypttab.lisp88
-rw-r--r--src/property/installer.lisp18
2 files changed, 97 insertions, 9 deletions
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
)))