From e57ef905a49701fb11bb649efa1e5727096747ce Mon Sep 17 00:00:00 2001 From: Jacob Payne Date: Wed, 8 Mar 2023 10:13:36 -0700 Subject: [PATCH] bug: Fix manual install not supporting configuration url (#963) * fixed manual install not supporting configuration url Signed-off-by: Jacob Payne * break out url logic and add testing. Signed-off-by: Jacob Payne --------- Signed-off-by: Jacob Payne Co-authored-by: Ettore Di Giacinto --- internal/agent/install.go | 53 ++++++++++++++++++++++++--------- internal/agent/install_test.go | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 14 deletions(-) create mode 100644 internal/agent/install_test.go diff --git a/internal/agent/install.go b/internal/agent/install.go index 9badda9..82a8981 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -1,12 +1,13 @@ package agent import ( + "context" "encoding/json" "errors" "fmt" + "net/url" "os" "os/exec" - "path/filepath" "strings" "syscall" "time" @@ -63,28 +64,24 @@ func displayInfo(agentConfig *Config) { } func ManualInstall(c string, options map[string]string, strictValidations bool) error { - dat, err := os.ReadFile(c) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + source, err := prepareConfiguration(ctx, c) if err != nil { return err } - dir, err := os.MkdirTemp("", "kairos-install") + cc, err := config.Scan(config.Directories(source), config.MergeBootLine, config.StrictValidation(strictValidations)) if err != nil { return err } - defer os.RemoveAll(dir) - - if err := os.WriteFile(filepath.Join(dir, "config.yaml"), dat, 0600); err != nil { - return err - } - - cc, err := config.Scan(config.Directories(dir), config.MergeBootLine, config.StrictValidation(strictValidations)) - if err != nil { - return err - } - options["cc"] = cc.String() + if options["device"] == "" { + options["device"] = cc.Install.Device + } + return RunInstall(options) } @@ -325,3 +322,31 @@ func ensureDataSourceReady() { } } } + +func prepareConfiguration(ctx context.Context, source string) (string, error) { + // 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 + } + + // 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 + } + + return f.Name(), nil +} diff --git a/internal/agent/install_test.go b/internal/agent/install_test.go new file mode 100644 index 0000000..2359071 --- /dev/null +++ b/internal/agent/install_test.go @@ -0,0 +1,54 @@ +package agent + +import ( + "context" + "github.com/kairos-io/kairos/pkg/config" + "gopkg.in/yaml.v3" + "os" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +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) + + Expect(err).ToNot(HaveOccurred()) + Expect(source).To(Equal(path)) + }) + + It("creates a configuration file containing the given url", func() { + source, err := prepareConfiguration(ctx, url) + + Expect(err).ToNot(HaveOccurred()) + Expect(source).ToNot(Equal(path)) + + f, err := os.Open(source) + Expect(err).ToNot(HaveOccurred()) + + var cfg config.Config + err = yaml.NewDecoder(f).Decode(&cfg) + Expect(err).ToNot(HaveOccurred()) + + Expect(cfg.ConfigURL).To(Equal(url)) + }) + + It("cleans up the configuration file after context is done", func() { + source, err := prepareConfiguration(ctx, url) + cancel() + + _, err = os.Stat(source) + Expect(os.IsNotExist(err)) + }) +}) + +func TestPrepareConfiguration(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "prepareConfiguration Suite") +}