From 037d6d3f5480a6d698d3f92240f457ee8bfc8153 Mon Sep 17 00:00:00 2001 From: derailed Date: Thu, 14 May 2020 18:27:02 -0600 Subject: [PATCH] update deps - fix ns issues --- Dockerfile | 2 +- cmd/root.go | 1 - go.mod | 2 +- go.sum | 2 ++ internal/config/config.go | 17 +++++------------ internal/view/app.go | 28 ++++++++++++++++++++-------- internal/view/command.go | 13 ++++++++++++- internal/view/container.go | 11 +++-------- internal/view/exec.go | 12 ++++++++---- internal/view/pod.go | 28 +++++++++++++++++----------- internal/view/popeye.go | 9 +++++++-- internal/view/pvc.go | 32 ++++++++++++++++++++++++++++++++ internal/view/registrar.go | 3 +++ internal/watch/factory.go | 7 ------- main.go | 2 ++ 15 files changed, 113 insertions(+), 56 deletions(-) create mode 100644 internal/view/pvc.go diff --git a/Dockerfile b/Dockerfile index fa8c4186..4342f7dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ FROM alpine:3.10.0 COPY --from=build /k9s/execs/k9s /bin/k9s ENV KUBE_LATEST_VERSION="v1.18.1" RUN apk add --update ca-certificates \ - && apk add --update -t deps curl \ + && apk add --update -t deps curl vim \ && curl -L https://storage.googleapis.com/kubernetes-release/release/${KUBE_LATEST_VERSION}/bin/linux/amd64/kubectl -o /usr/local/bin/kubectl \ && chmod +x /usr/local/bin/kubectl \ && apk del --purge deps \ diff --git a/cmd/root.go b/cmd/root.go index 6b5794ff..420aa137 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -105,7 +105,6 @@ func loadConfiguration() *config.Config { log.Warn().Msg("Unable to locate K9s config. Generating new configuration...") } - log.Debug().Msgf("DEMO MODE %#v", demoMode) if demoMode != nil { k9sCfg.SetDemoMode(*demoMode) } diff --git a/go.mod b/go.mod index e9961927..d6354609 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.13 require ( github.com/atotto/clipboard v0.1.2 - github.com/derailed/popeye v0.8.1 + github.com/derailed/popeye v0.8.2 github.com/derailed/tview v0.3.10 github.com/drone/envsubst v1.0.2 // indirect github.com/fatih/color v1.9.0 diff --git a/go.sum b/go.sum index 144800ea..93d1eeec 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xb github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/derailed/popeye v0.8.1 h1:N69XH0NZTBkrNj8qvUzy6Z6bP7+jx0AwollETqvc3dc= github.com/derailed/popeye v0.8.1/go.mod h1:OBHcJDa50VpE9QNyOU243bNOtHb29MyLlVHJolwlwas= +github.com/derailed/popeye v0.8.2 h1:O4JcIC3MwJS9pNKb8ZHLUJKoLPZW0gfcMqFoSYYdbAs= +github.com/derailed/popeye v0.8.2/go.mod h1:i4ge2tKHDKXgUq3NzFlIhVIBNHS0zFDMJWXsC2bVe2A= github.com/derailed/tview v0.3.10 h1:n+iQwYh9Ff9STdR5hBhp+rTJRlu59q2xP2pHvwQbYPw= github.com/derailed/tview v0.3.10/go.mod h1:GJ3k/TIzEE+sj1L09/usk6HrkjsdadSsb03eHgPbcII= github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= diff --git a/internal/config/config.go b/internal/config/config.go index ed4bc780..f7095839 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -84,13 +84,13 @@ func (c *Config) Refine(flags *genericclioptions.ConfigFlags) error { if c.K9s.CurrentContext == "" { return errors.New("Invalid kubeconfig context detected") } - ctx, ok := cfg.Contexts[c.K9s.CurrentContext] + context, ok := cfg.Contexts[c.K9s.CurrentContext] if !ok { return fmt.Errorf("The specified context %q does not exists in kubeconfig", c.K9s.CurrentContext) } - c.K9s.CurrentCluster = ctx.Cluster - if len(ctx.Namespace) != 0 { - if err := c.SetActiveNamespace(ctx.Namespace); err != nil { + c.K9s.CurrentCluster = context.Cluster + if len(context.Namespace) != 0 { + if err := c.SetActiveNamespace(context.Namespace); err != nil { return err } } @@ -124,13 +124,6 @@ func (c *Config) CurrentCluster() *Cluster { // ActiveNamespace returns the active namespace in the current cluster. func (c *Config) ActiveNamespace() string { - if c.client != nil { - ns := c.client.ActiveNamespace() - if client.IsNamespaced(ns) { - return ns - } - } - if cl := c.CurrentCluster(); cl != nil { if cl.Namespace != nil { return cl.Namespace.Active @@ -162,9 +155,9 @@ func (c *Config) SetActiveNamespace(ns string) error { if c.K9s.ActiveCluster() != nil { return c.K9s.ActiveCluster().Namespace.SetActive(ns, c.settings) } - err := errors.New("no active cluster. unable to set active namespace") log.Error().Err(err).Msg("SetActiveNamespace") + return err } diff --git a/internal/view/app.go b/internal/view/app.go index 5561f1a0..c7f83590 100644 --- a/internal/view/app.go +++ b/internal/view/app.go @@ -88,8 +88,13 @@ func (a *App) Init(version string, rate int) error { return errors.New("No client connection detected") } ns, err := a.Conn().Config().CurrentNamespaceName() + log.Debug().Msgf("CURRENT-NS %q -- %v", ns, err) if err != nil { - log.Info().Msg("No namespace specified using all namespaces") + log.Info().Msg("No namespace specified using cluster default namespace") + } else { + if err := a.Config.SetActiveNamespace(ns); err != nil { + log.Error().Err(err).Msgf("Fail to set active namespace to %q", ns) + } } a.factory = watch.NewFactory(a.Conn()) @@ -111,6 +116,13 @@ func (a *App) Init(version string, rate int) error { a.CmdBuff().SetSuggestionFn(a.suggestCommand()) a.CmdBuff().AddListener(a) + a.layout(ctx, version) + a.initSignals() + + return nil +} + +func (a *App) layout(ctx context.Context, version string) { flash := ui.NewFlash(a.App) go flash.Watch(ctx, a.Flash().Channel()) @@ -123,10 +135,6 @@ func (a *App) Init(version string, rate int) error { a.Main.AddPage("main", main, true, false) a.Main.AddPage("splash", ui.NewSplash(a.Styles, version), true, true) a.toggleHeader(!a.Config.K9s.GetHeadless()) - - a.initSignals() - - return nil } func (a *App) initSignals() { @@ -134,8 +142,12 @@ func (a *App) initSignals() { signal.Notify(sig, syscall.SIGABRT, syscall.SIGINT, syscall.SIGHUP, syscall.SIGQUIT) go func(sig chan os.Signal) { - <-sig - nukeK9sShell(a.Conn()) + signal := <-sig + if signal == syscall.SIGHUP { + a.BailOut() + return + } + nukeK9sShell(a) }(sig) } @@ -375,7 +387,7 @@ func (a *App) BailOut() { } }() - nukeK9sShell(a.Conn()) + nukeK9sShell(a) a.factory.Terminate() a.App.BailOut() } diff --git a/internal/view/command.go b/internal/view/command.go index db3fac26..fdeeb571 100644 --- a/internal/view/command.go +++ b/internal/view/command.go @@ -158,7 +158,18 @@ func (c *Command) run(cmd, path string, clearStack bool) error { } func (c *Command) defaultCmd() error { - if err := c.run(c.app.Config.ActiveView(), "", true); err != nil { + view := c.app.Config.ActiveView() + if view == "" { + return c.run("pod", "", true) + } + tokens := strings.Split(view, " ") + cmd := view + ns, err := c.app.Conn().Config().CurrentNamespaceName() + if err == nil { + cmd = tokens[0] + " " + ns + } + + if err := c.run(cmd, "", true); err != nil { log.Error().Err(err).Msgf("Saved command load failed. Loading default view") return c.run("pod", "", true) } diff --git a/internal/view/container.go b/internal/view/container.go index 2f2993cb..d1b51e48 100644 --- a/internal/view/container.go +++ b/internal/view/container.go @@ -50,15 +50,10 @@ func (c *Container) bindKeys(aa ui.KeyActions) { } aa.Add(ui.KeyActions{ - ui.KeyShiftF: ui.NewKeyAction("PortForward", c.portFwdCmd, true), - ui.KeyShiftT: ui.NewKeyAction("Sort Restart", c.GetTable().SortColCmd("RESTARTS", false), false), - ui.KeyShiftC: ui.NewKeyAction("Sort CPU", c.GetTable().SortColCmd(cpuCol, false), false), - ui.KeyShiftM: ui.NewKeyAction("Sort MEM", c.GetTable().SortColCmd(memCol, false), false), - ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", c.GetTable().SortColCmd("%CPU/R", false), false), - ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", c.GetTable().SortColCmd("%MEM/R", false), false), - tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", c.GetTable().SortColCmd("%CPU/L", false), false), - tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", c.GetTable().SortColCmd("%MEM/L", false), false), + ui.KeyShiftF: ui.NewKeyAction("PortForward", c.portFwdCmd, true), + ui.KeyShiftT: ui.NewKeyAction("Sort Restart", c.GetTable().SortColCmd("RESTARTS", false), false), }) + aa.Add(resourceSorters(c.GetTable())) } func (c *Container) k9sEnv() Env { diff --git a/internal/view/exec.go b/internal/view/exec.go index b229bb13..444c2075 100644 --- a/internal/view/exec.go +++ b/internal/view/exec.go @@ -135,8 +135,8 @@ const ( ) func ssh(a *App, node string) error { - nukeK9sShell(a.Conn()) - defer nukeK9sShell(a.Conn()) + nukeK9sShell(a) + defer nukeK9sShell(a) if err := launchShellPod(a, node); err != nil { return err } @@ -145,11 +145,15 @@ func ssh(a *App, node string) error { return nil } -func nukeK9sShell(c client.Connection) { +func nukeK9sShell(a *App) { + cl := a.Config.K9s.CurrentCluster + if !a.Config.K9s.Clusters[cl].FeatureGates.NodeShell { + return + } ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond) defer cancel() - err := c.DialOrDie().CoreV1().Pods(k9sShellNS).Delete(ctx, k9sShellPodName(), metav1.DeleteOptions{}) + err := a.Conn().DialOrDie().CoreV1().Pods(k9sShellNS).Delete(ctx, k9sShellPodName(), metav1.DeleteOptions{}) if kerrors.IsNotFound(err) { return } diff --git a/internal/view/pod.go b/internal/view/pod.go index 90aa4cb4..00146ca0 100644 --- a/internal/view/pod.go +++ b/internal/view/pod.go @@ -52,18 +52,13 @@ func (p *Pod) bindKeys(aa ui.KeyActions) { } aa.Add(ui.KeyActions{ - ui.KeyShiftR: ui.NewKeyAction("Sort Ready", p.GetTable().SortColCmd(readyCol, true), false), - ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd("RESTARTS", false), false), - ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(statusCol, true), false), - ui.KeyShiftC: ui.NewKeyAction("Sort CPU", p.GetTable().SortColCmd(cpuCol, false), false), - ui.KeyShiftM: ui.NewKeyAction("Sort MEM", p.GetTable().SortColCmd(memCol, false), false), - ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", p.GetTable().SortColCmd("%CPU", false), false), - ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", p.GetTable().SortColCmd("%MEM", false), false), - tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", p.GetTable().SortColCmd("%CPU/L", false), false), - tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", p.GetTable().SortColCmd("%MEM/L", false), false), - ui.KeyShiftI: ui.NewKeyAction("Sort IP", p.GetTable().SortColCmd("IP", true), false), - ui.KeyShiftO: ui.NewKeyAction("Sort Node", p.GetTable().SortColCmd("NODE", true), false), + ui.KeyShiftR: ui.NewKeyAction("Sort Ready", p.GetTable().SortColCmd(readyCol, true), false), + ui.KeyShiftT: ui.NewKeyAction("Sort Restart", p.GetTable().SortColCmd("RESTARTS", false), false), + ui.KeyShiftS: ui.NewKeyAction("Sort Status", p.GetTable().SortColCmd(statusCol, true), false), + ui.KeyShiftI: ui.NewKeyAction("Sort IP", p.GetTable().SortColCmd("IP", true), false), + ui.KeyShiftO: ui.NewKeyAction("Sort Node", p.GetTable().SortColCmd("NODE", true), false), }) + aa.Add(resourceSorters(p.GetTable())) } func (p *Pod) selectedContainer() string { @@ -318,3 +313,14 @@ func podIsRunning(f dao.Factory, path string) bool { log.Debug().Msgf("Phase %#v", re.Phase(po)) return re.Phase(po) == render.Running } + +func resourceSorters(t *Table) ui.KeyActions { + return ui.KeyActions{ + ui.KeyShiftC: ui.NewKeyAction("Sort CPU", t.SortColCmd(cpuCol, false), false), + ui.KeyShiftM: ui.NewKeyAction("Sort MEM", t.SortColCmd(memCol, false), false), + ui.KeyShiftX: ui.NewKeyAction("Sort %CPU (REQ)", t.SortColCmd("%CPU/R", false), false), + ui.KeyShiftZ: ui.NewKeyAction("Sort %MEM (REQ)", t.SortColCmd("%MEM/R", false), false), + tcell.KeyCtrlX: ui.NewKeyAction("Sort %CPU (LIM)", t.SortColCmd("%CPU/L", false), false), + tcell.KeyCtrlQ: ui.NewKeyAction("Sort %MEM (LIM)", t.SortColCmd("%MEM/L", false), false), + } +} diff --git a/internal/view/popeye.go b/internal/view/popeye.go index e2999073..7992627e 100644 --- a/internal/view/popeye.go +++ b/internal/view/popeye.go @@ -53,8 +53,13 @@ func (p *Popeye) decorateRows(data render.TableData) render.TableData { } sum += n } - score := sum / len(data.RowEvents) - p.GetTable().Extras = fmt.Sprintf("Score %d -- %s", score, grade(score)) + score, letter := 0, render.NAValue + if len(data.RowEvents) > 0 { + score = sum / len(data.RowEvents) + letter = grade(score) + } + p.GetTable().Extras = fmt.Sprintf("Score %d -- %s", score, letter) + return data } diff --git a/internal/view/pvc.go b/internal/view/pvc.go new file mode 100644 index 00000000..6bb3c542 --- /dev/null +++ b/internal/view/pvc.go @@ -0,0 +1,32 @@ +package view + +import ( + "github.com/derailed/k9s/internal/client" + "github.com/derailed/k9s/internal/render" + "github.com/derailed/k9s/internal/ui" +) + +// PersistentVolumeClaim represents a PVC custom viewer. +type PersistentVolumeClaim struct { + ResourceViewer +} + +// NewPersistentVolumeClaim returns a new viewer. +func NewPersistentVolumeClaim(gvr client.GVR) ResourceViewer { + d := PersistentVolumeClaim{ + ResourceViewer: NewBrowser(gvr), + } + d.SetBindKeysFn(d.bindKeys) + d.GetTable().SetColorerFn(render.PersistentVolumeClaim{}.ColorerFunc()) + + return &d +} + +func (d *PersistentVolumeClaim) bindKeys(aa ui.KeyActions) { + aa.Add(ui.KeyActions{ + ui.KeyShiftS: ui.NewKeyAction("Sort Status", d.GetTable().SortColCmd("STATUS", true), false), + ui.KeyShiftV: ui.NewKeyAction("Sort Volume", d.GetTable().SortColCmd("VOLUME", true), false), + ui.KeyShiftO: ui.NewKeyAction("Sort StorageClass", d.GetTable().SortColCmd("STORAGECLASS", true), false), + ui.KeyShiftC: ui.NewKeyAction("Sort Capacity", d.GetTable().SortColCmd("CAPACITY", true), false), + }) +} diff --git a/internal/view/registrar.go b/internal/view/registrar.go index b2979686..cfeb4922 100644 --- a/internal/view/registrar.go +++ b/internal/view/registrar.go @@ -45,6 +45,9 @@ func coreViewers(vv MetaViewers) { vv[client.NewGVR("v1/secrets")] = MetaViewer{ viewerFn: NewSecret, } + vv[client.NewGVR("v1/persistentvolumeclaims")] = MetaViewer{ + viewerFn: NewPersistentVolumeClaim, + } } func miscViewers(vv MetaViewers) { diff --git a/internal/watch/factory.go b/internal/watch/factory.go index 23e33298..e2d6cc2d 100644 --- a/internal/watch/factory.go +++ b/internal/watch/factory.go @@ -163,13 +163,6 @@ func (f *Factory) isClusterWide() bool { // CanForResource return an informer is user has access. func (f *Factory) CanForResource(ns, gvr string, verbs []string) (informers.GenericInformer, error) { - // If user can access resource cluster wide, prefer cluster wide factory. - if !client.IsClusterWide(ns) { - auth, err := f.Client().CanI(client.AllNamespaces, gvr, verbs) - if auth && err == nil { - return f.ForResource(client.AllNamespaces, gvr), nil - } - } auth, err := f.Client().CanI(ns, gvr, verbs) if err != nil { return nil, err diff --git a/main.go b/main.go index a040a539..77751e55 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,8 @@ package main import ( "os" + _ "net/http/pprof" + "github.com/derailed/k9s/cmd" "github.com/derailed/k9s/internal/config" "github.com/rs/zerolog"