github.com/kruglovmax/helm@v3.0.0-beta.3+incompatible/pkg/chart/loader/archive.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 loader
    18  
    19  import (
    20  	"archive/tar"
    21  	"bytes"
    22  	"compress/gzip"
    23  	"io"
    24  	"os"
    25  	"strings"
    26  
    27  	"github.com/pkg/errors"
    28  
    29  	"helm.sh/helm/pkg/chart"
    30  )
    31  
    32  // FileLoader loads a chart from a file
    33  type FileLoader string
    34  
    35  // Load loads a chart
    36  func (l FileLoader) Load() (*chart.Chart, error) {
    37  	return LoadFile(string(l))
    38  }
    39  
    40  // LoadFile loads from an archive file.
    41  func LoadFile(name string) (*chart.Chart, error) {
    42  	if fi, err := os.Stat(name); err != nil {
    43  		return nil, err
    44  	} else if fi.IsDir() {
    45  		return nil, errors.New("cannot load a directory")
    46  	}
    47  
    48  	raw, err := os.Open(name)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	defer raw.Close()
    53  
    54  	return LoadArchive(raw)
    55  }
    56  
    57  // LoadArchive loads from a reader containing a compressed tar archive.
    58  func LoadArchive(in io.Reader) (*chart.Chart, error) {
    59  	unzipped, err := gzip.NewReader(in)
    60  	if err != nil {
    61  		return &chart.Chart{}, err
    62  	}
    63  	defer unzipped.Close()
    64  
    65  	files := []*BufferedFile{}
    66  	tr := tar.NewReader(unzipped)
    67  	for {
    68  		b := bytes.NewBuffer(nil)
    69  		hd, err := tr.Next()
    70  		if err == io.EOF {
    71  			break
    72  		}
    73  		if err != nil {
    74  			return &chart.Chart{}, err
    75  		}
    76  
    77  		if hd.FileInfo().IsDir() {
    78  			// Use this instead of hd.Typeflag because we don't have to do any
    79  			// inference chasing.
    80  			continue
    81  		}
    82  
    83  		// Archive could contain \ if generated on Windows
    84  		delimiter := "/"
    85  		if strings.ContainsRune(hd.Name, '\\') {
    86  			delimiter = "\\"
    87  		}
    88  
    89  		parts := strings.Split(hd.Name, delimiter)
    90  		n := strings.Join(parts[1:], delimiter)
    91  
    92  		// Normalize the path to the / delimiter
    93  		n = strings.ReplaceAll(n, delimiter, "/")
    94  
    95  		if parts[0] == "Chart.yaml" {
    96  			return nil, errors.New("chart yaml not in base directory")
    97  		}
    98  
    99  		if _, err := io.Copy(b, tr); err != nil {
   100  			return &chart.Chart{}, err
   101  		}
   102  
   103  		files = append(files, &BufferedFile{Name: n, Data: b.Bytes()})
   104  		b.Reset()
   105  	}
   106  
   107  	if len(files) == 0 {
   108  		return nil, errors.New("no files in chart archive")
   109  	}
   110  
   111  	return LoadFiles(files)
   112  }