parent
6b5da1091e
commit
a8771b8c67
|
|
@ -16,3 +16,4 @@ cluster_info_test.go
|
||||||
*.test
|
*.test
|
||||||
*.log
|
*.log
|
||||||
*~
|
*~
|
||||||
|
pod1.go
|
||||||
|
|
@ -576,4 +576,4 @@ to make this project a reality!
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<img src="assets/imhotep_logo.png" width="32" height="auto"/> © 2019 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
<img src="assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_small.png" align="right" width="200" height="auto"/>
|
||||||
|
|
||||||
|
# Release v0.11.2
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
Thank you to all that contributed with flushing out issues and enhancements for 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. Your support, kindness and awesome suggestions to make K9s better is as ever very much noticed and appreciated!
|
||||||
|
|
||||||
|
Also if you dig this tool, please make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s_helm.png" align="center" width="300" height="auto"/>
|
||||||
|
|
||||||
|
Maintenance Release!
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Resolved Bugs/Features
|
||||||
|
|
||||||
|
* [Issue #469](https://github.com/derailed/k9s/issues/469)
|
||||||
|
* [Issue #468](https://github.com/derailed/k9s/issues/468)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2020 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
|
@ -39,19 +39,14 @@ type Pod struct {
|
||||||
|
|
||||||
// List returns a collection of nodes.
|
// List returns a collection of nodes.
|
||||||
func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||||
oo, err := p.Resource.List(ctx, ns)
|
|
||||||
if err != nil {
|
|
||||||
return oo, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pmx, ok := ctx.Value(internal.KeyMetrics).(*mv1beta1.PodMetricsList)
|
pmx, ok := ctx.Value(internal.KeyMetrics).(*mv1beta1.PodMetricsList)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Warn().Msgf("expecting context PodMetricsList")
|
log.Warn().Msgf("no metrics available for %q", p.gvr)
|
||||||
}
|
}
|
||||||
|
|
||||||
sel, ok := ctx.Value(internal.KeyFields).(string)
|
sel, ok := ctx.Value(internal.KeyFields).(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return oo, nil
|
return nil, fmt.Errorf("expecting a fieldSelector in context")
|
||||||
}
|
}
|
||||||
fsel, err := labels.ConvertSelectorToLabelsMap(sel)
|
fsel, err := labels.ConvertSelectorToLabelsMap(sel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -59,6 +54,11 @@ func (p *Pod) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||||
}
|
}
|
||||||
nodeName := fsel["spec.nodeName"]
|
nodeName := fsel["spec.nodeName"]
|
||||||
|
|
||||||
|
oo, err := p.Resource.List(ctx, ns)
|
||||||
|
if err != nil {
|
||||||
|
return oo, err
|
||||||
|
}
|
||||||
|
|
||||||
var res []runtime.Object
|
var res []runtime.Object
|
||||||
for _, o := range oo {
|
for _, o := range oo {
|
||||||
u, ok := o.(*unstructured.Unstructured)
|
u, ok := o.(*unstructured.Unstructured)
|
||||||
|
|
|
||||||
|
|
@ -47,5 +47,5 @@ func (r *Resource) List(ctx context.Context, ns string) ([]runtime.Object, error
|
||||||
lsel = sel.AsSelector()
|
lsel = sel.AsSelector()
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.Factory.List(r.gvr.String(), ns, true, lsel)
|
return r.Factory.List(r.gvr.String(), ns, false, lsel)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ func (t *Table) getClient() (*rest.RESTClient, error) {
|
||||||
gv := t.gvr.AsGV()
|
gv := t.gvr.AsGV()
|
||||||
crConfig.GroupVersion = &gv
|
crConfig.GroupVersion = &gv
|
||||||
crConfig.APIPath = "/apis"
|
crConfig.APIPath = "/apis"
|
||||||
if len(t.gvr.ToG()) == 0 {
|
if t.gvr.ToG() == "" {
|
||||||
crConfig.APIPath = "/api"
|
crConfig.APIPath = "/api"
|
||||||
}
|
}
|
||||||
codec, _ := t.codec()
|
codec, _ := t.codec()
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,10 @@ func (t *Table) refresh(ctx context.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, error) {
|
func (t *Table) list(ctx context.Context, a dao.Accessor) ([]runtime.Object, error) {
|
||||||
|
defer func(t time.Time) {
|
||||||
|
log.Debug().Msgf(" LIST elapsed %v", time.Since(t))
|
||||||
|
}(time.Now())
|
||||||
|
|
||||||
factory, ok := ctx.Value(internal.KeyFactory).(dao.Factory)
|
factory, ok := ctx.Value(internal.KeyFactory).(dao.Factory)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("expected Factory in context but got %T", ctx.Value(internal.KeyFactory))
|
return nil, fmt.Errorf("expected Factory in context but got %T", ctx.Value(internal.KeyFactory))
|
||||||
|
|
@ -212,7 +216,7 @@ func (t *Table) reconcile(ctx context.Context) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Debug().Msgf("LIST returned %d rows", len(oo))
|
log.Debug().Msgf(" LIST returned %d rows", len(oo))
|
||||||
|
|
||||||
var rows render.Rows
|
var rows render.Rows
|
||||||
if _, ok := meta.Renderer.(*render.Generic); ok {
|
if _, ok := meta.Renderer.(*render.Generic); ok {
|
||||||
|
|
@ -221,7 +225,7 @@ func (t *Table) reconcile(ctx context.Context) error {
|
||||||
return fmt.Errorf("expecting a meta table but got %T", oo[0])
|
return fmt.Errorf("expecting a meta table but got %T", oo[0])
|
||||||
}
|
}
|
||||||
rows = make(render.Rows, len(table.Rows))
|
rows = make(render.Rows, len(table.Rows))
|
||||||
if err := tableHydrate(t.namespace, table, rows, meta.Renderer); err != nil {
|
if err := genericHydrate(t.namespace, table, rows, meta.Renderer); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -287,6 +291,10 @@ func (t *Table) fireTableLoadFailed(err error) {
|
||||||
// Helpers...
|
// Helpers...
|
||||||
|
|
||||||
func hydrate(ns string, oo []runtime.Object, rr render.Rows, re Renderer) error {
|
func hydrate(ns string, oo []runtime.Object, rr render.Rows, re Renderer) error {
|
||||||
|
defer func(t time.Time) {
|
||||||
|
log.Debug().Msgf(" HYDRATE elapsed %v", time.Since(t))
|
||||||
|
}(time.Now())
|
||||||
|
|
||||||
for i, o := range oo {
|
for i, o := range oo {
|
||||||
if err := re.Render(o, ns, &rr[i]); err != nil {
|
if err := re.Render(o, ns, &rr[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -296,7 +304,7 @@ func hydrate(ns string, oo []runtime.Object, rr render.Rows, re Renderer) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func tableHydrate(ns string, table *metav1beta1.Table, rr render.Rows, re Renderer) error {
|
func genericHydrate(ns string, table *metav1beta1.Table, rr render.Rows, re Renderer) error {
|
||||||
gr, ok := re.(*render.Generic)
|
gr, ok := re.(*render.Generic)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("expecting generic renderer but got %T", re)
|
return fmt.Errorf("expecting generic renderer but got %T", re)
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ func (Deployment) ColorerFunc() ColorerFunc {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
markCol := 2
|
readyCol := 2
|
||||||
if !client.IsAllNamespaces(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
markCol = 1
|
readyCol--
|
||||||
}
|
}
|
||||||
tokens := strings.Split(r.Row.Fields[markCol], "/")
|
tokens := strings.Split(r.Row.Fields[readyCol], "/")
|
||||||
if tokens[0] != tokens[1] {
|
if tokens[0] != tokens[1] {
|
||||||
return ErrColor
|
return ErrColor
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@ func (DaemonSet) ColorerFunc() ColorerFunc {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
markCol := 2
|
desiredCol := 2
|
||||||
if !client.IsAllNamespaces(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
markCol = 1
|
desiredCol = 1
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+2]) {
|
if strings.TrimSpace(r.Row.Fields[desiredCol]) != strings.TrimSpace(r.Row.Fields[desiredCol+2]) {
|
||||||
return ErrColor
|
return ErrColor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ func (PodDisruptionBudget) ColorerFunc() ColorerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
markCol := 5
|
markCol := 5
|
||||||
if client.IsNamespaced(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
markCol = 4
|
markCol--
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) {
|
if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) {
|
||||||
return ErrColor
|
return ErrColor
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ func (p Pod) ColorerFunc() ColorerFunc {
|
||||||
c := DefaultColorer(ns, re)
|
c := DefaultColorer(ns, re)
|
||||||
|
|
||||||
readyCol := 2
|
readyCol := 2
|
||||||
if len(ns) != 0 {
|
if !client.IsAllNamespaces(ns) {
|
||||||
readyCol = 1
|
readyCol--
|
||||||
}
|
}
|
||||||
statusCol := readyCol + 1
|
statusCol := readyCol + 1
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ func (Pod) Header(ns string) HeaderRow {
|
||||||
Header{Name: "NAME"},
|
Header{Name: "NAME"},
|
||||||
Header{Name: "READY"},
|
Header{Name: "READY"},
|
||||||
Header{Name: "STATUS"},
|
Header{Name: "STATUS"},
|
||||||
Header{Name: "RS", Align: tview.AlignRight},
|
Header{Name: "RESTART", Align: tview.AlignRight},
|
||||||
Header{Name: "CPU", Align: tview.AlignRight},
|
Header{Name: "CPU", Align: tview.AlignRight},
|
||||||
Header{Name: "MEM", Align: tview.AlignRight},
|
Header{Name: "MEM", Align: tview.AlignRight},
|
||||||
Header{Name: "%CPU", Align: tview.AlignRight},
|
Header{Name: "%CPU", Align: tview.AlignRight},
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,9 @@ func (PersistentVolumeClaim) ColorerFunc() ColorerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
markCol := 2
|
markCol := 2
|
||||||
if client.IsNamespaced(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
markCol = 1
|
markCol--
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.TrimSpace(r.Row.Fields[markCol]) != "Bound" {
|
if strings.TrimSpace(r.Row.Fields[markCol]) != "Bound" {
|
||||||
c = ErrColor
|
c = ErrColor
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ func (ReplicaSet) ColorerFunc() ColorerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
markCol := 2
|
markCol := 2
|
||||||
if client.IsNamespaced(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
markCol = 1
|
markCol--
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) {
|
if strings.TrimSpace(r.Row.Fields[markCol]) != strings.TrimSpace(r.Row.Fields[markCol+1]) {
|
||||||
return ErrColor
|
return ErrColor
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ func (StatefulSet) ColorerFunc() ColorerFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
readyCol := 2
|
readyCol := 2
|
||||||
if client.IsNamespaced(ns) {
|
if !client.IsAllNamespaces(ns) {
|
||||||
readyCol--
|
readyCol--
|
||||||
}
|
}
|
||||||
tokens := strings.Split(strings.TrimSpace(r.Row.Fields[readyCol]), "/")
|
tokens := strings.Split(strings.TrimSpace(r.Row.Fields[readyCol]), "/")
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@ func (n *Namespace) useNsCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Namespace) useNamespace(ns string) {
|
func (n *Namespace) useNamespace(fqn string) {
|
||||||
|
_, ns := client.Namespaced(fqn)
|
||||||
log.Debug().Msgf("SWITCHING NS %q", ns)
|
log.Debug().Msgf("SWITCHING NS %q", ns)
|
||||||
n.App().switchNS(ns)
|
n.App().switchNS(ns)
|
||||||
if err := n.App().Config.SetActiveNamespace(ns); err != nil {
|
if err := n.App().Config.SetActiveNamespace(ns); err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue