diff --git a/pkg/action/common.go b/pkg/action/common.go index 7de3fa3..9d7e7f0 100644 --- a/pkg/action/common.go +++ b/pkg/action/common.go @@ -18,7 +18,10 @@ package action import ( config "github.com/kairos-io/kairos-agent/v2/pkg/config" + cnst "github.com/kairos-io/kairos-agent/v2/pkg/constants" "github.com/kairos-io/kairos-agent/v2/pkg/utils" + fsutils "github.com/kairos-io/kairos-agent/v2/pkg/utils/fs" + "path/filepath" ) // Hook is RunStage wrapper that only adds logic to ignore errors @@ -39,3 +42,15 @@ func ChrootHook(config *config.Config, hook string, chrootDir string, bindMounts } return utils.ChrootedCallback(config, chrootDir, bindMounts, callback) } + +func createExtraDirsInRootfs(cfg *config.Config, extradirs []string, target string) { + for _, d := range extradirs { + if exists, _ := fsutils.Exists(cfg.Fs, filepath.Join(target, d)); !exists { + cfg.Logger.Debugf("Creating extra dir %s under %s", d, target) + err := cfg.Fs.Mkdir(filepath.Join(target, d), cnst.DirPerm) + if err != nil { + cfg.Logger.Warnf("Failure creating extra dir %s in rootfs at %s", d, target) + } + } + } +} diff --git a/pkg/action/install.go b/pkg/action/install.go index ecead8b..2e2ca5a 100644 --- a/pkg/action/install.go +++ b/pkg/action/install.go @@ -177,6 +177,9 @@ func (i InstallAction) Run() (err error) { } cleanup.Push(func() error { return e.UnmountImage(&i.spec.Active) }) + // Create extra dirs in rootfs as afterwards this will be impossible due to RO system + createExtraDirsInRootfs(i.cfg, i.spec.ExtraDirsRootfs, i.spec.Active.MountPoint) + // Copy cloud-init if any err = e.CopyCloudConfig(i.spec.CloudInit) if err != nil { diff --git a/pkg/action/reset.go b/pkg/action/reset.go index af69501..789461d 100644 --- a/pkg/action/reset.go +++ b/pkg/action/reset.go @@ -168,6 +168,9 @@ func (r ResetAction) Run() (err error) { } cleanup.Push(func() error { return e.UnmountImage(&r.spec.Active) }) + // Create extra dirs in rootfs as afterwards this will be impossible due to RO system + createExtraDirsInRootfs(r.cfg, r.spec.ExtraDirsRootfs, r.spec.Active.MountPoint) + // install grub grub := utils.NewGrub(r.cfg) err = grub.Install( diff --git a/pkg/action/upgrade.go b/pkg/action/upgrade.go index 187d3c5..735af4d 100644 --- a/pkg/action/upgrade.go +++ b/pkg/action/upgrade.go @@ -181,6 +181,9 @@ func (u *UpgradeAction) Run() (err error) { } cleanup.Push(func() error { return e.UnmountImage(&upgradeImg) }) + // Create extra dirs in rootfs as afterwards this will be impossible due to RO system + createExtraDirsInRootfs(u.config, u.spec.ExtraDirsRootfs, upgradeImg.MountPoint) + // Selinux relabel // Doesn't make sense to relabel a readonly filesystem if upgradeImg.FS != constants.SquashFs { diff --git a/pkg/types/v1/config.go b/pkg/types/v1/config.go index c025780..9233889 100644 --- a/pkg/types/v1/config.go +++ b/pkg/types/v1/config.go @@ -56,6 +56,7 @@ type InstallSpec struct { Tty string `yaml:"tty,omitempty" mapstructure:"tty"` Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"` PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"` + ExtraDirsRootfs []string `yaml:"extra-dirs-rootfs,omitempty" mapstructure:"extra-dirs-rootfs"` Active Image `yaml:"system,omitempty" mapstructure:"system"` Recovery Image `yaml:"recovery-system,omitempty" mapstructure:"recovery-system"` Passive Image @@ -105,20 +106,20 @@ func (i *InstallSpec) ShouldShutdown() bool { return i.PowerOff } // ResetSpec struct represents all the reset action details type ResetSpec struct { - FormatPersistent bool `yaml:"reset-persistent,omitempty" mapstructure:"reset-persistent"` - FormatOEM bool `yaml:"reset-oem,omitempty" mapstructure:"reset-oem"` - Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"` - PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"` - - GrubDefEntry string `yaml:"grub-entry-name,omitempty" mapstructure:"grub-entry-name"` - Tty string `yaml:"tty,omitempty" mapstructure:"tty"` - Active Image `yaml:"system,omitempty" mapstructure:"system"` - Passive Image - Partitions ElementalPartitions - Target string - Efi bool - GrubConf string - State *InstallState + FormatPersistent bool `yaml:"reset-persistent,omitempty" mapstructure:"reset-persistent"` + FormatOEM bool `yaml:"reset-oem,omitempty" mapstructure:"reset-oem"` + Reboot bool `yaml:"reboot,omitempty" mapstructure:"reboot"` + PowerOff bool `yaml:"poweroff,omitempty" mapstructure:"poweroff"` + GrubDefEntry string `yaml:"grub-entry-name,omitempty" mapstructure:"grub-entry-name"` + Tty string `yaml:"tty,omitempty" mapstructure:"tty"` + ExtraDirsRootfs []string `yaml:"extra-dirs-rootfs,omitempty" mapstructure:"extra-dirs-rootfs"` + Active Image `yaml:"system,omitempty" mapstructure:"system"` + Passive Image + Partitions ElementalPartitions + Target string + Efi bool + GrubConf string + State *InstallState } // Sanitize checks the consistency of the struct, returns error @@ -137,12 +138,13 @@ func (r *ResetSpec) ShouldReboot() bool { return r.Reboot } func (r *ResetSpec) ShouldShutdown() bool { return r.PowerOff } type UpgradeSpec struct { - RecoveryUpgrade bool `yaml:"recovery,omitempty" mapstructure:"recovery"` - Active Image `yaml:"system,omitempty" mapstructure:"system"` - Recovery Image `yaml:"recovery-system,omitempty" mapstructure:"recovery-system"` - 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"` + RecoveryUpgrade bool `yaml:"recovery,omitempty" mapstructure:"recovery"` + Active Image `yaml:"system,omitempty" mapstructure:"system"` + Recovery Image `yaml:"recovery-system,omitempty" mapstructure:"recovery-system"` + 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"` + ExtraDirsRootfs []string `yaml:"extra-dirs-rootfs,omitempty" mapstructure:"extra-dirs-rootfs"` Passive Image Partitions ElementalPartitions State *InstallState