github.com/azure-devops-engineer/helm@v3.0.0-alpha.2+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 ValueOptions 40 41 Sign bool 42 Key string 43 Keyring string 44 Version string 45 AppVersion string 46 Destination string 47 DependencyUpdate bool 48 } 49 50 // NewPackage creates a new Package object with the given configuration. 51 func NewPackage() *Package { 52 return &Package{} 53 } 54 55 // Run executes 'helm package' against the given chart and returns the path to the packaged chart. 56 func (p *Package) Run(path string) (string, error) { 57 ch, err := loader.LoadDir(path) 58 if err != nil { 59 return "", err 60 } 61 62 combinedVals, err := chartutil.CoalesceValues(ch, p.ValueOptions.rawValues) 63 if err != nil { 64 return "", err 65 } 66 ch.Values = combinedVals 67 68 // If version is set, modify the version. 69 if p.Version != "" { 70 if err := setVersion(ch, p.Version); err != nil { 71 return "", err 72 } 73 } 74 75 if p.AppVersion != "" { 76 ch.Metadata.AppVersion = p.AppVersion 77 } 78 79 if reqs := ch.Metadata.Dependencies; reqs != nil { 80 if err := CheckDependencies(ch, reqs); err != nil { 81 return "", err 82 } 83 } 84 85 var dest string 86 if p.Destination == "." { 87 // Save to the current working directory. 88 dest, err = os.Getwd() 89 if err != nil { 90 return "", err 91 } 92 } else { 93 // Otherwise save to set destination 94 dest = p.Destination 95 } 96 97 name, err := chartutil.Save(ch, dest) 98 if err != nil { 99 return "", errors.Wrap(err, "failed to save") 100 } 101 102 if p.Sign { 103 err = p.Clearsign(name) 104 } 105 106 return name, err 107 } 108 109 func setVersion(ch *chart.Chart, ver string) error { 110 // Verify that version is a Version, and error out if it is not. 111 if _, err := semver.NewVersion(ver); err != nil { 112 return err 113 } 114 115 // Set the version field on the chart. 116 ch.Metadata.Version = ver 117 return nil 118 } 119 120 func (p *Package) Clearsign(filename string) error { 121 // Load keyring 122 signer, err := provenance.NewFromKeyring(p.Keyring, p.Key) 123 if err != nil { 124 return err 125 } 126 127 if err := signer.DecryptKey(promptUser); err != nil { 128 return err 129 } 130 131 sig, err := signer.ClearSign(filename) 132 if err != nil { 133 return err 134 } 135 136 return ioutil.WriteFile(filename+".prov", []byte(sig), 0755) 137 } 138 139 // promptUser implements provenance.PassphraseFetcher 140 func promptUser(name string) ([]byte, error) { 141 fmt.Printf("Password for key %q > ", name) 142 pw, err := terminal.ReadPassword(int(syscall.Stdin)) 143 fmt.Println() 144 return pw, err 145 }