github.com/danielqsj/helm@v2.0.0-alpha.4.0.20160908204436-976e0ba5199b+incompatible/cmd/helm/package.go (about) 1 /* 2 Copyright 2016 The Kubernetes Authors All rights reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "errors" 21 "fmt" 22 "io" 23 "io/ioutil" 24 "os" 25 "path/filepath" 26 27 "github.com/spf13/cobra" 28 29 "k8s.io/helm/pkg/chartutil" 30 "k8s.io/helm/pkg/helm" 31 "k8s.io/helm/pkg/provenance" 32 "k8s.io/helm/pkg/repo" 33 ) 34 35 const packageDesc = ` 36 This command packages a chart into a versioned chart archive file. If a path 37 is given, this will look at that path for a chart (which must contain a 38 Chart.yaml file) and then package that directory. 39 40 If no path is given, this will look in the present working directory for a 41 Chart.yaml file, and (if found) build the current directory into a chart. 42 43 Versioned chart archives are used by Helm package repositories. 44 ` 45 46 type packageCmd struct { 47 save bool 48 sign bool 49 path string 50 key string 51 keyring string 52 out io.Writer 53 } 54 55 func newPackageCmd(client helm.Interface, out io.Writer) *cobra.Command { 56 pkg := &packageCmd{ 57 out: out, 58 } 59 cmd := &cobra.Command{ 60 Use: "package [flags] [CHART_PATH] [...]", 61 Short: "package a chart directory into a chart archive", 62 Long: packageDesc, 63 RunE: func(cmd *cobra.Command, args []string) error { 64 if len(args) == 0 { 65 return fmt.Errorf("This command needs at least one argument, the path to the chart.") 66 } 67 if pkg.sign { 68 if pkg.key == "" { 69 return errors.New("--key is required for signing a package") 70 } 71 if pkg.keyring == "" { 72 return errors.New("--keyring is required for signing a package") 73 } 74 } 75 for i := 0; i < len(args); i++ { 76 pkg.path = args[i] 77 if err := pkg.run(cmd, args); err != nil { 78 return err 79 } 80 } 81 return nil 82 }, 83 } 84 85 f := cmd.Flags() 86 f.BoolVar(&pkg.save, "save", true, "save packaged chart to local chart repository") 87 f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package") 88 f.StringVar(&pkg.key, "key", "", "the name of the key to use when signing. Used if --sign is true.") 89 f.StringVar(&pkg.keyring, "keyring", defaultKeyring(), "the location of a public keyring") 90 91 return cmd 92 } 93 94 func (p *packageCmd) run(cmd *cobra.Command, args []string) error { 95 path, err := filepath.Abs(p.path) 96 if err != nil { 97 return err 98 } 99 100 ch, err := chartutil.LoadDir(path) 101 if err != nil { 102 return err 103 } 104 105 if filepath.Base(path) != ch.Metadata.Name { 106 return fmt.Errorf("directory name (%s) and Chart.yaml name (%s) must match", filepath.Base(path), ch.Metadata.Name) 107 } 108 109 // Save to the current working directory. 110 cwd, err := os.Getwd() 111 if err != nil { 112 return err 113 } 114 name, err := chartutil.Save(ch, cwd) 115 if err == nil && flagDebug { 116 cmd.Printf("Saved %s to current directory\n", name) 117 } 118 119 // Save to $HELM_HOME/local directory. This is second, because we don't want 120 // the case where we saved here, but didn't save to the default destination. 121 if p.save { 122 if err := repo.AddChartToLocalRepo(ch, localRepoDirectory()); err != nil { 123 return err 124 } else if flagDebug { 125 cmd.Printf("Saved %s to %s\n", name, localRepoDirectory()) 126 } 127 } 128 129 if p.sign { 130 err = p.clearsign(name) 131 } 132 133 return err 134 } 135 136 func (p *packageCmd) clearsign(filename string) error { 137 // Load keyring 138 signer, err := provenance.NewFromKeyring(p.keyring, p.key) 139 if err != nil { 140 return err 141 } 142 143 sig, err := signer.ClearSign(filename) 144 if err != nil { 145 return err 146 } 147 148 if flagDebug { 149 fmt.Fprintln(p.out, sig) 150 } 151 152 return ioutil.WriteFile(filename+".prov", []byte(sig), 0755) 153 }