github.com/appscode/helm@v3.0.0-alpha.1+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 validChartType, err := chartutil.IsValidChartType(ch) 63 if !validChartType { 64 return "", err 65 } 66 67 combinedVals, err := chartutil.CoalesceValues(ch, p.ValueOptions.rawValues) 68 if err != nil { 69 return "", err 70 } 71 ch.Values = combinedVals 72 73 // If version is set, modify the version. 74 if p.Version != "" { 75 if err := setVersion(ch, p.Version); err != nil { 76 return "", err 77 } 78 } 79 80 if p.AppVersion != "" { 81 ch.Metadata.AppVersion = p.AppVersion 82 } 83 84 if reqs := ch.Metadata.Dependencies; reqs != nil { 85 if err := CheckDependencies(ch, reqs); err != nil { 86 return "", err 87 } 88 } 89 90 var dest string 91 if p.Destination == "." { 92 // Save to the current working directory. 93 dest, err = os.Getwd() 94 if err != nil { 95 return "", err 96 } 97 } else { 98 // Otherwise save to set destination 99 dest = p.Destination 100 } 101 102 name, err := chartutil.Save(ch, dest) 103 if err != nil { 104 return "", errors.Wrap(err, "failed to save") 105 } 106 107 if p.Sign { 108 err = p.Clearsign(name) 109 } 110 111 return "", err 112 } 113 114 func setVersion(ch *chart.Chart, ver string) error { 115 // Verify that version is a Version, and error out if it is not. 116 if _, err := semver.NewVersion(ver); err != nil { 117 return err 118 } 119 120 // Set the version field on the chart. 121 ch.Metadata.Version = ver 122 return nil 123 } 124 125 func (p *Package) Clearsign(filename string) error { 126 // Load keyring 127 signer, err := provenance.NewFromKeyring(p.Keyring, p.Key) 128 if err != nil { 129 return err 130 } 131 132 if err := signer.DecryptKey(promptUser); err != nil { 133 return err 134 } 135 136 sig, err := signer.ClearSign(filename) 137 if err != nil { 138 return err 139 } 140 141 return ioutil.WriteFile(filename+".prov", []byte(sig), 0755) 142 } 143 144 // promptUser implements provenance.PassphraseFetcher 145 func promptUser(name string) ([]byte, error) { 146 fmt.Printf("Password for key %q > ", name) 147 pw, err := terminal.ReadPassword(int(syscall.Stdin)) 148 fmt.Println() 149 return pw, err 150 }