Skip to content

Commit

Permalink
Simple implementation of the tillerless mode (#531)
Browse files Browse the repository at this point in the history
Ref #449
  • Loading branch information
Patrick Valsecchi authored and mumoshu committed Apr 5, 2019
1 parent 72c43a2 commit 1acd07f
Show file tree
Hide file tree
Showing 13 changed files with 313 additions and 119 deletions.
1 change: 1 addition & 0 deletions Makefile
Expand Up @@ -42,6 +42,7 @@ clean:
.PHONY: clean

pristine: generate fmt
git diff | cat
git ls-files --exclude-standard --modified --deleted --others | diff /dev/null -
.PHONY: pristine

Expand Down
15 changes: 15 additions & 0 deletions README.md
Expand Up @@ -43,6 +43,7 @@ repositories:
#default values to set for args along with dedicated keys that can be set by contributers, cli args take precedence over these
helmDefaults:
tillerNamespace: tiller-namespace #dedicated default key for tiller-namespace
tillerless: false #dedicated default key for tillerless
kubeContext: kube-context #dedicated default key for kube-context (--kube-context)
# additional and global args passed to helm
args:
Expand Down Expand Up @@ -110,6 +111,10 @@ releases:
installed: true
# restores previous state in case of failed release
atomic: true
# name of the tiller namespace
tillerNamespace: vault
# if true, will use the helm-tiller plugin
tillerless: false
# enable TLS for request to Tiller
tls: true
# path to TLS CA certificate file (default "$HELM_HOME/ca.pem")
Expand Down Expand Up @@ -557,6 +562,16 @@ Then the environment secret `foo.bar` can be referenced by the below template ex
{{ .Environment.Values.foo.bar }}
```

## Tillerless

With the [helm-tiller](https://github.com/rimusz/helm-tiller) plugin installed, you can work without tiller installed.

To enable this mode, you need to define `tillerless: true` and set the `tillerNamespace` in the `helmDefaults` section
or in the `releases` entries.

Since every commands is run with `helm tiller run ...`, you have to disable concurrency. Otherwise you'll get
mysterious errors about the tiller daemon.

## Separating helmfile.yaml into multiple independent files

Once your `helmfile.yaml` got to contain too many releases,
Expand Down
2 changes: 1 addition & 1 deletion event/bus.go
Expand Up @@ -88,7 +88,7 @@ func (bus *Bus) Trigger(evt string, context map[string]interface{}) (bool, error
}
}

bytes, err := bus.Runner.Execute(command, args)
bytes, err := bus.Runner.Execute(command, args, map[string]string{})
bus.Logger.Debugf("hook[%s]: %s\n", name, string(bytes))

if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion event/bus_test.go
Expand Up @@ -13,7 +13,7 @@ var logger = helmexec.NewLogger(os.Stdout, "warn")
type runner struct {
}

func (r *runner) Execute(cmd string, args []string) ([]byte, error) {
func (r *runner) Execute(cmd string, args []string, env map[string]string) ([]byte, error) {
if cmd == "ng" {
return nil, fmt.Errorf("cmd failed due to invalid cmd: %s", cmd)
}
Expand Down
44 changes: 44 additions & 0 deletions helmexec/context.go
@@ -0,0 +1,44 @@
package helmexec

import (
"os"
"path/filepath"
)

type HelmContext struct {
Tillerless bool
TillerNamespace string
WorkerIndex int
}

func (context *HelmContext) GetTillerlessArgs(helmBinary string) []string {
if context.Tillerless {
if context.TillerNamespace != "" {
return []string{"tiller", "run", context.TillerNamespace, "--", helmBinary}
} else {
return []string{"tiller", "run", "--", helmBinary}
}
} else {
return []string{}
}
}

func (context *HelmContext) getTillerlessEnv() map[string]string {
if context.Tillerless {
result := map[string]string{
"HELM_TILLER_SILENT": "true",
// Changing the TILLER port doesn't really work: https://github.com/helm/helm/issues/3159
// So this is not used for the moment.
// "HELM_TILLER_PORT": strconv.Itoa(44134 + context.WorkerIndex),
}
if config := os.Getenv("KUBECONFIG"); config != "" {
absConfig, err := filepath.Abs(config)
if err == nil {
result["KUBECONFIG"] = absConfig
}
}
return result
} else {
return map[string]string{}
}
}
60 changes: 37 additions & 23 deletions helmexec/exec.go
Expand Up @@ -70,60 +70,68 @@ func (helm *execer) AddRepo(name, repository, certfile, keyfile, username, passw
args = append(args, "--username", username, "--password", password)
}
helm.logger.Infof("Adding repo %v %v", name, repository)
out, err := helm.exec(args...)
out, err := helm.exec(args, map[string]string{})
helm.write(out)
return err
}

func (helm *execer) UpdateRepo() error {
helm.logger.Info("Updating repo")
out, err := helm.exec("repo", "update")
out, err := helm.exec([]string{"repo", "update"}, map[string]string{})
helm.write(out)
return err
}

func (helm *execer) UpdateDeps(chart string) error {
helm.logger.Infof("Updating dependency %v", chart)
out, err := helm.exec("dependency", "update", chart)
out, err := helm.exec([]string{"dependency", "update", chart}, map[string]string{})
helm.write(out)
return err
}

func (helm *execer) BuildDeps(chart string) error {
helm.logger.Infof("Building dependency %v", chart)
out, err := helm.exec("dependency", "build", chart)
out, err := helm.exec([]string{"dependency", "build", chart}, map[string]string{})
helm.write(out)
return err
}

func (helm *execer) SyncRelease(name, chart string, flags ...string) error {
func (helm *execer) SyncRelease(context HelmContext, name, chart string, flags ...string) error {
helm.logger.Infof("Upgrading %v", chart)
out, err := helm.exec(append([]string{"upgrade", "--install", "--reset-values", name, chart}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "upgrade", "--install", "--reset-values", name, chart), flags...), env)
helm.write(out)
return err
}

func (helm *execer) ReleaseStatus(name string, flags ...string) error {
func (helm *execer) ReleaseStatus(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Getting status %v", name)
out, err := helm.exec(append([]string{"status", name}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "status", name), flags...), env)
helm.write(out)
return err
}

func (helm *execer) List(filter string, flags ...string) (string, error) {
func (helm *execer) List(context HelmContext, filter string, flags ...string) (string, error) {
helm.logger.Infof("Listing releases matching %v", filter)
out, err := helm.exec(append([]string{"list", filter}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "list", filter), flags...), env)
helm.write(out)
return string(out), err
}

func (helm *execer) DecryptSecret(name string) (string, error) {
func (helm *execer) DecryptSecret(context HelmContext, name string, flags ...string) (string, error) {
// Prevents https://github.com/roboll/helmfile/issues/258
helm.decryptionMutex.Lock()
defer helm.decryptionMutex.Unlock()

helm.logger.Infof("Decrypting secret %v", name)
out, err := helm.exec(append([]string{"secrets", "dec", name})...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "secrets", "dec", name), flags...), env)
helm.write(out)
if err != nil {
return "", err
Expand Down Expand Up @@ -162,47 +170,53 @@ func (helm *execer) DecryptSecret(name string) (string, error) {
}

func (helm *execer) TemplateRelease(chart string, flags ...string) error {
out, err := helm.exec(append([]string{"template", chart}, flags...)...)
out, err := helm.exec(append([]string{"template", chart}, flags...), map[string]string{})
helm.write(out)
return err
}

func (helm *execer) DiffRelease(name, chart string, flags ...string) error {
func (helm *execer) DiffRelease(context HelmContext, name, chart string, flags ...string) error {
helm.logger.Infof("Comparing %v %v", name, chart)
out, err := helm.exec(append([]string{"diff", "upgrade", "--allow-unreleased", name, chart}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "diff", "upgrade", "--allow-unreleased", name, chart), flags...), env)
helm.write(out)
return err
}

func (helm *execer) Lint(chart string, flags ...string) error {
helm.logger.Infof("Linting %v", chart)
out, err := helm.exec(append([]string{"lint", chart}, flags...)...)
out, err := helm.exec(append([]string{"lint", chart}, flags...), map[string]string{})
helm.write(out)
return err
}

func (helm *execer) Fetch(chart string, flags ...string) error {
helm.logger.Infof("Fetching %v", chart)
out, err := helm.exec(append([]string{"fetch", chart}, flags...)...)
out, err := helm.exec(append([]string{"fetch", chart}, flags...), map[string]string{})
helm.write(out)
return err
}

func (helm *execer) DeleteRelease(name string, flags ...string) error {
func (helm *execer) DeleteRelease(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Deleting %v", name)
out, err := helm.exec(append([]string{"delete", name}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "delete", name), flags...), env)
helm.write(out)
return err
}

func (helm *execer) TestRelease(name string, flags ...string) error {
func (helm *execer) TestRelease(context HelmContext, name string, flags ...string) error {
helm.logger.Infof("Testing %v", name)
out, err := helm.exec(append([]string{"test", name}, flags...)...)
preArgs := context.GetTillerlessArgs(helm.helmBinary)
env := context.getTillerlessEnv()
out, err := helm.exec(append(append(preArgs, "test", name), flags...), env)
helm.write(out)
return err
}

func (helm *execer) exec(args ...string) ([]byte, error) {
func (helm *execer) exec(args []string, env map[string]string) ([]byte, error) {
cmdargs := args
if len(helm.extra) > 0 {
cmdargs = append(cmdargs, helm.extra...)
Expand All @@ -211,7 +225,7 @@ func (helm *execer) exec(args ...string) ([]byte, error) {
cmdargs = append(cmdargs, "--kube-context", helm.kubeContext)
}
helm.logger.Debugf("exec: %s %s", helm.helmBinary, strings.Join(cmdargs, " "))
return helm.runner.Execute(helm.helmBinary, cmdargs)
return helm.runner.Execute(helm.helmBinary, cmdargs, env)
}

func (helm *execer) write(out []byte) {
Expand Down

0 comments on commit 1acd07f

Please sign in to comment.