Hello community, here is the log from the commit of package helm-mirror for openSUSE:Factory checked in at 2018-12-04 20:58:18 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/helm-mirror (Old) and /work/SRC/openSUSE:Factory/.helm-mirror.new.19453 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "helm-mirror" Tue Dec 4 20:58:18 2018 rev:2 rq:653849 version:0.2.0 Changes: -------- --- /work/SRC/openSUSE:Factory/helm-mirror/helm-mirror.changes 2018-11-18 23:31:58.457496979 +0100 +++ /work/SRC/openSUSE:Factory/.helm-mirror.new.19453/helm-mirror.changes 2018-12-04 20:58:28.732577054 +0100 @@ -1,0 +2,22 @@ +Tue Dec 4 11:24:37 UTC 2018 - Vicente Zepeda <vzepeda...@suse.com> + +## v0.2.0 + +### Added + +- `mirror inspect-images` flag `--output` usage updated, flag `--file-name` no longer needed. + - `-o file=filename` + - `-o json=filename.json` + - `-o yaml=filename.yaml` + - `-o skopeo=filename.yaml` + +- `helm-mirror` has a new flag `--new-root-url` new root url of the chart repository. + (eg: `https://mirror.local.lan/charts`). This will allow users to set the name of + their mirror server when getting all the charts. + +- `downloaded-index.yaml` file changes it's name to `index.yaml` to allow users to host quickly + a mirror chart server. + +fix bsc#1117783 + +------------------------------------------------------------------- Old: ---- helm-mirror-0.1.0.tar.gz New: ---- helm-mirror-0.2.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ helm-mirror.spec ++++++ --- /var/tmp/diff_new_pack.G0uQul/_old 2018-12-04 20:58:29.200576538 +0100 +++ /var/tmp/diff_new_pack.G0uQul/_new 2018-12-04 20:58:29.200576538 +0100 @@ -15,11 +15,12 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # + # Project name when using go tooling. %define project github.com/openSUSE/helm-mirror Name: helm-mirror -Version: 0.1.0 +Version: 0.2.0 Release: 0 Summary: Tool to mirror Helm repositories License: Apache-2.0 @@ -27,9 +28,9 @@ Url: https://github.com/openSUSE/helm-mirror Source: %{name}-%{version}.tar.gz BuildRequires: go >= 1.9.7 +BuildRequires: go-go-md2man BuildRequires: golang-packaging BuildRequires: golang(API) = 1.9 -BuildRequires: go-go-md2man Requires(post): %fillup_prereq BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ _service ++++++ --- /var/tmp/diff_new_pack.G0uQul/_old 2018-12-04 20:58:29.224576512 +0100 +++ /var/tmp/diff_new_pack.G0uQul/_new 2018-12-04 20:58:29.224576512 +0100 @@ -2,8 +2,8 @@ <service name="download_url" mode="disabled"> <param name="protocol">https</param> <param name="host">codeload.github.com</param> - <param name="path">openSUSE/helm-mirror/tar.gz/v0.1.0</param> - <param name="filename">helm-mirror-0.1.0.tar.gz</param> + <param name="path">openSUSE/helm-mirror/tar.gz/v0.2.0</param> + <param name="filename">helm-mirror-0.2.0.tar.gz</param> </service> <service name="recompress" mode="disabled"> <param name="compression">gz</param> ++++++ helm-mirror-0.1.0.tar.gz -> helm-mirror-0.2.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/CHANGELOG.md new/helm-mirror-0.2.0/CHANGELOG.md --- old/helm-mirror-0.1.0/CHANGELOG.md 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/CHANGELOG.md 2018-12-04 12:00:48.000000000 +0100 @@ -7,6 +7,24 @@ ## [Unreleased] +## v0.2.0 + +### Added + +- `mirror inspect-images` flag `--output` usage updated, flag `--file-name` no longer needed. + - `file=filename` + - `json=filename.json` + - `yaml=filename.yaml` + - `skopeo=filename.yaml` + +- `helm-mirror` has a new flag `--new-root-url` new root url of the chart repository. + (eg: `https://mirror.local.lan/charts`). This will allow users to set the name of + their mirror server when getting all the charts. + +- `downloaded-index.yaml` file changes it's name to `index.yaml` to allow users to host quickly + a mirror chart server. + + ## v0.1.0 ### Added diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/Makefile new/helm-mirror-0.2.0/Makefile --- old/helm-mirror-0.1.0/Makefile 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/Makefile 2018-12-04 12:00:48.000000000 +0100 @@ -112,7 +112,7 @@ $(GO) test -v ./... cover: - bash <cover.sh + bash <scripts/cover.sh bootstrap: dep ensure diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/README.md new/helm-mirror-0.2.0/README.md --- old/helm-mirror-0.1.0/README.md 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/README.md 2018-12-04 12:00:48.000000000 +0100 @@ -71,6 +71,7 @@ --cert-file string identify HTTPS client using this SSL certificate file -h, --help help for mirror --key-file string identify HTTPS client using this SSL key file + --new-root-url New root url of the chart repository (eg: `https://mirror.local.lan/charts`) --password string chart repository password --username string chart repository username -v, --verbose verbose output @@ -82,7 +83,7 @@ ### inspect-images -Extract all the images of the Helm Chart or +Extract all the container images listed in each Helm Chart or the Helm Charts in the folder provided. This command dumps the images on `stdout` by default, for more options check `output flag`. Example: @@ -103,29 +104,23 @@ -i, --ignore-errors ignores errors whiles processing charts. (Exit Code: 2) - --file-name string set the name of the output file. (default "images.out") - -```shell -helm mirror inspect-images /tmp/helm -o file --file-name images.txt -helm mirror inspect-images /tmp/helm -o json --file-name images.json -helm mirror inspect-images /tmp/helm -o yaml --file-name images.yaml -``` - -o, --output string choose an output for the list of images.(default "stdout") -- stdout: prints all images on stdout -- file: outputs all images to a file. (View file-name flag) -- json: outputs all images to a file in JSON format. (View file-name flag) -- yaml: outputs all images to a file in YAML format. (View file-name flag) -- skopeo: skopeo: outputs all images to a file in YAML format to be used as input - to Skopeo Sync. (View file-name flag) [1] +- file: outputs all images to a file +- json: outputs all images to a file in JSON format +- skopeo: outputs all images to a file in YAML format + to be used as source file with the 'skopeo sync' command. + For more information refer skopeo([1]). +- stdout: prints all images to standard output +- yaml: outputs all images to a file in YAML format ```shell helm mirror inspect-images /tmp/helm --output stdout helm mirror inspect-images /tmp/helm -o stdout -helm mirror inspect-images /tmp/helm -o file -helm mirror inspect-images /tmp/helm -o json -helm mirror inspect-images /tmp/helm -o yaml +helm mirror inspect-images /tmp/helm -o file=filename +helm mirror inspect-images /tmp/helm -o json=filename.json +helm mirror inspect-images /tmp/helm -o yaml=filename.yaml +helm mirror inspect-images /tmp/helm -o skopeo=filename.yaml ``` #### Global Flags diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/cmd/inspectImages.go new/helm-mirror-0.2.0/cmd/inspectImages.go --- old/helm-mirror-0.1.0/cmd/inspectImages.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/cmd/inspectImages.go 2018-12-04 12:00:48.000000000 +0100 @@ -19,17 +19,16 @@ "log" "path" "path/filepath" + "strings" "github.com/openSUSE/helm-mirror/formatter" "github.com/openSUSE/helm-mirror/service" - "github.com/spf13/cobra" ) var ( //IgnoreErrors ignores errors in processing charts IgnoreErrors bool - imagesFile string output string target string ) @@ -45,38 +44,34 @@ The [folder|tgzfile] has to be a full path. ` -const outputDesc = `choose an output for the list of images. Options: - -- stdout: prints all images on stdout -- file: outputs all images to a file. (View file-name flag) -- json: outputs all images to a file in JSON format. (View file-name flag) -- yaml: outputs all images to a file in YAML format. (View file-name flag) -- skopeo: outputs all images to a file in YAML format to be used as input - to Skopeo Sync. (View file-name flag) +const outputDesc = `choose an output for the list of images and specify +the file name, if not specified 'images.out' will be the default. +Options: + +- file: outputs all images to a file +- json: outputs all images to a file in JSON format +- skopeo: outputs all images to a file in YAML format + to be used as source file with the 'skopeo sync' command. + For more information refer to the 'skopeo sync' + documentation at https://github.com/SUSE/skopeo/blob/sync/docs/skopeo.1.md#skopeo-sync +- stdout: prints all images to standard output +- yaml: outputs all images to a file in YAML format Usage: - helm mirror inspect-images /tmp/helm --output stdout - helm mirror inspect-images /tmp/helm -o stdout - - helm mirror inspect-images /tmp/helm -o file - - helm mirror inspect-images /tmp/helm -o json - - helm mirror inspect-images /tmp/helm -o yaml - -` + - helm mirror inspect-images /tmp/helm -o file=filename + - helm mirror inspect-images /tmp/helm -o json=filename.json + - helm mirror inspect-images /tmp/helm -o yaml=filename.yaml + - helm mirror inspect-images /tmp/helm -o skopeo=filename.yaml -const fileNameDesc = `set the name of the output file. - -Usage: - - - helm mirror inspect-images /tmp/helm -o file --file-name images.txt - - helm mirror inspect-images /tmp/helm -o json --file-name images.json - - helm mirror inspect-images /tmp/helm -o yaml --file-name images.yaml ` // inspectImagesCmd represents the images command var inspectImagesCmd = &cobra.Command{ Use: "inspect-images [folder|tgzfile]", - Short: "Extract all the images of the Helm Charts.", + Short: "Extract all the container images listed in each chart.", Long: imagesDesc, Args: validateInspectImagesArgs, RunE: runInspectImages, @@ -85,7 +80,6 @@ func init() { inspectImagesCmd.PersistentFlags().BoolVarP(&IgnoreErrors, "ignore-errors", "i", false, "ignores errors whiles processing charts. (Exit Code: 2)") inspectImagesCmd.PersistentFlags().StringVarP(&output, "output", "o", "stdout", outputDesc) - inspectImagesCmd.PersistentFlags().StringVar(&imagesFile, "file-name", "images.out", fileNameDesc) rootCmd.AddCommand(inspectImagesCmd) } @@ -101,14 +95,19 @@ return nil } -func resolveFormatter(output string, fileName string, l *log.Logger) (formatter.Formatter, error) { - imagesFile, err := filepath.Abs(fileName) +func resolveFormatter(output string, l *log.Logger) (formatter.Formatter, error) { + a := strings.Split(output, "=") + imagesFile := "images.out" + if len(a) > 1 { + imagesFile = a[1] + } + imagesFile, err := filepath.Abs(imagesFile) if err != nil { l.Print("error: geting working directory") return nil, err } var t formatter.Type - switch output { + switch a[0] { case "file": t = formatter.FileType case "yaml": @@ -125,7 +124,7 @@ func runInspectImages(cmd *cobra.Command, args []string) error { target = args[0] - formatter, err := resolveFormatter(output, imagesFile, logger) + formatter, err := resolveFormatter(output, logger) if err != nil { return err } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/cmd/inspectImages_test.go new/helm-mirror-0.2.0/cmd/inspectImages_test.go --- old/helm-mirror-0.1.0/cmd/inspectImages_test.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/cmd/inspectImages_test.go 2018-12-04 12:00:48.000000000 +0100 @@ -3,6 +3,8 @@ import ( "log" "os" + "path" + "path/filepath" "reflect" "testing" @@ -38,26 +40,33 @@ } func Test_resolveFormatter(t *testing.T) { + abs, err := filepath.Abs("") + if err != nil { + t.Errorf("resolvefilePath() = %s", abs) + } + resultPath := path.Join(abs, "images.out") type args struct { - output string - fileName string - l *log.Logger + output string + l *log.Logger } tests := []struct { name string args args want formatter.Formatter }{ - {"1", args{"stdout", "test", fakeLog}, formatter.NewFormatter(formatter.StdoutType, "test", fakeLog)}, - {"2", args{"file", "/test", fakeLog}, formatter.NewFormatter(formatter.FileType, "/test", fakeLog)}, - {"3", args{"yaml", "/test", fakeLog}, formatter.NewFormatter(formatter.YamlType, "/test", fakeLog)}, - {"4", args{"json", "/test", fakeLog}, formatter.NewFormatter(formatter.JSONType, "/test", fakeLog)}, - {"5", args{"notexists", "test", fakeLog}, formatter.NewFormatter(formatter.StdoutType, "test", fakeLog)}, - {"6", args{"skopeo", "/test", fakeLog}, formatter.NewFormatter(formatter.SkopeoType, "/test", fakeLog)}, + {"1", args{"stdout", fakeLog}, formatter.NewFormatter(formatter.StdoutType, "images.out", fakeLog)}, + {"2.1", args{"file", fakeLog}, formatter.NewFormatter(formatter.FileType, resultPath, fakeLog)}, + {"2.2", args{"file=/test.txt", fakeLog}, formatter.NewFormatter(formatter.FileType, "/test.txt", fakeLog)}, + {"3.1", args{"yaml", fakeLog}, formatter.NewFormatter(formatter.YamlType, resultPath, fakeLog)}, + {"3.2", args{"yaml=/test.yaml", fakeLog}, formatter.NewFormatter(formatter.YamlType, "/test.yaml", fakeLog)}, + {"4.1", args{"json", fakeLog}, formatter.NewFormatter(formatter.JSONType, resultPath, fakeLog)}, + {"4.2", args{"json=/test.json", fakeLog}, formatter.NewFormatter(formatter.JSONType, "/test.json", fakeLog)}, + {"5", args{"notexists", fakeLog}, formatter.NewFormatter(formatter.StdoutType, resultPath, fakeLog)}, + {"6", args{"skopeo=/skopeo.yaml", fakeLog}, formatter.NewFormatter(formatter.SkopeoType, "/skopeo.yaml", fakeLog)}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got, _ := resolveFormatter(tt.args.output, tt.args.fileName, tt.args.l); !reflect.DeepEqual(got, tt.want) { + if got, _ := resolveFormatter(tt.args.output, tt.args.l); !reflect.DeepEqual(got, tt.want) { t.Errorf("resolveFormatter() = %v, want %v", got, tt.want) } }) @@ -67,7 +76,6 @@ func Test_runInspectImages(t *testing.T) { var cmd = &cobra.Command{} cmd.PersistentFlags().StringVarP(&output, "output", "o", "stdout", outputDesc) - cmd.PersistentFlags().StringVar(&imagesFile, "file-name", "images.out", fileNameDesc) type args struct { cmd *cobra.Command args []string diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/cmd/root.go new/helm-mirror-0.2.0/cmd/root.go --- old/helm-mirror-0.1.0/cmd/root.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/cmd/root.go 2018-12-04 12:00:48.000000000 +0100 @@ -30,17 +30,18 @@ var ( //Verbose defines if the command is being run with verbose mode - Verbose bool - folder string - repoURL *url.URL - flags = log.Ldate | log.Lmicroseconds | log.Lshortfile - prefix = "helm-mirror: " - logger *log.Logger - username string - password string - caFile string - certFile string - keyFile string + Verbose bool + folder string + repoURL *url.URL + flags = log.Ldate | log.Lmicroseconds | log.Lshortfile + prefix = "helm-mirror: " + logger *log.Logger + username string + password string + caFile string + certFile string + keyFile string + newRootURL string ) const rootDesc = `Mirror Helm Charts from an index file into a local folder. @@ -108,6 +109,7 @@ rootCmd.Flags().StringVar(&caFile, "ca-file", "", "verify certificates of HTTPS-enabled servers using this CA bundle") rootCmd.Flags().StringVar(&certFile, "cert-file", "", "identify HTTPS client using this SSL certificate file") rootCmd.Flags().StringVar(&keyFile, "key-file", "", "identify HTTPS client using this SSL key file") + rootCmd.Flags().StringVar(&newRootURL, "new-root-url", "", "New root url of the chart repository (eg: `https://mirror.local.lan/charts`)") rootCmd.AddCommand(newVersionCmd()) } @@ -149,6 +151,20 @@ return err } + rootURL := &url.URL{} + if newRootURL != "" { + rootURL, err = url.Parse(newRootURL) + if err != nil { + logger.Printf("error: new-root-url not a valid URL: %s", err) + return err + } + + if !strings.Contains(rootURL.Scheme, "http") { + logger.Printf("error: new-root-url not a valid URL protocol: `%s`", rootURL.Scheme) + return errors.New("error: new-root-url not a valid URL protocol") + } + } + config := repo.Entry{ Name: folder, URL: repoURL.String(), @@ -158,7 +174,7 @@ CertFile: certFile, KeyFile: keyFile, } - getService := service.NewGetService(config, Verbose, IgnoreErrors, logger) + getService := service.NewGetService(config, Verbose, IgnoreErrors, logger, rootURL.String()) err = getService.Get() if err != nil { return err diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/cmd/root_test.go new/helm-mirror-0.2.0/cmd/root_test.go --- old/helm-mirror-0.1.0/cmd/root_test.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/cmd/root_test.go 2018-12-04 12:00:48.000000000 +0100 @@ -1,7 +1,13 @@ package cmd import ( + "fmt" + "io/ioutil" + "log" + "net/http" "os" + "path" + "path/filepath" "testing" "github.com/spf13/cobra" @@ -31,6 +37,7 @@ {"5.4", args{c, []string{"ftps://url", "/target"}}, true}, {"6", args{c, []string{"ftps://url", "/target", "extra"}}, true}, {"7", args{c, []string{"help"}}, false}, + {"8", args{c, []string{"%", "/target", "extra"}}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -42,25 +49,98 @@ } func Test_runRoot(t *testing.T) { + dir, err := ioutil.TempDir("", "helmmirror") + if err != nil { + t.Errorf("creating temp dir: %s", err) + } + defer os.RemoveAll(dir) + svr := startHTTPServer() type args struct { - cmd *cobra.Command - args []string + cmd *cobra.Command + args []string + newRootURL string } tests := []struct { name string args args wantErr bool }{ - {"1", args{&cobra.Command{}, []string{"http://test", "/mr/mzxyptlk"}}, true}, - {"2", args{&cobra.Command{}, []string{"http://test", "/tmp/helm-mirror/test"}}, true}, + {"1", args{&cobra.Command{}, []string{"http://test", path.Join("/mr", "mzxyptlk")}, ""}, true}, + {"2", args{&cobra.Command{}, []string{"http://127.0.0.1:1793", dir}, ""}, false}, + {"3", args{&cobra.Command{}, []string{"%", dir}, ""}, true}, + {"4", args{&cobra.Command{}, []string{"http://test", dir}, "%"}, true}, + {"5", args{&cobra.Command{}, []string{"http://test", dir}, "ftp://test"}, true}, + {"6", args{&cobra.Command{}, []string{"http://127.0.0.1:1793", dir}, "https://test/com/charts"}, false}, + {"7", args{&cobra.Command{}, []string{"http://127.0.0.1:1111", dir}, "https://test/com/charts"}, true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + fmt.Printf("%s clean\n", filepath.Clean(dir)) + fmt.Printf("%v\n", tt.args.args[1]) + newRootURL = tt.args.newRootURL if err := runRoot(tt.args.cmd, tt.args.args); (err != nil) != tt.wantErr { t.Errorf("runRoot() error = %v, wantErr %v", err, tt.wantErr) } }) } - os.RemoveAll("/mr/mzxyptlk") - os.RemoveAll("/tmp/helm-mirror/test") + if err := svr.Shutdown(nil); err != nil { + t.Errorf("error stoping down web server") + } +} + +func startHTTPServer() *http.Server { + srv := &http.Server{Addr: ":1793"} + http.HandleFunc("/index.yaml", indexFile) + http.HandleFunc("/chart1-2.11.0.tgz", chartTgz) + http.HandleFunc("/chart2-1.0.1.tgz", chartTgz) + http.HandleFunc("/chart2-0.0.0-pre.tgz", chartTgz) + go func() { + if err := srv.ListenAndServe(); err != nil { + log.Printf("Httpserver: ListenAndServe() error: %s", err) + } + }() + return srv } + +func indexFile(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "binary/octet-stream") + w.Write(indexYaml) +} + +func chartTgz(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "binary/octet-stream") + w.Write(chartTGZ) +} + +var indexYaml = []byte(`apiVersion: v1 +entries: + chart1: + - apiVersion: v2 + created: 2018-09-20T00:00:00.000000000Z + description: A Helm chart for testing + digest: 8cc99f9cb669171776f7c6ec66069907579be91179f9201725fc6fc6f9ef1f29 + name: chart1 + urls: + - http://127.0.0.1:1793/chart1-2.11.0.tgz + version: 2.11.0 + chart2: + - apiVersion: v1 + created: 2018-09-20T00:00:00.000000000Z + description: A Helm chart for testing too + digest: 0c76ee9b4b78cb60fcce8c00ec0f5048cbe626fcaabe48f2f8e84b029e894f49 + name: chart2 + urls: + - http://127.0.0.1:1793/chart2-1.0.1.tgz + version: 1.0.1 + - apiVersion: v1 + created: 2018-09-20T00:00:00.000000000Z + description: A Helm chart for testing too + digest: e9a545006570b7fc5e4458f6eae178c2aa8f8e9e57eafac59869c856b86e862f + name: chart2 + urls: + - http://127.0.0.1:1793/chart2-0.0.0-pre.tgz + version: 0.0.0-pre +`) + +var chartTGZ = []byte{31, 139, 8, 0, 224, 223, 181, 91, 0, 3, 237, 193, 1, 13, 0, 0, 0, 194, + 160, 247, 79, 109, 14, 55, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 55, 3, 154, 222, 29, 39, 0, 40, 0, 0} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/cover.sh new/helm-mirror-0.2.0/cover.sh --- old/helm-mirror-0.1.0/cover.sh 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/cover.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -e -workdir=.cover -profile="coverage.txt" -mode=atomic - -rm -rf "$workdir" -mkdir "$workdir" - -for d in $(go list ./... | grep -v vendor); do - f="$workdir/$(echo $d | tr / -).cover" - go test -covermode="$mode" -coverprofile="$f" $d -done - -echo "mode: $mode" >"$profile" -grep -h -v "^mode:" "$workdir"/*.cover >>"$profile" - -rm -rf .cover diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/doc/man/helm-mirror-inspect-images.1.md new/helm-mirror-0.2.0/doc/man/helm-mirror-inspect-images.1.md --- old/helm-mirror-0.1.0/doc/man/helm-mirror-inspect-images.1.md 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/doc/man/helm-mirror-inspect-images.1.md 2018-12-04 12:00:48.000000000 +0100 @@ -1,15 +1,15 @@ -% mirror-inspect-images(1) # mirror inspect-images - Extract container images used by charts +% mirror-inspect-images(1) # mirror inspect-images - Extract all the container images listed in each chart. % SUSE LLC % OCTOBER 2018 # NAME -mirror inspect-images - Extract container images used by charts +mirror inspect-images - Extract all the container images listed in each chart. # SYNOPSIS **mirror inspect-images** target [**--help**|**-h**] # DESCRIPTION -**mirror inspect-images** Extracts all the images of the Helm Chart or +**mirror inspect-images** Extract all the container images listed in each Helm Chart or the Helm Charts in the folder provided. This command dumps the images on **stdout** by default. @@ -30,11 +30,9 @@ **-i, --ignore-errors** Ignores errors whiles processing charts. (Exit Code: 2) -**--file-name** - Sets the name of the output file. - **-o, --output** - Choose an output for the list of images. (**stdout**|json|yaml|file|skopeo[1]) + choose an output for the list of images and specify the file name, if not specified 'images.out' will be the default. + (file|json|skopeo[1]|**stdout**|yaml) # EXAMPLES The following examples show different ways to interact with **mirror inspect-images** @@ -50,12 +48,11 @@ % helm mirror inspect-images /tmp/helm/chart.tgz ``` -Inspect a folder and export to other formats, use **--file-name** to change -the name of the output file. +Inspect a folder and export to other formats. ``` -% helm mirror inspect-images /tmp/helm -o file --file-name images.txt -% helm mirror inspect-images /tmp/helm -o json --file-name images.json -% helm mirror inspect-images /tmp/helm -o yaml --file-name images.yaml +% helm mirror inspect-images /tmp/helm -o file=images.txt +% helm mirror inspect-images /tmp/helm -o json=images.json +% helm mirror inspect-images /tmp/helm -o yaml=images.yaml ``` Inspect a folder and ignore the errors while rendering the chart, this diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/doc/man/helm-mirror.1.md new/helm-mirror-0.2.0/doc/man/helm-mirror.1.md --- old/helm-mirror-0.1.0/doc/man/helm-mirror.1.md 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/doc/man/helm-mirror.1.md 2018-12-04 12:00:48.000000000 +0100 @@ -13,6 +13,7 @@ [**--cert-file**] [**--ignore-errors**] [**--key-file**] +[**--new-root-url**] [**--password**] [**--username**] [**--verbose**|**-v**] @@ -77,6 +78,9 @@ **--key-file** Identify HTTPS client using this SSL key file +**--new-root-url** + New root url of the chart repository (eg: `https://mirror.local.lan/charts`) + **--password** Chart repository password diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/install-binary.sh new/helm-mirror-0.2.0/install-binary.sh --- old/helm-mirror-0.1.0/install-binary.sh 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/install-binary.sh 1970-01-01 01:00:00.000000000 +0100 @@ -1,139 +0,0 @@ -#!/bin/bash - -# Shamelessly copied from https://github.com/databus23/helm-diff - -PROJECT_NAME="helm-mirror" -PROJECT_GH="openSUSE/$PROJECT_NAME" - -: ${HELM_PLUGIN_PATH:="$(helm home --debug=false)/plugins/helm-mirror"} - -# Convert the HELM_PLUGIN_PATH to unix if cygpath is -# available. This is the case when using MSYS2 or Cygwin -# on Windows where helm returns a Windows path but we -# need a Unix path - -if type cygpath > /dev/null 2>&1; then - HELM_PLUGIN_PATH=$(cygpath -u $HELM_PLUGIN_PATH) -fi - -if [[ $SKIP_BIN_INSTALL == "1" ]]; then - echo "Skipping binary install" - exit -fi - -# initArch discovers the architecture for this system. -initArch() { - ARCH=$(uname -m) - case $ARCH in - armv5*) ARCH="armv5";; - armv6*) ARCH="armv6";; - armv7*) ARCH="armv7";; - aarch64) ARCH="arm64";; - x86) ARCH="386";; - x86_64) ARCH="amd64";; - i686) ARCH="386";; - i386) ARCH="386";; - esac -} - -# initOS discovers the operating system for this system. -initOS() { - OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') - - case "$OS" in - # Msys support - msys*) OS='windows';; - # Minimalist GNU for Windows - mingw*) OS='windows';; - darwin) OS='macos';; - esac -} - -# verifySupported checks that the os/arch combination is supported for -# binary builds. -verifySupported() { - local supported="linux-amd64" - if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then - echo "No prebuild binary for ${OS}-${ARCH}." - exit 1 - fi - - if ! type "curl" > /dev/null && ! type "wget" > /dev/null; then - echo "Either curl or wget is required" - exit 1 - fi -} - -# getDownloadURL checks the latest available version. -getDownloadURL() { - local version=$(git -C $HELM_PLUGIN_PATH describe --tags --exact-match 2>/dev/null) - if [ -n "$version" ]; then - DOWNLOAD_URL="https://codeload.github.com/$PROJECT_GH/tar.gz/$version" - else - # Use the GitHub API to find the download url for this project. - local url="https://api.github.com/repos/$PROJECT_GH/releases/latest" - if type "curl" > /dev/null; then - DOWNLOAD_URL=$(curl -s $url | grep $OS | awk '/\"browser_download_url\":/{gsub( /[,\"]/,"", $2); print $2}') - elif type "wget" > /dev/null; then - DOWNLOAD_URL=$(wget -q -O - $url | grep $OS | awk '/\"browser_download_url\":/{gsub( /[,\"]/,"", $2); print $2}') - fi - fi -} - -# downloadFile downloads the latest binary package and also the checksum -# for that binary. -downloadFile() { - PLUGIN_TMP_FILE="/tmp/${PROJECT_NAME}.tgz" - echo "Downloading $DOWNLOAD_URL" - if type "curl" > /dev/null; then - curl -L "$DOWNLOAD_URL" -o "$PLUGIN_TMP_FILE" - elif type "wget" > /dev/null; then - wget -q -O "$PLUGIN_TMP_FILE" "$DOWNLOAD_URL" - fi -} - -# installFile verifies the SHA256 for the file, then unpacks and -# installs it. -installFile() { - HELM_TMP="/tmp/$PROJECT_NAME" - mkdir -p "$HELM_TMP" - tar xf "$PLUGIN_TMP_FILE" -C "$HELM_TMP" --strip-components=1 - HELM_TMP_BIN="$HELM_TMP/bin/mirror" - echo "Preparing to install into ${HELM_PLUGIN_PATH}" - mkdir -p "$HELM_PLUGIN_PATH/bin" - pushd "$HELM_TMP" - make mirror - cp "$HELM_TMP_BIN" "$HELM_PLUGIN_PATH/bin" - popd -} - -# fail_trap is executed if an error occurs. -fail_trap() { - result=$? - if [ "$result" != "0" ]; then - echo "Failed to install $PROJECT_NAME" - echo "For support, go to https://github.com/openSUSE/helm-mirror." - fi - exit $result -} - -# testVersion tests the installed client to make sure it is working. -testVersion() { - set +e - echo "$PROJECT_NAME installed into $HELM_PLUGIN_PATH/$PROJECT_NAME" - $HELM_PLUGIN_PATH/bin/mirror version - set -e -} - -# Execution - -#Stop execution on any error -trap "fail_trap" EXIT -set -e -initArch -initOS -verifySupported -getDownloadURL -downloadFile -installFile -testVersion \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/plugin.yaml new/helm-mirror-0.2.0/plugin.yaml --- old/helm-mirror-0.1.0/plugin.yaml 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/plugin.yaml 2018-12-04 12:00:48.000000000 +0100 @@ -1,10 +1,10 @@ name: "mirror" # plugin -version: "0.1.0" +version: "0.2.0" usage: "Mirror Helm Charts from a repository into a local folder." description: "Mirror Helm Charts from a repository into a local folder." useTunnel: true command: "$HELM_PLUGIN_DIR/bin/mirror" hooks: - install: "$HELM_PLUGIN_DIR/install-binary.sh" - update: "$HELM_PLUGIN_DIR/install-binary.sh" \ No newline at end of file + install: "$HELM_PLUGIN_DIR/scripts/install-binary.sh" + update: "$HELM_PLUGIN_DIR/scripts/install-binary.sh" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/scripts/cover.sh new/helm-mirror-0.2.0/scripts/cover.sh --- old/helm-mirror-0.1.0/scripts/cover.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/helm-mirror-0.2.0/scripts/cover.sh 2018-12-04 12:00:48.000000000 +0100 @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e +workdir=.cover +profile="coverage.txt" +mode=atomic + +rm -rf "$workdir" +mkdir "$workdir" + +for d in $(go list ./... | grep -v vendor); do + f="$workdir/$(echo $d | tr / -).cover" + go test -covermode="$mode" -coverprofile="$f" $d +done + +echo "mode: $mode" >"$profile" +grep -h -v "^mode:" "$workdir"/*.cover >>"$profile" + +rm -rf .cover diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/scripts/install-binary.sh new/helm-mirror-0.2.0/scripts/install-binary.sh --- old/helm-mirror-0.1.0/scripts/install-binary.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/helm-mirror-0.2.0/scripts/install-binary.sh 2018-12-04 12:00:48.000000000 +0100 @@ -0,0 +1,141 @@ +#!/bin/bash + +# Shamelessly copied from https://github.com/databus23/helm-diff + +PROJECT_NAME="helm-mirror" +PROJECT_GH="openSUSE/$PROJECT_NAME" + +: ${HELM_PLUGIN_PATH:="$(helm home --debug=false)/plugins/helm-mirror"} + +# Convert the HELM_PLUGIN_PATH to unix if cygpath is +# available. This is the case when using MSYS2 or Cygwin +# on Windows where helm returns a Windows path but we +# need a Unix path + +if type cygpath > /dev/null 2>&1; then + HELM_PLUGIN_PATH=$(cygpath -u $HELM_PLUGIN_PATH) +fi + +if [[ $SKIP_BIN_INSTALL == "1" ]]; then + echo "Skipping binary install" + exit +fi + +# initArch discovers the architecture for this system. +initArch() { + ARCH=$(uname -m) + case $ARCH in + armv5*) ARCH="armv5";; + armv6*) ARCH="armv6";; + armv7*) ARCH="armv7";; + aarch64) ARCH="arm64";; + x86) ARCH="386";; + x86_64) ARCH="amd64";; + i686) ARCH="386";; + i386) ARCH="386";; + esac +} + +# initOS discovers the operating system for this system. +initOS() { + OS=$(echo `uname`|tr '[:upper:]' '[:lower:]') + + case "$OS" in + # Msys support + msys*) OS='windows';; + # Minimalist GNU for Windows + mingw*) OS='windows';; + darwin) OS='macos';; + esac +} + +# verifySupported checks that the os/arch combination is supported for +# binary builds. +verifySupported() { + local supported="linux-amd64" + if ! echo "${supported}" | grep -q "${OS}-${ARCH}"; then + echo "No prebuild binary for ${OS}-${ARCH}." + exit 1 + fi + + if ! type "curl" > /dev/null && ! type "wget" > /dev/null; then + echo "Either curl or wget is required" + exit 1 + fi +} + +# getDownloadURL checks the latest available version. +getDownloadURL() { + local version=$(git -C $HELM_PLUGIN_PATH describe --tags --exact-match 2>/dev/null) + if [ -n "$version" ]; then + DOWNLOAD_URL="https://codeload.github.com/$PROJECT_GH/tar.gz/$version" + else + # Use the GitHub API to find the download url for this project. + local url="https://github.com/repos/$PROJECT_GH/releases/latest" + if type "curl" > /dev/null; then + version=$(curl -s $url | grep -o -E 'v.+\"' | awk '{split($0,a,/"/); print a[1]}') + elif type "wget" > /dev/null; then + version=$(wget -qSO- $url --max-redirect 0 2>&1 | grep Location: | awk '{split($0,a,/\//); print a[8]}') + fi + DOWNLOAD_URL="https://codeload.github.com/$PROJECT_GH/tar.gz/$version" + fi + echo "using download url ${DOWNLOAD_URL}" +} + +# downloadFile downloads the latest binary package and also the checksum +# for that binary. +downloadFile() { + PLUGIN_TMP_FILE="/tmp/${PROJECT_NAME}.tgz" + echo "Downloading $DOWNLOAD_URL" + if type "curl" > /dev/null; then + curl -L "$DOWNLOAD_URL" -o "$PLUGIN_TMP_FILE" + elif type "wget" > /dev/null; then + wget -q -O "$PLUGIN_TMP_FILE" "$DOWNLOAD_URL" + fi +} + +# installFile verifies the SHA256 for the file, then unpacks and +# installs it. +installFile() { + HELM_TMP="/tmp/$PROJECT_NAME" + mkdir -p "$HELM_TMP" + tar xf "$PLUGIN_TMP_FILE" -C "$HELM_TMP" --strip-components=1 + HELM_TMP_BIN="$HELM_TMP/bin/mirror" + echo "Preparing to install into ${HELM_PLUGIN_PATH}" + mkdir -p "$HELM_PLUGIN_PATH/bin" + pushd "$HELM_TMP" + make mirror + cp "$HELM_TMP_BIN" "$HELM_PLUGIN_PATH/bin" + popd +} + +# fail_trap is executed if an error occurs. +fail_trap() { + result=$? + if [ "$result" != "0" ]; then + echo "Failed to install $PROJECT_NAME" + echo "For support, go to https://github.com/openSUSE/helm-mirror." + fi + exit $result +} + +# testVersion tests the installed client to make sure it is working. +testVersion() { + set +e + echo "$PROJECT_NAME installed into $HELM_PLUGIN_PATH/$PROJECT_NAME" + $HELM_PLUGIN_PATH/bin/mirror version + set -e +} + +# Execution + +#Stop execution on any error +trap "fail_trap" EXIT +set -e +initArch +initOS +verifySupported +getDownloadURL +downloadFile +installFile +testVersion \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/service/get.go new/helm-mirror-0.2.0/service/get.go --- old/helm-mirror-0.1.0/service/get.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/service/get.go 2018-12-04 12:00:48.000000000 +0100 @@ -1,9 +1,13 @@ package service import ( + "bytes" "errors" + "fmt" "io/ioutil" "log" + "os" + "path" "strings" "k8s.io/helm/pkg/getter" @@ -11,6 +15,11 @@ "k8s.io/helm/pkg/repo" ) +const ( + downloadedFileName = "downloaded-index.yaml" + indexFileName = "index.yaml" +) + // GetServiceInterface defines a Get service type GetServiceInterface interface { Get() error @@ -22,15 +31,17 @@ verbose bool ignoreErrors bool logger *log.Logger + newRootURL string } // NewGetService return a new instace of GetService -func NewGetService(config repo.Entry, verbose bool, ignoreErrors bool, logger *log.Logger) GetServiceInterface { +func NewGetService(config repo.Entry, verbose bool, ignoreErrors bool, logger *log.Logger, newRootURL string) GetServiceInterface { return &GetService{ config: config, verbose: verbose, ignoreErrors: ignoreErrors, logger: logger, + newRootURL: newRootURL, } } @@ -41,7 +52,8 @@ return err } - err = chartRepo.DownloadIndexFile(g.config.Name + "/downloaded-index.yaml") + downloadedIndexPath := path.Join(g.config.Name, downloadedFileName) + err = chartRepo.DownloadIndexFile(downloadedIndexPath) if err != nil { return err } @@ -60,13 +72,21 @@ if err != nil { errs = append(errs, err.Error()) } - err = writeFile(g.config.Name+"/"+n+"-"+cc.Version+".tgz", b.Bytes(), g.logger) + chartFileName := fmt.Sprintf("%s-%s.tgz", n, cc.Version) + chartPath := path.Join(g.config.Name, chartFileName) + err = writeFile(chartPath, b.Bytes(), g.logger) if err != nil { errs = append(errs, err.Error()) } } } } + + err = prepareIndexFile(g.config.Name, g.config.URL, g.newRootURL, g.logger) + if err != nil { + errs = append(errs, err.Error()) + } + if len(errs) > 0 && !g.ignoreErrors { return errors.New(strings.Join(errs, "\n")) } @@ -81,3 +101,17 @@ } return nil } + +func prepareIndexFile(folder string, repoURL string, newRootURL string, log *log.Logger) error { + downloadedPath := path.Join(folder, downloadedFileName) + indexPath := path.Join(folder, indexFileName) + if newRootURL != "" { + indexContent, err := ioutil.ReadFile(downloadedPath) + if err != nil { + return err + } + content := bytes.Replace(indexContent, []byte(repoURL), []byte(newRootURL), -1) + writeFile(downloadedPath, []byte(content), log) + } + return os.Rename(downloadedPath, indexPath) +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/service/get_test.go new/helm-mirror-0.2.0/service/get_test.go --- old/helm-mirror-0.1.0/service/get_test.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/service/get_test.go 2018-12-04 12:00:48.000000000 +0100 @@ -1,10 +1,13 @@ package service import ( + "io/ioutil" "log" "net/http" "os" + "path" "reflect" + "strings" "testing" "k8s.io/helm/pkg/repo" @@ -19,34 +22,43 @@ } func TestNewGetService(t *testing.T) { - config := repo.Entry{Name: "/tmp/helmmirrortest", URL: "http://helmrepo"} - gService := &GetService{config: config, logger: fakeLogger} + dir, err := ioutil.TempDir("", "helmmirrortests") + if err != nil { + t.Errorf("Creating tmp directory: %s", err) + } + defer os.RemoveAll(dir) + config := repo.Entry{Name: dir, URL: "http://helmrepo"} + gService := &GetService{config: config, logger: fakeLogger, newRootURL: "https://newchartserver.com"} type args struct { helmRepo string workspace string verbose bool ignoreErrors bool logger *log.Logger + newRootURL string } tests := []struct { name string args args want GetServiceInterface }{ - {"1", args{"http://helmrepo", "/tmp/helmmirrortest", false, false, fakeLogger}, gService}, + {"1", args{"http://helmrepo", dir, false, false, fakeLogger, "https://newchartserver.com"}, gService}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := NewGetService(config, tt.args.verbose, tt.args.ignoreErrors, tt.args.logger); !reflect.DeepEqual(got, tt.want) { + if got := NewGetService(config, tt.args.verbose, tt.args.ignoreErrors, tt.args.logger, tt.args.newRootURL); !reflect.DeepEqual(got, tt.want) { t.Errorf("NewGetService() = %v, want %v", got, tt.want) } }) } - os.RemoveAll("/tmp/helmmirrortest") } func TestGetService_Get(t *testing.T) { - prepareTmp() + dir, err := prepareTmp() + if err != nil { + t.Errorf("loading testdata: %s", err) + } + defer os.RemoveAll(dir) svr := startHTTPServer() type fields struct { repoURL string @@ -62,7 +74,7 @@ {"1", fields{"", "", false, false}, true}, {"2", fields{"http://127.0.0.1", "", false, false}, true}, {"3", fields{"http://127.0.0.1:1793", "", false, false}, true}, - {"4", fields{"http://127.0.0.1:1793", tmp + "/get", false, false}, false}, + {"4", fields{"http://127.0.0.1:1793", path.Join(dir, "get"), false, false}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -78,7 +90,6 @@ }) } os.RemoveAll("downloaded-index.yaml") - tearDownTmp() if err := svr.Shutdown(nil); err != nil { t.Errorf("error stoping down web server") } @@ -129,5 +140,51 @@ func chartTgz(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "binary/octet-stream") - w.Write([]byte(chartTGZ)) + w.Write(chartTGZ) +} + +func Test_prepareIndexFile(t *testing.T) { + dir, err := prepareTmp() + if err != nil { + t.Errorf("loading testdata: %s", err) + } + defer os.RemoveAll(dir) + type args struct { + folder string + URL string + newRootURL string + log *log.Logger + } + tests := []struct { + name string + args args + wantErr bool + }{ + {"1", args{path.Join(dir, "processfolder"), "http://127.0.0.1:1793", "http://newchart.server.com", fakeLogger}, false}, + {"2", args{path.Join(dir, "processerrorfolder"), "http://127.0.0.1:1793", "http://newchart.server.com", fakeLogger}, true}, + {"3", args{path.Join(dir, "processfolder"), "http://127.0.0.1:1793", "", fakeLogger}, false}, + } + for _, tt := range tests { + ioutil.WriteFile(path.Join(dir, "processfolder", "downloaded-index.yaml"), []byte(indexYaml), 0666) + t.Run(tt.name, func(t *testing.T) { + if err := prepareIndexFile(tt.args.folder, tt.args.URL, tt.args.newRootURL, tt.args.log); (err != nil) != tt.wantErr { + t.Errorf("prepareIndexFile() error = %v, wantErr %v", err, tt.wantErr) + } + if tt.name == "1" { + contentBytes, err := ioutil.ReadFile(path.Join(dir, "processfolder", "index.yaml")) + if err != nil { + t.Log("Error reading index.yaml") + } + content := string(contentBytes) + count := strings.Count(content, tt.args.newRootURL) + if count != 3 { + t.Errorf("prepareIndexFile() replacedCount = %v, want replacedCount %v", count, 3) + } + _, err = os.Stat(path.Join(dir, "processfolder", "downloaded-index.yaml")) + if err == nil { + t.Errorf("prepareIndexFile() dowloaded-index.yaml not deleted") + } + } + }) + } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/service/inspectImages.go new/helm-mirror-0.2.0/service/inspectImages.go --- old/helm-mirror-0.1.0/service/inspectImages.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/service/inspectImages.go 2018-12-04 12:00:48.000000000 +0100 @@ -5,6 +5,7 @@ "bytes" "log" "os" + "path" "path/filepath" "reflect" "strings" @@ -78,14 +79,14 @@ func (i *ImagesService) processDirectory(target string) error { hasTgzCharts := false e := i.processTarget(target) - err := filepath.Walk(target, func(path string, info os.FileInfo, err error) error { + err := filepath.Walk(target, func(dir string, info os.FileInfo, err error) error { if err != nil { - i.logger.Printf("error: cannot access a path %q: %v\n", path, err) + i.logger.Printf("error: cannot access a dir %q: %v\n", dir, err) return err } if !info.IsDir() && strings.Contains(info.Name(), ".tgz") { hasTgzCharts = true - err := i.processTarget(target + string(os.PathSeparator) + info.Name()) + err := i.processTarget(path.Join(target, info.Name())) if err != nil && i.ignoreErrors { i.exitWithErrors = true } else if err != nil { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/helm-mirror-0.1.0/service/inspectImages_test.go new/helm-mirror-0.2.0/service/inspectImages_test.go --- old/helm-mirror-0.1.0/service/inspectImages_test.go 2018-10-15 15:47:54.000000000 +0200 +++ new/helm-mirror-0.2.0/service/inspectImages_test.go 2018-12-04 12:00:48.000000000 +0100 @@ -2,17 +2,20 @@ import ( "bytes" + "io/ioutil" "os" "os/exec" + "path" "reflect" "testing" "github.com/openSUSE/helm-mirror/formatter" ) -var buff bytes.Buffer -var tmp = "/tmp/mirror" -var fakeFormatter = &mockFormatter{} +var ( + buff bytes.Buffer + fakeFormatter = &mockFormatter{} +) func TestNewImagesService(t *testing.T) { type args struct { @@ -36,8 +39,15 @@ } func TestImagesService_Images(t *testing.T) { - prepareTmp() - defer tearDownTmp() + dir, err := prepareTmp() + if err != nil { + t.Errorf("loading testdata: %s", err) + } + defer os.RemoveAll(dir) + processPath := path.Join(dir, "processfolder") + errorPath := path.Join(dir, "processfoldererror") + testdataPath := path.Join(dir, "testdata") + processTgzPath := path.Join(dir, "processtgz") type fields struct { target string buff bytes.Buffer @@ -48,11 +58,12 @@ fields fields wantErr bool }{ - {"1", fields{tmp + "/processfolder", buff, false}, false}, - {"2", fields{tmp + "/testdata/chart6", buff, false}, true}, - {"3", fields{tmp + "/testdata/chart1.tgz", buff, false}, false}, - {"4", fields{tmp + "/mr/mzxyptlk", buff, false}, true}, - {"5", fields{tmp + "/processfoldererror", buff, true}, false}, + {"1", fields{processPath, buff, false}, false}, + {"2", fields{path.Join(testdataPath, "chart6"), buff, false}, true}, + {"3.1", fields{path.Join(testdataPath, "chart1"), buff, false}, false}, + {"3.2", fields{path.Join(processTgzPath, "chart1.tgz"), buff, false}, false}, + {"4", fields{path.Join(dir, "mr", "mzxyptlk"), buff, false}, true}, + {"5", fields{errorPath, buff, true}, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -72,7 +83,13 @@ } func TestImagesService_processDirectory(t *testing.T) { - prepareTmp() + dir, err := prepareTmp() + if err != nil { + t.Errorf("loading testdata: %s", err) + } + defer os.RemoveAll(dir) + processPath := path.Join(dir, "processfolder") + processTgzPath := path.Join(dir, "processtgz") type fields struct { target string imageFile string @@ -82,10 +99,10 @@ fields fields wantErr bool }{ - {"1", fields{tmp + "/processfolder", "images"}, false}, - {"2", fields{tmp + "/testdata", "images"}, true}, - {"3", fields{tmp + "/testdata/chart1.tgz", "images"}, true}, - {"4", fields{tmp + "/processfolder/chart6", "images"}, true}, + {"1", fields{processPath, "images"}, false}, + {"2", fields{processTgzPath, "images"}, true}, + {"3", fields{path.Join(processTgzPath, "chart1.tgz"), "images"}, true}, + {"4", fields{path.Join(processPath, "chart6.tgz"), "images"}, true}, } for _, tt := range tests { var buf bytes.Buffer @@ -101,24 +118,30 @@ } }) } - tearDownTmp() } func TestImagesService_processTarget(t *testing.T) { - prepareTmp() + dir, err := prepareTmp() + if err != nil { + t.Errorf("loading testdata: %s", err) + } + defer os.RemoveAll(dir) + processTgzPath := path.Join(dir, "processtgz") tests := []struct { name string target string + verbose bool wantBuf string wantErr bool }{ - {"1", tmp + "/testdata/chart1.tgz", "alpine:3.3\n", false}, - {"2", tmp + "/testdata/chart2.tgz", "beta.opensuse.com/alpha/opensuse:42.3\n", false}, - {"3", tmp + "/testdata/.tgz", "", true}, - {"4", tmp + "/testdata/chart3.tgz", "", false}, - {"5", tmp + "/testdata/chart4.tgz", "/alpha/opensuse:42.3\n", false}, - {"6", tmp + "/testdata/chart5.tgz", "", true}, - {"7", tmp + "/testdata/chart6", "", true}, + {"1", path.Join(processTgzPath, "chart1.tgz"), false, "alpine:3.3\n", false}, + {"2", path.Join(processTgzPath, "chart2.tgz"), false, "beta.opensuse.com/alpha/opensuse:42.3\n", false}, + {"3", path.Join(processTgzPath, ".tgz"), false, "", true}, + {"4", path.Join(processTgzPath, "chart3.tgz"), false, "", false}, + {"5", path.Join(processTgzPath, "chart4.tgz"), false, "/alpha/opensuse:42.3\n", false}, + {"6", path.Join(processTgzPath, "chart5.tgz"), false, "", true}, + {"7", path.Join(processTgzPath, "chart6"), false, "", true}, + {"8", path.Join(processTgzPath, "chart6"), true, "", true}, } for _, tt := range tests { var buf bytes.Buffer @@ -127,6 +150,7 @@ formatter: fakeFormatter, logger: fakeLogger, buffer: buf, + verbose: tt.verbose, } t.Run(tt.name, func(t *testing.T) { if err := i.processTarget(tt.target); (err != nil) != tt.wantErr { @@ -138,11 +162,9 @@ } }) } - tearDownTmp() } func Test_sanitizeImageString(t *testing.T) { - prepareTmp() tests := []struct { name string image string @@ -170,35 +192,55 @@ } }) } - tearDownTmp() } -func prepareTmp() { - os.MkdirAll(tmp+"/processfolder", 0777) - os.MkdirAll(tmp+"/processfoldererror", 0777) - os.MkdirAll(tmp+"/get", 0777) - cpCmd := exec.Command("cp", "-R", "testdata", tmp) - cpCmd.Run() - tarCmd := exec.Command("tar", "zcvf", tmp+"/testdata/chart1.tgz", "--directory="+tmp+"/testdata", "chart1") +func prepareTmp() (string, error) { + dir, err := ioutil.TempDir("", "helmmirror") + if err != nil { + return "", err + } + testdataPath := path.Join(dir, "testdata") + processPath := path.Join(dir, "processfolder") + processTgzPath := path.Join(dir, "processtgz") + errorPath := path.Join(dir, "processfoldererror") + getPath := path.Join(dir, "get") + os.MkdirAll(processPath, 0777) + os.MkdirAll(processTgzPath, 0777) + os.MkdirAll(errorPath, 0777) + os.MkdirAll(getPath, 0777) + wd, err := os.Getwd() + if err != nil { + return "", err + } + + err = os.Symlink(path.Join(wd, "testdata"), testdataPath) + if err != nil { + return "", err + } + tarCmd := exec.Command("tar", "zcvf", path.Join(processTgzPath, "chart1.tgz"), "--directory="+testdataPath, "chart1") tarCmd.Run() - tarCmd = exec.Command("tar", "zcvf", tmp+"/testdata/chart2.tgz", "--directory="+tmp+"/testdata", "chart2") + tarCmd = exec.Command("tar", "zcvf", path.Join(processTgzPath, "chart2.tgz"), "--directory="+testdataPath, "chart2") tarCmd.Run() - tarCmd = exec.Command("tar", "zcvf", tmp+"/testdata/chart3.tgz", "--directory="+tmp+"/testdata", "chart3") + tarCmd = exec.Command("tar", "zcvf", path.Join(processTgzPath, "chart3.tgz"), "--directory="+testdataPath, "chart3") tarCmd.Run() - tarCmd = exec.Command("tar", "zcvf", tmp+"/testdata/chart4.tgz", "--directory="+tmp+"/testdata", "chart4") + tarCmd = exec.Command("tar", "zcvf", path.Join(processTgzPath, "chart4.tgz"), "--directory="+testdataPath, "chart4") tarCmd.Run() - tarCmd = exec.Command("tar", "zcvf", tmp+"/testdata/chart5.tgz", "--directory="+tmp+"/testdata", "chart5") + tarCmd = exec.Command("tar", "zcvf", path.Join(processTgzPath, "chart5.tgz"), "--directory="+testdataPath, "chart5") tarCmd.Run() - tarCmd = exec.Command("tar", "zcvf", tmp+"/processfoldererror/chart6.tgz", "--directory="+tmp+"/testdata", "chart6") + tarCmd = exec.Command("tar", "zcvf", path.Join(errorPath, "chart6.tgz"), "--directory="+testdataPath, "chart6") tarCmd.Run() - cpCmd = exec.Command("cp", tmp+"/testdata/chart1.tgz", tmp+"/processfolder") - cpCmd.Run() - cpCmd = exec.Command("cp", tmp+"/testdata/chart2.tgz", tmp+"/processfolder") - cpCmd.Run() - cpCmd = exec.Command("cp", tmp+"/testdata/chart1.tgz", tmp+"/processfoldererror") - cpCmd.Run() -} -func tearDownTmp() { - os.RemoveAll(tmp) + err = os.Symlink(path.Join(processTgzPath, "chart1.tgz"), path.Join(processPath, "chart1.tgz")) + if err != nil { + return "", err + } + err = os.Symlink(path.Join(processTgzPath, "chart2.tgz"), path.Join(processPath, "chart2.tgz")) + if err != nil { + return "", err + } + err = os.Symlink(path.Join(processTgzPath, "chart1.tgz"), path.Join(errorPath, "chart1.tgz")) + if err != nil { + return "", err + } + return dir, err }