Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions initsystem/winscm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,28 @@ type WinSCM struct{}
func (WinSCM) String() string { return "winscm" }

// StartService starts a service.
//
// -WarningAction SilentlyContinue suppresses the benign "Waiting for service
// '…' to start..." progress warning that Start-Service emits when a service
// stays in StartPending for a moment (common on a cold first start). That
// warning goes to the warning stream, which lands on stderr under a subprocess,
// and rig treats any Windows stderr output as a failure. -ErrorAction Stop
// still turns a genuine start failure into a terminating (non-zero) error, so
// real failures are still detected.
func (c WinSCM) StartService(ctx context.Context, h cmd.ContextRunner, s string) error {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nStart-Service "+ps.SingleQuote(s)+" -ErrorAction Stop", cmd.PS()); err != nil {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nStart-Service "+ps.SingleQuote(s)+" -ErrorAction Stop -WarningAction SilentlyContinue", cmd.PS()); err != nil {
return fmt.Errorf("failed to start service %s: %w", s, err)
}
return nil
}

// StopService stops a service.
//
// -WarningAction SilentlyContinue suppresses the benign "Waiting for service
// '…' to stop..." progress warning (StopPending) for the same reason as
// StartService; -ErrorAction Stop still surfaces genuine failures.
func (c WinSCM) StopService(ctx context.Context, h cmd.ContextRunner, s string) error {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nStop-Service "+ps.SingleQuote(s)+" -ErrorAction Stop", cmd.PS()); err != nil {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nStop-Service "+ps.SingleQuote(s)+" -ErrorAction Stop -WarningAction SilentlyContinue", cmd.PS()); err != nil {
return fmt.Errorf("failed to stop service %s: %w", s, err)
}
return nil
Expand All @@ -41,8 +53,12 @@ func (c WinSCM) ServiceScriptPath(_ context.Context, _ cmd.ContextRunner, _ stri
}

// RestartService restarts a service.
//
// -WarningAction SilentlyContinue suppresses the benign "Waiting for service
// '…' to start/stop..." progress warnings for the same reason as StartService;
// -ErrorAction Stop still surfaces genuine failures.
func (c WinSCM) RestartService(ctx context.Context, h cmd.ContextRunner, s string) error {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nRestart-Service "+ps.SingleQuote(s)+" -ErrorAction Stop", cmd.PS()); err != nil {
if err := h.ExecContext(ctx, "$ErrorActionPreference='Stop'\nRestart-Service "+ps.SingleQuote(s)+" -ErrorAction Stop -WarningAction SilentlyContinue", cmd.PS()); err != nil {
return fmt.Errorf("failed to restart service %s: %w", s, err)
}
return nil
Expand Down
7 changes: 7 additions & 0 deletions initsystem/winscm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ func TestWinSCMStartService(t *testing.T) {
script := decodePSCmd(t, mr.LastCommand())
require.Contains(t, script, "Start-Service")
require.Contains(t, script, "-ErrorAction Stop")
// Suppresses the benign StartPending progress warning that otherwise
// lands on stderr and trips ErrWroteStderr on a slow/cold start.
require.Contains(t, script, "-WarningAction SilentlyContinue")
require.Contains(t, script, "'myservice'")
})
t.Run("failure", func(t *testing.T) {
Expand All @@ -63,6 +66,8 @@ func TestWinSCMStopService(t *testing.T) {
script := decodePSCmd(t, mr.LastCommand())
require.Contains(t, script, "Stop-Service")
require.Contains(t, script, "-ErrorAction Stop")
// Suppresses the benign StopPending progress warning (see StartService).
require.Contains(t, script, "-WarningAction SilentlyContinue")
require.Contains(t, script, "'myservice'")
})
t.Run("failure", func(t *testing.T) {
Expand All @@ -81,6 +86,8 @@ func TestWinSCMRestartService(t *testing.T) {
script := decodePSCmd(t, mr.LastCommand())
require.Contains(t, script, "Restart-Service")
require.Contains(t, script, "-ErrorAction Stop")
// Suppresses the benign start/stop progress warnings (see StartService).
require.Contains(t, script, "-WarningAction SilentlyContinue")
require.Contains(t, script, "'myservice'")
})
t.Run("failure", func(t *testing.T) {
Expand Down
Loading