Release v0.27.3 (#1970)
- [Issue #1968](https://github.com/derailed/k9s/issues/1968) Some skins are missing the definitions for the help menu - [Issue #1967](https://github.com/derailed/k9s/issues/1967) Helm cve-2023-25165 - [Issue #1964](https://github.com/derailed/k9s/issues/1964) logger.sinceSeconds config setting inconsistent with README - [Issue #1955](https://github.com/derailed/k9s/issues/1955) K9s crashes with empty resources and/or verbs in RBAC - [Issue #1954](https://github.com/derailed/k9s/issues/1954) Open very slow - [Issue #1883](https://github.com/derailed/k9s/issues/1883) Fix force deletion - [Issue #1788](https://github.com/derailed/k9s/issues/1788) Draining nodes cannot be forced - [Issue #1150](https://github.com/derailed/k9s/issues/1150) Add a persistent popup for drain failuresmine
parent
d4ae1c7a74
commit
7c76691c38
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.27.2
|
||||
VERSION ?= v0.27.3
|
||||
IMG_NAME := derailed/k9s
|
||||
IMAGE := ${IMG_NAME}:${VERSION}
|
||||
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ K9s uses aliases to navigate most K8s resources.
|
|||
| To view and switch to another Kubernetes namespace | `:`ns⏎ | |
|
||||
| To view all saved resources | `:`screendump or sd⏎ | |
|
||||
| To delete a resource (TAB and ENTER to confirm) | `ctrl-d` | |
|
||||
| To kill a resource (no confirmation dialog!) | `ctrl-k` | |
|
||||
| To kill a resource (no confirmation dialog, equivalent to kubectl delete --now) | `ctrl-k` | |
|
||||
| Launch pulses view | `:`pulses or pu⏎ | |
|
||||
| Launch XRay view | `:`xray RESOURCE [NAMESPACE]⏎ | RESOURCE can be one of po, svc, dp, rs, sts, ds, NAMESPACE is optional |
|
||||
| Launch Popeye view | `:`popeye or pop⏎ | See [popeye](#popeye) |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/k9s.png" align="center" width="800" height="auto"/>
|
||||
|
||||
# Release v0.27.3
|
||||
|
||||
## 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)
|
||||
|
||||
---
|
||||
|
||||
## ♫ Sounds Behind The Release ♭
|
||||
|
||||
* [Bitches Brew - Miles Davis](https://www.youtube.com/watch?v=50fB5L1vmn8)
|
||||
* [Sordid Affair - Röyksopp](https://www.youtube.com/watch?v=ECL5zO6ImsA)
|
||||
* [Love Inc - Booka Shade](https://www.youtube.com/watch?v=sgLxTcok8kQ)
|
||||
* [Twisted - Kaz James,Nick Morgan](https://www.youtube.com/watch?v=oOsYJ-Co8Y4)
|
||||
|
||||
---
|
||||
|
||||
## A Word From Our Sponsors...
|
||||
|
||||
To all the good folks below that opted to `pay it forward` and join our sponsorship program, I salute you!!
|
||||
|
||||
* [Astraea](https://github.com/s22)
|
||||
* [Arnaud Bienvenu](https://github.com/abienvenu)
|
||||
* [Eric Caleb](https://github.com/iamcaleberic)
|
||||
* [Sean Williams](https://github.com/SeanThomasWilliams)
|
||||
* [Federico Ragona](https://github.com/fedragon)
|
||||
|
||||
> Sponsorship cancellations since the last release: `7` ;(
|
||||
|
||||
---
|
||||
|
||||
## Maintenance Release
|
||||
|
||||
---
|
||||
|
||||
## Resolved Issues
|
||||
|
||||
* [Issue #1968](https://github.com/derailed/k9s/issues/1968) Some skins are missing the definitions for the help menu
|
||||
* [Issue #1967](https://github.com/derailed/k9s/issues/1967) Helm cve-2023-25165
|
||||
* [Issue #1964](https://github.com/derailed/k9s/issues/1964) logger.sinceSeconds config setting inconsistent with README
|
||||
* [Issue #1955](https://github.com/derailed/k9s/issues/1955) K9s crashes with empty resources and/or verbs in RBAC
|
||||
* [Issue #1954](https://github.com/derailed/k9s/issues/1954) Open very slow
|
||||
* [Issue #1883](https://github.com/derailed/k9s/issues/1883) Fix force deletion
|
||||
* [Issue #1788](https://github.com/derailed/k9s/issues/1788) Draining nodes cannot be forced
|
||||
* [Issue #1150](https://github.com/derailed/k9s/issues/1150) Add a persistent popup for drain failures
|
||||
|
||||
---
|
||||
|
||||
## Contributed PRs
|
||||
|
||||
Please give `Big Thanks!` and `ATTA Girls/Boys!` to all the fine contributors for making K9s better for all of us!!
|
||||
|
||||
* [PR #1969](https://github.com/derailed/k9s/pull/1969) fix: Add missing help menu to gruvbox-dark skin
|
||||
* [PR #1966](https://github.com/derailed/k9s/pull/1966) fix: Show meaningful error message when kubectl exec fails
|
||||
* [PR #1965](https://github.com/derailed/k9s/pull/1965) set default sinceSeconds to 300
|
||||
* [PR #1961](https://github.com/derailed/k9s/pull/1961) feat: Add sort by pod count on node view
|
||||
* [PR #1960](https://github.com/derailed/k9s/pull/1960) [Misc] Add Nightfox-theme
|
||||
|
||||
---
|
||||
|
||||
<img src="https://raw.githubusercontent.com/derailed/k9s/master/assets/imhotep_logo.png" width="32" height="auto"/> © 2022 Imhotep Software LLC. All materials licensed under [Apache v2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
|
@ -3,13 +3,14 @@ package cmd
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/derailed/k9s/internal/color"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/spf13/cobra"
|
||||
"gopkg.in/yaml.v2"
|
||||
"os"
|
||||
)
|
||||
|
||||
func infoCmd() *cobra.Command {
|
||||
|
|
@ -56,5 +57,9 @@ func getScreenDumpDirForInfo() string {
|
|||
log.Error().Err(err).Msgf("Unmarshal k9s config %v", err)
|
||||
return config.K9sDefaultScreenDumpDir
|
||||
}
|
||||
if cfg.K9s == nil {
|
||||
cfg.K9s = config.NewK9s()
|
||||
}
|
||||
|
||||
return cfg.K9s.GetScreenDumpDir()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ type Benchmark struct {
|
|||
}
|
||||
|
||||
// Delete nukes a resource.
|
||||
func (b *Benchmark) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
func (b *Benchmark) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ Grace) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@ import (
|
|||
"k8s.io/client-go/dynamic"
|
||||
)
|
||||
|
||||
type Grace int64
|
||||
|
||||
const (
|
||||
// DefaultGrace uses delete default termination policy.
|
||||
DefaultGrace Grace = -1
|
||||
|
||||
// ForceGrace sets delete grace-period to 0.
|
||||
ForceGrace Grace = 0
|
||||
|
||||
// NowGrace set delete grace-period to 1,
|
||||
NowGrace Grace = 1
|
||||
)
|
||||
|
||||
var _ Describer = (*Generic)(nil)
|
||||
|
||||
// Generic represents a generic resource.
|
||||
|
|
@ -88,7 +101,7 @@ func (g *Generic) ToYAML(path string, showManaged bool) (string, error) {
|
|||
}
|
||||
|
||||
// Delete deletes a resource.
|
||||
func (g *Generic) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error {
|
||||
func (g *Generic) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, grace Grace) error {
|
||||
ns, n := client.Namespaced(path)
|
||||
auth, err := g.Client().CanI(ns, g.gvr.String(), []string{client.DeleteVerb})
|
||||
if err != nil {
|
||||
|
|
@ -98,13 +111,13 @@ func (g *Generic) Delete(ctx context.Context, path string, propagation *metav1.D
|
|||
return fmt.Errorf("user is not authorized to delete %s", path)
|
||||
}
|
||||
|
||||
var gracePeriod *int64
|
||||
if grace != DefaultGrace {
|
||||
gracePeriod = (*int64)(&grace)
|
||||
}
|
||||
opts := metav1.DeleteOptions{
|
||||
PropagationPolicy: propagation,
|
||||
}
|
||||
|
||||
if force {
|
||||
var defaultKillGrace int64 = 1
|
||||
opts.GracePeriodSeconds = &defaultKillGrace
|
||||
GracePeriodSeconds: gracePeriod,
|
||||
}
|
||||
|
||||
dial, err := g.dynClient()
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ func (h *Helm) ToYAML(path string, showManaged bool) (string, error) {
|
|||
}
|
||||
|
||||
// Delete uninstall a Helm.
|
||||
func (h *Helm) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
func (h *Helm) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ Grace) error {
|
||||
ns, n := client.Namespaced(path)
|
||||
cfg, err := h.EnsureHelmConfig(ns)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -77,6 +77,7 @@ func (o DrainOptions) toDrainHelper(k kubernetes.Interface, w io.Writer) drain.H
|
|||
IgnoreAllDaemonSets: o.IgnoreAllDaemonSets,
|
||||
Out: w,
|
||||
ErrOut: w,
|
||||
Force: o.Force,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ type PortForward struct {
|
|||
}
|
||||
|
||||
// Delete deletes a portforward.
|
||||
func (p *PortForward) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ bool) error {
|
||||
func (p *PortForward) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ Grace) error {
|
||||
p.GetFactory().DeleteForwarder(path)
|
||||
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ type ScreenDump struct {
|
|||
}
|
||||
|
||||
// Delete a ScreenDump.
|
||||
func (d *ScreenDump) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, force bool) error {
|
||||
func (d *ScreenDump) Delete(_ context.Context, path string, _ *metav1.DeletionPropagation, _ Grace) error {
|
||||
return os.Remove(path)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ type Controller interface {
|
|||
// Nuker represents a resource deleter.
|
||||
type Nuker interface {
|
||||
// Delete removes a resource from the api server.
|
||||
Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error
|
||||
Delete(context.Context, string, *metav1.DeletionPropagation, Grace) error
|
||||
}
|
||||
|
||||
// Switchable represents a switchable resource.
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ func (t *Table) Get(ctx context.Context, path string) (runtime.Object, error) {
|
|||
}
|
||||
|
||||
// Delete deletes a resource.
|
||||
func (t *Table) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error {
|
||||
func (t *Table) Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, grace dao.Grace) error {
|
||||
meta, err := getMeta(ctx, t.gvr)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -122,7 +122,7 @@ func (t *Table) Delete(ctx context.Context, path string, propagation *metav1.Del
|
|||
return fmt.Errorf("no nuker for %q", meta.DAO.GVR())
|
||||
}
|
||||
|
||||
return nuker.Delete(ctx, path, propagation, force)
|
||||
return nuker.Delete(ctx, path, propagation, grace)
|
||||
}
|
||||
|
||||
// GetNamespace returns the model namespace.
|
||||
|
|
|
|||
|
|
@ -74,6 +74,9 @@ func (Policy) Render(o interface{}, gvr string, r *Row) error {
|
|||
// Helpers...
|
||||
|
||||
func cleanseResource(r string) string {
|
||||
if r == "" {
|
||||
return r
|
||||
}
|
||||
if r[0] == '/' {
|
||||
return r
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,11 +6,9 @@ import (
|
|||
"github.com/derailed/tview"
|
||||
)
|
||||
|
||||
const confirmKey = "confirm"
|
||||
const dialogKey = "dialog"
|
||||
|
||||
type (
|
||||
confirmFunc func()
|
||||
)
|
||||
type confirmFunc func()
|
||||
|
||||
// ShowConfirm pops a confirmation dialog.
|
||||
func ShowConfirm(styles config.Dialog, pages *ui.Pages, title, msg string, ack confirmFunc, cancel cancelFunc) {
|
||||
|
|
@ -22,12 +20,12 @@ func ShowConfirm(styles config.Dialog, pages *ui.Pages, title, msg string, ack c
|
|||
SetLabelColor(styles.LabelFgColor.Color()).
|
||||
SetFieldTextColor(styles.FieldFgColor.Color())
|
||||
f.AddButton("Cancel", func() {
|
||||
dismissConfirm(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
f.AddButton("OK", func() {
|
||||
ack()
|
||||
dismissConfirm(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
for i := 0; i < 2; i++ {
|
||||
|
|
@ -43,13 +41,13 @@ func ShowConfirm(styles config.Dialog, pages *ui.Pages, title, msg string, ack c
|
|||
modal.SetText(msg)
|
||||
modal.SetTextColor(styles.FgColor.Color())
|
||||
modal.SetDoneFunc(func(int, string) {
|
||||
dismissConfirm(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
pages.AddPage(confirmKey, modal, false, false)
|
||||
pages.ShowPage(confirmKey)
|
||||
pages.AddPage(dialogKey, modal, false, false)
|
||||
pages.ShowPage(dialogKey)
|
||||
}
|
||||
|
||||
func dismissConfirm(pages *ui.Pages) {
|
||||
pages.RemovePage(confirmKey)
|
||||
func dismiss(pages *ui.Pages) {
|
||||
pages.RemovePage(dialogKey)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ func TestConfirmDialog(t *testing.T) {
|
|||
}
|
||||
ShowConfirm(config.Dialog{}, p, "Blee", "Yo", ackFunc, caFunc)
|
||||
|
||||
d := p.GetPrimitive(confirmKey).(*tview.ModalForm)
|
||||
d := p.GetPrimitive(dialogKey).(*tview.ModalForm)
|
||||
assert.NotNil(t, d)
|
||||
|
||||
dismissConfirm(p)
|
||||
assert.Nil(t, p.GetPrimitive(confirmKey))
|
||||
dismiss(p)
|
||||
assert.Nil(t, p.GetPrimitive(dialogKey))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,15 @@ import (
|
|||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
const deleteKey = "delete"
|
||||
const (
|
||||
noDeletePropagation = "None"
|
||||
defaultPropagationIdx = 0
|
||||
)
|
||||
|
||||
const noDeletePropagation = "None"
|
||||
|
||||
const defaultPropagationIdx = 0
|
||||
type (
|
||||
okFunc func(propagation *metav1.DeletionPropagation, force bool)
|
||||
cancelFunc func()
|
||||
)
|
||||
|
||||
var propagationOptions []string = []string{
|
||||
string(metav1.DeletePropagationBackground),
|
||||
|
|
@ -20,11 +24,6 @@ var propagationOptions []string = []string{
|
|||
noDeletePropagation,
|
||||
}
|
||||
|
||||
type (
|
||||
okFunc func(propagation *metav1.DeletionPropagation, force bool)
|
||||
cancelFunc func()
|
||||
)
|
||||
|
||||
// ShowDelete pops a resource deletion dialog.
|
||||
func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, cancel cancelFunc) {
|
||||
propagation, force := "", false
|
||||
|
|
@ -47,7 +46,7 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca
|
|||
force = checked
|
||||
})
|
||||
f.AddButton("Cancel", func() {
|
||||
dismissDelete(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
f.AddButton("OK", func() {
|
||||
|
|
@ -58,7 +57,7 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca
|
|||
p := metav1.DeletionPropagation(propagation)
|
||||
ok(&p, force)
|
||||
}
|
||||
dismissDelete(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
for i := 0; i < 2; i++ {
|
||||
|
|
@ -74,13 +73,9 @@ func ShowDelete(styles config.Dialog, pages *ui.Pages, msg string, ok okFunc, ca
|
|||
confirm := tview.NewModalForm("<Delete>", f)
|
||||
confirm.SetText(msg)
|
||||
confirm.SetDoneFunc(func(int, string) {
|
||||
dismissDelete(pages)
|
||||
dismiss(pages)
|
||||
cancel()
|
||||
})
|
||||
pages.AddPage(deleteKey, confirm, false, false)
|
||||
pages.ShowPage(deleteKey)
|
||||
}
|
||||
|
||||
func dismissDelete(pages *ui.Pages) {
|
||||
pages.RemovePage(deleteKey)
|
||||
pages.AddPage(dialogKey, confirm, false, false)
|
||||
pages.ShowPage(dialogKey)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ func TestDeleteDialog(t *testing.T) {
|
|||
}
|
||||
ShowDelete(config.Dialog{}, p, "Yo", okFunc, caFunc)
|
||||
|
||||
d := p.GetPrimitive(deleteKey).(*tview.ModalForm)
|
||||
d := p.GetPrimitive(dialogKey).(*tview.ModalForm)
|
||||
assert.NotNil(t, d)
|
||||
|
||||
dismissDelete(p)
|
||||
assert.Nil(t, p.GetPrimitive(deleteKey))
|
||||
dismiss(p)
|
||||
assert.Nil(t, p.GetPrimitive(dialogKey))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/derailed/tview"
|
||||
)
|
||||
|
||||
// ShowConfirm pops a confirmation dialog.
|
||||
// ShowError pops an error dialog.
|
||||
func ShowError(styles config.Dialog, pages *ui.Pages, msg string) {
|
||||
f := tview.NewForm()
|
||||
f.SetItemPadding(0)
|
||||
|
|
@ -20,7 +20,7 @@ func ShowError(styles config.Dialog, pages *ui.Pages, msg string) {
|
|||
SetLabelColor(styles.LabelFgColor.Color()).
|
||||
SetFieldTextColor(tcell.ColorIndianRed)
|
||||
f.AddButton("Dismiss", func() {
|
||||
dismissError(pages)
|
||||
dismiss(pages)
|
||||
})
|
||||
if b := f.GetButton(0); b != nil {
|
||||
b.SetBackgroundColorActivated(styles.ButtonFocusBgColor.Color())
|
||||
|
|
@ -31,14 +31,10 @@ func ShowError(styles config.Dialog, pages *ui.Pages, msg string) {
|
|||
modal.SetText(cowTalk(msg))
|
||||
modal.SetTextColor(tcell.ColorOrangeRed)
|
||||
modal.SetDoneFunc(func(int, string) {
|
||||
dismissError(pages)
|
||||
dismiss(pages)
|
||||
})
|
||||
pages.AddPage(confirmKey, modal, false, false)
|
||||
pages.ShowPage(confirmKey)
|
||||
}
|
||||
|
||||
func dismissError(pages *ui.Pages) {
|
||||
pages.RemovePage(confirmKey)
|
||||
pages.AddPage(dialogKey, modal, false, false)
|
||||
pages.ShowPage(dialogKey)
|
||||
}
|
||||
|
||||
func cowTalk(says string) string {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package dialog
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
"github.com/derailed/tview"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestErrorDialog(t *testing.T) {
|
||||
p := ui.NewPages()
|
||||
|
||||
ShowError(config.Dialog{}, p, "Yo")
|
||||
|
||||
d := p.GetPrimitive(dialogKey).(*tview.ModalForm)
|
||||
assert.NotNil(t, d)
|
||||
dismiss(p)
|
||||
assert.Nil(t, p.GetPrimitive(dialogKey))
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/derailed/k9s/internal"
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
|
|
@ -80,7 +81,7 @@ func (t *mockModel) Get(ctx context.Context, path string) (runtime.Object, error
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockModel) Delete(ctx context.Context, path string, p *metav1.DeletionPropagation, f bool) error {
|
||||
func (t *mockModel) Delete(context.Context, string, *metav1.DeletionPropagation, dao.Grace) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
|
@ -78,5 +79,5 @@ type Tabular interface {
|
|||
RemoveListener(model.TableListener)
|
||||
|
||||
// Delete a resource.
|
||||
Delete(ctx context.Context, path string, propagation *metav1.DeletionPropagation, force bool) error
|
||||
Delete(context.Context, string, *metav1.DeletionPropagation, dao.Grace) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/derailed/k9s/internal"
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
|
|
@ -126,7 +127,7 @@ func (t *mockModel) Get(context.Context, string) (runtime.Object, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockModel) Delete(context.Context, string, *metav1.DeletionPropagation, bool) error {
|
||||
func (t *mockModel) Delete(context.Context, string, *metav1.DeletionPropagation, dao.Grace) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ func (b *Browser) bindKeys(aa ui.KeyActions) {
|
|||
tcell.KeyEscape: ui.NewSharedKeyAction("Filter Reset", b.resetCmd, false),
|
||||
tcell.KeyEnter: ui.NewSharedKeyAction("Filter", b.filterCmd, false),
|
||||
tcell.KeyHelp: ui.NewSharedKeyAction("Help", b.helpCmd, false),
|
||||
ui.KeyV: ui.NewSharedKeyAction("Zob", b.blahCmd, true),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -350,6 +351,28 @@ func (b *Browser) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (b *Browser) blahCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
b.Stop()
|
||||
defer b.Start()
|
||||
{
|
||||
v := NewDetails(b.app, "Results", "Blee", true)
|
||||
if err := v.app.inject(v, false); err != nil {
|
||||
v.app.Flash().Err(err)
|
||||
}
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
j := i
|
||||
b.app.QueueUpdateDraw(func() {
|
||||
log.Debug().Msgf("YO %d", j)
|
||||
fmt.Fprintf(v.GetWriter(), "Yo %d\n", j)
|
||||
time.Sleep(1 * time.Second)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Browser) describeCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
path := b.GetSelectedItem()
|
||||
if path == "" {
|
||||
|
|
@ -531,7 +554,7 @@ func (b *Browser) simpleDelete(selections []string, msg string) {
|
|||
b.app.Flash().Errf("Invalid nuker %T", b.accessor)
|
||||
continue
|
||||
}
|
||||
if err := nuker.Delete(context.Background(), sel, nil, false); err != nil {
|
||||
if err := nuker.Delete(context.Background(), sel, nil, dao.DefaultGrace); err != nil {
|
||||
b.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
b.app.factory.DeleteForwarder(sel)
|
||||
|
|
@ -551,7 +574,11 @@ func (b *Browser) resourceDelete(selections []string, msg string) {
|
|||
b.app.Flash().Infof("Delete resource %s %s", b.GVR(), selections[0])
|
||||
}
|
||||
for _, sel := range selections {
|
||||
if err := b.GetModel().Delete(b.defaultContext(), sel, propagation, force); err != nil {
|
||||
grace := dao.DefaultGrace
|
||||
if force {
|
||||
grace = dao.ForceGrace
|
||||
}
|
||||
if err := b.GetModel().Delete(b.defaultContext(), sel, propagation, grace); err != nil {
|
||||
b.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
b.app.factory.DeleteForwarder(sel)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package view
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
|
|
@ -159,6 +160,10 @@ func (d *Details) Update(buff string) *Details {
|
|||
return d
|
||||
}
|
||||
|
||||
func (d *Details) GetWriter() io.Writer {
|
||||
return d.text
|
||||
}
|
||||
|
||||
// SetSubject updates the subject.
|
||||
func (d *Details) SetSubject(s string) {
|
||||
d.subject = s
|
||||
|
|
|
|||
|
|
@ -281,7 +281,6 @@ func (h *Help) resetTitle() {
|
|||
|
||||
func (h *Help) addSpacer(c int) {
|
||||
cell := tview.NewTableCell(render.Pad("", h.maxKey))
|
||||
cell.SetBackgroundColor(h.App().Styles.BgColor())
|
||||
cell.SetExpansion(1)
|
||||
h.SetCell(0, c, cell)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,8 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
|
|
@ -71,13 +69,11 @@ func (n *Node) drainCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return evt
|
||||
}
|
||||
|
||||
defaults := dao.DrainOptions{
|
||||
opts := dao.DrainOptions{
|
||||
GracePeriodSeconds: -1,
|
||||
Timeout: 5 * time.Second,
|
||||
DeleteEmptyDirData: false,
|
||||
IgnoreAllDaemonSets: false,
|
||||
}
|
||||
ShowDrain(n, path, defaults, drainNode)
|
||||
ShowDrain(n, path, opts, drainNode)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
@ -94,19 +90,21 @@ func drainNode(v ResourceViewer, path string, opts dao.DrainOptions) {
|
|||
return
|
||||
}
|
||||
|
||||
buff := bytes.NewBufferString("")
|
||||
if err := m.Drain(path, opts, buff); err != nil {
|
||||
v.Stop()
|
||||
defer v.Start()
|
||||
{
|
||||
d := NewDetails(v.App(), "Drain Progress", path, true)
|
||||
if err := v.App().inject(d, false); err != nil {
|
||||
v.App().Flash().Err(err)
|
||||
}
|
||||
|
||||
if err := m.Drain(path, opts, d.GetWriter()); err != nil {
|
||||
v.App().Flash().Err(err)
|
||||
return
|
||||
}
|
||||
lines := strings.Split(buff.String(), "\n")
|
||||
for _, l := range lines {
|
||||
if len(l) > 0 {
|
||||
v.App().Flash().Info(l)
|
||||
}
|
||||
}
|
||||
v.Refresh()
|
||||
}
|
||||
}
|
||||
|
||||
func (n *Node) toggleCordonCmd(cordon bool) func(evt *tcell.EventKey) *tcell.EventKey {
|
||||
return func(evt *tcell.EventKey) *tcell.EventKey {
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ func (p *PortForward) deleteCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
for _, s := range selections {
|
||||
var pf dao.PortForward
|
||||
pf.Init(p.App().factory, client.NewGVR("portforwards"))
|
||||
if err := pf.Delete(context.Background(), s, nil, true); err != nil {
|
||||
if err := pf.Delete(context.Background(), s, nil, dao.DefaultGrace); err != nil {
|
||||
p.App().Flash().Err(err)
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ func (p *Pod) killCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
}
|
||||
p.GetTable().ShowDeleted()
|
||||
for _, path := range selections {
|
||||
if err := nuker.Delete(context.Background(), path, nil, true); err != nil {
|
||||
if err := nuker.Delete(context.Background(), path, nil, dao.NowGrace); err != nil {
|
||||
p.App().Flash().Errf("Delete failed with %s", err)
|
||||
} else {
|
||||
p.App().factory.DeleteForwarder(path)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/derailed/k9s/internal"
|
||||
"github.com/derailed/k9s/internal/client"
|
||||
"github.com/derailed/k9s/internal/config"
|
||||
"github.com/derailed/k9s/internal/dao"
|
||||
"github.com/derailed/k9s/internal/model"
|
||||
"github.com/derailed/k9s/internal/render"
|
||||
"github.com/derailed/k9s/internal/ui"
|
||||
|
|
@ -140,7 +141,7 @@ func (t *mockTableModel) Get(context.Context, string) (runtime.Object, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
func (t *mockTableModel) Delete(context.Context, string, *metav1.DeletionPropagation, bool) error {
|
||||
func (t *mockTableModel) Delete(context.Context, string, *metav1.DeletionPropagation, dao.Grace) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -672,7 +672,11 @@ func (x *Xray) resourceDelete(gvr client.GVR, spec *xray.NodeSpec, msg string) {
|
|||
x.app.Flash().Errf("Invalid nuker %T", accessor)
|
||||
return
|
||||
}
|
||||
if err := nuker.Delete(context.Background(), spec.Path(), nil, true); err != nil {
|
||||
grace := dao.DefaultGrace
|
||||
if force {
|
||||
grace = dao.ForceGrace
|
||||
}
|
||||
if err := nuker.Delete(context.Background(), spec.Path(), nil, grace); err != nil {
|
||||
x.app.Flash().Errf("Delete failed with `%s", err)
|
||||
} else {
|
||||
x.app.Flash().Infof("%s `%s deleted successfully", x.GVR(), spec.Path())
|
||||
|
|
|
|||
Loading…
Reference in New Issue