From 45cf6ecefdfff84de8c21bdb03ddea03ebae4e42 Mon Sep 17 00:00:00 2001 From: bbedward Date: Sun, 26 Jul 2026 15:00:40 -0400 Subject: [PATCH] sysupdate: fix gnome-terminal title (cherry picked from commit c367153bac9d60beea9f5b17a4deadaa702a6032) --- core/internal/server/sysupdate/executor.go | 3 ++- core/internal/server/sysupdate/manager.go | 23 +++++++++++------- .../server/sysupdate/upgrade_commands_test.go | 24 +++++++++++++++++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/core/internal/server/sysupdate/executor.go b/core/internal/server/sysupdate/executor.go index 1dc256d1a..a4b5afd49 100644 --- a/core/internal/server/sysupdate/executor.go +++ b/core/internal/server/sysupdate/executor.go @@ -143,7 +143,8 @@ func wrapInTerminal(term, title, shellCmd string, extraArgs []string) []string { case "konsole": argv = []string{term, "-p", "tabtitle=" + title} case "gnome-terminal": - argv = []string{term, "--title=" + title} + // --wait: the factory process otherwise returns immediately + argv = []string{term, "--wait", "--title=" + title} execFlag = "--" default: argv = []string{term} diff --git a/core/internal/server/sysupdate/manager.go b/core/internal/server/sysupdate/manager.go index 811168ebf..cd6e771d0 100644 --- a/core/internal/server/sysupdate/manager.go +++ b/core/internal/server/sysupdate/manager.go @@ -412,25 +412,30 @@ func (m *Manager) runCustomUpgrade(ctx context.Context, opts UpgradeOptions) { onLine := func(line string) { m.appendLog(line) } argv := wrapInTerminal(term, "DMS — System Update (custom)", opts.CustomCommand, opts.TerminalArgs) if err := Run(ctx, argv, RunOptions{OnLine: onLine}); err != nil { - code := ErrCodeBackendFailed switch { case errors.Is(ctx.Err(), context.DeadlineExceeded): - code = ErrCodeTimeout + m.failCustomUpgrade(ErrCodeTimeout, err) + return case errors.Is(ctx.Err(), context.Canceled): - code = ErrCodeCancelled + m.failCustomUpgrade(ErrCodeCancelled, err) + return } - m.mu.Lock() - m.state.Phase = PhaseError - m.state.Error = &ErrorInfo{Code: code, Message: err.Error()} - m.mu.Unlock() - m.markDirty() - return + // exit status reflects the trailing `read`, not the update command + m.appendLog(fmt.Sprintf("Terminal exited early: %v", err)) } m.finishSuccessfulUpgrade(false) m.runRefresh(context.Background(), false) } +func (m *Manager) failCustomUpgrade(code ErrorCode, err error) { + m.mu.Lock() + m.state.Phase = PhaseError + m.state.Error = &ErrorInfo{Code: code, Message: err.Error()} + m.mu.Unlock() + m.markDirty() +} + func (m *Manager) finishSuccessfulUpgrade(clearPackages bool) { m.appendLog("Upgrade complete.") diff --git a/core/internal/server/sysupdate/upgrade_commands_test.go b/core/internal/server/sysupdate/upgrade_commands_test.go index 257022ee9..2538ffb01 100644 --- a/core/internal/server/sysupdate/upgrade_commands_test.go +++ b/core/internal/server/sysupdate/upgrade_commands_test.go @@ -233,3 +233,27 @@ func TestUpgradeBackendsFiltersFlatpakOnly(t *testing.T) { t.Fatalf("upgradeBackends(mixed) = %#v, want dnf5 then flatpak", got) } } + +func TestWrapInTerminal(t *testing.T) { + tests := []struct { + term string + wantPrefix []string + }{ + {"kitty", []string{"kitty", "--class", "com.danklinux.dms", "-T", "Title"}}, + {"gnome-terminal", []string{"gnome-terminal", "--wait", "--title=Title"}}, + {"foot", []string{"foot", "--app-id=com.danklinux.dms", "--title=Title"}}, + } + for _, tt := range tests { + got := wrapInTerminal(tt.term, "Title", "echo hi", nil) + if len(got) < len(tt.wantPrefix) || !reflect.DeepEqual(got[:len(tt.wantPrefix)], tt.wantPrefix) { + t.Errorf("wrapInTerminal(%q) = %#v, want prefix %#v", tt.term, got, tt.wantPrefix) + } + tail := got[len(got)-3:] + if tail[0] != "sh" || tail[1] != "-c" { + t.Errorf("wrapInTerminal(%q) tail = %#v, want [sh -c ]", tt.term, tail) + } + if !strings.Contains(tail[2], "echo hi") { + t.Errorf("wrapInTerminal(%q) command %q does not contain shell command", tt.term, tail[2]) + } + } +}