Skip to content

Commit 9ff9b48

Browse files
committed
terminal cleanup for podman debugging
Signed-off-by: Kyle Quest <[email protected]>
1 parent 55a468f commit 9ff9b48

File tree

4 files changed

+168
-21
lines changed

4 files changed

+168
-21
lines changed

.github/workflows/codesee-arch-diagram.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

pkg/app/master/command/debug/handle_podman_runtime.go

Lines changed: 122 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,20 @@ import (
55
"fmt"
66
"io"
77
"os"
8+
"os/signal"
89
"strings"
910
"sync"
1011

12+
"github.com/moby/term"
13+
terminal "golang.org/x/term"
14+
1115
"github.com/containers/common/pkg/config"
16+
"github.com/containers/common/pkg/resize"
1217
"github.com/containers/podman/v5/libpod/define"
1318
"github.com/containers/podman/v5/pkg/bindings"
1419
"github.com/containers/podman/v5/pkg/bindings/containers"
1520
"github.com/containers/podman/v5/pkg/bindings/images"
21+
lsignal "github.com/containers/podman/v5/pkg/signal"
1622
"github.com/containers/podman/v5/pkg/specgen"
1723
log "github.com/sirupsen/logrus"
1824

@@ -485,6 +491,21 @@ func HandlePodmanRuntime(
485491
return
486492
}
487493

494+
if terminal.IsTerminal(int(os.Stdin.Fd())) {
495+
resize := make(chan resize.TerminalSize)
496+
497+
cancel, oldTermState, err := podmanTerminalAttach(connCtx, resize)
498+
if err != nil {
499+
return
500+
}
501+
defer func() {
502+
if err := podmanTerminalRestore(oldTermState); err != nil {
503+
log.Errorf("podmanTerminalRestore - %v", err)
504+
}
505+
}()
506+
defer cancel()
507+
}
508+
488509
r, w := io.Pipe()
489510
go io.Copy(w, os.Stdin)
490511

@@ -512,6 +533,87 @@ func HandlePodmanRuntime(
512533
logger.Trace("Debugger exited...")
513534
}
514535

536+
func podmanTerminalAttach(ctx context.Context, resize chan resize.TerminalSize) (context.CancelFunc, *term.State, error) {
537+
log.Debug("podmanTerminalAttach")
538+
539+
subCtx, cancel := context.WithCancel(ctx)
540+
541+
resizeTty(subCtx, resize)
542+
543+
oldTermState, err := term.SaveState(os.Stdin.Fd())
544+
if err != nil {
545+
// allow caller to not have to do any cleaning up if we error here
546+
cancel()
547+
return nil, nil, fmt.Errorf("unable to save terminal state: %w", err)
548+
}
549+
550+
log.SetFormatter(&rawFormatter{})
551+
if _, err := term.SetRawTerminal(os.Stdin.Fd()); err != nil {
552+
return cancel, nil, err
553+
}
554+
555+
return cancel, oldTermState, nil
556+
}
557+
558+
func podmanTerminalRestore(state *term.State) error {
559+
log.SetFormatter(&log.TextFormatter{})
560+
return term.RestoreTerminal(os.Stdin.Fd(), state)
561+
}
562+
563+
type rawFormatter struct {
564+
log.TextFormatter
565+
}
566+
567+
func (f *rawFormatter) Format(entry *log.Entry) ([]byte, error) {
568+
bytes, err := f.TextFormatter.Format(entry)
569+
if err != nil {
570+
return bytes, err
571+
}
572+
return append(bytes, '\r'), nil
573+
}
574+
575+
func getResize() *resize.TerminalSize {
576+
winsize, err := term.GetWinsize(os.Stdin.Fd())
577+
if err != nil {
578+
log.Warnf("Could not get terminal size %v", err)
579+
return nil
580+
}
581+
return &resize.TerminalSize{
582+
Width: winsize.Width,
583+
Height: winsize.Height,
584+
}
585+
}
586+
587+
func resizeTty(ctx context.Context, resize chan resize.TerminalSize) {
588+
sigchan := make(chan os.Signal, 1)
589+
signal.Notify(sigchan, lsignal.SIGWINCH)
590+
go func() {
591+
defer close(resize)
592+
// Update the terminal size immediately without waiting
593+
// for a SIGWINCH to get the correct initial size.
594+
resizeEvent := getResize()
595+
for {
596+
if resizeEvent == nil {
597+
select {
598+
case <-ctx.Done():
599+
return
600+
case <-sigchan:
601+
resizeEvent = getResize()
602+
}
603+
} else {
604+
select {
605+
case <-ctx.Done():
606+
return
607+
case <-sigchan:
608+
resizeEvent = getResize()
609+
case resize <- *resizeEvent:
610+
resizeEvent = nil
611+
}
612+
}
613+
}
614+
}()
615+
}
616+
515617
func podmanEnsureImage(logger *log.Entry, connCtx context.Context, image string) error {
516618
if image == "" {
517619
return nil
@@ -628,6 +730,23 @@ func listPodmanDebugContainersWithConfig(
628730
return listPodmanDebugContainers(connCtx, targetContainer, onlyActive)
629731
}
630732

733+
// https://github.com/containers/podman/blob/main/libpod/define/containerstate.go#L42
734+
// PCS - Podman Container State
735+
const (
736+
PCSUnknown = "unknown"
737+
PCSConfigured = "created"
738+
PCSCreated = "initialized"
739+
PCSRunning = "running"
740+
PCSStopped = "stopped"
741+
PCSPaused = "paused"
742+
PCSExited = "exited"
743+
PCSRemoving = "removing"
744+
PCSStopping = "stopping"
745+
//also referenced in the APIs/docs:
746+
PCSRestarting = "restarting"
747+
PCSDead = "dead"
748+
)
749+
631750
func listPodmanDebugContainers(
632751
connCtx context.Context,
633752
targetContainer string,
@@ -668,11 +787,11 @@ func listPodmanDebugContainers(
668787
}
669788

670789
switch container.State {
671-
case "created", "paused", "restarting": //"restarting" - confirm
790+
case PCSConfigured, PCSCreated, PCSPaused, PCSRestarting:
672791
info.State = CSWaiting
673-
case "running":
792+
case PCSRunning:
674793
info.State = CSRunning
675-
case "exited", "dead", "removing": //"removing" - confirm
794+
case PCSExited, PCSRemoving, PCSStopping, PCSStopped, PCSDead:
676795
info.State = CSTerminated
677796
default:
678797
info.State = CSOther

vendor/github.com/containers/common/pkg/resize/resize.go

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ github.com/containers/common/pkg/flag
261261
github.com/containers/common/pkg/machine
262262
github.com/containers/common/pkg/manifests
263263
github.com/containers/common/pkg/parse
264+
github.com/containers/common/pkg/resize
264265
github.com/containers/common/pkg/retry
265266
github.com/containers/common/pkg/signal
266267
github.com/containers/common/pkg/ssh

0 commit comments

Comments
 (0)