mirror of
https://github.com/helm/helm.git
synced 2026-03-28 21:35:17 -04:00
helm init --upgrade will downgrade (#2805)
* Don't downgrade tiller with helm init --upgrade unless --force-upgrade is specified Fix tests after merging master * Reformatting with gofmt
This commit is contained in:
parent
70192cda1a
commit
fa06dd176d
5 changed files with 87 additions and 2 deletions
|
|
@ -76,6 +76,7 @@ type initCmd struct {
|
|||
upgrade bool
|
||||
namespace string
|
||||
dryRun bool
|
||||
forceUpgrade bool
|
||||
skipRefresh bool
|
||||
out io.Writer
|
||||
home helmpath.Home
|
||||
|
|
@ -106,6 +107,7 @@ func newInitCmd(out io.Writer) *cobra.Command {
|
|||
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.upgrade, "upgrade", false, "upgrade if Tiller is already installed")
|
||||
f.BoolVar(&i.forceUpgrade, "force-upgrade", false, "force upgrade of Tiller to the current helm version")
|
||||
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.skipRefresh, "skip-refresh", false, "do not refresh (download) the local repository cache")
|
||||
|
|
@ -164,6 +166,7 @@ func (i *initCmd) run() error {
|
|||
i.opts.Namespace = i.namespace
|
||||
i.opts.UseCanary = i.canary
|
||||
i.opts.ImageSpec = i.image
|
||||
i.opts.ForceUpgrade = i.forceUpgrade
|
||||
i.opts.ServiceAccount = i.serviceAccount
|
||||
i.opts.MaxHistory = i.maxHistory
|
||||
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ limitations under the License.
|
|||
package installer // import "k8s.io/helm/cmd/helm/installer"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"strings"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/ghodss/yaml"
|
||||
"k8s.io/api/core/v1"
|
||||
"k8s.io/api/extensions/v1beta1"
|
||||
|
|
@ -30,6 +32,7 @@ import (
|
|||
"k8s.io/client-go/kubernetes"
|
||||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
extensionsclient "k8s.io/client-go/kubernetes/typed/extensions/v1beta1"
|
||||
"k8s.io/helm/pkg/version"
|
||||
|
||||
"k8s.io/helm/pkg/chartutil"
|
||||
)
|
||||
|
|
@ -60,6 +63,10 @@ func Upgrade(client kubernetes.Interface, opts *Options) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
existingImage := obj.Spec.Template.Spec.Containers[0].Image
|
||||
if !isNewerVersion(existingImage) && !opts.ForceUpgrade {
|
||||
return errors.New("current Tiller version is newer, use --force-upgrade to downgrade")
|
||||
}
|
||||
obj.Spec.Template.Spec.Containers[0].Image = opts.selectImage()
|
||||
obj.Spec.Template.Spec.Containers[0].ImagePullPolicy = opts.pullPolicy()
|
||||
obj.Spec.Template.Spec.ServiceAccountName = opts.ServiceAccount
|
||||
|
|
@ -75,6 +82,17 @@ func Upgrade(client kubernetes.Interface, opts *Options) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// isNewerVersion returns whether the current version is newer than the give image's version
|
||||
func isNewerVersion(image string) bool {
|
||||
split := strings.Split(image, ":")
|
||||
if len(split) < 2 {
|
||||
// If we don't know the version, we consider the current version newer
|
||||
return true
|
||||
}
|
||||
imageVersion := split[1]
|
||||
return semver.MustParse(version.Version).GreaterThan(semver.MustParse(imageVersion))
|
||||
}
|
||||
|
||||
// createDeployment creates the Tiller Deployment resource.
|
||||
func createDeployment(client extensionsclient.DeploymentsGetter, opts *Options) error {
|
||||
obj, err := deployment(opts)
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ func TestUpgrade(t *testing.T) {
|
|||
serviceAccount := "newServiceAccount"
|
||||
existingDeployment, _ := deployment(&Options{
|
||||
Namespace: v1.NamespaceDefault,
|
||||
ImageSpec: "imageToReplace",
|
||||
ImageSpec: "imageToReplace:v1.0.0",
|
||||
ServiceAccount: "serviceAccountToReplace",
|
||||
UseCanary: false,
|
||||
})
|
||||
|
|
@ -416,6 +416,66 @@ func TestUpgrade_serviceNotFound(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestUgrade_newerVersion(t *testing.T) {
|
||||
image := "gcr.io/kubernetes-helm/tiller:v2.0.0"
|
||||
serviceAccount := "newServiceAccount"
|
||||
existingDeployment, _ := deployment(&Options{
|
||||
Namespace: v1.NamespaceDefault,
|
||||
ImageSpec: "imageToReplace:v100.5.0",
|
||||
ServiceAccount: "serviceAccountToReplace",
|
||||
UseCanary: false,
|
||||
})
|
||||
existingService := service(v1.NamespaceDefault)
|
||||
|
||||
fc := &fake.Clientset{}
|
||||
fc.AddReactor("get", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||
return true, existingDeployment, nil
|
||||
})
|
||||
fc.AddReactor("update", "deployments", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||
obj := action.(testcore.UpdateAction).GetObject().(*v1beta1.Deployment)
|
||||
i := obj.Spec.Template.Spec.Containers[0].Image
|
||||
if i != image {
|
||||
t.Errorf("expected image = '%s', got '%s'", image, i)
|
||||
}
|
||||
sa := obj.Spec.Template.Spec.ServiceAccountName
|
||||
if sa != serviceAccount {
|
||||
t.Errorf("expected serviceAccountName = '%s', got '%s'", serviceAccount, sa)
|
||||
}
|
||||
return true, obj, nil
|
||||
})
|
||||
fc.AddReactor("get", "services", func(action testcore.Action) (bool, runtime.Object, error) {
|
||||
return true, existingService, nil
|
||||
})
|
||||
|
||||
opts := &Options{
|
||||
Namespace: v1.NamespaceDefault,
|
||||
ImageSpec: image,
|
||||
ServiceAccount: serviceAccount,
|
||||
ForceUpgrade: false,
|
||||
}
|
||||
if err := Upgrade(fc, opts); err == nil {
|
||||
t.Errorf("Expected error because the deployed version is newer")
|
||||
}
|
||||
|
||||
if actions := fc.Actions(); len(actions) != 1 {
|
||||
t.Errorf("unexpected actions: %v, expected 1 action got %d", actions, len(actions))
|
||||
}
|
||||
|
||||
opts = &Options{
|
||||
Namespace: v1.NamespaceDefault,
|
||||
ImageSpec: image,
|
||||
ServiceAccount: serviceAccount,
|
||||
ForceUpgrade: true,
|
||||
}
|
||||
if err := Upgrade(fc, opts); err != nil {
|
||||
t.Errorf("unexpected error: %#+v", err)
|
||||
}
|
||||
|
||||
if actions := fc.Actions(); len(actions) != 4 {
|
||||
t.Errorf("unexpected actions: %v, expected 4 action got %d", actions, len(actions))
|
||||
}
|
||||
}
|
||||
|
||||
func tlsTestFile(t *testing.T, path string) string {
|
||||
const tlsTestDir = "../../../testdata"
|
||||
path = filepath.Join(tlsTestDir, path)
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ type Options struct {
|
|||
// ServiceAccount is the Kubernetes service account to add to Tiller.
|
||||
ServiceAccount string
|
||||
|
||||
// Force allows to force upgrading tiller if deployed version is greater than current version
|
||||
ForceUpgrade bool
|
||||
|
||||
// ImageSpec indentifies the image Tiller will use when deployed.
|
||||
//
|
||||
// Valid if and only if UseCanary is false.
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ helm init
|
|||
--canary-image use the canary Tiller image
|
||||
-c, --client-only if set does not install Tiller
|
||||
--dry-run do not install local or remote
|
||||
--force-upgrade force upgrade of Tiller to the current helm version
|
||||
--history-max int limit the maximum number of revisions saved per release. Use 0 for no limit.
|
||||
--local-repo-url string URL for local repository (default "http://127.0.0.1:8879/charts")
|
||||
--net-host install Tiller with net=host
|
||||
|
|
@ -68,4 +69,4 @@ helm init
|
|||
### SEE ALSO
|
||||
* [helm](helm.md) - The Helm package manager for Kubernetes.
|
||||
|
||||
###### Auto generated by spf13/cobra on 7-Nov-2017
|
||||
###### Auto generated by spf13/cobra on 9-Jan-2018
|
||||
|
|
|
|||
Loading…
Reference in a new issue