diff --git a/cmd/control/bootstrap.go b/cmd/control/bootstrap.go index db2f94b0..eb19880e 100644 --- a/cmd/control/bootstrap.go +++ b/cmd/control/bootstrap.go @@ -1,9 +1,11 @@ package control import ( + "fmt" "io/ioutil" "os" "os/exec" + "path/filepath" "strings" "time" @@ -37,6 +39,20 @@ func BootstrapMain() { } } + log.Debugf("bootstrapAction: cryptsetup(%v)", cfg.Rancher.State.Cryptsetup) + if cfg.Rancher.State.Cryptsetup { + if err := cryptsetup(); err != nil { + log.Errorf("Failed to run cryptsetup: %v", err) + } + } + + log.Debugf("bootstrapAction: LvmScan(%v)", cfg.Rancher.State.LvmScan) + if cfg.Rancher.State.LvmScan { + if err := vgchange(); err != nil { + log.Errorf("Failed to run vgchange: %v", err) + } + } + stateScript := cfg.Rancher.State.Script log.Debugf("bootstrapAction: stateScript(%v)", stateScript) if stateScript != "" { @@ -75,6 +91,45 @@ func mdadmScan() error { return cmd.Run() } +func vgchange() error { + cmd := exec.Command("vgchange", "--activate", "ay") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + +func cryptsetup() error { + devices, err := util.BlkidType("crypto_LUKS") + if err != nil { + return err + } + + for _, cryptdevice := range devices { + fdRead, err := os.Open("/dev/console") + if err != nil { + return err + } + defer fdRead.Close() + + fdWrite, err := os.OpenFile("/dev/console", os.O_WRONLY|os.O_APPEND, 0) + if err != nil { + return err + } + defer fdWrite.Close() + + cmd := exec.Command("cryptsetup", "luksOpen", cryptdevice, fmt.Sprintf("luks-%s", filepath.Base(cryptdevice))) + cmd.Stdout = fdWrite + cmd.Stderr = fdWrite + cmd.Stdin = fdRead + + if err := cmd.Run(); err != nil { + log.Errorf("Failed to run cryptsetup for %s: %v", cryptdevice, err) + } + } + + return nil +} + func runRngd() error { // use /dev/urandom as random number input for rngd // this is a really bad idea diff --git a/config/schema.go b/config/schema.go index 6bd46c4d..5be1a81f 100644 --- a/config/schema.go +++ b/config/schema.go @@ -170,6 +170,8 @@ var schema = `{ "required": {"type": "boolean"}, "autoformat": {"$ref": "#/definitions/list_of_strings"}, "mdadm_scan": {"type": "boolean"}, + "cryptsetup": {"type": "boolean"}, + "lvm_scan": {"type": "boolean"}, "rngd": {"type": "boolean"}, "script": {"type": "string"}, "oem_fstype": {"type": "string"}, diff --git a/config/types.go b/config/types.go index 62389cf5..aad9c215 100644 --- a/config/types.go +++ b/config/types.go @@ -205,6 +205,8 @@ type StateConfig struct { Required bool `yaml:"required,omitempty"` Autoformat []string `yaml:"autoformat,omitempty"` MdadmScan bool `yaml:"mdadm_scan,omitempty"` + LvmScan bool `yaml:"lvm_scan,omitempty"` + Cryptsetup bool `yaml:"cryptsetup,omitempty"` Rngd bool `yaml:"rngd,omitempty"` Script string `yaml:"script,omitempty"` OemFsType string `yaml:"oem_fstype,omitempty"` diff --git a/pkg/util/util_linux.go b/pkg/util/util_linux.go index fd3ce4d4..f8be7de5 100644 --- a/pkg/util/util_linux.go +++ b/pkg/util/util_linux.go @@ -119,6 +119,28 @@ func Blkid(label string) (deviceName, deviceType string, err error) { return } +func BlkidType(deviceType string) (deviceNames []string, err error) { + // Not all blkid's have `blkid -L label (see busybox/alpine) + cmd := exec.Command("blkid") + cmd.Stderr = os.Stderr + out, err := cmd.Output() + if err != nil { + return nil, err + } + r := bytes.NewReader(out) + s := bufio.NewScanner(r) + for s.Scan() { + line := s.Text() + if !strings.Contains(line, `TYPE="`+deviceType+`"`) { + continue + } + d := strings.Split(line, ":") + deviceName := d[0] + deviceNames = append(deviceNames, deviceName) + } + return deviceNames, nil +} + // GetHypervisor tries to detect if we're running in a VM, and returns a string for its type func GetHypervisor() string { return cpuid.CPU.HypervisorName diff --git a/scripts/schema.json b/scripts/schema.json index 4e5e6cc3..435fb7f1 100644 --- a/scripts/schema.json +++ b/scripts/schema.json @@ -164,6 +164,8 @@ "required": {"type": "boolean"}, "autoformat": {"$ref": "#/definitions/list_of_strings"}, "mdadm_scan": {"type": "boolean"}, + "cryptsetup": {"type": "boolean"}, + "lvm_scan": {"type": "boolean"}, "script": {"type": "string"}, "oem_fstype": {"type": "string"}, "oem_dev": {"type": "string"}