Commit d54c351a authored by Michelle Noorali's avatar Michelle Noorali

Merge pull request #28 from michelleN/helm-init

feat(init): add local config step to init
parents d3cff27b 7d207d9a
...@@ -7,12 +7,38 @@ import ( ...@@ -7,12 +7,38 @@ import (
) )
var stdout = os.Stdout var stdout = os.Stdout
var helmHome string
var globalUsage = `The Kubernetes package manager
To begin working with Helm, run the 'helm init' command:
$ helm init
This will install Tiller to your running Kubernetes cluster.
It will also set up any necessary local configuration.
Commond actions from this point on include:
- helm search: search for charts
- helm fetch: download a chart to your local directory to view
- helm install: upload the chart to Kubernetes
- helm list: list releases of charts
ENVIRONMENT:
$HELM_HOME: Set an alternative location for Helm files.
By default, these are stored in ~/.helm
`
// RootCommand is the top-level command for Helm. // RootCommand is the top-level command for Helm.
var RootCommand = &cobra.Command{ var RootCommand = &cobra.Command{
Use: "helm", Use: "helm",
Short: "The Helm package manager for Kubernetes.", Short: "The Helm package manager for Kubernetes.",
Long: `Do long help here.`, Long: globalUsage,
}
func init() {
RootCommand.PersistentFlags().StringVar(&helmHome, "home", "$HOME/.helm", "location of you Helm files [$HELM_HOME]")
} }
func main() { func main() {
......
package main
import (
"fmt"
"github.com/spf13/cobra"
)
var longHomeHelp = `
This command displays the location of HELM_HOME. This is where
any helm configuration files live.
`
var homeCommand = &cobra.Command{
Use: "home",
Short: "Displays the location of HELM_HOME",
Long: longHomeHelp,
Run: Home,
}
func init() {
RootCommand.AddCommand(homeCommand)
}
func Home(cmd *cobra.Command, args []string) {
fmt.Println("helm home was called")
}
...@@ -3,6 +3,9 @@ package main ...@@ -3,6 +3,9 @@ package main
import ( import (
"errors" "errors"
"fmt" "fmt"
"io/ioutil"
"os"
"path/filepath"
"github.com/deis/tiller/pkg/client" "github.com/deis/tiller/pkg/client"
"github.com/deis/tiller/pkg/kubectl" "github.com/deis/tiller/pkg/kubectl"
...@@ -14,6 +17,10 @@ This command installs Tiller (the helm server side component) onto your ...@@ -14,6 +17,10 @@ This command installs Tiller (the helm server side component) onto your
Kubernetes Cluster and sets up local configuration in $HELM_HOME (default: ~/.helm/) Kubernetes Cluster and sets up local configuration in $HELM_HOME (default: ~/.helm/)
` `
const repositoriesPath = ".repositories"
const cachePath = "cache"
var defaultRepo = map[string]string{"default-name": "default-url"}
var tillerImg string var tillerImg string
func init() { func init() {
...@@ -34,18 +41,30 @@ func RunInit(cmd *cobra.Command, args []string) error { ...@@ -34,18 +41,30 @@ func RunInit(cmd *cobra.Command, args []string) error {
return errors.New("This command does not accept arguments. \n") return errors.New("This command does not accept arguments. \n")
} }
if err := EnsureHome(os.ExpandEnv(helmHome)); err != nil {
return err
}
if err := installTiller(); err != nil {
return err
}
fmt.Printf("Tiller (the helm server side component) has been installed into your Kubernetes Cluster.\n$HELM_HOME has also been configured at %s.\nHappy Helming!\n", helmHome)
return nil
}
func installTiller() error {
// TODO: take value of global flag kubectl and pass that in // TODO: take value of global flag kubectl and pass that in
runner := buildKubectlRunner("") runner := buildKubectlRunner("")
i := client.NewInstaller() i := client.NewInstaller()
i.Tiller["Image"] = tillerImg i.Tiller["Image"] = tillerImg
out, err := i.Install(runner) out, err := i.Install(runner)
if err != nil { if err != nil {
return fmt.Errorf("error installing %s %s", string(out), err) return fmt.Errorf("error installing %s %s", string(out), err)
} }
fmt.Printf("Tiller (the helm server side component) has been installed into your Kubernetes Cluster.\n")
return nil return nil
} }
...@@ -55,3 +74,40 @@ func buildKubectlRunner(kubectlPath string) kubectl.Runner { ...@@ -55,3 +74,40 @@ func buildKubectlRunner(kubectlPath string) kubectl.Runner {
} }
return &kubectl.RealRunner{} return &kubectl.RealRunner{}
} }
// EnsureHome checks to see if $HELM_HOME exists
//
// If $HELM_HOME does not exist, this function will create it.
func EnsureHome(home string) error {
configDirectories := []string{home, CacheDirectory(home)}
for _, p := range configDirectories {
if fi, err := os.Stat(p); err != nil {
fmt.Printf("Creating %s \n", p)
if err := os.MkdirAll(p, 0755); err != nil {
return fmt.Errorf("Could not create %s: %s", p, err)
}
} else if !fi.IsDir() {
return fmt.Errorf("%s must be a directory.", p)
}
}
repoPath := RepositoriesFile(home)
if fi, err := os.Stat(repoPath); err != nil {
fmt.Printf("Creating %s \n", repoPath)
if err := ioutil.WriteFile(repoPath, []byte("test-charts: https://www.googleapis.com/storage/v1/b/test-charts/o\n"), 0644); err != nil {
return err
}
} else if fi.IsDir() {
return fmt.Errorf("%s must be a file, not a directory.", repoPath)
}
return nil
}
func CacheDirectory(home string) string {
return filepath.Join(home, cachePath)
}
func RepositoriesFile(home string) string {
return filepath.Join(home, repositoriesPath)
}
package main package main
import ( import (
"io/ioutil"
"os"
"testing" "testing"
) )
func TestInit(t *testing.T) { func TestEnsureHome(t *testing.T) {
//TODO: call command and make sure no error is returned home := CreateTmpHome()
//TODO: check local config if err := EnsureHome(home); err != nil {
t.Errorf("%s", err)
}
dirs := []string{home, CacheDirectory(home)}
for _, dir := range dirs {
if fi, err := os.Stat(dir); err != nil {
t.Errorf("%s", err)
} else if !fi.IsDir() {
t.Errorf("%s is not a directory", fi)
}
}
if fi, err := os.Stat(RepositoriesFile(home)); err != nil {
t.Errorf("%s", err)
} else if fi.IsDir() {
t.Errorf("%s should not be a directory", fi)
}
}
func CreateTmpHome() string {
tmpHome, _ := ioutil.TempDir("", "helm_home")
defer os.Remove(tmpHome)
return tmpHome
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment