104 lines
2.3 KiB
Go
104 lines
2.3 KiB
Go
// SPDX-License-Identifier: Apache-2.0
|
|
// Copyright Authors of K9s
|
|
|
|
package view
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/derailed/k9s/internal/dao"
|
|
"github.com/derailed/k9s/internal/ui"
|
|
"github.com/derailed/k9s/internal/ui/dialog"
|
|
"github.com/derailed/tcell/v2"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
)
|
|
|
|
// RestartExtender represents a restartable resource.
|
|
type RestartExtender struct {
|
|
ResourceViewer
|
|
}
|
|
|
|
// NewRestartExtender returns a new extender.
|
|
func NewRestartExtender(v ResourceViewer) ResourceViewer {
|
|
r := RestartExtender{ResourceViewer: v}
|
|
v.AddBindKeysFn(r.bindKeys)
|
|
|
|
return &r
|
|
}
|
|
|
|
// BindKeys creates additional menu actions.
|
|
func (r *RestartExtender) bindKeys(aa *ui.KeyActions) {
|
|
if r.App().Config.IsReadOnly() {
|
|
return
|
|
}
|
|
aa.Add(ui.KeyR, ui.NewKeyActionWithOpts("Restart", r.restartCmd,
|
|
ui.ActionOpts{
|
|
Visible: true,
|
|
Dangerous: true,
|
|
},
|
|
))
|
|
}
|
|
|
|
func (r *RestartExtender) restartCmd(*tcell.EventKey) *tcell.EventKey {
|
|
paths := r.GetTable().GetSelectedItems()
|
|
if len(paths) == 0 || paths[0] == "" {
|
|
return nil
|
|
}
|
|
|
|
r.Stop()
|
|
defer r.Start()
|
|
msg := fmt.Sprintf("Restart %s %s?", singularize(r.GVR().R()), paths[0])
|
|
if len(paths) > 1 {
|
|
msg = fmt.Sprintf("Restart %d %s?", len(paths), r.GVR().R())
|
|
}
|
|
d := r.App().Styles.Dialog()
|
|
|
|
opts := dialog.RestartDialogOpts{
|
|
Title: "Confirm Restart",
|
|
Message: msg,
|
|
FieldManager: "kubectl-rollout",
|
|
Ack: func(opts *metav1.PatchOptions) bool {
|
|
ctx, cancel := context.WithTimeout(context.Background(), r.App().Conn().Config().CallTimeout())
|
|
defer cancel()
|
|
for _, path := range paths {
|
|
if err := r.restartRollout(ctx, path, opts); err != nil {
|
|
r.App().Flash().Err(err)
|
|
} else {
|
|
r.App().Flash().Infof("Restart in progress for `%s...", path)
|
|
}
|
|
}
|
|
return true
|
|
},
|
|
Cancel: func() {},
|
|
}
|
|
dialog.ShowRestart(&d, r.App().Content.Pages, &opts)
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *RestartExtender) restartRollout(ctx context.Context, path string, opts *metav1.PatchOptions) error {
|
|
res, err := dao.AccessorFor(r.App().factory, r.GVR())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
s, ok := res.(dao.Restartable)
|
|
if !ok {
|
|
return errors.New("resource is not restartable")
|
|
}
|
|
|
|
return s.Restart(ctx, path, opts)
|
|
}
|
|
|
|
// Helpers...
|
|
|
|
func singularize(s string) string {
|
|
if strings.LastIndex(s, "s") == len(s)-1 {
|
|
return s[:len(s)-1]
|
|
}
|
|
|
|
return s
|
|
}
|