move to clean crypt handling
This commit is contained in:
154
lvm.go
154
lvm.go
@ -7,18 +7,32 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"novit.nc/direktil/initrd/lvm"
|
||||
config "novit.tech/direktil/pkg/bootstrapconfig"
|
||||
)
|
||||
|
||||
func sortedKeys[T any](m map[string]T) (keys []string) {
|
||||
keys = make([]string, 0, len(m))
|
||||
for k := range m {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
return
|
||||
}
|
||||
|
||||
func setupLVM(cfg *config.Config) {
|
||||
if len(cfg.LVM) == 0 {
|
||||
log.Print("no LVM VG configured.")
|
||||
return
|
||||
}
|
||||
|
||||
// [dev] = filesystem
|
||||
// eg: [/dev/sda1] = ext4
|
||||
createdDevs := map[string]string{}
|
||||
|
||||
run("pvscan")
|
||||
run("vgscan", "--mknodes")
|
||||
|
||||
@ -27,17 +41,21 @@ func setupLVM(cfg *config.Config) {
|
||||
}
|
||||
|
||||
for _, vg := range cfg.LVM {
|
||||
setupLVs(vg)
|
||||
setupLVs(vg, createdDevs)
|
||||
}
|
||||
|
||||
run("vgchange", "--sysinit", "-a", "ly")
|
||||
|
||||
for _, vg := range cfg.LVM {
|
||||
setupCrypt(vg)
|
||||
}
|
||||
setupCrypt(cfg.Crypt, createdDevs)
|
||||
|
||||
for _, vg := range cfg.LVM {
|
||||
setupFS(vg)
|
||||
devs := make([]string, 0, len(createdDevs))
|
||||
for k := range createdDevs {
|
||||
devs = append(devs, k)
|
||||
}
|
||||
sort.Strings(devs)
|
||||
|
||||
for _, dev := range devs {
|
||||
setupFS(dev, createdDevs[dev])
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +131,7 @@ func setupVG(vg config.LvmVG) {
|
||||
}
|
||||
}
|
||||
|
||||
func setupLVs(vg config.LvmVG) {
|
||||
func setupLVs(vg config.LvmVG, createdDevs map[string]string) {
|
||||
lvsRep := lvm.LVSReport{}
|
||||
err := runJSON(&lvsRep, "lvs", "--reportformat", "json")
|
||||
if err != nil {
|
||||
@ -171,6 +189,12 @@ func setupLVs(vg config.LvmVG) {
|
||||
|
||||
dev := "/dev/" + vg.VG + "/" + lv.Name
|
||||
zeroDevStart(dev)
|
||||
|
||||
fs := lv.FS
|
||||
if fs == "" {
|
||||
fs = vg.Defaults.FS
|
||||
}
|
||||
createdDevs[dev] = fs
|
||||
}
|
||||
}
|
||||
|
||||
@ -188,21 +212,52 @@ func zeroDevStart(dev string) {
|
||||
}
|
||||
}
|
||||
|
||||
func setupCrypt(vg config.LvmVG) {
|
||||
cryptDevs := map[string]bool{}
|
||||
|
||||
func setupCrypt(devSpecs []config.CryptDev, createdDevs map[string]string) {
|
||||
var password []byte
|
||||
passwordVerified := false
|
||||
|
||||
for _, lv := range vg.LVs {
|
||||
if lv.Crypt == "" {
|
||||
// flat, expanded devices to open
|
||||
devNames := make([]config.CryptDev, 0, len(devSpecs))
|
||||
|
||||
for _, devSpec := range devSpecs {
|
||||
if devSpec.Dev == "" && devSpec.Prefix == "" {
|
||||
fatalf("crypt: name %q: no dev or match set", devSpec.Name)
|
||||
}
|
||||
if devSpec.Dev != "" && devSpec.Prefix != "" {
|
||||
fatalf("crypt: name %q: both dev (%q) and match (%q) are set", devSpec.Name, devSpec.Dev, devSpec.Prefix)
|
||||
}
|
||||
|
||||
if devSpec.Dev != "" {
|
||||
// already flat
|
||||
devNames = append(devNames, devSpec)
|
||||
continue
|
||||
}
|
||||
|
||||
if cryptDevs[lv.Crypt] {
|
||||
fatalf("duplicate crypt device name: %s", lv.Crypt)
|
||||
matches, err := filepath.Glob(devSpec.Prefix + "*")
|
||||
if err != nil {
|
||||
fatalf("failed to search for device matches: %v", err)
|
||||
}
|
||||
cryptDevs[lv.Crypt] = true
|
||||
|
||||
for _, m := range matches {
|
||||
suffix := m[len(devSpec.Prefix):]
|
||||
|
||||
devNames = append(devNames, config.CryptDev{Dev: m, Name: devSpec.Name + suffix})
|
||||
}
|
||||
}
|
||||
|
||||
cryptDevs := map[string]bool{}
|
||||
|
||||
for _, devName := range devNames {
|
||||
name, dev := devName.Name, devName.Dev
|
||||
|
||||
if name == "" {
|
||||
name = filepath.Base(dev)
|
||||
}
|
||||
|
||||
if cryptDevs[name] {
|
||||
fatalf("duplicate crypt device name: %s", name)
|
||||
}
|
||||
cryptDevs[name] = true
|
||||
|
||||
retryOpen:
|
||||
if len(password) == 0 {
|
||||
@ -213,7 +268,10 @@ func setupCrypt(vg config.LvmVG) {
|
||||
}
|
||||
}
|
||||
|
||||
dev := "/dev/" + vg.VG + "/" + lv.Name
|
||||
fs := createdDevs[dev]
|
||||
delete(createdDevs, dev)
|
||||
|
||||
tgtDev := "/dev/mapper/" + name
|
||||
|
||||
needFormat := !devInitialized(dev)
|
||||
if needFormat {
|
||||
@ -242,10 +300,20 @@ func setupCrypt(vg config.LvmVG) {
|
||||
if err != nil {
|
||||
fatalf("failed luksFormat: %v", err)
|
||||
}
|
||||
|
||||
createdDevs[tgtDev] = fs
|
||||
}
|
||||
|
||||
log.Print("openning encrypted device ", lv.Crypt, " from ", dev)
|
||||
cmd := exec.Command("cryptsetup", "open", dev, lv.Crypt, "--key-file=-")
|
||||
if len(password) == 0 {
|
||||
password = askSecret("crypt password")
|
||||
|
||||
if len(password) == 0 {
|
||||
fatalf("empty password given")
|
||||
}
|
||||
}
|
||||
|
||||
log.Print("openning encrypted device ", name, " from ", dev)
|
||||
cmd := exec.Command("cryptsetup", "open", dev, name, "--key-file=-")
|
||||
cmd.Stdin = bytes.NewBuffer(password)
|
||||
cmd.Stdout = stdout
|
||||
cmd.Stderr = stderr
|
||||
@ -261,7 +329,7 @@ func setupCrypt(vg config.LvmVG) {
|
||||
}
|
||||
|
||||
if needFormat {
|
||||
zeroDevStart("/dev/mapper/" + lv.Crypt)
|
||||
zeroDevStart(tgtDev)
|
||||
}
|
||||
|
||||
passwordVerified = true
|
||||
@ -294,33 +362,25 @@ func devInitialized(dev string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func setupFS(vg config.LvmVG) {
|
||||
for _, lv := range vg.LVs {
|
||||
dev := "/dev/" + vg.VG + "/" + lv.Name
|
||||
|
||||
if lv.Crypt != "" {
|
||||
dev = "/dev/mapper/" + lv.Crypt
|
||||
}
|
||||
|
||||
if devInitialized(dev) {
|
||||
log.Print("device ", dev, " already formatted")
|
||||
continue
|
||||
}
|
||||
|
||||
if lv.FS == "" {
|
||||
lv.FS = vg.Defaults.FS
|
||||
}
|
||||
|
||||
log.Print("formatting ", dev, " (", lv.FS, ")")
|
||||
args := make([]string, 0)
|
||||
|
||||
switch lv.FS {
|
||||
case "btrfs":
|
||||
args = append(args, "-f")
|
||||
case "ext4":
|
||||
args = append(args, "-F")
|
||||
}
|
||||
|
||||
run("mkfs."+lv.FS, append(args, dev)...)
|
||||
func setupFS(dev, fs string) {
|
||||
if devInitialized(dev) {
|
||||
log.Print("device ", dev, " already formatted")
|
||||
return
|
||||
}
|
||||
|
||||
if fs == "" {
|
||||
fs = "ext4"
|
||||
}
|
||||
|
||||
log.Print("formatting ", dev, " (", fs, ")")
|
||||
args := make([]string, 0)
|
||||
|
||||
switch fs {
|
||||
case "btrfs":
|
||||
args = append(args, "-f")
|
||||
case "ext4":
|
||||
args = append(args, "-F")
|
||||
}
|
||||
|
||||
run("mkfs."+fs, append(args, dev)...)
|
||||
}
|
||||
|
Reference in New Issue
Block a user