github.com/danielqsj/helm@v2.0.0-alpha.4.0.20160908204436-976e0ba5199b+incompatible/cmd/helm/package.go (about)

     1  /*
     2  Copyright 2016 The Kubernetes Authors All rights reserved.
     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 main
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"io/ioutil"
    24  	"os"
    25  	"path/filepath"
    26  
    27  	"github.com/spf13/cobra"
    28  
    29  	"k8s.io/helm/pkg/chartutil"
    30  	"k8s.io/helm/pkg/helm"
    31  	"k8s.io/helm/pkg/provenance"
    32  	"k8s.io/helm/pkg/repo"
    33  )
    34  
    35  const packageDesc = `
    36  This command packages a chart into a versioned chart archive file. If a path
    37  is given, this will look at that path for a chart (which must contain a
    38  Chart.yaml file) and then package that directory.
    39  
    40  If no path is given, this will look in the present working directory for a
    41  Chart.yaml file, and (if found) build the current directory into a chart.
    42  
    43  Versioned chart archives are used by Helm package repositories.
    44  `
    45  
    46  type packageCmd struct {
    47  	save    bool
    48  	sign    bool
    49  	path    string
    50  	key     string
    51  	keyring string
    52  	out     io.Writer
    53  }
    54  
    55  func newPackageCmd(client helm.Interface, out io.Writer) *cobra.Command {
    56  	pkg := &packageCmd{
    57  		out: out,
    58  	}
    59  	cmd := &cobra.Command{
    60  		Use:   "package [flags] [CHART_PATH] [...]",
    61  		Short: "package a chart directory into a chart archive",
    62  		Long:  packageDesc,
    63  		RunE: func(cmd *cobra.Command, args []string) error {
    64  			if len(args) == 0 {
    65  				return fmt.Errorf("This command needs at least one argument, the path to the chart.")
    66  			}
    67  			if pkg.sign {
    68  				if pkg.key == "" {
    69  					return errors.New("--key is required for signing a package")
    70  				}
    71  				if pkg.keyring == "" {
    72  					return errors.New("--keyring is required for signing a package")
    73  				}
    74  			}
    75  			for i := 0; i < len(args); i++ {
    76  				pkg.path = args[i]
    77  				if err := pkg.run(cmd, args); err != nil {
    78  					return err
    79  				}
    80  			}
    81  			return nil
    82  		},
    83  	}
    84  
    85  	f := cmd.Flags()
    86  	f.BoolVar(&pkg.save, "save", true, "save packaged chart to local chart repository")
    87  	f.BoolVar(&pkg.sign, "sign", false, "use a PGP private key to sign this package")
    88  	f.StringVar(&pkg.key, "key", "", "the name of the key to use when signing. Used if --sign is true.")
    89  	f.StringVar(&pkg.keyring, "keyring", defaultKeyring(), "the location of a public keyring")
    90  
    91  	return cmd
    92  }
    93  
    94  func (p *packageCmd) run(cmd *cobra.Command, args []string) error {
    95  	path, err := filepath.Abs(p.path)
    96  	if err != nil {
    97  		return err
    98  	}
    99  
   100  	ch, err := chartutil.LoadDir(path)
   101  	if err != nil {
   102  		return err
   103  	}
   104  
   105  	if filepath.Base(path) != ch.Metadata.Name {
   106  		return fmt.Errorf("directory name (%s) and Chart.yaml name (%s) must match", filepath.Base(path), ch.Metadata.Name)
   107  	}
   108  
   109  	// Save to the current working directory.
   110  	cwd, err := os.Getwd()
   111  	if err != nil {
   112  		return err
   113  	}
   114  	name, err := chartutil.Save(ch, cwd)
   115  	if err == nil && flagDebug {
   116  		cmd.Printf("Saved %s to current directory\n", name)
   117  	}
   118  
   119  	// Save to $HELM_HOME/local directory. This is second, because we don't want
   120  	// the case where we saved here, but didn't save to the default destination.
   121  	if p.save {
   122  		if err := repo.AddChartToLocalRepo(ch, localRepoDirectory()); err != nil {
   123  			return err
   124  		} else if flagDebug {
   125  			cmd.Printf("Saved %s to %s\n", name, localRepoDirectory())
   126  		}
   127  	}
   128  
   129  	if p.sign {
   130  		err = p.clearsign(name)
   131  	}
   132  
   133  	return err
   134  }
   135  
   136  func (p *packageCmd) clearsign(filename string) error {
   137  	// Load keyring
   138  	signer, err := provenance.NewFromKeyring(p.keyring, p.key)
   139  	if err != nil {
   140  		return err
   141  	}
   142  
   143  	sig, err := signer.ClearSign(filename)
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	if flagDebug {
   149  		fmt.Fprintln(p.out, sig)
   150  	}
   151  
   152  	return ioutil.WriteFile(filename+".prov", []byte(sig), 0755)
   153  }