commit
5b45819c62
|
|
@ -13,5 +13,8 @@ gen.sh
|
|||
*.test
|
||||
*.log
|
||||
*~
|
||||
pod1.go
|
||||
.project
|
||||
faas
|
||||
demos
|
||||
.settings/*
|
||||
demos
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ func (c *Container) Name() string { return containerTitle }
|
|||
func (c *Container) bindDangerousKeys(aa ui.KeyActions) {
|
||||
aa.Add(ui.KeyActions{
|
||||
ui.KeyS: ui.NewKeyAction("Shell", c.shellCmd, true),
|
||||
ui.KeyA: ui.NewKeyAction("Attach", c.attachCmd, true),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +96,19 @@ func (c *Container) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) attachCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
sel := c.GetTable().GetSelectedItem()
|
||||
if sel == "" {
|
||||
return evt
|
||||
}
|
||||
|
||||
c.Stop()
|
||||
defer c.Start()
|
||||
attachIn(c.App(), c.GetTable().Path, sel)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Container) portFwdCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
path := c.GetTable().GetSelectedItem()
|
||||
if path == "" {
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@ func TestHelp(t *testing.T) {
|
|||
v := view.NewHelp()
|
||||
|
||||
assert.Nil(t, v.Init(ctx))
|
||||
assert.Equal(t, 21, v.GetRowCount())
|
||||
assert.Equal(t, 22, v.GetRowCount())
|
||||
assert.Equal(t, 8, v.GetColumnCount())
|
||||
assert.Equal(t, "<ctrl-k>", strings.TrimSpace(v.GetCell(1, 0).Text))
|
||||
assert.Equal(t, "Kill", strings.TrimSpace(v.GetCell(1, 1).Text))
|
||||
assert.Equal(t, "<a>", strings.TrimSpace(v.GetCell(1, 0).Text))
|
||||
assert.Equal(t, "Attach", strings.TrimSpace(v.GetCell(1, 1).Text))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ func (p *Pod) bindDangerousKeys(aa ui.KeyActions) {
|
|||
aa.Add(ui.KeyActions{
|
||||
tcell.KeyCtrlK: ui.NewKeyAction("Kill", p.killCmd, true),
|
||||
ui.KeyS: ui.NewKeyAction("Shell", p.shellCmd, true),
|
||||
ui.KeyA: ui.NewKeyAction("Attach", p.attachCmd, true),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -130,6 +131,26 @@ func (p *Pod) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Pod) attachCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
path := p.GetTable().GetSelectedItem()
|
||||
if path == "" {
|
||||
return evt
|
||||
}
|
||||
|
||||
row := p.GetTable().GetSelectedRowIndex()
|
||||
status := ui.TrimCell(p.GetTable().SelectTable, row, p.GetTable().NameColIndex()+2)
|
||||
if status != render.Running {
|
||||
p.App().Flash().Errf("%s is not in a running state", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := containerAttachIn(p.App(), p, path, ""); err != nil {
|
||||
p.App().Flash().Err(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Helpers...
|
||||
|
||||
|
|
@ -175,6 +196,49 @@ func shellIn(a *App, path, co string) {
|
|||
}
|
||||
}
|
||||
|
||||
func containerAttachIn(a *App, comp model.Component, path, co string) error {
|
||||
if co != "" {
|
||||
resumeAttachIn(a, comp, path, co)
|
||||
return nil
|
||||
}
|
||||
|
||||
cc, err := fetchContainers(a.factory, path, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(cc) == 1 {
|
||||
resumeAttachIn(a, comp, path, cc[0])
|
||||
return nil
|
||||
}
|
||||
picker := NewPicker()
|
||||
picker.populate(cc)
|
||||
picker.SetSelectedFunc(func(_ int, co, _ string, _ rune) {
|
||||
resumeAttachIn(a, comp, path, co)
|
||||
})
|
||||
if err := a.inject(picker); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resumeAttachIn(a *App, c model.Component, path, co string) {
|
||||
c.Stop()
|
||||
defer c.Start()
|
||||
|
||||
attachIn(a, path, co)
|
||||
}
|
||||
|
||||
func attachIn(a *App, path, co string) {
|
||||
args := computeAttachArgs(path, co, a.Config.K9s.CurrentContext, a.Conn().Config().Flags().KubeConfig)
|
||||
|
||||
c := color.New(color.BgGreen).Add(color.FgBlack).Add(color.Bold)
|
||||
if !runK(a, shellOpts{clear: true, banner: c.Sprintf(bannerFmt, path, co), args: args}) {
|
||||
a.Flash().Err(errors.New("Attach exec failed"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func computeShellArgs(path, co, context string, kcfg *string) []string {
|
||||
args := make([]string, 0, 15)
|
||||
args = append(args, "exec", "-it")
|
||||
|
|
@ -192,6 +256,23 @@ func computeShellArgs(path, co, context string, kcfg *string) []string {
|
|||
return append(args, "--", "sh", "-c", shellCheck)
|
||||
}
|
||||
|
||||
func computeAttachArgs(path, co, context string, kcfg *string) []string {
|
||||
args := make([]string, 0, 15)
|
||||
args = append(args, "attach", "-it")
|
||||
args = append(args, "--context", context)
|
||||
ns, po := client.Namespaced(path)
|
||||
args = append(args, "-n", ns)
|
||||
args = append(args, po)
|
||||
if kcfg != nil && *kcfg != "" {
|
||||
args = append(args, "--kubeconfig", *kcfg)
|
||||
}
|
||||
if co != "" {
|
||||
args = append(args, "-c", co)
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
func fetchContainers(f *watch.Factory, path string, includeInit bool) ([]string, error) {
|
||||
o, err := f.Get("v1/pods", path, true, labels.Everything())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ func TestPodNew(t *testing.T) {
|
|||
|
||||
assert.Nil(t, po.Init(makeCtx()))
|
||||
assert.Equal(t, "Pods", po.Name())
|
||||
assert.Equal(t, 20, len(po.Hints()))
|
||||
assert.Equal(t, 21, len(po.Hints()))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ func (x *Xray) refreshActions() {
|
|||
aa[ui.KeyShiftL] = ui.NewKeyAction("Logs Previous", x.logsCmd(true), true)
|
||||
case "v1/pods":
|
||||
aa[ui.KeyS] = ui.NewKeyAction("Shell", x.shellCmd, true)
|
||||
aa[ui.KeyA] = ui.NewKeyAction("Attach", x.attachCmd, true)
|
||||
aa[ui.KeyL] = ui.NewKeyAction("Logs", x.logsCmd(false), true)
|
||||
aa[ui.KeyShiftL] = ui.NewKeyAction("Logs Previous", x.logsCmd(true), true)
|
||||
}
|
||||
|
|
@ -294,6 +295,30 @@ func (x *Xray) shellCmd(evt *tcell.EventKey) *tcell.EventKey {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *Xray) attachCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
|
||||
spec := x.selectedSpec()
|
||||
if spec == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if spec.Status() != "ok" {
|
||||
x.app.Flash().Errf("%s is not in a running state", spec.Path())
|
||||
return nil
|
||||
}
|
||||
|
||||
path, co := spec.Path(), ""
|
||||
if spec.GVR() == "containers" {
|
||||
path = *spec.ParentPath()
|
||||
}
|
||||
|
||||
if err := containerAttachIn(x.app, x, path, co); err != nil {
|
||||
x.app.Flash().Err(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *Xray) viewCmd(evt *tcell.EventKey) *tcell.EventKey {
|
||||
spec := x.selectedSpec()
|
||||
if spec == nil {
|
||||
|
|
|
|||
Loading…
Reference in New Issue