added restart functionality for pods

This commit is contained in:
christophe-duc 2026-01-07 22:10:09 -04:00
parent 264b4efc52
commit 3f417ec6b3
8 changed files with 1031 additions and 868 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,8 @@
package commands package commands
import ( import (
"context"
"fmt"
"time" "time"
"github.com/sasha-s/go-deadlock" "github.com/sasha-s/go-deadlock"
@ -32,6 +34,13 @@ func (p *Pod) State() string {
return p.Summary.Status return p.Summary.Status
} }
// Restart restarts the pod
func (p *Pod) Restart() error {
p.Log.Warn(fmt.Sprintf("restarting pod %s", p.Name))
ctx := context.Background()
return p.Runtime.RestartPod(ctx, p.ID, nil)
}
// HasContainers returns true if the pod has non-infra containers. // HasContainers returns true if the pod has non-infra containers.
func (p *Pod) HasContainers() bool { func (p *Pod) HasContainers() bool {
return len(p.Containers) > 0 return len(p.Containers) > 0

View file

@ -40,6 +40,7 @@ type ContainerRuntime interface {
// Pod operations // Pod operations
ListPods(ctx context.Context) ([]PodSummary, error) ListPods(ctx context.Context) ([]PodSummary, error)
PodStats(ctx context.Context, id string, stream bool) (<-chan PodStatsEntry, <-chan error) PodStats(ctx context.Context, id string, stream bool) (<-chan PodStatsEntry, <-chan error)
RestartPod(ctx context.Context, id string, timeout *int) error
// Events streams container/image/volume/network events // Events streams container/image/volume/network events
Events(ctx context.Context) (<-chan Event, <-chan error) Events(ctx context.Context) (<-chan Event, <-chan error)

View file

@ -438,6 +438,16 @@ func (r *LibpodRuntime) aggregatePodContainerStats(ctx context.Context, pod *lib
return entry, nil return entry, nil
} }
// RestartPod restarts a pod.
func (r *LibpodRuntime) RestartPod(ctx context.Context, id string, timeout *int) error {
pod, err := r.runtime.LookupPod(id)
if err != nil {
return err
}
_, err = pod.Restart(ctx)
return err
}
// Events streams container runtime events. // Events streams container runtime events.
// For libpod, we use a polling approach since direct event streaming requires more setup. // For libpod, we use a polling approach since direct event streaming requires more setup.
func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) { func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) {

View file

@ -145,6 +145,10 @@ func (r *LibpodRuntime) PodStats(ctx context.Context, id string, stream bool) (<
return statsChan, errChan return statsChan, errChan
} }
func (r *LibpodRuntime) RestartPod(ctx context.Context, id string, timeout *int) error {
return ErrLibpodNotAvailable
}
// Events returns an error channel on non-Linux platforms. // Events returns an error channel on non-Linux platforms.
func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) { func (r *LibpodRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) {
eventsChan := make(chan Event) eventsChan := make(chan Event)

View file

@ -40,8 +40,9 @@ type MockRuntime struct {
PruneNetworksFunc func(ctx context.Context) error PruneNetworksFunc func(ctx context.Context) error
// Pod operation mocks // Pod operation mocks
ListPodsFunc func(ctx context.Context) ([]PodSummary, error) ListPodsFunc func(ctx context.Context) ([]PodSummary, error)
PodStatsFunc func(ctx context.Context, id string, stream bool) (<-chan PodStatsEntry, <-chan error) PodStatsFunc func(ctx context.Context, id string, stream bool) (<-chan PodStatsEntry, <-chan error)
RestartPodFunc func(ctx context.Context, id string, timeout *int) error
// Event mock // Event mock
EventsFunc func(ctx context.Context) (<-chan Event, <-chan error) EventsFunc func(ctx context.Context) (<-chan Event, <-chan error)
@ -280,6 +281,14 @@ func (m *MockRuntime) PodStats(ctx context.Context, id string, stream bool) (<-c
return statsCh, errCh return statsCh, errCh
} }
func (m *MockRuntime) RestartPod(ctx context.Context, id string, timeout *int) error {
m.recordCall("RestartPod", id, timeout)
if m.RestartPodFunc != nil {
return m.RestartPodFunc(ctx, id, timeout)
}
return ErrMockNotImplemented
}
// Events // Events
func (m *MockRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) { func (m *MockRuntime) Events(ctx context.Context) (<-chan Event, <-chan error) {

View file

@ -340,6 +340,12 @@ func (r *SocketRuntime) PodStats(ctx context.Context, id string, stream bool) (<
return statsChan, errChan return statsChan, errChan
} }
// RestartPod restarts a pod.
func (r *SocketRuntime) RestartPod(ctx context.Context, id string, timeout *int) error {
_, err := pods.Restart(r.conn, id, nil)
return err
}
// aggregatePodStats combines stats from all containers in a pod into a single entry. // aggregatePodStats combines stats from all containers in a pod into a single entry.
func aggregatePodStats(reports []*types.PodStatsReport) PodStatsEntry { func aggregatePodStats(reports []*types.PodStatsReport) PodStatsEntry {
if len(reports) == 0 { if len(reports) == 0 {

View file

@ -568,7 +568,12 @@ func (gui *Gui) handleContainerRestart(g *gocui.Gui, v *gocui.View) error {
} }
if item.IsPod { if item.IsPod {
return gui.createErrorPanel("Restart not yet supported for pods") return gui.WithWaitingStatus(gui.Tr.RestartingStatus, func() error {
if err := item.Pod.Restart(); err != nil {
return gui.createErrorPanel(err.Error())
}
return nil
})
} }
ctr := item.Container ctr := item.Container