diff --git a/internal/agent/install.go b/internal/agent/install.go index afa0b9c9..12e93d33 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -1,10 +1,11 @@ package agent import ( - "context" + "bytes" "encoding/json" "errors" "fmt" + "io" "net/url" "os" "strings" @@ -28,7 +29,6 @@ import ( qr "github.com/mudler/go-nodepair/qrcode" "github.com/mudler/go-pluggable" "github.com/pterm/pterm" - "gopkg.in/yaml.v3" ) func displayInfo(agentConfig *Config) { @@ -54,10 +54,7 @@ func displayInfo(agentConfig *Config) { } func ManualInstall(c, sourceImgURL, device string, reboot, poweroff, strictValidations bool) error { - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - configSource, err := prepareConfiguration(ctx, c) + configSource, err := prepareConfiguration(c) if err != nil { return err } @@ -65,8 +62,8 @@ func ManualInstall(c, sourceImgURL, device string, reboot, poweroff, strictValid cliConf := generateInstallConfForCLIArgs(sourceImgURL) cliConfManualArgs := generateInstallConfForManualCLIArgs(device, reboot, poweroff) - cc, err := config.Scan(collector.Directories(configSource), - collector.Readers(strings.NewReader(cliConf), strings.NewReader(cliConfManualArgs)), + cc, err := config.Scan( + collector.Readers(configSource, strings.NewReader(cliConf), strings.NewReader(cliConfManualArgs)), collector.MergeBootLine, collector.StrictValidation(strictValidations), collector.NoLogs) if err != nil { @@ -324,32 +321,26 @@ func ensureDataSourceReady() { } } -func prepareConfiguration(ctx context.Context, source string) (string, error) { +func prepareConfiguration(source string) (io.Reader, error) { + var cfg io.Reader + // source can be either a file in the system or an url + // We need to differentiate between the two + // If its a local file, we just read it and return it + // If its a url, we need to create a configuration with the url and let the config.Scan handle it // if the source is not an url it is already a configuration path if u, err := url.Parse(source); err != nil || u.Scheme == "" { - return source, nil - } - - // create a configuration file with the source referenced - f, err := os.CreateTemp(os.TempDir(), "kairos-install-*.yaml") - if err != nil { - return "", err + file, err := os.ReadFile(source) + if err != nil { + return cfg, err + } + cfg = bytes.NewReader(file) + return cfg, nil } - // defer cleanup until after parent is done - go func() { - <-ctx.Done() - _ = os.RemoveAll(f.Name()) - }() - - cfg := config.Config{ - ConfigURL: source, - } - if err = yaml.NewEncoder(f).Encode(cfg); err != nil { - return "", err - } + cfgUrl := fmt.Sprintf(`config_url: %s`, source) + cfg = strings.NewReader(cfgUrl) - return f.Name(), nil + return cfg, nil } func generateInstallConfForCLIArgs(sourceImageURL string) string { diff --git a/internal/agent/install_test.go b/internal/agent/install_test.go index 79d5d900..f257001b 100644 --- a/internal/agent/install_test.go +++ b/internal/agent/install_test.go @@ -1,7 +1,6 @@ package agent import ( - "context" "fmt" v1 "github.com/kairos-io/kairos-agent/v2/pkg/types/v1" "os" @@ -26,40 +25,42 @@ const partTmpl = ` %d:%ss:%ss:2048s:ext4::type=83;` var _ = Describe("prepareConfiguration", func() { - path := "/foo/bar" url := "https://example.com" - ctx, cancel := context.WithCancel(context.Background()) - - It("returns a file path with no modifications", func() { - source, err := prepareConfiguration(ctx, path) + It("loads the content from a file path", func() { + temp, err := os.MkdirTemp("", "") Expect(err).ToNot(HaveOccurred()) - Expect(source).To(Equal(path)) - }) - - It("creates a configuration file containing the given url", func() { - source, err := prepareConfiguration(ctx, url) + defer os.RemoveAll(temp) + content, err := yaml.Marshal(config.Config{ + Debug: true, + Install: &config.Install{ + Device: "fake", + }, + }) Expect(err).ToNot(HaveOccurred()) - Expect(source).ToNot(Equal(path)) - - f, err := os.Open(source) + err = os.WriteFile(filepath.Join(temp, "config.yaml"), content, 0644) Expect(err).ToNot(HaveOccurred()) - var cfg config.Config - err = yaml.NewDecoder(f).Decode(&cfg) + source, err := prepareConfiguration(filepath.Join(temp, "config.yaml")) Expect(err).ToNot(HaveOccurred()) - Expect(cfg.ConfigURL).To(Equal(url)) + var cfg config.Config + err = yaml.NewDecoder(source).Decode(&cfg) + Expect(cfg.ConfigURL).To(BeEmpty()) + Expect(cfg.Debug).To(BeTrue()) + Expect(cfg.Install.Device).To(Equal("fake")) }) - It("cleans up the configuration file after context is done", func() { - source, err := prepareConfiguration(ctx, url) + It("creates a configuration file containing the given url", func() { + source, err := prepareConfiguration(url) Expect(err).ToNot(HaveOccurred()) - cancel() - _, err = os.Stat(source) - Expect(os.IsNotExist(err)) + var cfg config.Config + err = yaml.NewDecoder(source).Decode(&cfg) + Expect(err).ToNot(HaveOccurred()) + + Expect(cfg.ConfigURL).To(Equal(url)) }) })