Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions sdk/clusterplugin/clusterplugin_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package clusterplugin

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestClusterPlugin(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "ClusterPlugin Suite")
}
11 changes: 11 additions & 0 deletions sdk/clusterplugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"encoding/json"
"fmt"
"os"
"path/filepath"

"github.com/kairos-io/kairos/v4/sdk/bus"
fsutils "github.com/kairos-io/kairos/v4/sdk/utils/fs"
"github.com/mudler/go-pluggable"
yip "github.com/mudler/yip/pkg/schema"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -55,6 +57,15 @@ func (p ClusterPlugin) onBoot(event *pluggable.Event) pluggable.EventResponse {
configFilePath = config.Cluster.ClusterConfigPath
}

// On a UKI install or reset, this runs in the initramfs stage, before
// anything else has created the cloud-config directory (that normally
// happens as a side effect of the first RunStage call, post-pivot). Create
// it here rather than rely on that ordering.
if err := fsutils.MkdirAll(filesystem, filepath.Dir(configFilePath), 0755); err != nil {
response.Error = fmt.Sprintf("failed to create cloud config directory: %s", err.Error())
return response
}

// open our cloud configuration file for writing
f, err := filesystem.OpenFile(configFilePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
if err != nil {
Expand Down
78 changes: 78 additions & 0 deletions sdk/clusterplugin/plugin_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package clusterplugin

import (
"encoding/json"

"github.com/kairos-io/kairos/v4/sdk/bus"
"github.com/mudler/go-pluggable"
yip "github.com/mudler/yip/pkg/schema"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/twpayne/go-vfs/v4/vfst"
"gopkg.in/yaml.v3"
)

var _ = Describe("ClusterPlugin.onBoot", func() {
var plugin ClusterPlugin
var cleanup func()

BeforeEach(func() {
var testFS *vfst.TestFS
var err error
testFS, cleanup, err = vfst.NewTestFS(map[string]interface{}{})
Expect(err).ToNot(HaveOccurred())
filesystem = testFS

plugin = ClusterPlugin{
Provider: func(cluster Cluster) yip.YipConfig {
return yip.YipConfig{Name: "test"}
},
}
})

AfterEach(func() {
cleanup()
})

newBootEvent := func(cluster *Cluster) *pluggable.Event {
cfg := Config{Cluster: cluster}
cfgYAML, err := yaml.Marshal(cfg)
Expect(err).ToNot(HaveOccurred())

payload, err := json.Marshal(bus.EventPayload{Config: string(cfgYAML)})
Expect(err).ToNot(HaveOccurred())

return &pluggable.Event{Name: bus.EventBoot, Data: string(payload)}
}

// On a UKI install or reset, onBoot runs before anything else has created
// /usr/local/cloud-config: it normally comes into being as a side effect of
// the first RunStage call, which only happens post-pivot. Without creating
// the directory here, OpenFile fails with ENOENT.
It("creates the cloud-config directory when it does not exist yet", func() {
response := plugin.onBoot(newBootEvent(&Cluster{Role: RoleControlPlane}))
Expect(response.Errored()).To(BeFalse(), response.Error)

content, err := filesystem.ReadFile(clusterProviderCloudConfigFile)
Expect(err).ToNot(HaveOccurred())
Expect(string(content)).To(ContainSubstring("#cloud-config"))
})

It("creates the parent directory of a custom ClusterConfigPath", func() {
customPath := "/oem/custom/cluster-config.yaml"
response := plugin.onBoot(newBootEvent(&Cluster{Role: RoleControlPlane, ClusterConfigPath: customPath}))
Expect(response.Errored()).To(BeFalse(), response.Error)

content, err := filesystem.ReadFile(customPath)
Expect(err).ToNot(HaveOccurred())
Expect(string(content)).To(ContainSubstring("#cloud-config"))
})

It("is a no-op when config.Cluster is nil", func() {
response := plugin.onBoot(newBootEvent(nil))
Expect(response.Errored()).To(BeFalse(), response.Error)

_, err := filesystem.ReadFile(clusterProviderCloudConfigFile)
Expect(err).To(HaveOccurred())
})
})
Loading