From b7cd0de0a4c5e608cb4a88c1c7b966f573e709db Mon Sep 17 00:00:00 2001 From: Jacob Payne Date: Fri, 24 Feb 2023 14:10:48 -0700 Subject: [PATCH 1/2] fixed manual install not supporting configuration url Signed-off-by: Jacob Payne --- internal/agent/install.go | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/internal/agent/install.go b/internal/agent/install.go index 9badda983..173493891 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -4,9 +4,9 @@ import ( "encoding/json" "errors" "fmt" + "net/url" "os" "os/exec" - "path/filepath" "strings" "syscall" "time" @@ -63,28 +63,34 @@ func displayInfo(agentConfig *Config) { } func ManualInstall(c string, options map[string]string, strictValidations bool) error { - dat, err := os.ReadFile(c) - if err != nil { - return err - } + if _, err := url.Parse(c); err == nil { + f, err := os.CreateTemp(os.TempDir(), "kairos-install-*.yaml") + if err != nil { + return nil + } - dir, err := os.MkdirTemp("", "kairos-install") - if err != nil { - return err - } - defer os.RemoveAll(dir) + cfg := config.Config{ + ConfigURL: c, + } + if err = yaml.NewEncoder(f).Encode(cfg); err != nil { + return err + } - if err := os.WriteFile(filepath.Join(dir, "config.yaml"), dat, 0600); err != nil { - return err + c = f.Name() + + defer os.RemoveAll(f.Name()) } - cc, err := config.Scan(config.Directories(dir), config.MergeBootLine, config.StrictValidation(strictValidations)) + cc, err := config.Scan(config.Directories(c), 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) } From f3e1cb8724d76cb48136f439c8ec77b8639c0f55 Mon Sep 17 00:00:00 2001 From: Jacob Payne Date: Wed, 1 Mar 2023 10:19:40 -0700 Subject: [PATCH 2/2] break out url logic and add testing. Signed-off-by: Jacob Payne --- internal/agent/install.go | 51 ++++++++++++++++++++++---------- internal/agent/install_test.go | 54 ++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 16 deletions(-) create mode 100644 internal/agent/install_test.go diff --git a/internal/agent/install.go b/internal/agent/install.go index 173493891..82a89811c 100644 --- a/internal/agent/install.go +++ b/internal/agent/install.go @@ -1,6 +1,7 @@ package agent import ( + "context" "encoding/json" "errors" "fmt" @@ -63,25 +64,15 @@ func displayInfo(agentConfig *Config) { } func ManualInstall(c string, options map[string]string, strictValidations bool) error { - if _, err := url.Parse(c); err == nil { - f, err := os.CreateTemp(os.TempDir(), "kairos-install-*.yaml") - if err != nil { - return nil - } - - cfg := config.Config{ - ConfigURL: c, - } - if err = yaml.NewEncoder(f).Encode(cfg); err != nil { - return err - } - - c = f.Name() + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - defer os.RemoveAll(f.Name()) + source, err := prepareConfiguration(ctx, c) + if err != nil { + return err } - cc, err := config.Scan(config.Directories(c), config.MergeBootLine, config.StrictValidation(strictValidations)) + cc, err := config.Scan(config.Directories(source), config.MergeBootLine, config.StrictValidation(strictValidations)) if err != nil { return err } @@ -331,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 000000000..23590716a --- /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") +}