diff --git a/pkg/action/build-disk.go b/pkg/action/build-disk.go index f50da912b70..ba94cf2b0bd 100644 --- a/pkg/action/build-disk.go +++ b/pkg/action/build-disk.go @@ -101,8 +101,8 @@ func WithDiskBootloader(bootloader types.Bootloader) BuildDiskActionOption { } } -func (b *BuildDiskAction) buildDiskHook(hook string) error { - return Hook(&b.cfg.Config, hook, b.cfg.Strict, b.cfg.CloudInitPaths...) +func (b *BuildDiskAction) buildDiskHook(hook string, workdir string) error { + return Hook(&b.cfg.Config, hook, b.cfg.Strict, workdir, b.cfg.CloudInitPaths...) } func (b *BuildDiskAction) buildDiskChrootHook(hook string, root string) error { @@ -149,7 +149,7 @@ func (b *BuildDiskAction) BuildDiskRun() (err error) { //nolint:gocyclo rawImg = filepath.Join(b.cfg.OutDir, rawImg) // Before disk hook happens before doing anything - err = b.buildDiskHook(constants.BeforeDiskHook) + err = b.buildDiskHook(constants.BeforeDiskHook, workdir) if err != nil { return elementalError.NewFromError(err, elementalError.HookBeforeDisk) } @@ -226,7 +226,7 @@ func (b *BuildDiskAction) BuildDiskRun() (err error) { //nolint:gocyclo return elementalError.NewFromError(err, elementalError.HookAfterDiskChroot) } } - err = b.buildDiskHook(constants.AfterDiskHook) + err = b.buildDiskHook(constants.AfterDiskHook, workdir) if err != nil { return elementalError.NewFromError(err, elementalError.HookAfterDisk) } @@ -257,7 +257,7 @@ func (b *BuildDiskAction) BuildDiskRun() (err error) { //nolint:gocyclo return err } - err = b.buildDiskHook(constants.PostDiskHook) + err = b.buildDiskHook(constants.PostDiskHook, workdir) if err != nil { return elementalError.NewFromError(err, elementalError.HookPostDisk) } diff --git a/pkg/action/common.go b/pkg/action/common.go index c1a01250ea8..f51d29d5d1d 100644 --- a/pkg/action/common.go +++ b/pkg/action/common.go @@ -17,6 +17,8 @@ limitations under the License. package action import ( + "os" + "github.com/sirupsen/logrus" elementalError "github.com/rancher/elemental-toolkit/v2/pkg/error" @@ -25,12 +27,31 @@ import ( ) // Hook is RunStage wrapper that only adds logic to ignore errors -// in case types.RunConfig.Strict is set to false -func Hook(config *types.Config, hook string, strict bool, cloudInitPaths ...string) error { +// in case types.RunConfig.Strict is set to false and changes the default working directory +// to the given one. Previous working directory is restored after the method execution. +func Hook(config *types.Config, hook string, strict bool, workdir string, cloudInitPaths ...string) (err error) { + var currentPath string + config.Logger.Infof("Running %s hook", hook) + if workdir != "" { + currentPath, err = os.Getwd() + if err != nil { + return err + } + err = os.Chdir(workdir) + if err != nil { + return err + } + defer func() { + nErr := os.Chdir(currentPath) + if err == nil && nErr != nil { + err = nErr + } + }() + } oldLevel := config.Logger.GetLevel() config.Logger.SetLevel(logrus.ErrorLevel) - err := utils.RunStage(config, hook, strict, cloudInitPaths...) + err = utils.RunStage(config, hook, strict, cloudInitPaths...) config.Logger.SetLevel(oldLevel) if !strict { err = nil @@ -41,7 +62,7 @@ func Hook(config *types.Config, hook string, strict bool, cloudInitPaths ...stri // ChrootHook executes Hook inside a chroot environment func ChrootHook(config *types.Config, hook string, strict bool, chrootDir string, bindMounts map[string]string, cloudInitPaths ...string) (err error) { callback := func() error { - return Hook(config, hook, strict, cloudInitPaths...) + return Hook(config, hook, strict, "", cloudInitPaths...) } return utils.ChrootedCallback(config, chrootDir, bindMounts, callback) } diff --git a/pkg/action/install.go b/pkg/action/install.go index ee6395fe11b..c2a76994d6e 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -82,7 +82,7 @@ func NewInstallAction(cfg *types.RunConfig, spec *types.InstallSpec, opts ...Ins } func (i *InstallAction) installHook(hook string) error { - return Hook(&i.cfg.Config, hook, i.cfg.Strict, i.cfg.CloudInitPaths...) + return Hook(&i.cfg.Config, hook, i.cfg.Strict, "", i.cfg.CloudInitPaths...) } func (i *InstallAction) installChrootHook(hook string, root string) error { diff --git a/pkg/action/reset.go b/pkg/action/reset.go index db5840f5e7f..5404a06a4eb 100644 --- a/pkg/action/reset.go +++ b/pkg/action/reset.go @@ -33,7 +33,7 @@ import ( ) func (r *ResetAction) resetHook(hook string) error { - return Hook(&r.cfg.Config, hook, r.cfg.Strict, r.cfg.CloudInitPaths...) + return Hook(&r.cfg.Config, hook, r.cfg.Strict, "", r.cfg.CloudInitPaths...) } func (r *ResetAction) resetChrootHook(hook string, root string) error { diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 97451232377..5acdb055292 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -103,7 +103,7 @@ func (u UpgradeAction) Error(s string, args ...interface{}) { func (u UpgradeAction) upgradeHook(hook string) error { u.Info("Applying '%s' hook", hook) - return Hook(&u.cfg.Config, hook, u.cfg.Strict, u.cfg.CloudInitPaths...) + return Hook(&u.cfg.Config, hook, u.cfg.Strict, "", u.cfg.CloudInitPaths...) } func (u UpgradeAction) upgradeChrootHook(hook string, root string) error { diff --git a/pkg/features/embedded/arm-firmware/system/oem/00_armfirmware.yaml b/pkg/features/embedded/arm-firmware/system/oem/00_armfirmware.yaml new file mode 100644 index 00000000000..b12f1bb8603 --- /dev/null +++ b/pkg/features/embedded/arm-firmware/system/oem/00_armfirmware.yaml @@ -0,0 +1,20 @@ +name: "Set ARM Firmware" +stages: + after-install-chroot: + - &pifirmware + name: Raspberry PI post hook + if: '[ -d "/boot/vc" ]' + commands: + - cp -rf /boot/vc/* /run/elemental/efi/ + + after-upgrade-chroot: + - <<: *pifirmware + + after-reset-chroot: + - <<: *pifirmware + + after-disk: + - name: Raspberry PI post hook + if: '[ -d "./recovery.img.root/boot/vc" ]' + commands: + - cp -rf ./recovery.img.root/boot/vc/* ./efi/ \ No newline at end of file diff --git a/pkg/features/features.go b/pkg/features/features.go index ffebca0251a..4afc1c44fea 100644 --- a/pkg/features/features.go +++ b/pkg/features/features.go @@ -54,6 +54,7 @@ const ( FeatureCloudConfigEssentials = "cloud-config-essentials" FeatureBootAssessment = "boot-assessment" FeatureAutologin = "autologin" + FeatureArmFirmware = "arm-firmware" ) var ( @@ -67,6 +68,7 @@ var ( FeatureCloudConfigDefaults, FeatureCloudConfigEssentials, FeatureBootAssessment, + FeatureArmFirmware, } Default = []string{ @@ -171,6 +173,8 @@ func Get(names []string) ([]*Feature, error) { features = append(features, New(name, units)) case FeatureAutologin: features = append(features, New(name, nil)) + case FeatureArmFirmware: + features = append(features, New(name, nil)) default: notFound = append(notFound, name) }