# HG changeset patch # User Florent Aide <florent.aide@gmail.com> # Date 1654615741 -7200 # Tue Jun 07 17:29:01 2022 +0200 # Node ID 5597730a795c859c8fc43d4be93f51b126afd11d # Parent 99503dc86cb6590feae8a76e9d7b54cb4a626ee8 allow charts to use relative paths && launch commands in config dir diff --git a/runner/config.go b/runner/config.go --- a/runner/config.go +++ b/runner/config.go @@ -34,7 +34,7 @@ Args []Arg `mapstructure:"args"` } -func (k CmdCreate) BuildArgs(namespace string, args []Arg) []string { +func (k CmdCreateKey) BuildArgs(namespace string, args []Arg) []string { output := []string{ "-n", namespace, "create", @@ -63,6 +63,22 @@ APIVersion string `mapstructure:"apiVersion"` Kind string `mapstructure:"kind"` Spec Spec `mapstructure:"spec"` + Dir string // the directory in which we found the config file +} + +// Absolutize makes all chart paths absolute +func (c *Config) Absolutize(dir string) error { + for name, chart := range c.Spec.Charts { + resolvedChartPath := filepath.Join(dir, chart.Path) + absChartPath, err := filepath.Abs(resolvedChartPath) + if err != nil { + return fmt.Errorf("failed to find abs() for %s: %w", resolvedChartPath, err) + } + + chart.Path = absChartPath + c.Spec.Charts[name] = chart + } + return nil } // NewConfig returns a *Config @@ -88,7 +104,7 @@ cmdConfig.RootDir = rootDir cmdConfig.Layers = append(cmdConfig.Layers, configDir) cmdConfig.Spec.Charts = make(map[string]CmdChart) - cmdConfig.Spec.Creates = make(map[CmdCreate][]Arg) + cmdConfig.Spec.Creates = make(map[CmdCreateKey]CmdCreate) cmdConfig.Namespace = "" cmdConfig.Logger = logger return cmdConfig @@ -115,6 +131,10 @@ if err != nil { return fmt.Errorf("failed to create config from %s: %w", dir, err) } + config.Dir = dir + if err := config.Absolutize(dir); err != nil { + return fmt.Errorf("failed to absolutize config from dir: %s, %w", dir, err) + } // first config dir must return a real config... // others can be skipped if config == nil && len(configLayers) == 0 { @@ -146,9 +166,7 @@ configLayers[i], configLayers[j] = configLayers[j], configLayers[i] } - fmt.Printf("%+v\n", configLayers) for _, config := range configLayers { - fmt.Printf("%+v\n", config) c.Namespace = config.Spec.NameSpace c.MergeVariables(config) @@ -157,8 +175,11 @@ } for _, k := range config.Spec.Creates { - cmdCreate := CmdCreate{Type: k.Type, Name: k.Name} - c.Spec.Creates[cmdCreate] = k.Args + cmdCreate := CmdCreateKey{Type: k.Type, Name: k.Name} + c.Spec.Creates[cmdCreate] = CmdCreate{ + Dir: config.Dir, + Args: k.Args, + } } } @@ -184,11 +205,16 @@ return cfg, nil } -type CmdCreate struct { +type CmdCreateKey struct { Type string `mapstructure:"type"` Name string `mapstructure:"name"` } +type CmdCreate struct { + Dir string + Args []Arg +} + type CmdConfig struct { Spec CmdSpec RootDir string @@ -202,7 +228,7 @@ Variables []Variable Charts CmdCharts Ytt Ytt - Creates map[CmdCreate][]Arg + Creates map[CmdCreateKey]CmdCreate } type Ytt []string @@ -220,7 +246,7 @@ if !stat.IsDir() { hydratedPaths, err := hydrateFiles(tmpDir, variables, []string{entryPath}) if err != nil { - return nil, fmt.Errorf("Failed to hydrate %s: %w", entryPath, err) + return nil, fmt.Errorf("failed to hydrate %s: %w", entryPath, err) } entryPath = hydratedPaths[0] } diff --git a/runner/config_test.go b/runner/config_test.go --- a/runner/config_test.go +++ b/runner/config_test.go @@ -12,7 +12,7 @@ ) var ( - fixtures = "fixtures/f1" + fixtures = "fixtures/f1" ) func TestConfig(t *testing.T) { @@ -21,8 +21,8 @@ // first config.spec.variables entry name should be VAULT_KV in our test file assert.Equal(t, "VAULT_KV", config.Spec.Variables[0].Name) assert.Equal(t, "orus.io", config.Spec.Variables[0].Value) - assert.Equal(t, "vendor/helm/postgresql", config.Spec.Charts["postgres"].Path) - assert.Equal(t, "vendor/ytt/odoo", config.Spec.Charts["odoo"].Path) + assert.Equal(t, "../vendor/helm/postgresql", config.Spec.Charts["postgres"].Path) + assert.Equal(t, "../vendor/ytt/odoo", config.Spec.Charts["odoo"].Path) } func TestYttBuildArgs(t *testing.T) { @@ -73,8 +73,18 @@ }() require.NoError(t, c.Initialize(tmpDir)) require.Equal(t, 1, len(c.Spec.Creates)) - for k, a := range c.Spec.Creates { - args := k.BuildArgs(c.Namespace, a) + + assert.True(t, filepath.IsAbs(c.Spec.Charts["postgres"].Path)) + crKey := runner.CmdCreateKey{ + Type: "configmap", + Name: "xbus-pipelines", + } + cr, ok := c.Spec.Creates[crKey] + assert.True(t, ok) + require.Equal(t, 1, len(cr.Args)) + + for k, create := range c.Spec.Creates { + args := k.BuildArgs(c.Namespace, create.Args) assert.Equal( t, []string{ diff --git a/runner/fixtures/f1/base/beaver.yml b/runner/fixtures/f1/base/beaver.yml --- a/runner/fixtures/f1/base/beaver.yml +++ b/runner/fixtures/f1/base/beaver.yml @@ -9,13 +9,13 @@ charts: postgres: type: helm - path: vendor/helm/postgresql + path: ../vendor/helm/postgresql odoo: type: ytt - path: vendor/ytt/odoo + path: ../vendor/ytt/odoo create: - type: configmap name: xbus-pipelines args: - flag: --from-file - value: base/pipelines + value: pipelines diff --git a/runner/main.go b/runner/main.go --- a/runner/main.go +++ b/runner/main.go @@ -52,10 +52,13 @@ return fmt.Errorf("unsupported chart %s type: %q", chart.Path, chart.Type) } } - for create, args := range r.config.Spec.Creates { - strArgs := create.BuildArgs(r.config.Namespace, args) - name := fmt.Sprintf("%s_%s", create.Type, create.Name) - cmds[name] = cmd.NewCmd(kubectlCmd, strArgs...) + + for key, create := range r.config.Spec.Creates { + strArgs := key.BuildArgs(r.config.Namespace, create.Args) + name := fmt.Sprintf("%s_%s", key.Type, key.Name) + c := cmd.NewCmd(kubectlCmd, strArgs...) + c.Dir = create.Dir + cmds[name] = c } // run commands or print them @@ -96,7 +99,7 @@ } // create ytt additional command - args , err := r.config.PrepareYttArgs(tmpDir, r.config.Layers, compiled) + args, err := r.config.PrepareYttArgs(tmpDir, r.config.Layers, compiled) if err != nil { return fmt.Errorf("cannot prepare ytt args: %w", err) }