From 65ca573b59ca027346577a74c59dcd0ffdab38f3 Mon Sep 17 00:00:00 2001 From: Anirudh M Date: Tue, 9 Jun 2020 18:15:24 +0530 Subject: [PATCH] Add list, repo update, install release code --- Makefile | 7 ++-- cmd/service/service.go | 71 +++++++++++++++++++++++++++++++++++++++++ go.sum | 2 ++ pkg/http/install.go | 42 ++++++++++++++++++++++++ pkg/http/list.go | 36 +++++++++++++++++++++ pkg/http/repo_update.go | 54 +++++++++++++++++++++++++++++++ 6 files changed, 209 insertions(+), 3 deletions(-) create mode 100644 cmd/service/service.go create mode 100644 pkg/http/install.go create mode 100644 pkg/http/list.go create mode 100644 pkg/http/repo_update.go diff --git a/Makefile b/Makefile index 7d254e919..85e5138ba 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ BINDIR := $(CURDIR)/bin DIST_DIRS := find * -type d -exec TARGETS := darwin/amd64 linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64le linux/s390x windows/amd64 TARGET_OBJS ?= darwin-amd64.tar.gz darwin-amd64.tar.gz.sha256 linux-amd64.tar.gz linux-amd64.tar.gz.sha256 linux-386.tar.gz linux-386.tar.gz.sha256 linux-arm.tar.gz linux-arm.tar.gz.sha256 linux-arm64.tar.gz linux-arm64.tar.gz.sha256 linux-ppc64le.tar.gz linux-ppc64le.tar.gz.sha256 linux-s390x.tar.gz linux-s390x.tar.gz.sha256 windows-amd64.zip windows-amd64.zip.sha256 -BINNAME ?= helm +BINNAME ?= helm3 GOPATH = $(shell go env GOPATH) DEP = $(GOPATH)/bin/dep @@ -58,11 +58,12 @@ all: build # build .PHONY: build -build: $(BINDIR)/$(BINNAME) +build: $(BINDIR)/$(BINNAME) $(BINDIR)/$(BINNAME)-server $(BINDIR)/$(BINNAME): $(SRC) GO111MODULE=on go build $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $(BINDIR)/$(BINNAME) ./cmd/helm - +$(BINDIR)/$(BINNAME)-server: $(SRC) + GO111MODULE=on go build $(GOFLAGS) -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $(BINDIR)/$(BINNAME)-server ./cmd/service # ------------------------------------------------------------------------------ # test diff --git a/cmd/service/service.go b/cmd/service/service.go new file mode 100644 index 000000000..f0868c699 --- /dev/null +++ b/cmd/service/service.go @@ -0,0 +1,71 @@ +package main + +import ( + "fmt" + "log" + "os" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/gates" + "helm.sh/helm/v3/pkg/http" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var ( + settings = cli.New() +) + +func debug(format string, v ...interface{}) { + format = fmt.Sprintf("[debug] %s\n", format) + log.Output(2, fmt.Sprintf(format, v...)) +} + +const FeatureGateOCI = gates.Gate("HELM_EXPERIMENTAL_OCI") + +// Input: repositories.yaml, repositories cache (optional), chart location + +func main() { + actionConfig := new(action.Configuration) + for k, v := range settings.EnvVars() { + fmt.Println(k, v) + } + if err := actionConfig.Init(settings.RESTClientGetter(), settings.Namespace(), os.Getenv("HELM_DRIVER"), debug); err != nil { + log.Fatalf("error getting configuration: %v", err) + return + } + if _, err := actionConfig.KubernetesClientSet(); err != nil { + log.Fatalf("error initilizing kubernetes client configuration: %v", err) + return + } + + listReleases(actionConfig) + helmRepoUpdate() + // this has to be added in repositories: https://charts.bitnami.com/bitnami + installRelease(actionConfig, "bitnami/redis", "bitnami-redis-2") +} + +func listReleases(cfg *action.Configuration) { + releases, err := http.List(cfg) + if err != nil { + panic(err) + } + fmt.Println(string(releases)) +} + +func helmRepoUpdate() { + err := http.HelmRepoUpdate() + if err != nil { + panic(err) + } +} + +func installRelease(cfg *action.Configuration, chartPath string, releaseName string) { + fmt.Printf("installing chart: %s. release name: %s ", chartPath, releaseName) + _, err := http.Install(cfg, chartPath, releaseName) + if err != nil { + fmt.Println("error installing chart", err) + return + } + fmt.Printf("installed chart: %s release: %s successfully", chartPath, releaseName) +} diff --git a/go.sum b/go.sum index 312152e1f..e4fc771d5 100644 --- a/go.sum +++ b/go.sum @@ -663,6 +663,8 @@ gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +helm.sh/helm v1.2.1 h1:Jrn7kKQqQ/hnFWZEX+9pMFvYqFexkzrBnGqYBmIph7c= +helm.sh/helm v2.16.7+incompatible h1:3Hp8GLmr6uuBNYGmTQ4p3J4N6xKqxvFDswxHAOposlM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/http/install.go b/pkg/http/install.go new file mode 100644 index 000000000..8ad1402aa --- /dev/null +++ b/pkg/http/install.go @@ -0,0 +1,42 @@ +package http + +import ( + "fmt" + + "helm.sh/helm/v3/pkg/action" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/cli" + "helm.sh/helm/v3/pkg/release" +) + +var ( + settings = cli.New() +) + +func Install(cfg *action.Configuration, chartName, relName string) (*release.Release, error) { + settings := cli.New() + + opts := make(map[string]interface{}) + + install := action.NewInstall(cfg) + install.ReleaseName = relName + install.Namespace = "default" + + fmt.Printf("%+v %#v\n", install, settings) + cp, err := install.ChartPathOptions.LocateChart(chartName, settings) + if err != nil { + return nil, err + } + var requestedChart *chart.Chart + if requestedChart, err = loader.Load(cp); err != nil { + return nil, err + } + + release, err := install.Run(requestedChart, opts) + if err != nil { + return nil, err + } + // deal with dependent charts later + return release, nil +} diff --git a/pkg/http/list.go b/pkg/http/list.go new file mode 100644 index 000000000..4f9478888 --- /dev/null +++ b/pkg/http/list.go @@ -0,0 +1,36 @@ +package http + +import ( + "encoding/json" + + "helm.sh/helm/v3/pkg/action" +) + +type helmRelease struct { + Release string `json:"release"` + Namespace string `json:"namespace"` +} + +func List(cfg *action.Configuration) ([]byte, error) { + list := action.NewList(cfg) + + list.SetStateMask() + + results, err := list.Run() + if err != nil { + return nil, err + } + + var helmReleases []helmRelease + + for _, res := range results { + r := helmRelease{Release: res.Name, Namespace: res.Namespace} + helmReleases = append(helmReleases, r) + } + + jsonReleases, err := json.Marshal(helmReleases) + if err != nil { + return nil, err + } + return jsonReleases, err +} diff --git a/pkg/http/repo_update.go b/pkg/http/repo_update.go new file mode 100644 index 000000000..5e3bc1ed3 --- /dev/null +++ b/pkg/http/repo_update.go @@ -0,0 +1,54 @@ +package http + +import ( + "fmt" + "io" + "os" + "sync" + + "helm.sh/helm/v3/pkg/getter" + "helm.sh/helm/v3/pkg/repo" +) + +type repoUpdateOptions struct { + update func([]*repo.ChartRepository, io.Writer) + repoFile string +} + +func HelmRepoUpdate() error { + o := &repoUpdateOptions{update: updateCharts} + o.repoFile = settings.RepositoryConfig + f, err := repo.LoadFile(o.repoFile) + if err != nil { + return err + } + var repos []*repo.ChartRepository + for _, cfg := range f.Repositories { + r, err := repo.NewChartRepository(cfg, getter.All(settings)) + if err != nil { + return err + } + repos = append(repos, r) + } + + o.update(repos, os.Stdout) + return nil +} + +func updateCharts(repos []*repo.ChartRepository, out io.Writer) { + fmt.Fprintln(out, "Hang tight while we grab the latest from your chart repositories...") + var wg sync.WaitGroup + for _, re := range repos { + wg.Add(1) + go func(re *repo.ChartRepository) { + defer wg.Done() + if _, err := re.DownloadIndexFile(); err != nil { + fmt.Fprintf(out, "...Unable to get an update from the %q chart repository (%s):\n\t%s\n", re.Config.Name, re.Config.URL, err) + } else { + fmt.Fprintf(out, "...Successfully got an update from the %q chart repository\n", re.Config.Name) + } + }(re) + } + wg.Wait() + fmt.Fprintln(out, "Update Complete. ⎈ Happy Helming!⎈ ") +}