Skip to content

Commit

Permalink
Merge pull request #9 from hypnoglow/delete-action
Browse files Browse the repository at this point in the history
Delete action
  • Loading branch information
hypnoglow authored Oct 16, 2017
2 parents 3db1927 + 0c320c0 commit e1c6db2
Show file tree
Hide file tree
Showing 14 changed files with 370 additions and 133 deletions.
9 changes: 0 additions & 9 deletions .github/TODO.md

This file was deleted.

23 changes: 20 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The installation itself is simple as:

You can install a specific release version:

$ helm plugin install https://github.com/hypnoglow/helm-s3.git --version 0.2.0
$ helm plugin install https://github.com/hypnoglow/helm-s3.git --version 0.4.0

To use the plugin, you do not need any special dependencies. The installer will
download versioned release with prebuilt binary from [github releases](https://github.com/hypnoglow/helm-s3/releases).
Expand Down Expand Up @@ -58,7 +58,7 @@ Fetching also works:

$ helm fetch s3://bucket-name/charts/epicservice-0.5.1.tgz

### Init & Push
### Init

To create a new repository, use **init**:

Expand All @@ -67,10 +67,12 @@ To create a new repository, use **init**:
This command generates an empty **index.yaml** and uploads it to the S3 bucket
under `/charts` key.

To push to this repo by it's name, you need to add it first:
To work with this repo by it's name, first you need to add it using native helm command:

$ helm repo add mynewrepo s3://bucket-name/charts

### Push

Now you can push your chart to this repo:

$ helm s3 push ./epicservice-0.7.2.tgz mynewrepo
Expand All @@ -85,6 +87,21 @@ Now your pushed chart is available:
NAME VERSION DESCRIPTION
mynewrepo/epicservice 0.7.2 A Helm chart.

### Delete

To delete specific chart version from the repository:

$ helm s3 delete epicservice --version 0.7.2 mynewrepo

As always, remote repo index updated automatically again. To sync local, run:

$ helm repo update

The chart is deleted from the repo:

$ helm search mynewrepo/epicservice
No results found

## Uninstall

$ helm plugin remove s3
Expand Down
73 changes: 73 additions & 0 deletions cmd/helms3/delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package main

import (
"context"
"fmt"

"github.com/pkg/errors"

"github.com/hypnoglow/helm-s3/pkg/awss3"
"github.com/hypnoglow/helm-s3/pkg/awsutil"
"github.com/hypnoglow/helm-s3/pkg/helmutil"
"github.com/hypnoglow/helm-s3/pkg/index"
)

func runDelete(name, version, repoName string) error {
repoEntry, err := helmutil.LookupRepoEntry(repoName)
if err != nil {
return err
}

awsConfig, err := awsutil.Config()
if err != nil {
return errors.Wrap(err, "get aws config")
}

storage := awss3.NewStorage(awsConfig)

// Fetch current index.

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()

b, err := storage.FetchRaw(ctx, repoEntry.URL+"/index.yaml")
if err != nil {
return errors.WithMessage(err, "fetch current repo index")
}

idx, err := index.LoadBytes(b)
if err != nil {
return errors.WithMessage(err, "load index from downloaded file")
}

// Update index.

chartVersion, err := idx.Delete(name, version)
if err != nil {
return err
}

idxReader, err := idx.Reader()
if err != nil {
return errors.Wrap(err, "get index reader")
}

// Delete the file from S3 and replace index file.

if len(chartVersion.URLs) < 1 {
return fmt.Errorf("chart version index record has no urls")
}
uri := chartVersion.URLs[0]

ctx, cancel = context.WithTimeout(context.Background(), defaultTimeout*2)
defer cancel()

if err := storage.Delete(ctx, uri); err != nil {
return errors.WithMessage(err, "delete chart file from s3")
}
if _, err := storage.Upload(ctx, repoEntry.URL+"/index.yaml", idxReader); err != nil {
return errors.WithMessage(err, "upload new index to s3")
}

return nil
}
4 changes: 3 additions & 1 deletion cmd/helms3/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ func runInit(uri string) error {
return errors.WithMessage(err, "get aws config")
}

storage := awss3.NewStorage(awsConfig)

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()

if _, err := awss3.Upload(ctx, uri+"/index.yaml", r, awsConfig); err != nil {
if _, err := storage.Upload(ctx, uri+"/index.yaml", r); err != nil {
return errors.WithMessage(err, "upload index to s3")
}

Expand Down
34 changes: 29 additions & 5 deletions cmd/helms3/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ var (
)

const (
actionPush = "push"
actionInit = "init"
actionVersion = "version"
actionInit = "init"
actionPush = "push"
actionDelete = "delete"

defaultTimeout = time.Second * 5
)
Expand All @@ -29,25 +31,42 @@ func main() {
}

cli := kingpin.New("helm s3", "")
cli.Version(version)
cli.Command(actionVersion, "Show plugin version.")

initCmd := cli.Command(actionInit, "Initialize empty repository on AWS S3.")
initURI := initCmd.Arg("uri", "URI of repository, e.g. s3://awesome-bucket/charts").
Required().
String()
pushCmd := cli.Command(actionPush, "Push chart to repository.")

pushCmd := cli.Command(actionPush, "Push chart to the repository.")
pushChartPath := pushCmd.Arg("chartPath", "Path to a chart, e.g. ./epicservice-0.5.1.tgz").
Required().
String()
pushTargetRepository := pushCmd.Arg("repo", "Target repository to runPush").
pushTargetRepository := pushCmd.Arg("repo", "Target repository to push to").
Required().
String()

deleteCmd := cli.Command(actionDelete, "Delete chart from the repository.").Alias("del")
deleteChartName := deleteCmd.Arg("chartName", "Name of chart to delete").
Required().
String()
deleteChartVersion := deleteCmd.Flag("version", "Version of chart to delete").
Required().
String()
deleteTargetRepository := deleteCmd.Arg("repo", "Target repository to delete from").
Required().
String()

action := kingpin.MustParse(cli.Parse(os.Args[1:]))
if action == "" {
cli.Usage(os.Args[1:])
os.Exit(0)
}

switch action {
case actionVersion:
fmt.Print(version)
return

case actionInit:
if err := runInit(*initURI); err != nil {
Expand All @@ -62,5 +81,10 @@ func main() {
}
return

case actionDelete:
if err := runDelete(*deleteChartName, *deleteChartVersion, *deleteTargetRepository); err != nil {
log.Fatal(err)
}
return
}
}
4 changes: 3 additions & 1 deletion cmd/helms3/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ func runProxy(uri string) error {
return errors.WithMessage(err, "get aws config")
}

storage := awss3.NewStorage(awsConfig)

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()

b, err := awss3.FetchRaw(ctx, uri, awsConfig)
b, err := storage.FetchRaw(ctx, uri)
if err != nil {
return errors.WithMessage(err, "fetch from s3")
}
Expand Down
53 changes: 19 additions & 34 deletions cmd/helms3/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ import (

"github.com/pkg/errors"
"k8s.io/helm/pkg/chartutil"
"k8s.io/helm/pkg/helm/environment"
"k8s.io/helm/pkg/helm/helmpath"
"k8s.io/helm/pkg/provenance"
"k8s.io/helm/pkg/repo"

"github.com/hypnoglow/helm-s3/pkg/awss3"
"github.com/hypnoglow/helm-s3/pkg/awsutil"
"github.com/hypnoglow/helm-s3/pkg/helmutil"
"github.com/hypnoglow/helm-s3/pkg/index"
)

Expand All @@ -26,7 +24,17 @@ func runPush(chartPath string, repoName string) error {

dir := filepath.Dir(fpath)
fname := filepath.Base(fpath)
os.Chdir(dir)

if err := os.Chdir(dir); err != nil {
return errors.Wrapf(err, "change dir to %s", dir)
}

awsConfig, err := awsutil.Config()
if err != nil {
return errors.Wrap(err, "get aws config")
}

storage := awss3.NewStorage(awsConfig)

// Load chart and calculate required params like hash.

Expand All @@ -35,7 +43,7 @@ func runPush(chartPath string, repoName string) error {
return fmt.Errorf("file %s is not a helm chart archive", fname)
}

repoURL, err := lookupRepoURL(repoName)
repoEntry, err := helmutil.LookupRepoEntry(repoName)
if err != nil {
return err
}
Expand All @@ -47,14 +55,10 @@ func runPush(chartPath string, repoName string) error {

// Fetch current index.

awsConfig, err := awsutil.Config()
if err != nil {
return errors.Wrap(err, "get aws config")
}

ctx, cancel := context.WithTimeout(context.Background(), defaultTimeout)
defer cancel()
b, err := awss3.FetchRaw(ctx, repoURL+"/index.yaml", awsConfig)

b, err := storage.FetchRaw(ctx, repoEntry.URL+"/index.yaml")
if err != nil {
return errors.WithMessage(err, "fetch current repo index")
}
Expand All @@ -66,7 +70,7 @@ func runPush(chartPath string, repoName string) error {

// Update index.

idx.Add(chart.GetMetadata(), fname, repoURL, hash)
idx.Add(chart.GetMetadata(), fname, repoEntry.URL, hash)
idx.SortEntries()

// Finally, upload both chart file and index.
Expand All @@ -82,32 +86,13 @@ func runPush(chartPath string, repoName string) error {

ctx, cancel = context.WithTimeout(context.Background(), defaultTimeout*2)
defer cancel()
if _, err := awss3.Upload(ctx, repoURL+"/"+fname, fchart, awsConfig); err != nil {

if _, err := storage.Upload(ctx, repoEntry.URL+"/"+fname, fchart); err != nil {
return errors.WithMessage(err, "upload chart to s3")
}
if _, err := awss3.Upload(ctx, repoURL+"/index.yaml", idxReader, awsConfig); err != nil {
if _, err := storage.Upload(ctx, repoEntry.URL+"/index.yaml", idxReader); err != nil {
return errors.WithMessage(err, "upload index to s3")
}

return nil
}

func lookupRepoURL(name string) (string, error) {
h := helmpath.Home(environment.DefaultHelmHome)
if os.Getenv("HELM_HOME") != "" {
h = helmpath.Home(os.Getenv("HELM_HOME"))
}

repoFile, err := repo.LoadRepositoriesFile(h.RepositoryFile())
if err != nil {
return "", errors.Wrap(err, "load repo file")
}

for _, r := range repoFile.Repositories {
if r.Name == name {
return r.URL, nil
}
}

return "", errors.Errorf("repo with name %s not found, try `helm repo add %s <uri>`", name, name)
}
Loading

0 comments on commit e1c6db2

Please sign in to comment.