switch over the kubectl logs vs k9s logview + bug fixes
parent
6cdccf1d53
commit
e41b141edb
|
|
@ -0,0 +1,30 @@
|
||||||
|
# Release v0.2.0
|
||||||
|
|
||||||
|
## 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 #97](https://github.com/derailed/k9s/issues/97)
|
||||||
|
Changed log view to now use kubectl logs shell command.
|
||||||
|
There was some issues with the previous implementation with missing info and panics.
|
||||||
|
NOTE! User must type Ctrl-C to exit the logs and navigate back to K9s
|
||||||
|
+ Reordered containers to show spec.containers first vs spec.initcontainers.
|
||||||
|
+ [Feature #29]((https://github.com/derailed/k9s/issues/29))
|
||||||
|
Side effect of #97 Log coloring if present, will now show in the terminal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resolved Bugs
|
||||||
|
|
||||||
|
* [Issue #99](https://github.com/derailed/k9s/issues/99)
|
||||||
|
* [Issue #100](https://github.com/derailed/k9s/issues/100)
|
||||||
1
go.sum
1
go.sum
|
|
@ -139,6 +139,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2 h1:+DCIGbF/swA92ohVg0//6X2IVY3KZs6p9mix0ziNYJM=
|
||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e h1:XEcLGV2fKy3FrsoJVCkX+lMhqc9Suj7J5L/wldA1wu4=
|
||||||
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||||
google.golang.org/api v0.0.0-20181220000619-583d854617af h1:iQMS7JKv/0w/iiWf1M49Cg3dmOkBoBZT5KheqPDpaac=
|
google.golang.org/api v0.0.0-20181220000619-583d854617af h1:iQMS7JKv/0w/iiWf1M49Cg3dmOkBoBZT5KheqPDpaac=
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,9 @@ func initK9sConfig() {
|
||||||
|
|
||||||
if c, ok := cfg.Contexts[ctx]; ok {
|
if c, ok := cfg.Contexts[ctx]; ok {
|
||||||
config.Root.K9s.CurrentCluster = c.Cluster
|
config.Root.K9s.CurrentCluster = c.Cluster
|
||||||
|
if len(c.Namespace) != 0 {
|
||||||
|
config.Root.SetActiveNamespace(c.Namespace)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic(fmt.Sprintf("The specified context `%s does not exists in kubeconfig", cfg.CurrentContext))
|
panic(fmt.Sprintf("The specified context `%s does not exists in kubeconfig", cfg.CurrentContext))
|
||||||
}
|
}
|
||||||
|
|
@ -134,6 +137,8 @@ func run(cmd *cobra.Command, args []string) {
|
||||||
{
|
{
|
||||||
app.Init(version, refreshRate, k8sFlags)
|
app.Init(version, refreshRate, k8sFlags)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
// Clear screen
|
||||||
|
print("\033[H\033[2J")
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
app.Stop()
|
app.Stop()
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
|
|
|
||||||
|
|
@ -75,12 +75,13 @@ 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) {
|
func (c *Config) SetActiveNamespace(ns string) error {
|
||||||
|
log.Debugf("Setting active namespace `%s", ns)
|
||||||
if c.K9s.ActiveCluster() != nil {
|
if c.K9s.ActiveCluster() != nil {
|
||||||
c.K9s.ActiveCluster().Namespace.SetActive(ns)
|
return c.K9s.ActiveCluster().Namespace.SetActive(ns, c.settings)
|
||||||
} else {
|
|
||||||
log.Debug("Doh! no active cluster. unable to set active namespace")
|
|
||||||
}
|
}
|
||||||
|
log.Error("Doh! no active cluster. unable to set active namespace")
|
||||||
|
return fmt.Errorf("no active cluster. unable to set active namespace")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ActiveView returns the active view in the current cluster.
|
// ActiveView returns the active view in the current cluster.
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,7 @@ func TestConfigSaveFile(t *testing.T) {
|
||||||
m.When(ksMock.CurrentClusterName()).ThenReturn("minikube", nil)
|
m.When(ksMock.CurrentClusterName()).ThenReturn("minikube", nil)
|
||||||
m.When(ksMock.CurrentNamespaceName()).ThenReturn("default", nil)
|
m.When(ksMock.CurrentNamespaceName()).ThenReturn("default", nil)
|
||||||
m.When(ksMock.ClusterNames()).ThenReturn([]string{"minikube", "fred", "blee"}, nil)
|
m.When(ksMock.ClusterNames()).ThenReturn([]string{"minikube", "fred", "blee"}, nil)
|
||||||
|
m.When(ksMock.NamespaceNames()).ThenReturn([]string{"default"}, nil)
|
||||||
|
|
||||||
cfg := config.NewConfig(ksMock)
|
cfg := config.NewConfig(ksMock)
|
||||||
cfg.Load("test_assets/k9s.yml")
|
cfg.Load("test_assets/k9s.yml")
|
||||||
|
|
@ -153,6 +154,7 @@ func TestConfigReset(t *testing.T) {
|
||||||
m.When(ksMock.CurrentClusterName()).ThenReturn("blee", nil)
|
m.When(ksMock.CurrentClusterName()).ThenReturn("blee", nil)
|
||||||
m.When(ksMock.CurrentNamespaceName()).ThenReturn("default", nil)
|
m.When(ksMock.CurrentNamespaceName()).ThenReturn("default", nil)
|
||||||
m.When(ksMock.ClusterNames()).ThenReturn([]string{"blee"}, nil)
|
m.When(ksMock.ClusterNames()).ThenReturn([]string{"blee"}, nil)
|
||||||
|
m.When(ksMock.NamespaceNames()).ThenReturn([]string{"default"}, nil)
|
||||||
|
|
||||||
cfg := config.NewConfig(ksMock)
|
cfg := config.NewConfig(ksMock)
|
||||||
cfg.Load("test_assets/k9s.yml")
|
cfg.Load("test_assets/k9s.yml")
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,5 @@ func (k *K9s) Validate(ks KubeSettings) {
|
||||||
if _, ok := k.Clusters[k.CurrentCluster]; !ok {
|
if _, ok := k.Clusters[k.CurrentCluster]; !ok {
|
||||||
k.Clusters[k.CurrentCluster] = NewCluster()
|
k.Clusters[k.CurrentCluster] = NewCluster()
|
||||||
}
|
}
|
||||||
|
k.Clusters[k.CurrentCluster].Validate(ks)
|
||||||
if ns, err := ks.CurrentNamespaceName(); err == nil && len(ns) != 0 {
|
|
||||||
k.Clusters[k.CurrentCluster].Namespace.Active = ns
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ 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)
|
||||||
nn, err := ks.NamespaceNames()
|
nn, err := ks.NamespaceNames()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -46,9 +47,11 @@ func (n *Namespace) Validate(ks KubeSettings) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetActive set the active namespace.
|
// SetActive set the active namespace.
|
||||||
func (n *Namespace) SetActive(ns string) {
|
func (n *Namespace) SetActive(ns string, ks KubeSettings) error {
|
||||||
|
log.Debug("Setting active ns ", ns)
|
||||||
n.Active = ns
|
n.Active = ns
|
||||||
n.addFavNS(ns)
|
n.addFavNS(ns)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Namespace) isAllNamespace() bool {
|
func (n *Namespace) isAllNamespace() bool {
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ func TestNSValidateNoNS(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNSSetActive(t *testing.T) {
|
func TestNSSetActive(t *testing.T) {
|
||||||
|
allNS := []string{"ns4", "ns3", "ns2", "ns1", "all", "default"}
|
||||||
uu := []struct {
|
uu := []struct {
|
||||||
ns string
|
ns string
|
||||||
fav []string
|
fav []string
|
||||||
|
|
@ -60,30 +61,30 @@ func TestNSSetActive(t *testing.T) {
|
||||||
{"ns1", []string{"ns1", "all", "default"}},
|
{"ns1", []string{"ns1", "all", "default"}},
|
||||||
{"ns2", []string{"ns2", "ns1", "all", "default"}},
|
{"ns2", []string{"ns2", "ns1", "all", "default"}},
|
||||||
{"ns3", []string{"ns3", "ns2", "ns1", "all", "default"}},
|
{"ns3", []string{"ns3", "ns2", "ns1", "all", "default"}},
|
||||||
{"ns4", []string{"ns4", "ns3", "ns2", "ns1", "all", "default"}},
|
{"ns4", allNS},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ksMock := NewMockKubeSettings()
|
||||||
|
m.When(ksMock.NamespaceNames()).ThenReturn(allNS, nil)
|
||||||
|
|
||||||
ns := config.NewNamespace()
|
ns := config.NewNamespace()
|
||||||
for _, u := range uu {
|
for _, u := range uu {
|
||||||
ns.SetActive(u.ns)
|
err := ns.SetActive(u.ns, ksMock)
|
||||||
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, u.ns, ns.Active)
|
assert.Equal(t, u.ns, ns.Active)
|
||||||
assert.Equal(t, u.fav, ns.Favorites)
|
assert.Equal(t, u.fav, ns.Favorites)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNSRmFavNS(t *testing.T) {
|
func TestNSValidateRmFavs(t *testing.T) {
|
||||||
ns := config.NewNamespace()
|
allNS := []string{"default", "kube-system"}
|
||||||
uu := []struct {
|
|
||||||
ns string
|
|
||||||
fav []string
|
|
||||||
}{
|
|
||||||
{"all", []string{"default", "kube-system"}},
|
|
||||||
{"kube-system", []string{"default"}},
|
|
||||||
{"blee", []string{"default"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, u := range uu {
|
ksMock := NewMockKubeSettings()
|
||||||
ns.SetActive(u.ns)
|
m.When(ksMock.NamespaceNames()).ThenReturn(allNS, nil)
|
||||||
assert.Equal(t, u.ns, ns.Active)
|
|
||||||
}
|
ns := config.NewNamespace()
|
||||||
|
ns.Favorites = []string{"default", "fred", "blee"}
|
||||||
|
|
||||||
|
ns.Validate(ksMock)
|
||||||
|
assert.Equal(t, []string{"default"}, ns.Favorites)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,19 +211,18 @@ func (c *Config) CurrentNamespaceName() (string, error) {
|
||||||
return ctx.Namespace, nil
|
return ctx.Namespace, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", fmt.Errorf("No active namespace specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamespaceNames fetch all available namespaces on current cluster.
|
// NamespaceNames fetch all available namespaces on current cluster.
|
||||||
func (c *Config) NamespaceNames() ([]string, error) {
|
func (c *Config) NamespaceNames() ([]string, error) {
|
||||||
var nn []string
|
|
||||||
ll, err := NewNamespace().List("")
|
ll, err := NewNamespace().List("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nn, err
|
return []string{}, err
|
||||||
}
|
}
|
||||||
nn = make([]string, len(nn))
|
nn := make([]string, 0, len(ll))
|
||||||
for i, n := range ll {
|
for _, n := range ll {
|
||||||
nn[i] = n.(v1.Namespace).Name
|
nn = append(nn, n.(v1.Namespace).Name)
|
||||||
}
|
}
|
||||||
return nn, nil
|
return nn, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package k8s_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/derailed/k9s/internal/k8s"
|
"github.com/derailed/k9s/internal/k8s"
|
||||||
|
|
@ -68,15 +69,17 @@ func TestConfigCurrentNamespace(t *testing.T) {
|
||||||
uu := []struct {
|
uu := []struct {
|
||||||
flags *genericclioptions.ConfigFlags
|
flags *genericclioptions.ConfigFlags
|
||||||
namespace string
|
namespace string
|
||||||
|
err error
|
||||||
}{
|
}{
|
||||||
{&genericclioptions.ConfigFlags{KubeConfig: &kubeConfig}, ""},
|
{&genericclioptions.ConfigFlags{KubeConfig: &kubeConfig}, "", fmt.Errorf("No active namespace specified")},
|
||||||
{&genericclioptions.ConfigFlags{KubeConfig: &kubeConfig, Namespace: &name}, "blee"},
|
{&genericclioptions.ConfigFlags{KubeConfig: &kubeConfig, Namespace: &name}, "blee", nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
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()
|
||||||
assert.Nil(t, err)
|
fmt.Println("CRap", ns, err)
|
||||||
|
assert.Equal(t, u.err, err)
|
||||||
assert.Equal(t, u.namespace, ns)
|
assert.Equal(t, u.namespace, ns)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,14 @@ func (*Pod) Containers(ns, n string, includeInit bool) ([]string, error) {
|
||||||
return cc, err
|
return cc, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, c := range po.Spec.Containers {
|
||||||
|
cc = append(cc, c.Name)
|
||||||
|
}
|
||||||
if includeInit {
|
if includeInit {
|
||||||
for _, c := range po.Spec.InitContainers {
|
for _, c := range po.Spec.InitContainers {
|
||||||
cc = append(cc, c.Name)
|
cc = append(cc, c.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, c := range po.Spec.Containers {
|
|
||||||
cc = append(cc, c.Name)
|
|
||||||
}
|
|
||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,9 +63,11 @@ func (v *cmdView) active(f bool) {
|
||||||
v.activated = f
|
v.activated = f
|
||||||
if f {
|
if f {
|
||||||
log.Debug("CmdView was activated...")
|
log.Debug("CmdView was activated...")
|
||||||
|
v.SetBackgroundColor(tcell.ColorDodgerBlue)
|
||||||
v.activate()
|
v.activate()
|
||||||
} else {
|
} else {
|
||||||
log.Debug("CmdView was deactivated!")
|
log.Debug("CmdView was deactivated!")
|
||||||
|
v.SetBackgroundColor(tcell.ColorDefault)
|
||||||
v.Clear()
|
v.Clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,61 @@
|
||||||
package views
|
package views
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func run(app *appView, args ...string) bool {
|
func runK(app *appView, args ...string) bool {
|
||||||
|
bin, err := exec.LookPath("kubectl")
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Unable to find kubeclt command in path")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debugf("Running command > %s %s", bin, args)
|
||||||
return app.Suspend(func() {
|
return app.Suspend(func() {
|
||||||
if err := execute(args...); err != nil {
|
if err := execute(bin, args...); err != nil {
|
||||||
log.Error("Command failed:", err, args)
|
log.Errorf("Command exited: %T %v %v", err, err, args)
|
||||||
app.flash(flashErr, "Doh! command failed", err.Error())
|
app.flash(flashErr, err.Error())
|
||||||
}
|
}
|
||||||
log.Debug("Command exec successfully!")
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func execute(args ...string) error {
|
func run1(app *appView, bin string, args ...string) bool {
|
||||||
bin, err := exec.LookPath("kubectl")
|
return app.Suspend(func() {
|
||||||
if err != nil {
|
if err := execute(bin, args...); err != nil {
|
||||||
return err
|
log.Errorf("Command exited: %T %v %v", err, err, args)
|
||||||
}
|
app.flash(flashErr, "Command exited: ", err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func execute(bin string, args ...string) error {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
sigChan := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
|
||||||
|
go func() {
|
||||||
|
<-sigChan
|
||||||
|
log.Debug("Command canceled with signal!")
|
||||||
|
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
|
||||||
return cmd.Run()
|
err := cmd.Run()
|
||||||
|
log.Debug("Command return status ", err)
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return errors.New("canceled by operator")
|
||||||
|
default:
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,10 +39,12 @@ func (v *namespaceView) useNamespace(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
ns := v.getSelectedItem()
|
ns := v.getSelectedItem()
|
||||||
config.Root.SetActiveNamespace(ns)
|
if err := config.Root.SetActiveNamespace(ns); err != nil {
|
||||||
|
v.app.flash(flashErr, err.Error())
|
||||||
|
} else {
|
||||||
|
v.app.flash(flashInfo, fmt.Sprintf("Namespace %s is now active!", ns))
|
||||||
|
}
|
||||||
config.Root.Save()
|
config.Root.Save()
|
||||||
v.refresh()
|
|
||||||
v.app.flash(flashInfo, fmt.Sprintf("Setting namespace `%s as your default namespace", ns))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package views
|
package views
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"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"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
@ -57,26 +59,6 @@ func (v *podView) getSelection() string {
|
||||||
|
|
||||||
// Handlers...
|
// Handlers...
|
||||||
|
|
||||||
func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|
||||||
if !v.rowSelected() {
|
|
||||||
return evt
|
|
||||||
}
|
|
||||||
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
|
||||||
if err != nil {
|
|
||||||
v.app.flash(flashErr, err.Error())
|
|
||||||
log.Error(err)
|
|
||||||
return evt
|
|
||||||
}
|
|
||||||
l := v.GetPrimitive("logs").(*logsView)
|
|
||||||
l.deleteAllPages()
|
|
||||||
for _, c := range cc {
|
|
||||||
l.addContainer(c)
|
|
||||||
}
|
|
||||||
v.switchPage("logs")
|
|
||||||
l.init()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
// func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
// if !v.rowSelected() {
|
// if !v.rowSelected() {
|
||||||
// return evt
|
// return evt
|
||||||
|
|
@ -84,22 +66,49 @@ func (v *podView) logsCmd(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("Error fetching containers", err)
|
// log.Error(err)
|
||||||
// return evt
|
// return evt
|
||||||
// }
|
// }
|
||||||
// if len(cc) == 1 {
|
// l := v.GetPrimitive("logs").(*logsView)
|
||||||
// v.showLogs(v.selectedItem, "")
|
// l.deleteAllPages()
|
||||||
// } else {
|
// for _, c := range cc {
|
||||||
// p := v.GetPrimitive("choose").(*selectList)
|
// l.addContainer(c)
|
||||||
// p.populate(cc)
|
|
||||||
// p.SetSelectedFunc(func(i int, t, d string, r rune) {
|
|
||||||
// v.showLogs(v.selectedItem, t)
|
|
||||||
// })
|
|
||||||
// v.switchPage("choose")
|
|
||||||
// }
|
// }
|
||||||
// return evt
|
// v.switchPage("logs")
|
||||||
|
// l.init()
|
||||||
|
// return nil
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
func (v *podView) logsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
|
if !v.rowSelected() {
|
||||||
|
return evt
|
||||||
|
}
|
||||||
|
|
||||||
|
previous := false
|
||||||
|
if evt.Rune() == 'p' {
|
||||||
|
log.Debug("Previous logs detected")
|
||||||
|
previous = true
|
||||||
|
}
|
||||||
|
|
||||||
|
cc, err := fetchContainers(v.list, v.selectedItem, true)
|
||||||
|
if err != nil {
|
||||||
|
v.app.flash(flashErr, err.Error())
|
||||||
|
log.Error("Error fetching containers", err)
|
||||||
|
return evt
|
||||||
|
}
|
||||||
|
if len(cc) == 1 {
|
||||||
|
v.showLogs(v.selectedItem, "", previous)
|
||||||
|
} else {
|
||||||
|
p := v.GetPrimitive("choose").(*selectList)
|
||||||
|
p.populate(cc)
|
||||||
|
p.SetSelectedFunc(func(i int, t, d string, r rune) {
|
||||||
|
v.showLogs(v.selectedItem, t, previous)
|
||||||
|
})
|
||||||
|
v.switchPage("choose")
|
||||||
|
}
|
||||||
|
return evt
|
||||||
|
}
|
||||||
|
|
||||||
func (v *podView) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
func (v *podView) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
if !v.rowSelected() {
|
if !v.rowSelected() {
|
||||||
return evt
|
return evt
|
||||||
|
|
@ -113,7 +122,6 @@ func (v *podView) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
if len(cc) == 1 {
|
if len(cc) == 1 {
|
||||||
v.shellIn(v.selectedItem, "")
|
v.shellIn(v.selectedItem, "")
|
||||||
} else {
|
} else {
|
||||||
// v.showPicker(cc)
|
|
||||||
p := v.GetPrimitive("choose").(*selectList)
|
p := v.GetPrimitive("choose").(*selectList)
|
||||||
p.populate(cc)
|
p.populate(cc)
|
||||||
p.SetSelectedFunc(func(i int, t, d string, r rune) {
|
p.SetSelectedFunc(func(i int, t, d string, r rune) {
|
||||||
|
|
@ -138,17 +146,20 @@ func (v *podView) shellIn(path, co string) {
|
||||||
}
|
}
|
||||||
args = append(args, "--", "sh")
|
args = append(args, "--", "sh")
|
||||||
log.Debug("Shell args", args)
|
log.Debug("Shell args", args)
|
||||||
run(v.app, args...)
|
runK(v.app, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *podView) showLogs(path, co string) {
|
func (v *podView) showLogs(path, co string, previous bool) {
|
||||||
ns, po := namespaced(path)
|
ns, po := namespaced(path)
|
||||||
args := []string{"logs", "-f", "-n", ns, po}
|
args := make([]string, 0, 10)
|
||||||
|
args = append(args, "logs", "-f")
|
||||||
if len(co) != 0 {
|
if len(co) != 0 {
|
||||||
args = append(args, "-c", co)
|
args = append(args, "-c", co)
|
||||||
|
v.app.flash(flashInfo, fmt.Sprintf("Viewing logs from container %s on pod %s", co, po))
|
||||||
|
} else {
|
||||||
|
v.app.flash(flashInfo, fmt.Sprintf("Viewing logs from pod %s", po))
|
||||||
}
|
}
|
||||||
log.Debug("Logs Args", args)
|
runK(v.app, append(args, "-n", ns, po)...)
|
||||||
run(v.app, args...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *podView) extraActions(aa keyActions) {
|
func (v *podView) extraActions(aa keyActions) {
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ func (v *resourceView) editCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
ns, s := namespaced(v.selectedItem)
|
ns, s := namespaced(v.selectedItem)
|
||||||
run(v.app, "edit", v.list.GetName(), "-n", ns, s)
|
runK(v.app, "edit", v.list.GetName(), "-n", ns, s)
|
||||||
return evt
|
return evt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue