github.com/zsuzhengdu/helm@v3.0.0-beta.3+incompatible/pkg/action/package.go (about) 1 /* 2 Copyright The Helm Authors. 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 action 18 19 import ( 20 "fmt" 21 "io/ioutil" 22 "os" 23 "syscall" 24 25 "github.com/Masterminds/semver" 26 "github.com/pkg/errors" 27 "golang.org/x/crypto/ssh/terminal" 28 29 "helm.sh/helm/pkg/chart" 30 "helm.sh/helm/pkg/chart/loader" 31 "helm.sh/helm/pkg/chartutil" 32 "helm.sh/helm/pkg/provenance" 33 ) 34 35 // Package is the action for packaging a chart. 36 // 37 // It provides the implementation of 'helm package'. 38 type Package struct { 39 Sign bool 40 Key string 41 Keyring string 42 Version string 43 AppVersion string 44 Destination string 45 DependencyUpdate bool 46 47 RepositoryConfig string 48 RepositoryCache string 49 } 50 51 // NewPackage creates a new Package object with the given configuration. 52 func NewPackage() *Package { 53 return &Package{} 54 } 55 56 // Run executes 'helm package' against the given chart and returns the path to the packaged chart. 57 func (p *Package) Run(path string, vals map[string]interface{}) (string, error) { 58 ch, err := loader.LoadDir(path) 59 if err != nil { 60 return "", err 61 } 62 63 combinedVals, err := chartutil.CoalesceValues(ch, vals) 64 if err != nil { 65 return "", err 66 } 67 ch.Values = combinedVals 68 69 // If version is set, modify the version. 70 if p.Version != "" { 71 if err := setVersion(ch, p.Version); err != nil { 72 return "", err 73 } 74 } 75 76 if p.AppVersion != "" { 77 ch.Metadata.AppVersion = p.AppVersion 78 } 79 80 if reqs := ch.Metadata.Dependencies; reqs != nil { 81 if err := CheckDependencies(ch, reqs); err != nil { 82 return "", err 83 } 84 } 85 86 var dest string 87 if p.Destination == "." { 88 // Save to the current working directory. 89 dest, err = os.Getwd() 90 if err != nil { 91 return "", err 92 } 93 } else { 94 // Otherwise save to set destination 95 dest = p.Destination 96 } 97 98 name, err := chartutil.Save(ch, dest) 99 if err != nil { 100 return "", errors.Wrap(err, "failed to save") 101 } 102 103 if p.Sign { 104 err = p.Clearsign(name) 105 } 106 107 return name, err 108 } 109 110 func setVersion(ch *chart.Chart, ver string) error { 111 // Verify that version is a Version, and error out if it is not. 112 if _, err := semver.NewVersion(ver); err != nil { 113 return err 114 } 115 116 // Set the version field on the chart. 117 ch.Metadata.Version = ver 118 return nil 119 } 120 121 func (p *Package) Clearsign(filename string) error { 122 // Load keyring 123 signer, err := provenance.NewFromKeyring(p.Keyring, p.Key) 124 if err != nil { 125 return err 126 } 127 128 if err := signer.DecryptKey(promptUser); err != nil { 129 return err 130 } 131 132 sig, err := signer.ClearSign(filename) 133 if err != nil { 134 return err 135 } 136 137 return ioutil.WriteFile(filename+".prov", []byte(sig), 0644) 138 } 139 140 // promptUser implements provenance.PassphraseFetcher 141 func promptUser(name string) ([]byte, error) { 142 fmt.Printf("Password for key %q > ", name) 143 pw, err := terminal.ReadPassword(int(syscall.Stdin)) 144 fmt.Println() 145 return pw, err 146 }