• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

k8snetworkplumbingwg / sriov-network-operator / 29730932395

20 Jul 2026 09:18AM UTC coverage: 63.857% (-0.2%) from 64.037%
29730932395

Pull #1088

github

web-flow
Merge 1bdf02c83 into c7299a048
Pull Request #1088: Rebootloop Limit Feature

57 of 162 new or added lines in 5 files covered. (35.19%)

10 existing lines in 2 files now uncovered.

9977 of 15624 relevant lines covered (63.86%)

0.71 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.0
/pkg/host/internal/reboottracker/reboot_tracker.go
1
/*
2
Copyright 2026.
3

4
Licensed under the Apache License, Version 2.0 (the "License");
5
you may not use this file except in compliance with the License.
6
You may obtain a copy of the License at
7

8
        http://www.apache.org/licenses/LICENSE-2.0
9

10
Unless required by applicable law or agreed to in writing, software
11
distributed under the License is distributed on an "AS IS" BASIS,
12
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
See the License for the specific language governing permissions and
14
limitations under the License.
15
*/
16
package reboottracker
17

18
import (
19
        "fmt"
20
        "os"
21
        "path/filepath"
22

23
        "gopkg.in/yaml.v3"
24
        "sigs.k8s.io/controller-runtime/pkg/log"
25

26
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/consts"
27
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/host/types"
28
        "github.com/k8snetworkplumbingwg/sriov-network-operator/pkg/utils"
29
)
30

31
type rebootTracker struct{}
32

33
func New() types.RebootTrackerInterface {
1✔
34
        return &rebootTracker{}
1✔
35
}
1✔
36

NEW
37
func (r *rebootTracker) GetRebootCount(generation int64) (int, error) {
×
NEW
38
        tracker, err := r.readTrackerFile()
×
NEW
39
        if err != nil {
×
NEW
40
                return 0, fmt.Errorf("failed to read reboot tracker: %w", err)
×
NEW
41
        }
×
NEW
42
        if tracker == nil || tracker.Generation != generation {
×
NEW
43
                return 0, nil
×
NEW
44
        }
×
NEW
45
        return tracker.RebootCount, nil
×
46
}
47

NEW
48
func (r *rebootTracker) IncrementRebootCounter(generation int64) error {
×
NEW
49
        tracker, err := r.readTrackerFile()
×
NEW
50
        if err != nil {
×
NEW
51
                return fmt.Errorf("failed to read reboot tracker: %w", err)
×
NEW
52
        }
×
53

NEW
54
        if tracker == nil || tracker.Generation != generation {
×
NEW
55
                tracker = &types.RebootTrackerFile{
×
NEW
56
                        Generation:  generation,
×
NEW
57
                        RebootCount: 0,
×
NEW
58
                }
×
NEW
59
        }
×
NEW
60
        tracker.RebootCount++
×
NEW
61

×
NEW
62
        if err := r.writeTrackerFile(tracker); err != nil {
×
NEW
63
                return fmt.Errorf("failed to write reboot tracker: %w", err)
×
NEW
64
        }
×
NEW
65
        return nil
×
66
}
67

NEW
68
func (r *rebootTracker) ResetRebootCounter(generation int64) error {
×
NEW
69
        tracker := &types.RebootTrackerFile{
×
NEW
70
                Generation:  generation,
×
NEW
71
                RebootCount: 0,
×
NEW
72
        }
×
NEW
73
        if err := r.writeTrackerFile(tracker); err != nil {
×
NEW
74
                return fmt.Errorf("failed to write reboot tracker: %w", err)
×
NEW
75
        }
×
NEW
76
        return nil
×
77
}
78

NEW
79
func (r *rebootTracker) readTrackerFile() (*types.RebootTrackerFile, error) {
×
NEW
80
        path := utils.GetHostExtensionPath(consts.SriovRebootTrackerFilePath)
×
NEW
81

×
NEW
82
        rawData, err := os.ReadFile(path)
×
NEW
83
        if err != nil {
×
NEW
84
                if os.IsNotExist(err) {
×
NEW
85
                        log.Log.V(2).Info("readTrackerFile(): file does not exist")
×
NEW
86
                        return nil, nil
×
NEW
87
                }
×
NEW
88
                return nil, fmt.Errorf("failed to read file %s: %w", path, err)
×
89
        }
90

NEW
91
        tracker := &types.RebootTrackerFile{}
×
NEW
92
        if err := yaml.Unmarshal(rawData, tracker); err != nil {
×
NEW
93
                return nil, fmt.Errorf("failed to unmarshal file %s: %w", path, err)
×
NEW
94
        }
×
NEW
95
        return tracker, nil
×
96
}
97

NEW
98
func (r *rebootTracker) writeTrackerFile(tracker *types.RebootTrackerFile) error {
×
NEW
99
        path := utils.GetHostExtensionPath(consts.SriovRebootTrackerFilePath)
×
NEW
100
        dir := filepath.Dir(path)
×
NEW
101

×
NEW
102
        if err := os.MkdirAll(dir, 0o755); err != nil {
×
NEW
103
                return fmt.Errorf("failed to create directory %s: %w", dir, err)
×
NEW
104
        }
×
105

NEW
106
        out, err := yaml.Marshal(tracker)
×
NEW
107
        if err != nil {
×
NEW
108
                return fmt.Errorf("failed to marshal reboot tracker: %w", err)
×
NEW
109
        }
×
110

NEW
111
        log.Log.V(2).Info("writeTrackerFile(): write tracker",
×
NEW
112
                "content", string(out), "path", path)
×
NEW
113

×
NEW
114
        tmp := path + ".tmp"
×
NEW
115
        if err := os.WriteFile(tmp, out, 0o644); err != nil {
×
NEW
116
                return fmt.Errorf("failed to write temp file %s: %w", tmp, err)
×
NEW
117
        }
×
NEW
118
        if err := os.Rename(tmp, path); err != nil {
×
NEW
119
                return fmt.Errorf("failed to rename temp file to %s: %w", path, err)
×
NEW
120
        }
×
NEW
121
        return nil
×
122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc