github.com/danielqsj/helm@v2.0.0-alpha.4.0.20160908204436-976e0ba5199b+incompatible/cmd/helm/init.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  	"os"
    24  	"strings"
    25  
    26  	"github.com/spf13/cobra"
    27  
    28  	"k8s.io/helm/cmd/helm/installer"
    29  )
    30  
    31  const initDesc = `
    32  This command installs Tiller (the helm server side component) onto your
    33  Kubernetes Cluster and sets up local configuration in $HELM_HOME (default: ~/.helm/)
    34  `
    35  
    36  var (
    37  	defaultRepository    = "kubernetes-charts"
    38  	defaultRepositoryURL = "http://storage.googleapis.com/kubernetes-charts"
    39  )
    40  
    41  type initCmd struct {
    42  	image      string
    43  	clientOnly bool
    44  	out        io.Writer
    45  }
    46  
    47  func newInitCmd(out io.Writer) *cobra.Command {
    48  	i := &initCmd{
    49  		out: out,
    50  	}
    51  	cmd := &cobra.Command{
    52  		Use:   "init",
    53  		Short: "initialize Helm on both client and server",
    54  		Long:  initDesc,
    55  		RunE: func(cmd *cobra.Command, args []string) error {
    56  			if len(args) != 0 {
    57  				return errors.New("This command does not accept arguments")
    58  			}
    59  			return i.run()
    60  		},
    61  	}
    62  	cmd.Flags().StringVarP(&i.image, "tiller-image", "i", "", "override tiller image")
    63  	cmd.Flags().BoolVarP(&i.clientOnly, "client-only", "c", false, "If set does not install tiller")
    64  	return cmd
    65  }
    66  
    67  // runInit initializes local config and installs tiller to Kubernetes Cluster
    68  func (i *initCmd) run() error {
    69  	if err := ensureHome(); err != nil {
    70  		return err
    71  	}
    72  
    73  	if !i.clientOnly {
    74  		if err := installer.Install(tillerNamespace, i.image, flagDebug); err != nil {
    75  			if !strings.Contains(err.Error(), `"tiller-deploy" already exists`) {
    76  				return fmt.Errorf("error installing: %s", err)
    77  			}
    78  			fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster. (Use --client-only to suppress this message.)")
    79  		} else {
    80  			fmt.Fprintln(i.out, "\nTiller (the helm server side component) has been installed into your Kubernetes Cluster.")
    81  		}
    82  	} else {
    83  		fmt.Fprintln(i.out, "Not installing tiller due to 'client-only' flag having been set")
    84  	}
    85  	fmt.Fprintln(i.out, "Happy Helming!")
    86  	return nil
    87  }
    88  
    89  func requireHome() error {
    90  	dirs := []string{homePath(), repositoryDirectory(), cacheDirectory(), localRepoDirectory()}
    91  	for _, d := range dirs {
    92  		if fi, err := os.Stat(d); err != nil {
    93  			return fmt.Errorf("directory %q is not configured", d)
    94  		} else if !fi.IsDir() {
    95  			return fmt.Errorf("expected %q to be a directory", d)
    96  		}
    97  	}
    98  	return nil
    99  }
   100  
   101  // ensureHome checks to see if $HELM_HOME exists
   102  //
   103  // If $HELM_HOME does not exist, this function will create it.
   104  func ensureHome() error {
   105  	configDirectories := []string{homePath(), repositoryDirectory(), cacheDirectory(), localRepoDirectory()}
   106  
   107  	for _, p := range configDirectories {
   108  		if fi, err := os.Stat(p); err != nil {
   109  			fmt.Printf("Creating %s \n", p)
   110  			if err := os.MkdirAll(p, 0755); err != nil {
   111  				return fmt.Errorf("Could not create %s: %s", p, err)
   112  			}
   113  		} else if !fi.IsDir() {
   114  			return fmt.Errorf("%s must be a directory", p)
   115  		}
   116  	}
   117  
   118  	repoFile := repositoriesFile()
   119  	if fi, err := os.Stat(repoFile); err != nil {
   120  		fmt.Printf("Creating %s \n", repoFile)
   121  		if _, err := os.Create(repoFile); err != nil {
   122  			return err
   123  		}
   124  		if err := addRepository(defaultRepository, defaultRepositoryURL); err != nil {
   125  			return err
   126  		}
   127  	} else if fi.IsDir() {
   128  		return fmt.Errorf("%s must be a file, not a directory", repoFile)
   129  	}
   130  
   131  	localRepoIndexFile := localRepoDirectory(localRepoIndexFilePath)
   132  	if fi, err := os.Stat(localRepoIndexFile); err != nil {
   133  		fmt.Printf("Creating %s \n", localRepoIndexFile)
   134  		_, err := os.Create(localRepoIndexFile)
   135  		if err != nil {
   136  			return err
   137  		}
   138  
   139  		//TODO: take this out and replace with helm update functionality
   140  		os.Symlink(localRepoIndexFile, cacheDirectory("local-index.yaml"))
   141  	} else if fi.IsDir() {
   142  		return fmt.Errorf("%s must be a file, not a directory", localRepoIndexFile)
   143  	}
   144  
   145  	fmt.Printf("$HELM_HOME has been configured at %s.\n", helmHome)
   146  	return nil
   147  }