diff --git a/cmd/vm/cmd_container.go b/cmd/vm/cmd_container.go index d586a3e..6df316f 100644 --- a/cmd/vm/cmd_container.go +++ b/cmd/vm/cmd_container.go @@ -98,8 +98,8 @@ func runContainer(image, name string, detach bool, memory, cpus, sshPort int) er core.Print(nil, "%s %s", successStyle.Render(i18n.Label("started")), c.ID) core.Print(nil, "%s %d", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID) core.Println() - core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]})) - core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]})) + core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": shortContainerID(c.ID)})) + core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": shortContainerID(c.ID)})) } else { core.Println() core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID) @@ -184,13 +184,23 @@ func listContainers(all bool) error { } core.Print(w, "%s\t%s\t%s\t%s\t%s\t%d", - c.ID[:8], c.Name, imageName, status, duration, c.PID) + shortContainerID(c.ID), c.Name, imageName, status, duration, c.PID) + } + + if err := w.Flush(); err != nil { + return coreerr.E("listContainers", "flush output", err) } - _ = w.Flush() return nil } +func shortContainerID(id string) string { + if len(id) <= 8 { + return id + } + return id[:8] +} + func formatDuration(d time.Duration) string { if d < time.Minute { return core.Sprintf("%ds", int(d.Seconds())) @@ -233,7 +243,7 @@ func stopContainer(id string) error { return err } - core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.stop.stopping")), fullID[:8]) + core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.stop.stopping")), shortContainerID(fullID)) ctx := context.Background() if err := manager.Stop(ctx, fullID); err != nil { diff --git a/cmd/vm/cmd_templates.go b/cmd/vm/cmd_templates.go index 95cfb69..c4594f4 100644 --- a/cmd/vm/cmd_templates.go +++ b/cmd/vm/cmd_templates.go @@ -88,7 +88,9 @@ func listTemplates() error { } core.Print(w, "%s\t%s", repoNameStyle.Render(tmpl.Name), desc) } - _ = w.Flush() + if err := w.Flush(); err != nil { + return coreerr.E("listTemplates", "flush output", err) + } core.Println() core.Print(nil, "%s %s", i18n.T("cmd.vm.templates.hint.show"), dimStyle.Render("core vm templates show ")) @@ -209,8 +211,8 @@ func RunFromTemplate(templateName string, vars map[string]string, runOpts contai core.Print(nil, "%s %s", successStyle.Render(i18n.T("common.label.started")), c.ID) core.Print(nil, "%s %d", dimStyle.Render(i18n.T("cmd.vm.label.pid")), c.PID) core.Println() - core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": c.ID[:8]})) - core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": c.ID[:8]})) + core.Println(i18n.T("cmd.vm.hint.view_logs", map[string]any{"ID": shortContainerID(c.ID)})) + core.Println(i18n.T("cmd.vm.hint.stop", map[string]any{"ID": shortContainerID(c.ID)})) } else { core.Println() core.Print(nil, "%s %s", dimStyle.Render(i18n.T("cmd.vm.label.container_stopped")), c.ID) diff --git a/devenv/devops.go b/devenv/devops.go index fc721c7..2f22f25 100644 --- a/devenv/devops.go +++ b/devenv/devops.go @@ -43,7 +43,7 @@ func New(m io.Medium) (*DevOps, error) { return nil, coreerr.E("devops.New", "failed to create image manager", err) } - mgr, err := container.NewLinuxKitManager(io.Local) + mgr, err := container.NewLinuxKitManager(m) if err != nil { return nil, coreerr.E("devops.New", "failed to create container manager", err) } diff --git a/devenv/images.go b/devenv/images.go index 375164f..ec50ccf 100644 --- a/devenv/images.go +++ b/devenv/images.go @@ -16,7 +16,6 @@ import ( // ImageManager handles image downloads and updates. type ImageManager struct { medium io.Medium - config *Config manifest *Manifest sources []sources.ImageSource } @@ -83,7 +82,6 @@ func NewImageManager(m io.Medium, cfg *Config) (*ImageManager, error) { return &ImageManager{ medium: m, - config: cfg, manifest: manifest, sources: srcs, }, nil diff --git a/devenv/images_test.go b/devenv/images_test.go index 4f199dc..cd0dceb 100644 --- a/devenv/images_test.go +++ b/devenv/images_test.go @@ -240,7 +240,6 @@ func TestImageManager_InstallNoSourceAvailable_Bad(t *testing.T) { // Create manager with empty sources mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: nil, // no sources } @@ -301,7 +300,6 @@ func TestImageManager_InstallWithMockSource_Good(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{mock}, } @@ -330,7 +328,6 @@ func TestImageManager_InstallDownloadError_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{mock}, } @@ -351,7 +348,6 @@ func TestImageManager_InstallVersionError_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{mock}, } @@ -377,7 +373,6 @@ func TestImageManager_InstallSkipsUnavailableSource_Good(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{unavailableMock, availableMock}, } @@ -402,7 +397,6 @@ func TestImageManager_CheckUpdateWithMockSource_Good(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{ medium: io.Local, Images: map[string]ImageInfo{ @@ -432,7 +426,6 @@ func TestImageManager_CheckUpdateNoUpdate_Good(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{ medium: io.Local, Images: map[string]ImageInfo{ @@ -461,7 +454,6 @@ func TestImageManager_CheckUpdateNoSource_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{ medium: io.Local, Images: map[string]ImageInfo{ @@ -489,7 +481,6 @@ func TestImageManager_CheckUpdateVersionError_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{ medium: io.Local, Images: map[string]ImageInfo{ @@ -511,7 +502,6 @@ func TestImageManager_InstallEmptySources_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{}, // Empty slice, not nil } @@ -530,7 +520,6 @@ func TestImageManager_InstallAllUnavailable_Bad(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{medium: io.Local, Images: make(map[string]ImageInfo), path: coreutil.JoinPath(tmpDir, "manifest.json")}, sources: []sources.ImageSource{mock1, mock2}, } @@ -549,7 +538,6 @@ func TestImageManager_CheckUpdateFirstSourceUnavailable_Good(t *testing.T) { mgr := &ImageManager{ medium: io.Local, - config: DefaultConfig(), manifest: &Manifest{ medium: io.Local, Images: map[string]ImageInfo{ diff --git a/linuxkit.go b/linuxkit.go index c248df1..b24e40d 100644 --- a/linuxkit.go +++ b/linuxkit.go @@ -351,11 +351,13 @@ type followReader struct { ctx context.Context cancel context.CancelFunc reader *bufio.Reader - medium io.Medium - path string } func newFollowReader(ctx context.Context, m io.Medium, path string) (*followReader, error) { + if ctx == nil { + ctx = context.Background() + } + file, err := m.Open(path) if err != nil { return nil, err @@ -370,8 +372,6 @@ func newFollowReader(ctx context.Context, m io.Medium, path string) (*followRead ctx: ctx, cancel: cancel, reader: bufio.NewReader(file), - medium: m, - path: path, }, nil } diff --git a/state.go b/state.go index 2d28023..5bb3178 100644 --- a/state.go +++ b/state.go @@ -116,6 +116,10 @@ func (s *State) SaveState() error { // Add adds a container to the state and persists it. func (s *State) Add(c *Container) error { + if c == nil { + return core.E("State.Add", "container cannot be nil", nil) + } + s.mu.Lock() s.Containers[c.ID] = c s.mu.Unlock() @@ -140,6 +144,10 @@ func (s *State) Get(id string) (*Container, bool) { // Update updates a container in the state and persists it. func (s *State) Update(c *Container) error { + if c == nil { + return core.E("State.Update", "container cannot be nil", nil) + } + s.mu.Lock() s.Containers[c.ID] = c s.mu.Unlock()