From 0374c4f63d056df01c3e9e8cf4d77a6461169070 Mon Sep 17 00:00:00 2001 From: Erik Wilson Date: Wed, 29 Jan 2020 16:40:49 -0700 Subject: [PATCH] Add --disable flag --- pkg/cli/cmds/server.go | 8 +++-- pkg/cli/server/server.go | 20 ++++++----- pkg/daemons/config/types.go | 3 +- pkg/deploy/controller.go | 70 ++++++++++++++++++++++++++++++++++++- pkg/deploy/stage.go | 7 +--- pkg/server/server.go | 5 ++- 6 files changed, 91 insertions(+), 22 deletions(-) diff --git a/pkg/cli/cmds/server.go b/pkg/cli/cmds/server.go index 4178af2cd9..fd083cc908 100644 --- a/pkg/cli/cmds/server.go +++ b/pkg/cli/cmds/server.go @@ -193,8 +193,8 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command { Destination: &ServerConfig.DefaultLocalStoragePath, }, cli.StringSliceFlag{ - Name: "no-deploy", - Usage: "(components) Do not deploy packaged components (valid items: coredns, servicelb, traefik, local-storage, metrics-server)", + Name: "disable", + Usage: "(components) Do not deploy packaged components and delete any deployed components (valid items: coredns, servicelb, traefik, local-storage, metrics-server)", }, cli.BoolFlag{ Name: "disable-scheduler", @@ -272,6 +272,10 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command { // Hidden/Deprecated flags below FlannelFlag, + cli.StringSliceFlag{ + Name: "no-deploy", + Usage: "(deprecated) Do not deploy packaged components (valid items: coredns, servicelb, traefik, local-storage, metrics-server)", + }, cli.StringFlag{ Name: "cluster-secret", Usage: "(deprecated) use --token", diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index af435e6d3f..06afca8e11 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -151,19 +151,21 @@ func run(app *cli.Context, cfg *cmds.Server) error { serverConfig.ControlConfig.DefaultLocalStoragePath = cfg.DefaultLocalStoragePath } - noDeploys := make([]string, 0) + serverConfig.ControlConfig.Skips = map[string]bool{} for _, noDeploy := range app.StringSlice("no-deploy") { - for _, splitNoDeploy := range strings.Split(noDeploy, ",") { - noDeploys = append(noDeploys, splitNoDeploy) + for _, v := range strings.Split(noDeploy, ",") { + serverConfig.ControlConfig.Skips[v] = true } } - - for _, noDeploy := range noDeploys { - if noDeploy == "servicelb" { - serverConfig.DisableServiceLB = true - continue + serverConfig.ControlConfig.Disables = map[string]bool{} + for _, disable := range app.StringSlice("disable") { + for _, v := range strings.Split(disable, ",") { + serverConfig.ControlConfig.Skips[v] = true + serverConfig.ControlConfig.Disables[v] = true } - serverConfig.ControlConfig.Skips = append(serverConfig.ControlConfig.Skips, noDeploy) + } + if serverConfig.ControlConfig.Skips["servicelb"] { + serverConfig.DisableServiceLB = true } logrus.Info("Starting k3s ", app.App.Version) diff --git a/pkg/daemons/config/types.go b/pkg/daemons/config/types.go index eef6711776..d846d88e78 100644 --- a/pkg/daemons/config/types.go +++ b/pkg/daemons/config/types.go @@ -96,7 +96,8 @@ type Control struct { KubeConfigOutput string KubeConfigMode string DataDir string - Skips []string + Skips map[string]bool + Disables map[string]bool Datastore endpoint.Config NoScheduler bool ExtraAPIArgs []string diff --git a/pkg/deploy/controller.go b/pkg/deploy/controller.go index a111c81ecd..6b241281f3 100644 --- a/pkg/deploy/controller.go +++ b/pkg/deploy/controller.go @@ -22,8 +22,10 @@ import ( "github.com/rancher/wrangler/pkg/objectset" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" yamlDecoder "k8s.io/apimachinery/pkg/util/yaml" ) @@ -32,12 +34,13 @@ const ( startKey = "_start_" ) -func WatchFiles(ctx context.Context, apply apply.Apply, addons v1.AddonController, bases ...string) error { +func WatchFiles(ctx context.Context, apply apply.Apply, addons v1.AddonController, disables map[string]bool, bases ...string) error { w := &watcher{ apply: apply, addonCache: addons.Cache(), addons: addons, bases: bases, + disables: disables, } addons.Enqueue("", startKey) @@ -56,6 +59,7 @@ type watcher struct { addonCache v1.AddonCache addons v1.AddonClient bases []string + disables map[string]bool } func (w *watcher) start(ctx context.Context) { @@ -111,6 +115,12 @@ func (w *watcher) listFilesIn(base string, force bool) error { var errs []error for _, path := range keys { + if shouldDisableService(base, path, w.disables) { + if err := w.delete(path); err != nil { + errs = append(errs, errors2.Wrapf(err, "failed to delete %s", path)) + } + continue + } if skipFile(files[path].Name(), skips) { continue } @@ -162,6 +172,39 @@ func (w *watcher) deploy(path string, compareChecksum bool) error { return err } +func (w *watcher) delete(path string) error { + name := name(path) + addon, err := w.addon(name) + if err != nil { + return err + } + + // ensure that the addon is completely removed before deleting the objectSet, + // so return when err == nil, otherwise pods may get stuck terminating + if err := w.addons.Delete(addon.Namespace, addon.Name, &metav1.DeleteOptions{}); err == nil || !errors.IsNotFound(err) { + return err + } + + content, err := ioutil.ReadFile(path) + if err != nil { + return err + } + objectSet, err := objectSet(content) + if err != nil { + return err + } + var gvk []schema.GroupVersionKind + for k := range objectSet.ObjectsByGVK() { + gvk = append(gvk, k) + } + // apply an empty set with owner & gvk data to delete + if err := w.apply.WithOwner(&addon).WithGVK(gvk...).Apply(nil); err != nil { + return err + } + + return os.Remove(path) +} + func (w *watcher) addon(name string) (v12.Addon, error) { addon, err := w.addonCache.Get(ns, name) if errors.IsNotFound(err) { @@ -269,3 +312,28 @@ func skipFile(fileName string, skips map[string]bool) bool { return true } } + +func shouldDisableService(base, fileName string, disables map[string]bool) bool { + relFile := strings.TrimPrefix(fileName, base) + namePath := strings.Split(relFile, string(os.PathSeparator)) + for i := 1; i < len(namePath); i++ { + subPath := filepath.Join(namePath[0:i]...) + if disables[subPath] { + return true + } + } + switch { + case strings.HasSuffix(fileName, ".json"): + case strings.HasSuffix(fileName, ".yml"): + case strings.HasSuffix(fileName, ".yaml"): + default: + return false + } + baseFile := filepath.Base(fileName) + suffix := filepath.Ext(baseFile) + baseName := strings.TrimSuffix(baseFile, suffix) + if disables[baseName] { + return true + } + return false +} diff --git a/pkg/deploy/stage.go b/pkg/deploy/stage.go index 7818ff836d..1e8d109cf9 100644 --- a/pkg/deploy/stage.go +++ b/pkg/deploy/stage.go @@ -11,12 +11,7 @@ import ( "github.com/sirupsen/logrus" ) -func Stage(dataDir string, templateVars map[string]string, skipList []string) error { - skips := map[string]bool{} - for _, skip := range skipList { - skips[skip] = true - } - +func Stage(dataDir string, templateVars map[string]string, skips map[string]bool) error { staging: for _, name := range AssetNames() { nameNoExtension := strings.TrimSuffix(name, filepath.Ext(name)) diff --git a/pkg/server/server.go b/pkg/server/server.go index a43f5232fb..e0ca1a8f9e 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -27,7 +27,6 @@ import ( v1 "github.com/rancher/wrangler-api/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/pkg/leader" "github.com/rancher/wrangler/pkg/resolvehome" - "github.com/rancher/wrangler/pkg/slice" "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/net" @@ -127,7 +126,7 @@ func startWrangler(ctx context.Context, config *Config) error { } func masterControllers(ctx context.Context, sc *Context, config *Config) error { - if !slice.ContainsString(config.ControlConfig.Skips, "coredns") { + if !config.ControlConfig.Skips["coredns"] { if err := node.Register(ctx, sc.Core.Core().V1().ConfigMap(), sc.Core.Core().V1().Node()); err != nil { return err } @@ -176,7 +175,7 @@ func stageFiles(ctx context.Context, sc *Context, controlConfig *config.Control) return err } - return deploy.WatchFiles(ctx, sc.Apply, sc.K3s.K3s().V1().Addon(), dataDir) + return deploy.WatchFiles(ctx, sc.Apply, sc.K3s.K3s().V1().Addon(), controlConfig.Disables, dataDir) } func HomeKubeConfig(write, rootless bool) (string, error) {