worked on logs + ansi support + bugs
parent
0b0a723c68
commit
f0a0c8f06d
|
|
@ -141,10 +141,11 @@ K9s uses aliases to navigate most K8s resources.
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
|
|
||||||
This initial drop is brittle. K9s will most likely blow up if...
|
This initial drop is brittle. K9s will most likely blow up...
|
||||||
|
|
||||||
|
1. You're running older versions of Kubernetes. K9s works best Kubernetes 1.10+
|
||||||
1. You don't have enough RBAC fu to manage your cluster
|
1. You don't have enough RBAC fu to manage your cluster
|
||||||
2. Your cluster does not run a metric server.
|
1. Your cluster does not run a metric server.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
# Release v0.2.2
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Thank you to all that contributed with flushing out issues with K9s! I'll try
|
||||||
|
to mark some of these issues as fixed. But if you don't mind grab the latest
|
||||||
|
rev and see if we're happier with some of the fixes!
|
||||||
|
|
||||||
|
If you've filed an issue please help me verify and close.
|
||||||
|
|
||||||
|
Thank you so much for your support!!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Change Logs
|
||||||
|
|
||||||
|
+ [Feature #98](https://github.com/derailed/k9s/issues/98) Pod view with node name.
|
||||||
|
+ [Feature #29](https://github.com/derailed/k9s/issues/29) Support ANSI colors in logs.
|
||||||
|
+ [Feature #105](https://github.com/derailed/k9s/issues/29) [Experimental] Add support for manual refresh.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resolved Bugs
|
||||||
|
|
||||||
|
+ [Issue #102](https://github.com/derailed/k9s/issues/102)
|
||||||
|
+ [Issue #104](https://github.com/derailed/k9s/issues/104)
|
||||||
3
go.mod
3
go.mod
|
|
@ -23,7 +23,8 @@ require (
|
||||||
github.com/onsi/gomega v1.4.3 // indirect
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
github.com/petergtz/pegomock v0.0.0-20181206220228-b113d17a7e81
|
github.com/petergtz/pegomock v0.0.0-20181206220228-b113d17a7e81
|
||||||
github.com/sirupsen/logrus v1.3.0
|
github.com/rs/zerolog v1.12.0
|
||||||
|
github.com/sirupsen/logrus v1.3.0 // indirect
|
||||||
github.com/spf13/cobra v0.0.3
|
github.com/spf13/cobra v0.0.3
|
||||||
github.com/spf13/pflag v1.0.3 // indirect
|
github.com/spf13/pflag v1.0.3 // indirect
|
||||||
github.com/stretchr/testify v1.2.2
|
github.com/stretchr/testify v1.2.2
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -98,6 +98,8 @@ github.com/prometheus/common v0.0.0-20181218105931-67670fe90761/go.mod h1:daVV7q
|
||||||
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
github.com/rivo/tview v0.0.0-20190213202703-b373355e9db4/go.mod h1:J4W+hErFfITUbyFAEXizpmkuxX7ZN56dopxHB4XQhMw=
|
github.com/rivo/tview v0.0.0-20190213202703-b373355e9db4/go.mod h1:J4W+hErFfITUbyFAEXizpmkuxX7ZN56dopxHB4XQhMw=
|
||||||
|
github.com/rs/zerolog v1.12.0 h1:aqZ1XRadoS8IBknR5IDFvGzbHly1X9ApIqOroooQF/c=
|
||||||
|
github.com/rs/zerolog v1.12.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
github.com/sirupsen/logrus v1.3.0 h1:hI/7Q+DtNZ2kINb6qt/lS+IyXnHQe9e90POfeewL/ME=
|
||||||
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||||
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
github.com/spf13/cobra v0.0.3 h1:ZlrZ4XsMRm04Fr5pSFxBgfND2EBVa1nLpiy1stUsX/8=
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"github.com/derailed/k9s/internal/config"
|
"github.com/derailed/k9s/internal/config"
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
"github.com/derailed/k9s/internal/views"
|
"github.com/derailed/k9s/internal/views"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
@ -55,7 +56,7 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func initK9s() {
|
func initK9s() {
|
||||||
log.Info("🐶 K9s starting up...")
|
log.Info().Msg("🐶 K9s starting up...")
|
||||||
|
|
||||||
// Load K9s config file...
|
// Load K9s config file...
|
||||||
cfg := k8s.NewConfig(k8sFlags)
|
cfg := k8s.NewConfig(k8sFlags)
|
||||||
|
|
@ -64,14 +65,14 @@ func initK9s() {
|
||||||
|
|
||||||
// Init K8s connection...
|
// Init K8s connection...
|
||||||
k8s.InitConnectionOrDie(cfg)
|
k8s.InitConnectionOrDie(cfg)
|
||||||
log.Info("✅ Kubernetes connectivity")
|
log.Info().Msg("✅ Kubernetes connectivity")
|
||||||
|
|
||||||
config.Root.Save()
|
config.Root.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initK9sConfig() {
|
func initK9sConfig() {
|
||||||
if err := config.Root.Load(config.K9sConfigFile); err != nil {
|
if err := config.Root.Load(config.K9sConfigFile); err != nil {
|
||||||
log.Warnf("Unable to locate K9s config. Generating new configuration...")
|
log.Warn().Msg("Unable to locate K9s config. Generating new configuration...")
|
||||||
}
|
}
|
||||||
config.Root.K9s.RefreshRate = refreshRate
|
config.Root.K9s.RefreshRate = refreshRate
|
||||||
|
|
||||||
|
|
@ -93,7 +94,7 @@ func initK9sConfig() {
|
||||||
config.Root.SetActiveNamespace(cfg.Contexts[ctx].Namespace)
|
config.Root.SetActiveNamespace(cfg.Contexts[ctx].Namespace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log.Debugf("Active Context `%v`", ctx)
|
log.Debug().Msgf("Active Context `%v`", ctx)
|
||||||
|
|
||||||
if isSet(k8sFlags.Namespace) {
|
if isSet(k8sFlags.Namespace) {
|
||||||
config.Root.SetActiveNamespace(*k8sFlags.Namespace)
|
config.Root.SetActiveNamespace(*k8sFlags.Namespace)
|
||||||
|
|
@ -120,16 +121,27 @@ func isSet(s *string) bool {
|
||||||
// Execute root command
|
// Execute root command
|
||||||
func Execute() {
|
func Execute() {
|
||||||
if err := rootCmd.Execute(); err != nil {
|
if err := rootCmd.Execute(); err != nil {
|
||||||
log.Panic(err)
|
log.Panic().Err(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseLevel(level string) zerolog.Level {
|
||||||
|
switch level {
|
||||||
|
case "debug":
|
||||||
|
return zerolog.DebugLevel
|
||||||
|
case "warn":
|
||||||
|
return zerolog.WarnLevel
|
||||||
|
case "error":
|
||||||
|
return zerolog.ErrorLevel
|
||||||
|
case "fatal":
|
||||||
|
return zerolog.FatalLevel
|
||||||
|
default:
|
||||||
|
return zerolog.InfoLevel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func run(cmd *cobra.Command, args []string) {
|
func run(cmd *cobra.Command, args []string) {
|
||||||
level, err := log.ParseLevel(logLevel)
|
zerolog.SetGlobalLevel(parseLevel(logLevel))
|
||||||
if err != nil {
|
|
||||||
level = log.DebugLevel
|
|
||||||
}
|
|
||||||
log.SetLevel(level)
|
|
||||||
|
|
||||||
initK9s()
|
initK9s()
|
||||||
|
|
||||||
|
|
@ -140,7 +152,7 @@ func run(cmd *cobra.Command, args []string) {
|
||||||
clearScreen()
|
clearScreen()
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
app.Stop()
|
app.Stop()
|
||||||
fmt.Println(err)
|
log.Error().Msgf("Boom! %#v", err)
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
"gopkg.in/yaml.v2"
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -76,11 +76,11 @@ func (c *Config) FavNamespaces() []string {
|
||||||
|
|
||||||
// SetActiveNamespace set the active namespace in the current cluster.
|
// SetActiveNamespace set the active namespace in the current cluster.
|
||||||
func (c *Config) SetActiveNamespace(ns string) error {
|
func (c *Config) SetActiveNamespace(ns string) error {
|
||||||
log.Debugf("Setting active namespace `%s", ns)
|
log.Debug().Msgf("Setting active namespace `%s", ns)
|
||||||
if c.K9s.ActiveCluster() != nil {
|
if c.K9s.ActiveCluster() != nil {
|
||||||
return c.K9s.ActiveCluster().Namespace.SetActive(ns, c.settings)
|
return c.K9s.ActiveCluster().Namespace.SetActive(ns, c.settings)
|
||||||
}
|
}
|
||||||
log.Error("Doh! no active cluster. unable to set active namespace")
|
log.Error().Msg("Doh! no active cluster. unable to set active namespace")
|
||||||
return fmt.Errorf("no active cluster. unable to set active namespace")
|
return fmt.Errorf("no active cluster. unable to set active namespace")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ func (c *Config) Load(path string) error {
|
||||||
|
|
||||||
// Save configuration to disk.
|
// Save configuration to disk.
|
||||||
func (c *Config) Save() error {
|
func (c *Config) Save() error {
|
||||||
log.Debugf("[Config] Saving configuration...")
|
log.Debug().Msg("[Config] Saving configuration...")
|
||||||
c.Validate()
|
c.Validate()
|
||||||
return c.SaveFile(K9sConfigFile)
|
return c.SaveFile(K9sConfigFile)
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ func (c *Config) SaveFile(path string) error {
|
||||||
EnsurePath(path, DefaultDirMod)
|
EnsurePath(path, DefaultDirMod)
|
||||||
cfg, err := yaml.Marshal(c)
|
cfg, err := yaml.Marshal(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("[Config] Unable to save K9s config file: %v", err)
|
log.Error().Msgf("[Config] Unable to save K9s config file: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ioutil.WriteFile(path, cfg, 0644)
|
return ioutil.WriteFile(path, cfg, 0644)
|
||||||
|
|
@ -140,9 +140,9 @@ func (c *Config) Validate() {
|
||||||
|
|
||||||
// Dump debug...
|
// Dump debug...
|
||||||
func (c *Config) Dump(msg string) {
|
func (c *Config) Dump(msg string) {
|
||||||
log.Debug(msg)
|
log.Debug().Msg(msg)
|
||||||
log.Debugf("Current Context: %s\n", c.K9s.CurrentCluster)
|
log.Debug().Msgf("Current Context: %s\n", c.K9s.CurrentCluster)
|
||||||
for k, cl := range c.K9s.Clusters {
|
for k, cl := range c.K9s.Clusters {
|
||||||
log.Debugf("K9s cluster: %s -- %s\n", k, cl.Namespace)
|
log.Debug().Msgf("K9s cluster: %s -- %s\n", k, cl.Namespace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,14 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/config"
|
"github.com/derailed/k9s/internal/config"
|
||||||
m "github.com/petergtz/pegomock"
|
m "github.com/petergtz/pegomock"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigValidate(t *testing.T) {
|
func TestConfigValidate(t *testing.T) {
|
||||||
setup(t)
|
setup(t)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ func EnsurePath(path string, mod os.FileMode) {
|
||||||
dir := filepath.Dir(path)
|
dir := filepath.Dir(path)
|
||||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
||||||
if err = os.Mkdir(dir, mod); err != nil {
|
if err = os.Mkdir(dir, mod); err != nil {
|
||||||
log.Errorf("Unable to create K9s home config dir: %v", err)
|
log.Error().Msgf("Unable to create K9s home config dir: %v", err)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -27,20 +27,20 @@ func NewNamespace() *Namespace {
|
||||||
|
|
||||||
// Validate a namespace is setup correctly
|
// Validate a namespace is setup correctly
|
||||||
func (n *Namespace) Validate(ks KubeSettings) {
|
func (n *Namespace) Validate(ks KubeSettings) {
|
||||||
log.Debug("Validating favorites...", n.Active)
|
log.Debug().Msgf("Validating favorites... %s", n.Active)
|
||||||
nn, err := ks.NamespaceNames()
|
nn, err := ks.NamespaceNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !n.isAllNamespace() && !InList(nn, n.Active) {
|
if !n.isAllNamespace() && !InList(nn, n.Active) {
|
||||||
log.Debugf("[Config] Validation error active namespace resetting to `default")
|
log.Debug().Msg("[Config] Validation error active namespace resetting to `default")
|
||||||
n.Active = defaultNS
|
n.Active = defaultNS
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ns := range n.Favorites {
|
for _, ns := range n.Favorites {
|
||||||
if ns != allNS && !InList(nn, ns) {
|
if ns != allNS && !InList(nn, ns) {
|
||||||
log.Debugf("[Config] Invalid favorite found '%s' - %t", ns, n.isAllNamespace())
|
log.Debug().Msgf("[Config] Invalid favorite found '%s' - %t", ns, n.isAllNamespace())
|
||||||
n.rmFavNS(ns)
|
n.rmFavNS(ns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ func (n *Namespace) Validate(ks KubeSettings) {
|
||||||
|
|
||||||
// SetActive set the active namespace.
|
// SetActive set the active namespace.
|
||||||
func (n *Namespace) SetActive(ns string, ks KubeSettings) error {
|
func (n *Namespace) SetActive(ns string, ks KubeSettings) error {
|
||||||
log.Debug("Setting active ns ", ns)
|
log.Debug().Msgf("Setting active ns %s", ns)
|
||||||
n.Active = ns
|
n.Active = ns
|
||||||
n.addFavNS(ns)
|
n.addFavNS(ns)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
|
@ -239,7 +239,7 @@ func (c *Config) ConfigAccess() (clientcmd.ConfigAccess, error) {
|
||||||
// RawConfig fetch the current kubeconfig with no overrides.
|
// RawConfig fetch the current kubeconfig with no overrides.
|
||||||
func (c *Config) RawConfig() (clientcmdapi.Config, error) {
|
func (c *Config) RawConfig() (clientcmdapi.Config, error) {
|
||||||
if c.rawConfig != nil && c.rawConfig.CurrentContext != c.currentContext {
|
if c.rawConfig != nil && c.rawConfig.CurrentContext != c.currentContext {
|
||||||
log.Debugf("Context swith detected...")
|
log.Debug().Msg("Context swith detected...")
|
||||||
c.currentContext = c.rawConfig.CurrentContext
|
c.currentContext = c.rawConfig.CurrentContext
|
||||||
c.reset()
|
c.reset()
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +248,7 @@ func (c *Config) RawConfig() (clientcmdapi.Config, error) {
|
||||||
if err := c.configFromFlags(); err != nil {
|
if err := c.configFromFlags(); err != nil {
|
||||||
return clientcmdapi.Config{}, err
|
return clientcmdapi.Config{}, err
|
||||||
}
|
}
|
||||||
log.Debugf("Reloading RawConfig...")
|
log.Debug().Msg("Reloading RawConfig...")
|
||||||
cfg, err := c.clientConfig.RawConfig()
|
cfg, err := c.clientConfig.RawConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cfg, err
|
return cfg, err
|
||||||
|
|
@ -269,7 +269,7 @@ func (c *Config) RESTConfig() (*restclient.Config, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.restConfig, err
|
return c.restConfig, err
|
||||||
}
|
}
|
||||||
log.Debugf("Connecting to API Server %s", c.restConfig.Host)
|
log.Debug().Msgf("Connecting to API Server %s", c.restConfig.Host)
|
||||||
}
|
}
|
||||||
return c.restConfig, nil
|
return c.restConfig, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,15 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
zerolog.SetGlobalLevel(zerolog.FatalLevel)
|
||||||
|
}
|
||||||
|
|
||||||
func TestConfigCurrentContext(t *testing.T) {
|
func TestConfigCurrentContext(t *testing.T) {
|
||||||
name, kubeConfig := "blee", "./assets/config"
|
name, kubeConfig := "blee", "./assets/config"
|
||||||
uu := []struct {
|
uu := []struct {
|
||||||
|
|
@ -78,7 +83,6 @@ func TestConfigCurrentNamespace(t *testing.T) {
|
||||||
for _, u := range uu {
|
for _, u := range uu {
|
||||||
cfg := k8s.NewConfig(u.flags)
|
cfg := k8s.NewConfig(u.flags)
|
||||||
ns, err := cfg.CurrentNamespaceName()
|
ns, err := cfg.CurrentNamespaceName()
|
||||||
fmt.Println("CRap", ns, err)
|
|
||||||
assert.Equal(t, u.err, err)
|
assert.Equal(t, u.err, err)
|
||||||
assert.Equal(t, u.namespace, ns)
|
assert.Equal(t, u.namespace, ns)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,5 +38,5 @@ func (*HPA) List(ns string) (Collection, error) {
|
||||||
// Delete a service
|
// Delete a service
|
||||||
func (*HPA) Delete(ns, n string) error {
|
func (*HPA) Delete(ns, n string) error {
|
||||||
opts := metav1.DeleteOptions{}
|
opts := metav1.DeleteOptions{}
|
||||||
return conn.dialOrDie().Autoscaling().HorizontalPodAutoscalers(ns).Delete(n, &opts)
|
return conn.dialOrDie().AutoscalingV2beta2().HorizontalPodAutoscalers(ns).Delete(n, &opts)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
|
@ -53,7 +53,7 @@ func (j *Job) Containers(ns, n string, includeInit bool) ([]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Debug("Containers found assoc pod", pod)
|
log.Debug().Msgf("Containers found assoc pod %v", pod)
|
||||||
return NewPod().(Loggable).Containers(ns, pod, includeInit)
|
return NewPod().(Loggable).Containers(ns, pod, includeInit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -63,7 +63,6 @@ func (j *Job) Logs(ns, n, co string, lines int64, prev bool) *restclient.Request
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Println("Logs found assoc pod", pod)
|
|
||||||
return NewPod().(Loggable).Logs(ns, pod, co, lines, prev)
|
return NewPod().(Loggable).Logs(ns, pod, co, lines, prev)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package k8s
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
|
@ -73,7 +73,7 @@ func (r *Resource) getClient() *rest.RESTClient {
|
||||||
crConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: codecs}
|
crConfig.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: codecs}
|
||||||
crRestClient, err := rest.RESTClientFor(&crConfig)
|
crRestClient, err := rest.RESTClientFor(&crConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal().Err(err)
|
||||||
}
|
}
|
||||||
return crRestClient
|
return crRestClient
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions/printers"
|
"k8s.io/cli-runtime/pkg/genericclioptions/printers"
|
||||||
|
|
@ -103,7 +103,7 @@ func (*Base) marshalObject(o runtime.Object) (string, error) {
|
||||||
)
|
)
|
||||||
err := p.PrintObj(o, &buff)
|
err := p.PrintObj(o, &buff)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Marshal Error %v", err)
|
log.Error().Msgf("Marshal Error %v", err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
return buff.String(), nil
|
return buff.String(), nil
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SwitchableRes represents a resource that can be switched.
|
// SwitchableRes represents a resource that can be switched.
|
||||||
|
|
@ -52,7 +52,7 @@ func (r *Context) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(k8s.NamedContext)
|
ii := i.(k8s.NamedContext)
|
||||||
c.instance = &ii
|
c.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown context type %#v", i)
|
log.Fatal().Msgf("unknown context type %#v", i)
|
||||||
}
|
}
|
||||||
c.path = c.instance.Name
|
c.path = c.instance.Name
|
||||||
return c
|
return c
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/rbac/v1"
|
v1 "k8s.io/api/rbac/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (r *ClusterRole) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.ClusterRole)
|
ii := i.(v1.ClusterRole)
|
||||||
c.instance = &ii
|
c.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown context type %#v", i)
|
log.Fatal().Msgf("unknown context type %#v", i)
|
||||||
}
|
}
|
||||||
c.path = c.instance.Name
|
c.path = c.instance.Name
|
||||||
return c
|
return c
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/rbac/v1"
|
v1 "k8s.io/api/rbac/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (r *ClusterRoleBinding) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.ClusterRoleBinding)
|
ii := i.(v1.ClusterRoleBinding)
|
||||||
c.instance = &ii
|
c.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown context type %#v", i)
|
log.Fatal().Msgf("unknown context type %#v", i)
|
||||||
}
|
}
|
||||||
c.path = c.instance.Name
|
c.path = c.instance.Name
|
||||||
return c
|
return c
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
@ -52,7 +52,7 @@ func (r *CRD) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(unstructured.Unstructured)
|
ii := i.(unstructured.Unstructured)
|
||||||
c.instance = &ii
|
c.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("unknown context type %#v", i)
|
log.Fatal().Msgf("unknown context type %#v", i)
|
||||||
}
|
}
|
||||||
meta := c.instance.Object["metadata"].(map[string]interface{})
|
meta := c.instance.Object["metadata"].(map[string]interface{})
|
||||||
c.path = meta["name"].(string)
|
c.path = meta["name"].(string)
|
||||||
|
|
@ -90,7 +90,7 @@ func (r *CRD) Fields(ns string) Row {
|
||||||
meta := i.Object["metadata"].(map[string]interface{})
|
meta := i.Object["metadata"].(map[string]interface{})
|
||||||
t, err := time.Parse(time.RFC3339, meta["creationTimestamp"].(string))
|
t, err := time.Parse(time.RFC3339, meta["creationTimestamp"].(string))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Fields timestamp", err)
|
log.Error().Msgf("Fields timestamp %v", err)
|
||||||
}
|
}
|
||||||
return append(ff, meta["name"].(string), toAge(metav1.Time{t}))
|
return append(ff, meta["name"].(string), toAge(metav1.Time{t}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -63,7 +63,7 @@ func (*CronJob) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(batchv1beta1.CronJob)
|
ii := i.(batchv1beta1.CronJob)
|
||||||
job.instance = &ii
|
job.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
job.path = job.namespacedName(job.instance.ObjectMeta)
|
job.path = job.namespacedName(job.instance.ObjectMeta)
|
||||||
return job
|
return job
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
@ -60,12 +60,12 @@ func (*Custom) NewInstance(i interface{}) Columnar {
|
||||||
t := i.(metav1beta1.TableRow)
|
t := i.(metav1beta1.TableRow)
|
||||||
cr.instance = &t
|
cr.instance = &t
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
var obj map[string]interface{}
|
var obj map[string]interface{}
|
||||||
err := json.Unmarshal(cr.instance.Object.Raw, &obj)
|
err := json.Unmarshal(cr.instance.Object.Raw, &obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
}
|
}
|
||||||
meta := obj["metadata"].(map[string]interface{})
|
meta := obj["metadata"].(map[string]interface{})
|
||||||
ns := ""
|
ns := ""
|
||||||
|
|
@ -137,7 +137,7 @@ func (r *Custom) Fields(ns string) Row {
|
||||||
var obj map[string]interface{}
|
var obj map[string]interface{}
|
||||||
err := json.Unmarshal(r.instance.Object.Raw, &obj)
|
err := json.Unmarshal(r.instance.Object.Raw, &obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return Row{}
|
return Row{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/apps/v1"
|
v1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*Deployment) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Deployment)
|
ii := i.(v1.Deployment)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
extv1beta1 "k8s.io/api/extensions/v1beta1"
|
extv1beta1 "k8s.io/api/extensions/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*DaemonSet) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(extv1beta1.DaemonSet)
|
ii := i.(extv1beta1.DaemonSet)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (*Endpoints) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Endpoints)
|
ii := i.(v1.Endpoints)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ func (*Event) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Event)
|
ii := i.(v1.Event)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/autoscaling/v1"
|
|
||||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -53,7 +52,7 @@ func (*HPA) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(autoscalingv2beta2.HorizontalPodAutoscaler)
|
ii := i.(autoscalingv2beta2.HorizontalPodAutoscaler)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
@ -67,8 +66,8 @@ func (r *HPA) Marshal(path string) (string, error) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
hpa := i.(*v1.HorizontalPodAutoscaler)
|
hpa := i.(*autoscalingv2beta2.HorizontalPodAutoscaler)
|
||||||
hpa.TypeMeta.APIVersion = "autoscaling/v1"
|
hpa.TypeMeta.APIVersion = "autoscaling/v2beta2"
|
||||||
hpa.TypeMeta.Kind = "HorizontalPodAutoscaler"
|
hpa.TypeMeta.Kind = "HorizontalPodAutoscaler"
|
||||||
return r.marshalObject(hpa)
|
return r.marshalObject(hpa)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,12 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
|
res "k8s.io/apimachinery/pkg/api/resource"
|
||||||
|
|
||||||
m "github.com/petergtz/pegomock"
|
m "github.com/petergtz/pegomock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
v1 "k8s.io/api/autoscaling/v1"
|
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,26 +89,46 @@ func TestHPAListDescribe(t *testing.T) {
|
||||||
|
|
||||||
// Helpers...
|
// Helpers...
|
||||||
|
|
||||||
func k8sHPA() *v1.HorizontalPodAutoscaler {
|
func k8sHPA() *autoscalingv2beta2.HorizontalPodAutoscaler {
|
||||||
var i int32 = 1
|
var i int32 = 1
|
||||||
return &v1.HorizontalPodAutoscaler{
|
return &autoscalingv2beta2.HorizontalPodAutoscaler{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
Namespace: "blee",
|
Namespace: "blee",
|
||||||
Name: "fred",
|
Name: "fred",
|
||||||
CreationTimestamp: metav1.Time{Time: testTime()},
|
CreationTimestamp: metav1.Time{Time: testTime()},
|
||||||
},
|
},
|
||||||
Spec: v1.HorizontalPodAutoscalerSpec{
|
Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
|
||||||
ScaleTargetRef: v1.CrossVersionObjectReference{
|
ScaleTargetRef: autoscalingv2beta2.CrossVersionObjectReference{
|
||||||
Kind: "fred",
|
Kind: "fred",
|
||||||
Name: "blee",
|
Name: "blee",
|
||||||
},
|
},
|
||||||
MinReplicas: &i,
|
MinReplicas: &i,
|
||||||
MaxReplicas: 1,
|
MaxReplicas: 1,
|
||||||
TargetCPUUtilizationPercentage: &i,
|
Metrics: []autoscalingv2beta2.MetricSpec{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ResourceMetricSourceType,
|
||||||
|
Resource: &autoscalingv2beta2.ResourceMetricSource{
|
||||||
|
Name: v1.ResourceCPU,
|
||||||
|
Target: autoscalingv2beta2.MetricTarget{
|
||||||
|
Type: autoscalingv2beta2.UtilizationMetricType,
|
||||||
},
|
},
|
||||||
Status: v1.HorizontalPodAutoscalerStatus{
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Status: autoscalingv2beta2.HorizontalPodAutoscalerStatus{
|
||||||
CurrentReplicas: 1,
|
CurrentReplicas: 1,
|
||||||
CurrentCPUUtilizationPercentage: &i,
|
CurrentMetrics: []autoscalingv2beta2.MetricStatus{
|
||||||
|
{
|
||||||
|
Type: autoscalingv2beta2.ResourceMetricSourceType,
|
||||||
|
Resource: &autoscalingv2beta2.ResourceMetricStatus{
|
||||||
|
Name: v1.ResourceCPU,
|
||||||
|
Current: autoscalingv2beta2.MetricValueStatus{
|
||||||
|
Value: &res.Quantity{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +138,7 @@ func newHPA() resource.Columnar {
|
||||||
}
|
}
|
||||||
|
|
||||||
func hpaYaml() string {
|
func hpaYaml() string {
|
||||||
return `apiVersion: autoscaling/v1
|
return `apiVersion: autoscaling/v2beta2
|
||||||
kind: HorizontalPodAutoscaler
|
kind: HorizontalPodAutoscaler
|
||||||
metadata:
|
metadata:
|
||||||
creationTimestamp: "2018-12-14T17:36:43Z"
|
creationTimestamp: "2018-12-14T17:36:43Z"
|
||||||
|
|
@ -123,13 +146,24 @@ metadata:
|
||||||
namespace: blee
|
namespace: blee
|
||||||
spec:
|
spec:
|
||||||
maxReplicas: 1
|
maxReplicas: 1
|
||||||
|
metrics:
|
||||||
|
- resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
type: Resource
|
||||||
minReplicas: 1
|
minReplicas: 1
|
||||||
scaleTargetRef:
|
scaleTargetRef:
|
||||||
kind: fred
|
kind: fred
|
||||||
name: blee
|
name: blee
|
||||||
targetCPUUtilizationPercentage: 1
|
|
||||||
status:
|
status:
|
||||||
currentCPUUtilizationPercentage: 1
|
conditions: null
|
||||||
|
currentMetrics:
|
||||||
|
- resource:
|
||||||
|
current:
|
||||||
|
value: "0"
|
||||||
|
name: cpu
|
||||||
|
type: Resource
|
||||||
currentReplicas: 1
|
currentReplicas: 1
|
||||||
desiredReplicas: 0
|
desiredReplicas: 0
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/api/extensions/v1beta1"
|
"k8s.io/api/extensions/v1beta1"
|
||||||
)
|
)
|
||||||
|
|
@ -51,7 +51,7 @@ func (*Ingress) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1beta1.Ingress)
|
ii := i.(v1beta1.Ingress)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/batch/v1"
|
v1 "k8s.io/api/batch/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/duration"
|
"k8s.io/apimachinery/pkg/util/duration"
|
||||||
)
|
)
|
||||||
|
|
@ -54,7 +54,7 @@ func (*Job) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Job)
|
ii := i.(v1.Job)
|
||||||
job.instance = &ii
|
job.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
job.path = job.namespacedName(job.instance.ObjectMeta)
|
job.path = job.namespacedName(job.instance.ObjectMeta)
|
||||||
return job
|
return job
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"k8s.io/apimachinery/pkg/util/sets"
|
"k8s.io/apimachinery/pkg/util/sets"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ func (*Node) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Node)
|
ii := i.(v1.Node)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
@ -81,7 +81,7 @@ func (r *Node) List(ns string) (Columnars, error) {
|
||||||
cc := make(Columnars, 0, len(nn))
|
cc := make(Columnars, 0, len(nn))
|
||||||
mx, err := r.metricSvc.PerNodeMetrics(nn)
|
mx, err := r.metricSvc.PerNodeMetrics(nn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("No metrics: %#v", err)
|
log.Warn().Msgf("No metrics: %#v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(nn); i++ {
|
for i := 0; i < len(nn); i++ {
|
||||||
|
|
@ -99,7 +99,7 @@ func (r *Node) Marshal(path string) (string, error) {
|
||||||
ns, n := namespaced(path)
|
ns, n := namespaced(path)
|
||||||
i, err := r.caller.Get(ns, n)
|
i, err := r.caller.Get(ns, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (*Namespace) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Namespace)
|
ii := i.(v1.Namespace)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
@ -59,7 +59,7 @@ func (r *Namespace) Marshal(path string) (string, error) {
|
||||||
ns, n := namespaced(path)
|
ns, n := namespaced(path)
|
||||||
i, err := r.caller.Get(ns, n)
|
i, err := r.caller.Get(ns, n)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ func (r *Pod) NewInstance(i interface{}) Columnar {
|
||||||
po := ptr.(v1.Pod)
|
po := ptr.(v1.Pod)
|
||||||
pod.instance = &po
|
pod.instance = &po
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
pod.path = r.namespacedName(pod.instance.ObjectMeta)
|
pod.path = r.namespacedName(pod.instance.ObjectMeta)
|
||||||
return pod
|
return pod
|
||||||
|
|
@ -169,7 +169,7 @@ func (r *Pod) List(ns string) (Columnars, error) {
|
||||||
|
|
||||||
metrics, err := r.metricSvc.PodMetrics()
|
metrics, err := r.metricSvc.PodMetrics()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn(err)
|
log.Error().Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cc := make(Columnars, 0, len(ii))
|
cc := make(Columnars, 0, len(ii))
|
||||||
|
|
@ -221,7 +221,7 @@ func (r *Pod) Fields(ns string) Row {
|
||||||
r.metrics.CPU,
|
r.metrics.CPU,
|
||||||
r.metrics.Mem,
|
r.metrics.Mem,
|
||||||
i.Status.PodIP,
|
i.Status.PodIP,
|
||||||
i.Status.HostIP,
|
i.Spec.NodeName,
|
||||||
string(i.Status.QOSClass),
|
string(i.Status.QOSClass),
|
||||||
toAge(i.ObjectMeta.CreationTimestamp),
|
toAge(i.ObjectMeta.CreationTimestamp),
|
||||||
)
|
)
|
||||||
|
|
@ -231,15 +231,6 @@ func (r *Pod) Fields(ns string) Row {
|
||||||
func (r *Pod) ExtFields() Properties {
|
func (r *Pod) ExtFields() Properties {
|
||||||
i := r.instance
|
i := r.instance
|
||||||
|
|
||||||
// po := k8s.Pod{}
|
|
||||||
// e, err := po.Events(i.Namespace, i.Name)
|
|
||||||
// if err != nil {
|
|
||||||
// log.Error("Boom!", err)
|
|
||||||
// }
|
|
||||||
// if len(e.Items) > 0 {
|
|
||||||
// log.Println("Events", ee.Items)
|
|
||||||
// }
|
|
||||||
|
|
||||||
return Properties{
|
return Properties{
|
||||||
"Priority": strconv.Itoa(int(*i.Spec.Priority)),
|
"Priority": strconv.Itoa(int(*i.Spec.Priority)),
|
||||||
"Priority Class": missing(i.Spec.PriorityClassName),
|
"Priority Class": missing(i.Spec.PriorityClassName),
|
||||||
|
|
@ -249,22 +240,9 @@ func (r *Pod) ExtFields() Properties {
|
||||||
"Init Containers": r.toContainers(i.Spec.InitContainers),
|
"Init Containers": r.toContainers(i.Spec.InitContainers),
|
||||||
"Node Selectors": mapToStr(i.Spec.NodeSelector),
|
"Node Selectors": mapToStr(i.Spec.NodeSelector),
|
||||||
"Volumes": r.toVolumes(i.Spec.Volumes),
|
"Volumes": r.toVolumes(i.Spec.Volumes),
|
||||||
// "Events": r.toEvents(e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (r *Pod) toEvents(e *v1.EventList) []string {
|
|
||||||
// ss := make([]string, 0, len(e.Items)+1)
|
|
||||||
// for _, h := range([]string{"Type", "Reason", "From", "Message", "Age"}) {
|
|
||||||
// ss[0] = fmt.Printf("%10s %10s %20s %30s", )
|
|
||||||
// }
|
|
||||||
// for i, e := range e.Items {
|
|
||||||
// ss[i] = e.
|
|
||||||
|
|
||||||
// }
|
|
||||||
// return ss
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (r *Pod) toVolumes(vv []v1.Volume) map[string]interface{} {
|
func (r *Pod) toVolumes(vv []v1.Volume) map[string]interface{} {
|
||||||
m := make(map[string]interface{}, len(vv))
|
m := make(map[string]interface{}, len(vv))
|
||||||
for _, v := range vv {
|
for _, v := range vv {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -51,7 +51,7 @@ func (*PV) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.PersistentVolume)
|
ii := i.(v1.PersistentVolume)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -48,7 +48,7 @@ func (*PVC) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.PersistentVolumeClaim)
|
ii := i.(v1.PersistentVolumeClaim)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*ReplicationController) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.ReplicationController)
|
ii := i.(v1.ReplicationController)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/rbac/v1"
|
v1 "k8s.io/api/rbac/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -52,7 +52,7 @@ func (*Role) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Role)
|
ii := i.(v1.Role)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/rbac/v1"
|
v1 "k8s.io/api/rbac/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*RoleBinding) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.RoleBinding)
|
ii := i.(v1.RoleBinding)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/apps/v1"
|
v1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*ReplicaSet) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.ReplicaSet)
|
ii := i.(v1.ReplicaSet)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*ServiceAccount) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.ServiceAccount)
|
ii := i.(v1.ServiceAccount)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/apps/v1"
|
v1 "k8s.io/api/apps/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -50,7 +50,7 @@ func (*StatefulSet) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.StatefulSet)
|
ii := i.(v1.StatefulSet)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ func (*Service) NewInstance(i interface{}) Columnar {
|
||||||
ii := i.(v1.Service)
|
ii := i.(v1.Service)
|
||||||
cm.instance = &ii
|
cm.instance = &ii
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown %#v", i)
|
log.Fatal().Msgf("Unknown %#v", i)
|
||||||
}
|
}
|
||||||
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
cm.path = cm.namespacedName(cm.instance.ObjectMeta)
|
||||||
return cm
|
return cm
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -42,7 +42,7 @@ func newAliasView(app *appView) *aliasView {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
log.Debug("Alias GR bailing out!")
|
log.Debug().Msg("Alias GR bailing out!")
|
||||||
return
|
return
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(1 * time.Second):
|
||||||
v.update(v.hydrate())
|
v.update(v.hydrate())
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/config"
|
"github.com/derailed/k9s/internal/config"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -136,7 +136,7 @@ func (a *appView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
key = tcell.Key(evt.Rune())
|
key = tcell.Key(evt.Rune())
|
||||||
}
|
}
|
||||||
if a, ok := a.actions[key]; ok {
|
if a, ok := a.actions[key]; ok {
|
||||||
log.Debug(">> AppView handled key: ", tcell.KeyNames[key])
|
log.Debug().Msgf(">> AppView handled key: %s", tcell.KeyNames[key])
|
||||||
return a.action(evt)
|
return a.action(evt)
|
||||||
}
|
}
|
||||||
return evt
|
return evt
|
||||||
|
|
@ -178,8 +178,11 @@ func (a *appView) gotoCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *appView) activateCmd(evt *tcell.EventKey) *tcell.EventKey {
|
func (a *appView) activateCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
|
if a.cmdView.inCmdMode() {
|
||||||
|
return evt
|
||||||
|
}
|
||||||
a.flash(flashInfo, "Entering command mode...")
|
a.flash(flashInfo, "Entering command mode...")
|
||||||
log.Debug("Entering app command mode...")
|
log.Debug().Msg("Entering app command mode...")
|
||||||
a.cmdBuff.setActive(true)
|
a.cmdBuff.setActive(true)
|
||||||
a.cmdBuff.clear()
|
a.cmdBuff.clear()
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultPrompt = "%c> %s"
|
const defaultPrompt = "%c> %s"
|
||||||
|
|
@ -62,7 +62,7 @@ func (v *cmdView) changed(s string) {
|
||||||
func (v *cmdView) active(f bool) {
|
func (v *cmdView) active(f bool) {
|
||||||
v.activated = f
|
v.activated = f
|
||||||
if f {
|
if f {
|
||||||
log.Debug("CmdView was activated...")
|
log.Debug().Msg("CmdView was activated...")
|
||||||
v.SetBackgroundColor(tcell.ColorDodgerBlue)
|
v.SetBackgroundColor(tcell.ColorDodgerBlue)
|
||||||
v.activate()
|
v.activate()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const detailsTitleFmt = " [aqua::b]%s([fuchsia::b]%s[aqua::-])[aqua::-] "
|
const detailsTitleFmt = " [aqua::b]%s([fuchsia::b]%s[aqua::-])[aqua::-] "
|
||||||
|
|
@ -26,6 +26,11 @@ type detailsView struct {
|
||||||
numSelections int
|
numSelections int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
regionRX = regexp.MustCompile(`\["([a-zA-Z0-9_,;: \-\.]*)"\]`)
|
||||||
|
escapeRX = regexp.MustCompile(`\[([a-zA-Z0-9_,;: \-\."#]+)\[(\[*)\]`)
|
||||||
|
)
|
||||||
|
|
||||||
func newDetailsView(app *appView, backFn actionHandler) *detailsView {
|
func newDetailsView(app *appView, backFn actionHandler) *detailsView {
|
||||||
v := detailsView{TextView: tview.NewTextView(), app: app, actions: make(keyActions)}
|
v := detailsView{TextView: tview.NewTextView(), app: app, actions: make(keyActions)}
|
||||||
{
|
{
|
||||||
|
|
@ -74,7 +79,7 @@ func (v *detailsView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a, ok := v.actions[key]; ok {
|
if a, ok := v.actions[key]; ok {
|
||||||
log.Debug(">> DetailsView handled ", tcell.KeyNames[key])
|
log.Debug().Msgf(">> DetailsView handled %s", tcell.KeyNames[key])
|
||||||
return a.action(evt)
|
return a.action(evt)
|
||||||
}
|
}
|
||||||
return evt
|
return evt
|
||||||
|
|
@ -128,8 +133,9 @@ func (v *detailsView) searchCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
func (v *detailsView) search(evt *tcell.EventKey) {
|
func (v *detailsView) search(evt *tcell.EventKey) {
|
||||||
v.numSelections = 0
|
v.numSelections = 0
|
||||||
v.Highlight()
|
v.Highlight()
|
||||||
log.Debug("Searching...", v.cmdBuff, v.numSelections)
|
log.Debug().Msgf("Searching... %s - %d", v.cmdBuff, v.numSelections)
|
||||||
v.SetText(v.decorateLines(v.GetText(true), v.cmdBuff.String()))
|
v.Highlight("")
|
||||||
|
v.SetText(v.decorateLines(v.GetText(false), v.cmdBuff.String()))
|
||||||
|
|
||||||
if v.cmdBuff.empty() {
|
if v.cmdBuff.empty() {
|
||||||
v.app.flash(flashWarn, "Clearing out search query...")
|
v.app.flash(flashWarn, "Clearing out search query...")
|
||||||
|
|
@ -203,9 +209,13 @@ func (v *detailsView) decorateLines(buff, q string) string {
|
||||||
rx := regexp.MustCompile(`(?i)` + q)
|
rx := regexp.MustCompile(`(?i)` + q)
|
||||||
lines := strings.Split(buff, "\n")
|
lines := strings.Split(buff, "\n")
|
||||||
for i, l := range lines {
|
for i, l := range lines {
|
||||||
|
l = regionRX.ReplaceAllString(l, "")
|
||||||
|
l = escapeRX.ReplaceAllString(l, "")
|
||||||
if m := rx.FindString(l); len(m) > 0 {
|
if m := rx.FindString(l); len(m) > 0 {
|
||||||
lines[i] = rx.ReplaceAllString(l, fmt.Sprintf(`["%d"]%s[""]`, v.numSelections, m))
|
lines[i] = rx.ReplaceAllString(l, fmt.Sprintf(`["%d"]%s[""]`, v.numSelections, m))
|
||||||
v.numSelections++
|
v.numSelections++
|
||||||
|
} else {
|
||||||
|
lines[i] = l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return strings.Join(lines, "\n")
|
return strings.Join(lines, "\n")
|
||||||
|
|
|
||||||
|
|
@ -10,13 +10,13 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runK(app *appView, args ...string) bool {
|
func runK(app *appView, args ...string) bool {
|
||||||
bin, err := exec.LookPath("kubectl")
|
bin, err := exec.LookPath("kubectl")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Unable to find kubeclt command in path")
|
log.Error().Msgf("Unable to find kubeclt command in path %v", err)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ func runK(app *appView, args ...string) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := execute(bin, args...); err != nil {
|
if err := execute(bin, args...); err != nil {
|
||||||
log.Errorf("Command exited: %T %v %v", err, err, args)
|
log.Error().Msgf("Command exited: %T %v %v", err, err, args)
|
||||||
app.flash(flashErr, "Command exited:", err.Error())
|
app.flash(flashErr, "Command exited:", err.Error())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -40,7 +40,7 @@ func runK(app *appView, args ...string) bool {
|
||||||
func run1(app *appView, bin string, args ...string) bool {
|
func run1(app *appView, bin string, args ...string) bool {
|
||||||
return app.Suspend(func() {
|
return app.Suspend(func() {
|
||||||
if err := execute(bin, args...); err != nil {
|
if err := execute(bin, args...); err != nil {
|
||||||
log.Errorf("Command exited: %T %v %v", err, err, args)
|
log.Error().Msgf("Command exited: %T %v %v", err, err, args)
|
||||||
app.flash(flashErr, "Command exited: ", err.Error())
|
app.flash(flashErr, "Command exited: ", err.Error())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -48,7 +48,7 @@ func run1(app *appView, bin string, args ...string) bool {
|
||||||
|
|
||||||
func execute(bin string, args ...string) error {
|
func execute(bin string, args ...string) error {
|
||||||
clearScreen()
|
clearScreen()
|
||||||
log.Debugf("Running command > %s %s", bin, strings.Join(args, " "))
|
log.Debug().Msgf("Running command > %s %s", bin, strings.Join(args, " "))
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
|
@ -56,14 +56,14 @@ func execute(bin string, args ...string) error {
|
||||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||||||
go func() {
|
go func() {
|
||||||
<-sigChan
|
<-sigChan
|
||||||
log.Debug("Command canceled with signal!")
|
log.Debug().Msg("Command canceled with signal!")
|
||||||
cancel()
|
cancel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
cmd := exec.Command(bin, args...)
|
cmd := exec.Command(bin, args...)
|
||||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
log.Debug("Command return status ", err)
|
log.Debug().Msgf("Command return status %v", err)
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return errors.New("canceled by operator")
|
return errors.New("canceled by operator")
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const (
|
||||||
flashWarn
|
flashWarn
|
||||||
flashErr
|
flashErr
|
||||||
flashFatal
|
flashFatal
|
||||||
flashDelay = 5
|
flashDelay = 3
|
||||||
|
|
||||||
emoDoh = "😗"
|
emoDoh = "😗"
|
||||||
emoRed = "😡"
|
emoRed = "😡"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type infoView struct {
|
type infoView struct {
|
||||||
|
|
@ -77,7 +77,7 @@ func (v *infoView) refresh() {
|
||||||
|
|
||||||
mx, err := cluster.Metrics()
|
mx, err := cluster.Metrics()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c := v.GetCell(row, 1)
|
c := v.GetCell(row, 1)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package views
|
||||||
import (
|
import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type jobView struct {
|
type jobView struct {
|
||||||
|
|
@ -48,7 +48,7 @@ func (v *jobView) logs(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.app.flash(flashErr, err.Error())
|
v.app.flash(flashErr, err.Error())
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,14 @@ package views
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/derailed/tview"
|
||||||
)
|
)
|
||||||
|
|
||||||
type logView struct {
|
type logView struct {
|
||||||
*detailsView
|
*detailsView
|
||||||
|
ansiWriter io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLogView(title string, parent loggable) *logView {
|
func newLogView(title string, parent loggable) *logView {
|
||||||
|
|
@ -13,14 +17,19 @@ func newLogView(title string, parent loggable) *logView {
|
||||||
{
|
{
|
||||||
v.SetBorderPadding(0, 0, 1, 1)
|
v.SetBorderPadding(0, 0, 1, 1)
|
||||||
v.setCategory("Logs")
|
v.setCategory("Logs")
|
||||||
v.SetDynamicColors(false)
|
v.SetDynamicColors(true)
|
||||||
v.SetWrap(true)
|
v.SetWrap(true)
|
||||||
v.setTitle(parent.getSelection())
|
v.setTitle(parent.getSelection())
|
||||||
}
|
}
|
||||||
|
v.ansiWriter = tview.ANSIWriter(v)
|
||||||
return &v
|
return &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *logView) logLine(line string) {
|
||||||
|
fmt.Fprintln(l.ansiWriter, line)
|
||||||
|
}
|
||||||
|
|
||||||
func (l *logView) log(lines fmt.Stringer) {
|
func (l *logView) log(lines fmt.Stringer) {
|
||||||
l.Clear()
|
l.Clear()
|
||||||
fmt.Fprintln(l, lines.String())
|
fmt.Fprintln(l.ansiWriter, lines.String())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -26,16 +26,13 @@ type logsView struct {
|
||||||
containers []string
|
containers []string
|
||||||
actions keyActions
|
actions keyActions
|
||||||
cancelFunc context.CancelFunc
|
cancelFunc context.CancelFunc
|
||||||
buffer *logBuffer
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newLogsView(parent loggable) *logsView {
|
func newLogsView(parent loggable) *logsView {
|
||||||
maxBuff := config.Root.K9s.LogBufferSize
|
|
||||||
v := logsView{
|
v := logsView{
|
||||||
Pages: tview.NewPages(),
|
Pages: tview.NewPages(),
|
||||||
parent: parent,
|
parent: parent,
|
||||||
containers: []string{},
|
containers: []string{},
|
||||||
buffer: newLogBuffer(int(maxBuff), true),
|
|
||||||
}
|
}
|
||||||
v.setActions(keyActions{
|
v.setActions(keyActions{
|
||||||
tcell.KeyEscape: {description: "Back", action: v.back},
|
tcell.KeyEscape: {description: "Back", action: v.back},
|
||||||
|
|
@ -57,27 +54,31 @@ func (v *logsView) init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *logsView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
func (v *logsView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
|
key := evt.Key()
|
||||||
|
if key == tcell.KeyRune {
|
||||||
|
key = tcell.Key(evt.Rune())
|
||||||
|
}
|
||||||
|
|
||||||
if kv, ok := v.CurrentPage().Item.(keyHandler); ok {
|
if kv, ok := v.CurrentPage().Item.(keyHandler); ok {
|
||||||
if kv.keyboard(evt) == nil {
|
if kv.keyboard(evt) == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
key := evt.Key()
|
if evt.Key() == tcell.KeyRune {
|
||||||
if key == tcell.KeyRune {
|
|
||||||
if i, err := strconv.Atoi(string(evt.Rune())); err == nil {
|
if i, err := strconv.Atoi(string(evt.Rune())); err == nil {
|
||||||
if _, ok := numKeys[i]; ok {
|
if _, ok := numKeys[i]; ok {
|
||||||
v.load(i - 1)
|
v.load(i - 1)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
key = tcell.Key(evt.Rune())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if m, ok := v.actions[key]; ok {
|
if m, ok := v.actions[key]; ok {
|
||||||
log.Debug(">> LogsView handled ", tcell.KeyNames[key])
|
log.Debug().Msgf(">> LogsView handled %s", tcell.KeyNames[key])
|
||||||
return m.action(evt)
|
return m.action(evt)
|
||||||
}
|
}
|
||||||
|
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,6 +102,7 @@ func (v *logsView) addContainer(n string) {
|
||||||
l := newLogView(n, v.parent)
|
l := newLogView(n, v.parent)
|
||||||
{
|
{
|
||||||
l.SetInputCapture(v.keyboard)
|
l.SetInputCapture(v.keyboard)
|
||||||
|
l.backFn = v.back
|
||||||
}
|
}
|
||||||
v.AddPage(n, l, true, false)
|
v.AddPage(n, l, true, false)
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +116,12 @@ func (v *logsView) deleteAllPages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *logsView) stop() {
|
func (v *logsView) stop() {
|
||||||
v.killLogIfAny()
|
if v.cancelFunc == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Debug().Msg("Canceling logs...")
|
||||||
|
v.cancelFunc()
|
||||||
|
v.cancelFunc = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *logsView) load(i int) {
|
func (v *logsView) load(i int) {
|
||||||
|
|
@ -122,60 +129,31 @@ func (v *logsView) load(i int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v.SwitchToPage(v.containers[i])
|
v.SwitchToPage(v.containers[i])
|
||||||
v.buffer.clear()
|
|
||||||
if err := v.doLoad(v.parent.getSelection(), v.containers[i]); err != nil {
|
if err := v.doLoad(v.parent.getSelection(), v.containers[i]); err != nil {
|
||||||
v.parent.appView().flash(flashErr, err.Error())
|
v.parent.appView().flash(flashErr, err.Error())
|
||||||
v.buffer.add("😂 Doh! No logs are available at this time. Check again later on...")
|
|
||||||
l := v.CurrentPage().Item.(*logView)
|
l := v.CurrentPage().Item.(*logView)
|
||||||
l.log(v.buffer)
|
l.logLine("😂 Doh! No logs are available at this time. Check again later on...")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v.parent.appView().SetFocus(v)
|
v.parent.appView().SetFocus(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *logsView) killLogIfAny() {
|
|
||||||
if v.cancelFunc == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
v.cancelFunc()
|
|
||||||
v.cancelFunc = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *logsView) doLoad(path, co string) error {
|
func (v *logsView) doLoad(path, co string) error {
|
||||||
v.killLogIfAny()
|
v.stop()
|
||||||
|
|
||||||
c := make(chan string)
|
c := make(chan string)
|
||||||
go func() {
|
go func() {
|
||||||
l, count, first := v.CurrentPage().Item.(*logView), 0, true
|
l := v.CurrentPage().Item.(*logView)
|
||||||
l.setTitle(path + ":" + co)
|
l.setTitle(path + ":" + co)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case line, ok := <-c:
|
case line, ok := <-c:
|
||||||
if !ok {
|
if !ok {
|
||||||
if v.buffer.length() > 0 {
|
l.logLine("--- No more logs ---")
|
||||||
v.buffer.add("--- No more logs ---")
|
|
||||||
l.log(v.buffer)
|
|
||||||
l.ScrollToEnd()
|
l.ScrollToEnd()
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
v.buffer.add(line)
|
l.logLine(line)
|
||||||
case <-time.After(refreshRate):
|
|
||||||
if count == maxCleanse {
|
|
||||||
log.Debug("Cleansing logs")
|
|
||||||
v.buffer.cleanse()
|
|
||||||
count = 0
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
if v.buffer.length() == 0 {
|
|
||||||
l.Clear()
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
l.log(v.buffer)
|
|
||||||
if first {
|
|
||||||
l.ScrollToEnd()
|
|
||||||
first = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
@ -185,8 +163,8 @@ func (v *logsView) doLoad(path, co string) error {
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("Resource %T is not tailable", v.parent.getList().Resource)
|
return fmt.Errorf("Resource %T is not tailable", v.parent.getList().Resource)
|
||||||
}
|
}
|
||||||
maxBuff := config.Root.K9s.LogBufferSize
|
maxBuff := int64(config.Root.K9s.LogBufferSize)
|
||||||
cancelFn, err := res.Logs(c, ns, po, co, int64(maxBuff), false)
|
cancelFn, err := res.Logs(c, ns, po, co, maxBuff, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cancelFn()
|
cancelFn()
|
||||||
return err
|
return err
|
||||||
|
|
@ -237,7 +215,6 @@ func (v *logsView) pageDown(*tcell.EventKey) *tcell.EventKey {
|
||||||
func (v *logsView) clearLogs(*tcell.EventKey) *tcell.EventKey {
|
func (v *logsView) clearLogs(*tcell.EventKey) *tcell.EventKey {
|
||||||
if p := v.CurrentPage(); p != nil {
|
if p := v.CurrentPage(); p != nil {
|
||||||
v.parent.appView().flash(flashInfo, "Clearing logs...")
|
v.parent.appView().flash(flashInfo, "Clearing logs...")
|
||||||
v.buffer.clear()
|
|
||||||
p.Item.(*logView).Clear()
|
p.Item.(*logView).Clear()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -143,7 +143,7 @@ func (a keyActions) toHints() hints {
|
||||||
mnemonic: name,
|
mnemonic: name,
|
||||||
display: a[tcell.Key(k)].description})
|
display: a[tcell.Key(k)].description})
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("Unable to local KeyName for %#v", k)
|
log.Error().Msgf("Unable to local KeyName for %#v", k)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hh
|
return hh
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type podView struct {
|
type podView struct {
|
||||||
|
|
@ -60,14 +60,13 @@ func (v *podView) getSelection() string {
|
||||||
// Handlers...
|
// Handlers...
|
||||||
|
|
||||||
func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
log.Println("Selected", v.rowSelected())
|
|
||||||
if !v.rowSelected() {
|
if !v.rowSelected() {
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.app.flash(flashErr, err.Error())
|
v.app.flash(flashErr, err.Error())
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
l := v.GetPrimitive("logs").(*logsView)
|
l := v.GetPrimitive("logs").(*logsView)
|
||||||
|
|
@ -117,7 +116,7 @@ func (v *podView) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
cc, err := fetchContainers(v.list, v.selectedItem, false)
|
cc, err := fetchContainers(v.list, v.selectedItem, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.app.flash(flashErr, err.Error())
|
v.app.flash(flashErr, err.Error())
|
||||||
log.Error("Error fetching containers", err)
|
log.Error().Msgf("Error fetching containers %v", err)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
if len(cc) == 1 {
|
if len(cc) == 1 {
|
||||||
|
|
@ -146,7 +145,7 @@ func (v *podView) shellIn(path, co string) {
|
||||||
args = append(args, "-c", co)
|
args = append(args, "-c", co)
|
||||||
}
|
}
|
||||||
args = append(args, "--", "sh")
|
args = append(args, "--", "sh")
|
||||||
log.Debug("Shell args", args)
|
log.Debug().Msgf("Shell args %v", args)
|
||||||
runK(v.app, args...)
|
runK(v.app, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const noSelection = ""
|
const noSelection = ""
|
||||||
|
|
@ -74,7 +74,7 @@ func (v *resourceView) init(ctx context.Context, ns string) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
log.Debugf("%s watcher canceled!", v.title)
|
log.Debug().Msgf("%s watcher canceled!", v.title)
|
||||||
return
|
return
|
||||||
case <-time.After(time.Duration(initTick) * time.Second):
|
case <-time.After(time.Duration(initTick) * time.Second):
|
||||||
v.refresh()
|
v.refresh()
|
||||||
|
|
@ -118,6 +118,12 @@ func (v *resourceView) hints() hints {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Actions...
|
// Actions...
|
||||||
|
|
||||||
|
func (v *resourceView) refreshCmd(*tcell.EventKey) *tcell.EventKey {
|
||||||
|
log.Debug().Msg("Refreshing resource...")
|
||||||
|
v.refresh()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (v *resourceView) backCmd(*tcell.EventKey) *tcell.EventKey {
|
func (v *resourceView) backCmd(*tcell.EventKey) *tcell.EventKey {
|
||||||
v.switchPage(v.list.GetName())
|
v.switchPage(v.list.GetName())
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -145,7 +151,7 @@ func (v *resourceView) describeCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
raw, err := v.list.Resource().Describe(v.title, sel)
|
raw, err := v.list.Resource().Describe(v.title, sel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.app.flash(flashErr, "Unable to describeCmd this resource", err.Error())
|
v.app.flash(flashErr, "Unable to describeCmd this resource", err.Error())
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
details := v.GetPrimitive("details").(*detailsView)
|
details := v.GetPrimitive("details").(*detailsView)
|
||||||
|
|
@ -168,7 +174,7 @@ func (v *resourceView) viewCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
raw, err := v.list.Resource().Marshal(sel)
|
raw, err := v.list.Resource().Marshal(sel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
v.app.flash(flashErr, "Unable to marshal resource", err.Error())
|
v.app.flash(flashErr, "Unable to marshal resource", err.Error())
|
||||||
log.Error(err)
|
log.Error().Err(err)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
details := v.GetPrimitive("details").(*detailsView)
|
details := v.GetPrimitive("details").(*detailsView)
|
||||||
|
|
@ -324,6 +330,8 @@ func (v *resourceView) refreshActions() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
aa[tcell.KeyCtrlR] = newKeyAction("Refresh", v.refreshCmd)
|
||||||
|
|
||||||
if v.list.Access(resource.EditAccess) {
|
if v.list.Access(resource.EditAccess) {
|
||||||
aa[KeyE] = newKeyAction("Edit", v.editCmd)
|
aa[KeyE] = newKeyAction("Edit", v.editCmd)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/derailed/k9s/internal/resource"
|
"github.com/derailed/k9s/internal/resource"
|
||||||
"github.com/derailed/tview"
|
"github.com/derailed/tview"
|
||||||
"github.com/gdamore/tcell"
|
"github.com/gdamore/tcell"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
@ -83,7 +83,7 @@ func (v *tableView) keyboard(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
if a, ok := v.actions[key]; ok {
|
if a, ok := v.actions[key]; ok {
|
||||||
log.Debug(">> TableView handled ", tcell.KeyNames[key])
|
log.Debug().Msgf(">> TableView handled %s", tcell.KeyNames[key])
|
||||||
return a.action(evt)
|
return a.action(evt)
|
||||||
}
|
}
|
||||||
return evt
|
return evt
|
||||||
|
|
@ -125,7 +125,7 @@ func (v *tableView) activateCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
}
|
}
|
||||||
|
|
||||||
v.app.flash(flashInfo, "Filtering...")
|
v.app.flash(flashInfo, "Filtering...")
|
||||||
log.Info("Entering filtering mode...")
|
log.Info().Msg("Entering filtering mode...")
|
||||||
v.cmdBuff.reset()
|
v.cmdBuff.reset()
|
||||||
v.cmdBuff.setActive(true)
|
v.cmdBuff.setActive(true)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
6
main.go
6
main.go
|
|
@ -5,7 +5,8 @@ import (
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/cmd"
|
"github.com/derailed/k9s/internal/cmd"
|
||||||
"github.com/derailed/k9s/internal/config"
|
"github.com/derailed/k9s/internal/config"
|
||||||
log "github.com/sirupsen/logrus"
|
"github.com/rs/zerolog"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
_ "k8s.io/client-go/plugin/pkg/client/auth"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -14,8 +15,7 @@ func init() {
|
||||||
|
|
||||||
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
|
mod := os.O_CREATE | os.O_APPEND | os.O_WRONLY
|
||||||
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
|
if file, err := os.OpenFile(config.K9sLogs, mod, config.DefaultFileMod); err == nil {
|
||||||
log.SetOutput(file)
|
log.Logger = log.Output(zerolog.ConsoleWriter{Out: file})
|
||||||
log.SetFormatter(&log.TextFormatter{FullTimestamp: true, ForceColors: true})
|
|
||||||
} else {
|
} else {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue