github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/pusher/ocipusher.go (about) 1 /* 2 Copyright The Helm Authors. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package pusher 17 18 import ( 19 "fmt" 20 "io/ioutil" 21 "os" 22 "path" 23 "strings" 24 25 "github.com/pkg/errors" 26 27 "github.com/stefanmcshane/helm/pkg/chart/loader" 28 "github.com/stefanmcshane/helm/pkg/registry" 29 ) 30 31 // OCIPusher is the default OCI backend handler 32 type OCIPusher struct { 33 opts options 34 } 35 36 // Push performs a Push from repo.Pusher. 37 func (pusher *OCIPusher) Push(chartRef, href string, options ...Option) error { 38 for _, opt := range options { 39 opt(&pusher.opts) 40 } 41 return pusher.push(chartRef, href) 42 } 43 44 func (pusher *OCIPusher) push(chartRef, href string) error { 45 stat, err := os.Stat(chartRef) 46 if err != nil { 47 if os.IsNotExist(err) { 48 return errors.Errorf("%s: no such file", chartRef) 49 } 50 return err 51 } 52 if stat.IsDir() { 53 return errors.New("cannot push directory, must provide chart archive (.tgz)") 54 } 55 56 meta, err := loader.Load(chartRef) 57 if err != nil { 58 return err 59 } 60 61 client := pusher.opts.registryClient 62 63 chartBytes, err := ioutil.ReadFile(chartRef) 64 if err != nil { 65 return err 66 } 67 68 var pushOpts []registry.PushOption 69 provRef := fmt.Sprintf("%s.prov", chartRef) 70 if _, err := os.Stat(provRef); err == nil { 71 provBytes, err := ioutil.ReadFile(provRef) 72 if err != nil { 73 return err 74 } 75 pushOpts = append(pushOpts, registry.PushOptProvData(provBytes)) 76 } 77 78 ref := fmt.Sprintf("%s:%s", 79 path.Join(strings.TrimPrefix(href, fmt.Sprintf("%s://", registry.OCIScheme)), meta.Metadata.Name), 80 meta.Metadata.Version) 81 82 _, err = client.Push(chartBytes, ref, pushOpts...) 83 return err 84 } 85 86 // NewOCIPusher constructs a valid OCI client as a Pusher 87 func NewOCIPusher(ops ...Option) (Pusher, error) { 88 registryClient, err := registry.NewClient( 89 registry.ClientOptEnableCache(true), 90 ) 91 if err != nil { 92 return nil, err 93 } 94 95 client := OCIPusher{ 96 opts: options{ 97 registryClient: registryClient, 98 }, 99 } 100 101 for _, opt := range ops { 102 opt(&client.opts) 103 } 104 105 return &client, nil 106 }