Skip to content

Commit

Permalink
Add --reboot and --poweroff flags (#66)
Browse files Browse the repository at this point in the history
Signed-off-by: David Cassany <dcassany@suse.com>
  • Loading branch information
davidcassany authored Feb 1, 2022
1 parent b4ac656 commit aa7fe62
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 8 deletions.
8 changes: 6 additions & 2 deletions cmd/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ var installCmd = &cobra.Command{
// Note that vars with ELEMENTAL in front and that match entries in the config (only one level deep) are overwritten automatically
cfg.Target = args[0]

cfg.DigestSetup()
err = cfg.DigestSetup()
if err != nil {
return err
}
cmd.SilenceUsage = true

cfg.Logger.Infof("Install called")
Expand Down Expand Up @@ -75,9 +78,10 @@ func init() {
installCmd.Flags().BoolP("force-efi", "", false, "Forces an EFI installation")
installCmd.Flags().BoolP("force-gpt", "", false, "Forces a GPT partition table")
installCmd.Flags().BoolP("strict", "", false, "Enable strict check of hooks (They need to exit with 0)")
installCmd.Flags().BoolP("poweroff", "", false, "Shutdown the system after install")
installCmd.Flags().BoolP("tty", "", false, "Add named tty to grub")
installCmd.Flags().BoolP("force", "", false, "Force install")
installCmd.Flags().BoolP("reboot", "", false, "Reboot the system after install")
installCmd.Flags().BoolP("poweroff", "", false, "Shutdown the system after install")

viper.BindPFlags(installCmd.Flags())

Expand Down
4 changes: 4 additions & 0 deletions pkg/action/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ var _ = Describe("Actions", func() {
config.ActiveImage.Size = activeSize
config.ActiveImage.RootTree = activeTree
config.ActiveImage.MountPoint = activeMount
config.Reboot = true
Expect(install.Run()).To(BeNil())
Expect(runner.IncludesCmds([][]string{{"reboot", "-f"}}))
})

It("Successfully installs despite hooks failure", func() {
Expand All @@ -134,7 +136,9 @@ var _ = Describe("Actions", func() {
config.ActiveImage.Size = activeSize
config.ActiveImage.RootTree = activeTree
config.ActiveImage.MountPoint = activeMount
config.PowerOff = true
Expect(install.Run()).To(BeNil())
Expect(runner.IncludesCmds([][]string{{"poweroff", "-f"}}))
})

It("Successfully installs from ISO", func() {
Expand Down
11 changes: 9 additions & 2 deletions pkg/action/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,14 @@ func (i InstallAction) Run() (err error) {
if err != nil {
return err
}
// profit!
// TODO poweroff or reboot or nothing

// Reboot, poweroff or nothing
if i.Config.Reboot {
i.Config.Logger.Infof("Rebooting in 5 seconds")
return utils.Reboot(i.Config.Runner, 5)
} else if i.Config.PowerOff {
i.Config.Logger.Infof("Shutting down in 5 seconds")
return utils.Shutdown(i.Config.Runner, 5)
}
return err
}
33 changes: 29 additions & 4 deletions pkg/types/v1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package v1

import (
"errors"
"fmt"
dockTypes "github.com/docker/docker/api/types"
"github.com/mudler/luet/pkg/api/core/context"
Expand Down Expand Up @@ -189,6 +190,8 @@ type RunConfig struct {
NoVerify bool `yaml:"no-verify,omitempty" mapstructure:"no-verify"`
CloudInitPaths string `yaml:"CLOUD_INIT_PATHS,omitempty" mapstructure:"CLOUD_INIT_PATHS"`
GrubDefEntry string `yaml:"GRUB_ENTRY_NAME,omitempty" mapstructure:"GRUB_ENTRY_NAME"`
Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"`
PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"`
// Internally used to track stuff around
PartTable string
BootFlag string
Expand Down Expand Up @@ -330,13 +333,30 @@ func (r *RunConfig) setupStyle() {
r.Partitions = append(r.Partitions, part)
}

// sanityChecks just verifies some potential inconsistencies on configuration
func (r RunConfig) sanityChecks() error {
err := errors.New("Invalid options")
if r.Reboot && r.PowerOff {
r.Logger.Errorf("'reboot' and 'poweroff' are mutually exclusive options")
return err
}

if r.CosignPubKey != "" && !r.Cosign {
r.Logger.Errorf("'cosign-key' requires 'cosing' option to be enabled")
return err
}

if r.Cosign && r.CosignPubKey == "" {
r.Logger.Warnf("No 'cosign-key' option set, keyless cosign verification is experimental")
}

return nil
}

// setupLuet will initialize Luet interface if required
func (r *RunConfig) setupLuet() {
if r.DockerImg != "" {
plugins := []string{}
if r.Cosign && r.CosignPubKey == "" {
r.Logger.Warnf("Keyless cosign verification is experimental, consider setting a public key")
}
if !r.NoVerify {
plugins = append(plugins, cnst.LuetMtreePlugin)
}
Expand All @@ -345,9 +365,14 @@ func (r *RunConfig) setupLuet() {
}

// DigestSetup will gather what partition table and bootflag we need for the current system
func (r *RunConfig) DigestSetup() {
func (r *RunConfig) DigestSetup() error {
err := r.sanityChecks()
if err != nil {
return err
}
r.setupStyle()
r.setupLuet()
return nil
}

// BuildConfig represents the config we need for building isos, raw images, artifacts
Expand Down
16 changes: 16 additions & 0 deletions pkg/utils/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ func SyncData(source string, target string, excludes ...string) error {
return task.Run()
}

// Reboot reboots the system afater the given delay (in seconds) time passed.
func Reboot(runner v1.Runner, delay time.Duration) error {
time.Sleep(delay * time.Second)
_, err := runner.Run("reboot", "-f")
return err
}

// Shutdown halts the system afater the given delay (in seconds) time passed.
func Shutdown(runner v1.Runner, delay time.Duration) error {
time.Sleep(delay * time.Second)
_, err := runner.Run("poweroff", "-f")
return err
}

// CosignVerify runs a cosign validation for the give image and given public key. If no
// key is provided then it attempts a keyless validation (experimental feature).
func CosignVerify(fs afero.Fs, runner v1.Runner, image string, publicKey string, debug bool) (string, error) {
args := []string{}

Expand Down
21 changes: 21 additions & 0 deletions pkg/utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"io/ioutil"
"os"
"testing"
"time"
)

func getNamesFromListFiles(list []os.FileInfo) []string {
Expand Down Expand Up @@ -197,6 +198,26 @@ var _ = Describe("Utils", func() {
Expect(err).NotTo(BeNil())
})
})
Context("Reboot and shutdown", func() {
var runner *v1mock.TestRunnerV2
BeforeEach(func() {
runner = v1mock.NewTestRunnerV2()
})
It("reboots", func() {
start := time.Now()
utils.Reboot(runner, 2)
duration := time.Since(start)
Expect(runner.CmdsMatch([][]string{{"reboot", "-f"}})).To(BeNil())
Expect(duration.Seconds() >= 2).To(BeTrue())
})
It("shuts down", func() {
start := time.Now()
utils.Shutdown(runner, 3)
duration := time.Since(start)
Expect(runner.CmdsMatch([][]string{{"poweroff", "-f"}})).To(BeNil())
Expect(duration.Seconds() >= 3).To(BeTrue())
})
})
Context("CopyFile", func() {
It("Copies source to target", func() {
fs.Create("/some/file")
Expand Down

0 comments on commit aa7fe62

Please sign in to comment.