Commit f763c88f authored by Adam Reese's avatar Adam Reese Committed by GitHub

Merge pull request #1786 from mortenlj/master

Add `--upgrade` option to `init`. Fixes #1782.
parents 6f023b32 eeaacc4a
...@@ -65,6 +65,7 @@ type initCmd struct { ...@@ -65,6 +65,7 @@ type initCmd struct {
image string image string
clientOnly bool clientOnly bool
canary bool canary bool
upgrade bool
namespace string namespace string
dryRun bool dryRun bool
out io.Writer out io.Writer
...@@ -94,6 +95,7 @@ func newInitCmd(out io.Writer) *cobra.Command { ...@@ -94,6 +95,7 @@ func newInitCmd(out io.Writer) *cobra.Command {
f := cmd.Flags() f := cmd.Flags()
f.StringVarP(&i.image, "tiller-image", "i", "", "override tiller image") f.StringVarP(&i.image, "tiller-image", "i", "", "override tiller image")
f.BoolVar(&i.canary, "canary-image", false, "use the canary tiller image") f.BoolVar(&i.canary, "canary-image", false, "use the canary tiller image")
f.BoolVar(&i.upgrade, "upgrade", false, "upgrade if tiller is already installed")
f.BoolVarP(&i.clientOnly, "client-only", "c", false, "if set does not install tiller") f.BoolVarP(&i.clientOnly, "client-only", "c", false, "if set does not install tiller")
f.BoolVar(&i.dryRun, "dry-run", false, "do not install local or remote") f.BoolVar(&i.dryRun, "dry-run", false, "do not install local or remote")
...@@ -130,7 +132,15 @@ func (i *initCmd) run() error { ...@@ -130,7 +132,15 @@ func (i *initCmd) run() error {
if !kerrors.IsAlreadyExists(err) { if !kerrors.IsAlreadyExists(err) {
return fmt.Errorf("error installing: %s", err) return fmt.Errorf("error installing: %s", err)
} }
fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster. (Use --client-only to suppress this message.)") if i.upgrade {
if err := installer.Upgrade(i.kubeClient, i.namespace, i.image, i.canary); err != nil {
return fmt.Errorf("error when upgrading: %s", err)
}
fmt.Fprintln(i.out, "\nTiller (the helm server side component) has been upgraded to the current version.")
} else {
fmt.Fprintln(i.out, "Warning: Tiller is already installed in the cluster.\n"+
"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)")
}
} else { } else {
fmt.Fprintln(i.out, "\nTiller (the helm server side component) has been installed into your Kubernetes Cluster.") fmt.Fprintln(i.out, "\nTiller (the helm server side component) has been installed into your Kubernetes Cluster.")
} }
......
...@@ -89,7 +89,8 @@ func TestInitCmd_exsits(t *testing.T) { ...@@ -89,7 +89,8 @@ func TestInitCmd_exsits(t *testing.T) {
if err := cmd.run(); err != nil { if err := cmd.run(); err != nil {
t.Errorf("expected error: %v", err) t.Errorf("expected error: %v", err)
} }
expected := "Warning: Tiller is already installed in the cluster. (Use --client-only to suppress this message.)" expected := "Warning: Tiller is already installed in the cluster.\n" +
"(Use --client-only to suppress this message, or --upgrade to upgrade Tiller to the current version.)"
if !strings.Contains(buf.String(), expected) { if !strings.Contains(buf.String(), expected) {
t.Errorf("expected %q, got %q", expected, buf.String()) t.Errorf("expected %q, got %q", expected, buf.String())
} }
......
...@@ -43,15 +43,32 @@ func Install(client extensionsclient.DeploymentsGetter, namespace, image string, ...@@ -43,15 +43,32 @@ func Install(client extensionsclient.DeploymentsGetter, namespace, image string,
return err return err
} }
// Upgrade uses kubernetes client to upgrade tiller to current version
//
// Returns an error if the command failed.
func Upgrade(client extensionsclient.DeploymentsGetter, namespace, image string, canary bool) error {
obj, err := client.Deployments(namespace).Get("tiller-deploy")
if err != nil {
return err
}
obj.Spec.Template.Spec.Containers[0].Image = selectImage(image, canary)
_, err = client.Deployments(namespace).Update(obj)
return err
}
// deployment gets the deployment object that installs Tiller. // deployment gets the deployment object that installs Tiller.
func deployment(namespace, image string, canary bool) *extensions.Deployment { func deployment(namespace, image string, canary bool) *extensions.Deployment {
return generateDeployment(namespace, selectImage(image, canary))
}
func selectImage(image string, canary bool) string {
switch { switch {
case canary: case canary:
image = defaultImage + ":canary" image = defaultImage + ":canary"
case image == "": case image == "":
image = fmt.Sprintf("%s:%s", defaultImage, version.Version) image = fmt.Sprintf("%s:%s", defaultImage, version.Version)
} }
return generateDeployment(namespace, image) return image
} }
// DeploymentManifest gets the manifest (as a string) that describes the Tiller Deployment // DeploymentManifest gets the manifest (as a string) that describes the Tiller Deployment
......
...@@ -103,3 +103,22 @@ func TestInstall_canary(t *testing.T) { ...@@ -103,3 +103,22 @@ func TestInstall_canary(t *testing.T) {
t.Errorf("unexpected error: %#+v", err) t.Errorf("unexpected error: %#+v", err)
} }
} }
func TestUpgrade(t *testing.T) {
image := "gcr.io/kubernetes-helm/tiller:v2.0.0"
fc := fake.NewSimpleClientset(deployment(api.NamespaceDefault, "imageToReplace", false))
fc.AddReactor("update", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
obj := action.(testcore.CreateAction).GetObject().(*extensions.Deployment)
i := obj.Spec.Template.Spec.Containers[0].Image
if i != image {
t.Errorf("expected image = '%s', got '%s'", image, i)
}
return true, obj, nil
})
err := Upgrade(fc.Extensions(), api.NamespaceDefault, image, false)
if err != nil {
t.Errorf("unexpected error: %#+v", err)
}
}
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