diff --git a/internal/agent/hooks/gruboptions.go b/internal/agent/hooks/gruboptions.go new file mode 100644 index 0000000..2d0afaa --- /dev/null +++ b/internal/agent/hooks/gruboptions.go @@ -0,0 +1,38 @@ +package hook + +import ( + "fmt" + "strings" + + config "github.com/c3os-io/c3os/pkg/config" + "github.com/c3os-io/c3os/pkg/utils" +) + +type GrubOptions struct{} + +func (b GrubOptions) Run(c config.Config) error { + oem, _ := utils.SH("blkid -L COS_OEM") + if oem == "" { + fmt.Println("OEM partition not found") + return nil // do not error out + } + + oem = strings.TrimSuffix(oem, "\n") + + oemMount, err := utils.SH(fmt.Sprintf("mkdir /tmp/oem && mount %s /tmp/oem", oem)) + if err != nil { + fmt.Printf("could not mount oem: %s\n", oemMount+err.Error()) + return nil // do not error out + } + + for k, v := range c.Install.GrubOptions { + out, err := utils.SH(fmt.Sprintf("grub2-editenv /tmp/oem/grubenv set %s=%s", k, v)) + if err != nil { + fmt.Printf("could not set boot option: %s\n", out+err.Error()) + return nil // do not error out + } + } + + utils.SH("umount /tmp/oem") //nolint:errcheck + return nil +} diff --git a/internal/agent/hooks/hook.go b/internal/agent/hooks/hook.go new file mode 100644 index 0000000..b914c60 --- /dev/null +++ b/internal/agent/hooks/hook.go @@ -0,0 +1,24 @@ +package hook + +import ( + config "github.com/c3os-io/c3os/pkg/config" +) + +type Interface interface { + Run(c config.Config) error +} + +var All = []Interface{ + &RunStage{}, // Shells out to stages defined from the container image + &GrubOptions{}, // Set custom GRUB options + &Lifecycle{}, // Handles poweroff/reboot by config options +} + +func Run(c config.Config, hooks ...Interface) error { + for _, h := range hooks { + if err := h.Run(c); err != nil { + return err + } + } + return nil +} diff --git a/internal/agent/hooks/lifecycle.go b/internal/agent/hooks/lifecycle.go new file mode 100644 index 0000000..0f15a57 --- /dev/null +++ b/internal/agent/hooks/lifecycle.go @@ -0,0 +1,19 @@ +package hook + +import ( + config "github.com/c3os-io/c3os/pkg/config" + "github.com/c3os-io/c3os/pkg/utils" +) + +type Lifecycle struct{} + +func (s Lifecycle) Run(c config.Config) error { + if c.Install.Reboot { + utils.Reboot() + } + + if c.Install.Poweroff { + utils.PowerOFF() + } + return nil +} diff --git a/internal/agent/hooks/runstage.go b/internal/agent/hooks/runstage.go new file mode 100644 index 0000000..e20a253 --- /dev/null +++ b/internal/agent/hooks/runstage.go @@ -0,0 +1,16 @@ +package hook + +import ( + config "github.com/c3os-io/c3os/pkg/config" + "github.com/c3os-io/c3os/pkg/utils" + + events "github.com/c3os-io/c3os/sdk/bus" +) + +type RunStage struct{} + +func (r RunStage) Run(c config.Config) error { + utils.SH("elemental run-stage c3os-install.after") //nolint:errcheck + events.RunHookScript("/usr/bin/c3os-agent.install.after.hook") //nolint:errcheck + return nil +} diff --git a/internal/agent/install.go b/internal/agent/install.go index 90337b5..0e00428 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -14,6 +14,7 @@ import ( config "github.com/c3os-io/c3os/pkg/config" + hook "github.com/c3os-io/c3os/internal/agent/hooks" "github.com/c3os-io/c3os/internal/bus" "github.com/c3os-io/c3os/internal/cmd" @@ -196,6 +197,15 @@ func RunInstall(options map[string]string) error { _, reboot := options["reboot"] _, poweroff := options["poweroff"] + if c.Install == nil { + c.Install = &config.Install{} + } + if poweroff { + c.Install.Poweroff = true + } + if reboot { + c.Install.Reboot = true + } err := ioutil.WriteFile(f.Name(), []byte(cloudInit), os.ModePerm) if err != nil { @@ -215,15 +225,10 @@ func RunInstall(options map[string]string) error { fmt.Println(err) os.Exit(1) } - utils.SH("elemental run-stage c3os-install.after") //nolint:errcheck - events.RunHookScript("/usr/bin/c3os-agent.install.after.hook") //nolint:errcheck - if reboot || c.Install != nil && c.Install.Reboot { - utils.Reboot() + if err := hook.Run(*c, hook.All...); err != nil { + return err } - if poweroff || c.Install != nil && c.Install.Poweroff { - utils.PowerOFF() - } return nil }