Skip to content
This repository has been archived by the owner on Nov 1, 2022. It is now read-only.

helm/v3: import repositories from file #124

Merged
merged 1 commit into from
Nov 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cmd/helm-operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,12 @@ func main() {
TLSHostname: *tillerTLSHostname,
}))
case v3.VERSION:
helmClients.Add(v3.VERSION, v3.New(log.With(logger, "component", "helm", "version", "v3"), cfg))
client := v3.New(log.With(logger, "component", "helm", "version", "v3"), cfg)
// TODO(hidde): remove hardcoded path
if err := client.(*v3.HelmV3).RepositoryImport("/var/fluxd/helm/repository/repositories.yaml"); err != nil {
mainLogger.Log("warning", "failed to import Helm chart repositories from path", "err", err)
}
helmClients.Add(v3.VERSION, client)
default:
mainLogger.Log("error", fmt.Sprintf("%s is not a supported Helm version, ignoring...", v))
continue
Expand Down
8 changes: 5 additions & 3 deletions pkg/helm/v3/dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import (
"github.com/go-kit/kit/log"

"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/helmpath"
)

func (h *HelmV3) DependencyUpdate(chartPath string) error {
repositoryConfigLock.RLock()
defer repositoryConfigLock.RUnlock()

out := &logWriter{h.logger}
man := &downloader.Manager{
Out: out,
ChartPath: chartPath,
RepositoryConfig: helmpath.ConfigPath("repositories.yaml"),
RepositoryCache: helmpath.CachePath("repository"),
RepositoryConfig: repositoryConfig,
RepositoryCache: repositoryCache,
}
return man.Update()
}
Expand Down
9 changes: 7 additions & 2 deletions pkg/helm/v3/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"k8s.io/kubectl/pkg/cmd/util"

"helm.sh/helm/v3/pkg/action"
"helm.sh/helm/v3/pkg/helmpath"
"helm.sh/helm/v3/pkg/kube"
"helm.sh/helm/v3/pkg/storage"
"helm.sh/helm/v3/pkg/storage/driver"
Expand All @@ -25,7 +26,11 @@ import (

const VERSION = "v3"

var defaultClusterName = "in-cluster"
var (
defaultClusterName = "in-cluster"
repositoryConfig = helmpath.ConfigPath("repositories.yaml")
repositoryCache = helmpath.CachePath("repository")
)

type HelmOptions struct {
Driver string
Expand Down Expand Up @@ -147,7 +152,7 @@ func newConfig(host, username, token string, caCert []byte) clientcmdapi.Config
AuthInfo: username,
},
},
AuthInfos: map[string]*clientcmdapi.AuthInfo{
AuthInfos: map[string]*clientcmdapi.AuthInfo{
username: {
Token: token,
},
Expand Down
153 changes: 153 additions & 0 deletions pkg/helm/v3/repository.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package v3

import (
"os"
"sync"

"github.com/pkg/errors"

"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/repo"
)

var (
repositoryConfigLock sync.RWMutex
getters = getter.Providers{{
Schemes: []string{"http", "https"},
New: getter.NewHTTPGetter,
}}
)

func (h *HelmV3) RepositoryIndex() error {
repositoryConfigLock.RLock()
defer repositoryConfigLock.RUnlock()

f, err := loadRepositoryConfig()
if err != nil {
return err
}

var wg sync.WaitGroup
for _, c := range f.Repositories {
r, err := newChartRepository(c)
if err != nil {
return err
}
wg.Add(1)
go func(r *repo.ChartRepository) {
if _, err := r.DownloadIndexFile(); err != nil {
h.logger.Log("error", "unable to get an update from the chart repository", "url", r.Config.URL, "err", err)
} else {
h.logger.Log("info", "successfully got an update from the chart repository", "url", r.Config.URL)
}
wg.Done()
}(r)
}
wg.Wait()
return nil
}

func (h *HelmV3) RepositoryAdd(name, url, username, password, certFile, keyFile, caFile string) error {
repositoryConfigLock.Lock()
defer repositoryConfigLock.Unlock()

f, err := loadRepositoryConfig()
if err != nil {
return err
}

c := &repo.Entry{
Name: name,
URL: url,
Username: username,
Password: password,
CertFile: certFile,
KeyFile: keyFile,
CAFile: caFile,
}
f.Add(c)

if f.Has(name) {
return errors.New("chart repository with name %s already exists")
}

r, err := newChartRepository(c)
if err != nil {
return err
}
if _, err = r.DownloadIndexFile(); err != nil {
return err
}

return f.WriteFile(repositoryConfig, 0644)
}

func (h *HelmV3) RepositoryRemove(name string) error {
repositoryConfigLock.Lock()
defer repositoryConfigLock.Unlock()

f, err := repo.LoadFile(repositoryConfig)
if err != nil {
return err
}
f.Remove(name)

return f.WriteFile(repositoryConfig, 0644)
}

func (h *HelmV3) RepositoryImport(path string) error {
s, err := repo.LoadFile(path)
if err != nil {
return err
}

repositoryConfigLock.Lock()
defer repositoryConfigLock.Unlock()

t, err := loadRepositoryConfig()
if err != nil {
return err
}

for _, c := range s.Repositories {
if t.Has(c.Name) {
h.logger.Log("error", "repository with name already exists", "name", c.Name, "url", c.URL)
continue
}
r, err := newChartRepository(c)
if err != nil {
h.logger.Log("error", err, "name", c.Name, "url", c.URL)
continue
}
if _, err := r.DownloadIndexFile(); err != nil {
h.logger.Log("error", err, "name", c.Name, "url", c.URL)
continue
}

t.Add(c)
h.logger.Log("info", "successfully imported repository", "name", c.Name, "url", c.URL)
}

return t.WriteFile(repositoryConfig, 0644)
}

// newChartRepository constructs a new `repo.ChartRepository`
// for the given `repo.Entry`. It exists to stay in control
// of the cache path and getters while duplicating as less
// code as possible.
func newChartRepository(e *repo.Entry) (*repo.ChartRepository, error) {
cr, err := repo.NewChartRepository(e, getters)
if err != nil {
return nil, err
}
cr.CachePath = repositoryCache
return cr, err
}

func loadRepositoryConfig() (*repo.File, error) {
r, err := repo.LoadFile(repositoryConfig)
if err != nil && !os.IsNotExist(errors.Cause(err)) {
return nil, err
}
return r, nil
}