kairos-agent/internal/agent/hooks/mounts.go
Oz Tiram 6e5c87a717 sparkles: custom user bind and ephemeral mounts (#692)
*  custom user bind and ephemeral mounts

Users can now specify custom and ephemeral mounts in cloud-init under
the `install` section, e.g.:

```
users:
 - name: kairos
...
install:
  auto: true
  device: "auto"
  bind_mounts:
  - /mnt/bind1
  - /mnt/bind2
  ephemeral_mounts:
  - /mnt/ephemeral
  - /mnt/ephemeral2
...
```
Ephemeral mounts are mounted as RW - but changes are discarded when the
machine is restart.
Bind mounts will persist changes after restarted.

This is a fix for #210

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Add the custom user mount to /cos/run/cos-layout.env

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Add docs for custom user mounts in configuration example

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Reuse test_install function

DRY the code, change how we call the function install_test

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Enable custom mount tests and install tests

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Enable tests in CI

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Remove duplicate if check

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Remove uneeded fmt.Println ...

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Use separate label for custom mounts

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* 🔧 Earthfile - DRY ginkgo

We repeat this a more than twice so just extract to own
target...

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Correct return type for  ContainElements

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Remove CLOUD_INIT from custom mounts test

This is not needed here.

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* Fix qemu-test-* earthly targets

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* 🔧 Fix CPU passing to VM

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* 🔧 remove apt cache after install qemu

Helps deal with space running out in the CI.

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

* 📖 Document custom mounts

Signed-off-by: Oz Tiram <oz@spectrocloud.com>

---------

Signed-off-by: Oz Tiram <oz@spectrocloud.com>
Co-authored-by: Ettore Di Giacinto <mudler@users.noreply.github.com>
2023-02-03 11:04:02 +01:00

60 lines
1.7 KiB
Go

package hook
import (
"fmt"
"os"
"path/filepath"
"strings"
config "github.com/kairos-io/kairos/pkg/config"
"github.com/kairos-io/kairos/pkg/machine"
"github.com/mudler/yip/pkg/schema"
yip "github.com/mudler/yip/pkg/schema"
"gopkg.in/yaml.v1"
)
type CustomMounts struct{}
func saveCloudConfig(name config.Stage, yc yip.YipConfig) error {
yipYAML, err := yaml.Marshal(yc)
if err != nil {
return err
}
return os.WriteFile(filepath.Join("/oem", fmt.Sprintf("10_%s.yaml", name)), yipYAML, 0400)
}
// Read the keys sections ephemeral_mounts and bind mounts from install key in the cloud config.
// If not empty write an environment file to /run/cos/custom-layout.env.
// That env file is in turn read by /overlay/files/system/oem/11_persistency.yaml in fs.after stage.
func (cm CustomMounts) Run(c config.Config) error {
//fmt.Println("Custom mounts hook")
//fmt.Println(strings.Join(c.Install.BindMounts, " "))
//fmt.Println(strings.Join(c.Install.EphemeralMounts, " "))
if len(c.Install.BindMounts) == 0 && len(c.Install.EphemeralMounts) == 0 {
return nil
}
machine.Mount("COS_OEM", "/oem") //nolint:errcheck
defer func() {
machine.Umount("/oem") //nolint:errcheck
}()
var mountsList = map[string]string{}
mountsList["CUSTOM_BIND_MOUNTS"] = strings.Join(c.Install.BindMounts, " ")
mountsList["CUSTOM_EPHEMERAL_MOUNTS"] = strings.Join(c.Install.EphemeralMounts, " ")
config := yip.YipConfig{Stages: map[string][]schema.Stage{
"rootfs": []yip.Stage{{
Name: "user_custom_mounts",
EnvironmentFile: "/run/cos/custom-layout.env",
Environment: mountsList,
}},
}}
saveCloudConfig("user_custom_mounts", config) //nolint:errcheck
return nil
}