parent
6881892433
commit
7603f27c9a
2
Makefile
2
Makefile
|
|
@ -11,7 +11,7 @@ DATE ?= $(shell TZ=UTC date -j -f "%s" ${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:
|
|||
else
|
||||
DATE ?= $(shell date -u -d @${SOURCE_DATE_EPOCH} +"%Y-%m-%dT%H:%M:%SZ")
|
||||
endif
|
||||
VERSION ?= v0.40.0
|
||||
VERSION ?= v0.40.1
|
||||
IMG_NAME := derailed/k9s
|
||||
IMAGE := ${IMG_NAME}:${VERSION}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>
|
||||
|
||||
# Release v0.40.1
|
||||
|
||||
## 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 are, as ever, very much noted and appreciated!
|
||||
Also big thanks to all that have allocated their own time to help others on both slack and on this repo!!
|
||||
|
||||
As you may know, K9s is not pimped out by corps with deep pockets, thus if you feel K9s is helping your Kubernetes journey,
|
||||
please consider joining our [sponsorship program](https://github.com/sponsors/derailed) and/or make some noise on social! [@kitesurfer](https://twitter.com/kitesurfer)
|
||||
|
||||
On Slack? Please join us [K9slackers](https://join.slack.com/t/k9sers/shared_invite/enQtOTA5MDEyNzI5MTU0LWQ1ZGI3MzliYzZhZWEyNzYxYzA3NjE0YTk1YmFmNzViZjIyNzhkZGI0MmJjYzhlNjdlMGJhYzE2ZGU1NjkyNTM)
|
||||
|
||||
## Maintenance Release!
|
||||
|
||||
😳 Aye! Buzz kill on the 0.40.0 aftermath... 🙀 👻
|
||||
|
||||
---
|
||||
|
||||
## Videos Are In The Can!
|
||||
|
||||
Please dial [K9s Channel](https://www.youtube.com/channel/UC897uwPygni4QIjkPCpgjmw) for up coming content...
|
||||
|
||||
* [K9s v0.40.0 <Column Blow> Sneak peek](https://youtu.be/iy6RDozAM4A)
|
||||
* [K9s v0.31.0 Configs+Sneak peek](https://youtu.be/X3444KfjguE)
|
||||
* [K9s v0.30.0 Sneak peek](https://youtu.be/mVBc1XneRJ4)
|
||||
* [Vulnerability Scans](https://youtu.be/ULkl0MsaidU)
|
||||
|
||||
---
|
||||
|
||||
## Resolved Issues
|
||||
|
||||
* [#3113](https://github.com/derailed/k9s/issues/3113) 0.40.0 can't retain temporary view sort
|
||||
* [#3111](https://github.com/derailed/k9s/issues/3111) k9s can't describe or print YAML for HPAs in all namespaces view
|
||||
* [#2966](https://github.com/derailed/k9s/issues/2966) Go to the Contexts page and filter, contexts that are matched will be filtered ou
|
||||
* [#2962](https://github.com/derailed/k9s/issues/2962) Small colour/filtering related bug
|
||||
* [#2961](https://github.com/derailed/k9s/issues/2961) Drain node with the -disable-eviction
|
||||
* [#2958](https://github.com/derailed/k9s/issues/2958) Restart count in container view associated with the wrong container
|
||||
* [#2945](https://github.com/derailed/k9s/issues/2945) Could we add ServiceAccount Column in v1/POD view
|
||||
|
||||
---
|
||||
|
||||
## Contributed PRs
|
||||
|
||||
Please be sure to give `Big Thanks!` and `ATTA Girls/Boys!` to all the fine contributors for making K9s better for all of us!!
|
||||
|
||||
* [#3094](https://github.com/derailed/k9s/pull/3094) Log in as root to the node.
|
||||
* [#3033](https://github.com/derailed/k9s/pull/3033) Skip cache invalidation on failed connection
|
||||
* [#2965](https://github.com/derailed/k9s/pull/2965) Make menu foreground style configurable through skins
|
||||
* [#2952](https://github.com/derailed/k9s/pull/2952) A modest attempt to improve the logo aesthetics
|
||||
* [#2833](https://github.com/derailed/k9s/pull/2833) allow scaling custom resource
|
||||
* [#2799](https://github.com/derailed/k9s/pull/2799) feat(app): add history navigation with [ and ], most recent command with -
|
||||
* [#2719](https://github.com/derailed/k9s/pull/2719) fix: stop table header cells from being selectable
|
||||
* [#2865](https://github.com/derailed/k9s/pull/2865) Feature/DisableAutoscroll
|
||||
|
||||
---
|
||||
|
||||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2024 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
|
@ -4,7 +4,6 @@ package dao
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
|
@ -24,13 +23,30 @@ type Dynamic struct {
|
|||
Generic
|
||||
}
|
||||
|
||||
// Get returns a given resource as a table object.
|
||||
func (d *Dynamic) Get(ctx context.Context, path string) (runtime.Object, error) {
|
||||
return nil, errors.New("Not implemented")
|
||||
oo, err := d.toTable(ctx, path)
|
||||
if err != nil || len(oo) == 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return oo[0], nil
|
||||
}
|
||||
|
||||
// List returns a collection of resources as one or more table objects.
|
||||
func (d *Dynamic) List(ctx context.Context, ns string) ([]runtime.Object, error) {
|
||||
return d.toTable(ctx, ns)
|
||||
}
|
||||
|
||||
func (d *Dynamic) toTable(ctx context.Context, fqn string) ([]runtime.Object, error) {
|
||||
strLabel, _ := ctx.Value(internal.KeyLabels).(string)
|
||||
|
||||
opts := []string{d.gvr.R()}
|
||||
ns, n := client.Namespaced(fqn)
|
||||
if n != "" {
|
||||
opts = append(opts, n)
|
||||
}
|
||||
|
||||
allNS := client.IsAllNamespaces(ns)
|
||||
flags := cmdutil.NewMatchVersionFlags(d.getFactory().Client().Config().Flags())
|
||||
f := cmdutil.NewFactory(flags)
|
||||
|
|
@ -40,7 +56,7 @@ func (d *Dynamic) List(ctx context.Context, ns string) ([]runtime.Object, error)
|
|||
LabelSelectorParam(strLabel).
|
||||
FieldSelectorParam("").
|
||||
RequestChunksOf(0).
|
||||
ResourceTypeOrNameArgs(true, d.gvr.R()).
|
||||
ResourceTypeOrNameArgs(true, opts...).
|
||||
ContinueOnError().
|
||||
Latest().
|
||||
Flatten().
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"github.com/rs/zerolog/log"
|
||||
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -17,8 +18,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -32,19 +32,19 @@ const (
|
|||
// MetaAccess tracks resources metadata.
|
||||
var MetaAccess = NewMeta()
|
||||
|
||||
var stdGroups = map[string]struct{}{
|
||||
"apps/v1": {},
|
||||
"autoscaling/v1": {},
|
||||
"autoscaling/v2": {},
|
||||
"autoscaling/v2beta1": {},
|
||||
"autoscaling/v2beta2": {},
|
||||
"batch/v1": {},
|
||||
"batch/v1beta1": {},
|
||||
"extensions/v1beta1": {},
|
||||
"policy/v1beta1": {},
|
||||
"policy/v1": {},
|
||||
"v1": {},
|
||||
}
|
||||
var stdGroups = sets.New[string](
|
||||
"apps/v1",
|
||||
"autoscaling/v1",
|
||||
"autoscaling/v2",
|
||||
"autoscaling/v2beta1",
|
||||
"autoscaling/v2beta2",
|
||||
"batch/v1",
|
||||
"batch/v1beta1",
|
||||
"extensions/v1beta1",
|
||||
"policy/v1beta1",
|
||||
"policy/v1",
|
||||
"v1",
|
||||
)
|
||||
|
||||
func (m ResourceMetas) clear() {
|
||||
for k := range m {
|
||||
|
|
@ -381,20 +381,15 @@ func loadPreferred(f Factory, m ResourceMetas) error {
|
|||
}
|
||||
|
||||
func isStandardGroup(gv string) bool {
|
||||
if _, ok := stdGroups[gv]; ok {
|
||||
return true
|
||||
}
|
||||
|
||||
return strings.Contains(gv, "k8s.io")
|
||||
return stdGroups.Has(gv) || strings.Contains(gv, "k8s.io")
|
||||
}
|
||||
|
||||
var deprecatedGVRs = map[client.GVR]struct{}{
|
||||
client.NewGVR("extensions/v1beta1/ingresses"): {},
|
||||
}
|
||||
var deprecatedGVRs = sets.New[client.GVR](
|
||||
client.NewGVR("extensions/v1beta1/ingresses"),
|
||||
)
|
||||
|
||||
func isDeprecated(gvr client.GVR) bool {
|
||||
_, ok := deprecatedGVRs[gvr]
|
||||
return ok
|
||||
return deprecatedGVRs.Has(gvr)
|
||||
}
|
||||
|
||||
// loadCRDs Wait for the cache to synced and then add some additional properties to CRD.
|
||||
|
|
|
|||
|
|
@ -84,9 +84,9 @@ var Registry = map[string]ResourceMeta{
|
|||
},
|
||||
|
||||
// Core...
|
||||
// "v1/endpoints": {
|
||||
// Renderer: &render.Endpoints{},
|
||||
// },
|
||||
"v1/endpoints": {
|
||||
Renderer: &render.Endpoints{},
|
||||
},
|
||||
"v1/pods": {
|
||||
DAO: &dao.Pod{},
|
||||
Renderer: render.NewPod(),
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ import (
|
|||
"k8s.io/client-go/util/jsonpath"
|
||||
)
|
||||
|
||||
// ColsSpecs represents a collection of column specification ie NAME:spec|flags.
|
||||
type ColsSpecs []string
|
||||
|
||||
// NewColsSpecs returns a new instance.
|
||||
func NewColsSpecs(cols ...string) ColsSpecs {
|
||||
return ColsSpecs(cols)
|
||||
}
|
||||
|
|
@ -40,6 +42,7 @@ func (cc ColsSpecs) parseSpecs() (ColumnSpecs, error) {
|
|||
return specs, nil
|
||||
}
|
||||
|
||||
// RenderedCols tracks a collection of column header and cust column parse expression.
|
||||
type RenderedCols []RenderedCol
|
||||
|
||||
func (rr RenderedCols) hydrateRow(row *model1.Row) {
|
||||
|
|
@ -50,6 +53,7 @@ func (rr RenderedCols) hydrateRow(row *model1.Row) {
|
|||
row.Fields = ff
|
||||
}
|
||||
|
||||
// HasHeader checks if a given header is present in the collection.
|
||||
func (rr RenderedCols) HasHeader(n string) bool {
|
||||
for _, r := range rr {
|
||||
if r.has(n) {
|
||||
|
|
@ -60,26 +64,31 @@ func (rr RenderedCols) HasHeader(n string) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// RenderedCol represents a column header and a column spec.
|
||||
type RenderedCol struct {
|
||||
Header model1.HeaderColumn
|
||||
Value string
|
||||
}
|
||||
|
||||
// Has checks if the header column match the given name.
|
||||
func (r RenderedCol) has(n string) bool {
|
||||
return r.Header.Name == n
|
||||
}
|
||||
|
||||
// ColumnSpec tracks a header column and an options cust column spec.
|
||||
type ColumnSpec struct {
|
||||
Header model1.HeaderColumn
|
||||
Spec string
|
||||
}
|
||||
|
||||
// ColumnSpecs tracks a collection of column specs.
|
||||
type ColumnSpecs []ColumnSpec
|
||||
|
||||
func (c ColumnSpecs) isEmpty() bool {
|
||||
return len(c) == 0
|
||||
}
|
||||
|
||||
// Header builds a new header that is a super set of custom and/or default header.
|
||||
func (cc ColumnSpecs) Header(rh model1.Header) model1.Header {
|
||||
hh := make(model1.Header, 0, len(cc))
|
||||
for _, h := range cc {
|
||||
|
|
|
|||
|
|
@ -92,18 +92,26 @@ func (t *Table) Render(o any, ns string, r *model1.Row) error {
|
|||
func (t *Table) defaultRow(row *metav1.TableRow, ns string, r *model1.Row) error {
|
||||
th := t.defaultHeader()
|
||||
ons, name := ns, UnknownValue
|
||||
if row.Object.Object != nil {
|
||||
m, _ := meta.Accessor(row.Object.Object)
|
||||
if m != nil {
|
||||
switch {
|
||||
case row.Object.Object != nil:
|
||||
if m, _ := meta.Accessor(row.Object.Object); m != nil {
|
||||
ons, name = m.GetNamespace(), m.GetName()
|
||||
}
|
||||
} else if idx, ok := th.IndexOf("NAME", true); ok && idx >= 0 {
|
||||
name = row.Cells[idx].(string)
|
||||
if idx, ok := th.IndexOf("NAMESPACE", true); ok && idx >= 0 {
|
||||
ons = row.Cells[idx].(string)
|
||||
case row.Object.Raw != nil:
|
||||
var pm metav1.PartialObjectMetadata
|
||||
if err := json.Unmarshal(row.Object.Raw, &pm); err != nil {
|
||||
return err
|
||||
}
|
||||
ons, name = pm.Namespace, pm.Name
|
||||
default:
|
||||
if idx, ok := th.IndexOf("NAME", true); ok && idx >= 0 {
|
||||
name = row.Cells[idx].(string)
|
||||
if idx, ok := th.IndexOf("NAMESPACE", true); ok && idx >= 0 {
|
||||
ons = row.Cells[idx].(string)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
|
||||
if client.IsClusterWide(ons) {
|
||||
ons = client.ClusterScope
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,9 +157,12 @@ func (t *Table) GVR() client.GVR { return t.gvr }
|
|||
func (t *Table) ViewSettingsChanged(vs *config.ViewSetting) {
|
||||
if t.setViewSetting(vs) {
|
||||
if vs == nil {
|
||||
t.setSortCol(model1.SortColumn{})
|
||||
if !t.getMSort() {
|
||||
t.setSortCol(model1.SortColumn{})
|
||||
}
|
||||
} else {
|
||||
t.setMSort(false)
|
||||
}
|
||||
t.setMSort(false)
|
||||
t.Refresh()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
name: k9s
|
||||
base: core22
|
||||
version: 'v0.40.0'
|
||||
version: 'v0.40.1'
|
||||
summary: K9s is a CLI to view and manage your Kubernetes clusters.
|
||||
description: |
|
||||
K9s is a CLI to view and manage your Kubernetes clusters. By leveraging a terminal UI, you can easily traverse Kubernetes resources and view the state of your clusters in a single powerful session.
|
||||
|
|
|
|||
Loading…
Reference in New Issue