Skip to content

Commit f7363ea

Browse files
committed
Fix lints on Darwin
Fixes lint errors lke these: Error: pkg/apis/k0s/v1beta1/cplb.go:143:4: SA4023(related information): the lhs of the comparison is the 2nd return value of this function call (staticcheck) k.VRRPInstances[i].Interface, err = getNIC(k.VRRPInstances[i].Interface) ^ Error: pkg/apis/k0s/v1beta1/cplb.go:144:7: SA4023: this comparison is always true (staticcheck) if err != nil { ^ Error: pkg/supervisor/supervisor.go:244:2: SA4023(related information): the lhs of the comparison is the 2nd return value of this function call (staticcheck) ph, err := openPID(p) ^ Error: pkg/supervisor/supervisor.go:245:5: SA4023: this comparison is always true (staticcheck) if err != nil { ^ Signed-off-by: Tom Wieczorek <[email protected]>
1 parent 6b0f8d0 commit f7363ea

File tree

7 files changed

+132
-118
lines changed

7 files changed

+132
-118
lines changed

pkg/apis/k0s/v1beta1/cplb.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,7 @@ func (k *KeepalivedSpec) validateVRRPInstances(getDefaultNICFn func() (string, e
140140
}
141141
k.VRRPInstances[i].Interface = nic
142142
} else if _, err := net.ParseMAC(k.VRRPInstances[i].Interface); err == nil {
143-
k.VRRPInstances[i].Interface, err = getNIC(k.VRRPInstances[i].Interface)
144-
if err != nil {
145-
errs = append(errs, fmt.Errorf("failed to get NIC for MAC address %s: %w", k.VRRPInstances[i].Interface, err))
146-
}
143+
macToInterfaceName(&k.VRRPInstances[i].Interface, &errs)
147144
}
148145

149146
if k.VRRPInstances[i].VirtualRouterID == 0 {

pkg/apis/k0s/v1beta1/cplb_linux.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ func getDefaultNIC() (string, error) {
3232
return "", errors.New("default route not found")
3333
}
3434

35+
func macToInterfaceName(val *string, errs *[]error) {
36+
if interfaceName, err := getNIC(*val); err != nil {
37+
*errs = append(*errs, fmt.Errorf("failed to get NIC for MAC address %s: %w", *val, err))
38+
} else {
39+
*val = interfaceName
40+
}
41+
}
42+
3543
func getNIC(mac string) (string, error) {
3644
links, err := netlink.LinkList()
3745
if err != nil {

pkg/apis/k0s/v1beta1/cplb_other.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package v1beta1
77

88
import (
9+
"errors"
910
"fmt"
1011
"runtime"
1112
)
@@ -14,6 +15,6 @@ func getDefaultNIC() (string, error) {
1415
return "", fmt.Errorf("getDefaultNIC on %s is not supported", runtime.GOOS)
1516
}
1617

17-
func getNIC(_ string) (string, error) {
18-
return "", fmt.Errorf("getNIC on %s is not supported", runtime.GOOS)
18+
func macToInterfaceName(_ *string, errs *[]error) {
19+
*errs = append(*errs, fmt.Errorf("%w on %s: resolving interface names for MAC addresses", errors.ErrUnsupported, runtime.GOOS))
1920
}

pkg/supervisor/prochandle.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,115 @@
1+
//go:build linux || windows
2+
13
// SPDX-FileCopyrightText: 2024 k0s authors
24
// SPDX-License-Identifier: Apache-2.0
35

46
package supervisor
57

68
import (
9+
"context"
10+
"errors"
11+
"fmt"
712
"io"
13+
"math"
14+
"os"
15+
"slices"
16+
"syscall"
17+
"time"
18+
19+
"k8s.io/apimachinery/pkg/util/wait"
820
)
921

22+
func (s *Supervisor) cleanupPID(pid int) error {
23+
ph, err := openPID(pid)
24+
if err != nil {
25+
if errors.Is(err, syscall.ESRCH) {
26+
return nil // no such process, nothing to cleanup
27+
}
28+
return fmt.Errorf("cannot open process for PID %d from PID file %s: %w", pid, s.PidFile, err)
29+
}
30+
defer ph.Close()
31+
32+
if managed, err := s.isK0sManaged(ph); err != nil {
33+
if errors.Is(err, os.ErrProcessDone) {
34+
return nil
35+
}
36+
return err
37+
} else if !managed {
38+
return nil
39+
}
40+
41+
if err := s.terminateAndWait(ph); err != nil {
42+
return fmt.Errorf("while waiting for termination of PID %d from PID file %s: %w", pid, s.PidFile, err)
43+
}
44+
45+
return nil
46+
}
47+
48+
// Tries to gracefully terminate a process and waits for it to exit. If the
49+
// process is still running after several attempts, it returns an error instead
50+
// of forcefully killing the process.
51+
func (s *Supervisor) terminateAndWait(ph procHandle) error {
52+
if err := ph.requestGracefulTermination(); err != nil {
53+
if errors.Is(err, os.ErrProcessDone) {
54+
return nil
55+
}
56+
return fmt.Errorf("failed to request graceful termination: %w", err)
57+
}
58+
59+
errTimeout := errors.New("process did not terminate in time")
60+
ctx, cancel := context.WithTimeoutCause(context.TODO(), s.TimeoutStop, errTimeout)
61+
defer cancel()
62+
return s.awaitTermination(ctx, ph)
63+
}
64+
65+
// Checks if the process handle refers to a k0s-managed process. A process is
66+
// considered k0s-managed if:
67+
// - The executable path matches.
68+
// - The process environment contains `_K0S_MANAGED=yes`.
69+
func (s *Supervisor) isK0sManaged(ph procHandle) (bool, error) {
70+
if cmd, err := ph.cmdline(); err != nil {
71+
// Only error out if the error doesn't indicate that getting the command
72+
// line is unsupported. In that case, ignore the error and proceed to
73+
// the environment check.
74+
if !errors.Is(err, errors.ErrUnsupported) {
75+
return false, err
76+
}
77+
} else if len(cmd) > 0 && cmd[0] != s.BinPath {
78+
return false, nil
79+
}
80+
81+
if env, err := ph.environ(); err != nil {
82+
return false, err
83+
} else if !slices.Contains(env, k0sManaged) {
84+
return false, nil
85+
}
86+
87+
return true, nil
88+
}
89+
90+
func (s *Supervisor) awaitTermination(ctx context.Context, ph procHandle) error {
91+
s.log.Debug("Polling for process termination")
92+
backoff := wait.Backoff{
93+
Duration: 25 * time.Millisecond,
94+
Cap: 3 * time.Second,
95+
Steps: math.MaxInt32,
96+
Factor: 1.5,
97+
Jitter: 0.1,
98+
}
99+
100+
if err := wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
101+
return ph.hasTerminated()
102+
}); err != nil {
103+
if err == ctx.Err() { //nolint:errorlint // the equal check is intended
104+
return context.Cause(ctx)
105+
}
106+
107+
return err
108+
}
109+
110+
return nil
111+
}
112+
10113
// A handle to a running process. May be used to inspect the process properties
11114
// and terminate it.
12115
type procHandle interface {

pkg/supervisor/prochandle_darwin.go

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

pkg/supervisor/prochandle_other.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//go:build !linux && !windows
2+
3+
// SPDX-FileCopyrightText: 2025 k0s authors
4+
// SPDX-License-Identifier: Apache-2.0
5+
6+
package supervisor
7+
8+
import (
9+
"errors"
10+
"fmt"
11+
"runtime"
12+
)
13+
14+
func (s *Supervisor) cleanupPID(pid int) error {
15+
return fmt.Errorf("%w on %s: cleanup for PID %d from PID file %s", errors.ErrUnsupported, runtime.GOOS, pid, s.PidFile)
16+
}

pkg/supervisor/supervisor.go

Lines changed: 1 addition & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,16 @@ import (
88
"errors"
99
"fmt"
1010
"io"
11-
"math"
1211
"os"
1312
"os/exec"
1413
"path/filepath"
15-
"slices"
1614
"sort"
1715
"strconv"
1816
"strings"
1917
"sync"
20-
"syscall"
2118
"time"
2219

2320
"github.com/sirupsen/logrus"
24-
"k8s.io/apimachinery/pkg/util/wait"
2521

2622
"github.com/k0sproject/k0s/internal/pkg/dir"
2723
"github.com/k0sproject/k0s/internal/pkg/log"
@@ -241,94 +237,7 @@ func (s *Supervisor) maybeCleanupPIDFile() error {
241237
return fmt.Errorf("failed to parse PID file %s: %w", s.PidFile, err)
242238
}
243239

244-
ph, err := openPID(p)
245-
if err != nil {
246-
if errors.Is(err, syscall.ESRCH) {
247-
return nil // no such process, nothing to cleanup
248-
}
249-
return fmt.Errorf("cannot interact with PID %d from PID file %s: %w", p, s.PidFile, err)
250-
}
251-
defer ph.Close()
252-
253-
if managed, err := s.isK0sManaged(ph); err != nil {
254-
if errors.Is(err, os.ErrProcessDone) {
255-
return nil
256-
}
257-
return err
258-
} else if !managed {
259-
return nil
260-
}
261-
262-
if err := s.terminateAndWait(ph); err != nil {
263-
return fmt.Errorf("while waiting for termination of PID %d from PID file %s: %w", p, s.PidFile, err)
264-
}
265-
266-
return nil
267-
}
268-
269-
// Tries to gracefully terminate a process and waits for it to exit. If the
270-
// process is still running after several attempts, it returns an error instead
271-
// of forcefully killing the process.
272-
func (s *Supervisor) terminateAndWait(ph procHandle) error {
273-
if err := ph.requestGracefulTermination(); err != nil {
274-
if errors.Is(err, os.ErrProcessDone) {
275-
return nil
276-
}
277-
return fmt.Errorf("failed to request graceful termination: %w", err)
278-
}
279-
280-
errTimeout := errors.New("process did not terminate in time")
281-
ctx, cancel := context.WithTimeoutCause(context.TODO(), s.TimeoutStop, errTimeout)
282-
defer cancel()
283-
return s.awaitTermination(ctx, ph)
284-
}
285-
286-
// Checks if the process handle refers to a k0s-managed process. A process is
287-
// considered k0s-managed if:
288-
// - The executable path matches.
289-
// - The process environment contains `_K0S_MANAGED=yes`.
290-
func (s *Supervisor) isK0sManaged(ph procHandle) (bool, error) {
291-
if cmd, err := ph.cmdline(); err != nil {
292-
// Only error out if the error doesn't indicate that getting the command
293-
// line is unsupported. In that case, ignore the error and proceed to
294-
// the environment check.
295-
if !errors.Is(err, errors.ErrUnsupported) {
296-
return false, err
297-
}
298-
} else if len(cmd) > 0 && cmd[0] != s.BinPath {
299-
return false, nil
300-
}
301-
302-
if env, err := ph.environ(); err != nil {
303-
return false, err
304-
} else if !slices.Contains(env, k0sManaged) {
305-
return false, nil
306-
}
307-
308-
return true, nil
309-
}
310-
311-
func (s *Supervisor) awaitTermination(ctx context.Context, ph procHandle) error {
312-
s.log.Debug("Polling for process termination")
313-
backoff := wait.Backoff{
314-
Duration: 25 * time.Millisecond,
315-
Cap: 3 * time.Second,
316-
Steps: math.MaxInt32,
317-
Factor: 1.5,
318-
Jitter: 0.1,
319-
}
320-
321-
if err := wait.ExponentialBackoffWithContext(ctx, backoff, func(context.Context) (bool, error) {
322-
return ph.hasTerminated()
323-
}); err != nil {
324-
if err == ctx.Err() { //nolint:errorlint // the equal check is intended
325-
return context.Cause(ctx)
326-
}
327-
328-
return err
329-
}
330-
331-
return nil
240+
return s.cleanupPID(p)
332241
}
333242

334243
// Prepare the env for exec:

0 commit comments

Comments
 (0)