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

kubevirt / kubevirt / 835c5fca-3b9f-4ec1-8e06-e5d561ca17ed

23 Oct 2025 01:23PM UTC coverage: 70.353% (+0.02%) from 70.331%
835c5fca-3b9f-4ec1-8e06-e5d561ca17ed

push

prow

web-flow
Merge pull request #15008 from fossedihelm/fix-upgrades

Fix possible nil pointer caused by migration during kv upgrade

7 of 7 new or added lines in 1 file covered. (100.0%)

508 existing lines in 11 files now uncovered.

69120 of 98248 relevant lines covered (70.35%)

610.85 hits per line

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

86.14
/pkg/virt-handler/node-labeller/cpu_plugin.go
1
/*
2
 * This file is part of the KubeVirt project
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
 * Copyright The KubeVirt Authors.
17
 *
18
 */
19

20
package nodelabeller
21

22
import (
23
        "encoding/xml"
24
        "fmt"
25
        "os"
26
        "path/filepath"
27
        "slices"
28

29
        v1 "kubevirt.io/api/core/v1"
30
        "kubevirt.io/client-go/log"
31

32
        "kubevirt.io/kubevirt/pkg/virt-handler/node-labeller/util"
33
)
34

35
const (
36
        isSupported            string = "yes"
37
        isUnusable             string = "no"
38
        isRequired             string = "require"
39
        NodeLabellerVolumePath        = "/var/lib/kubevirt-node-labeller/"
40

41
        supportedFeaturesXml = "supported_features.xml"
42
)
43

44
func (n *NodeLabeller) getSupportedCpuModels(obsoleteCPUsx86 map[string]bool) []string {
23✔
45
        supportedCPUModels := make([]string, 0)
23✔
46

23✔
47
        if obsoleteCPUsx86 == nil {
24✔
48
                obsoleteCPUsx86 = util.DefaultObsoleteCPUModels
1✔
49
        }
1✔
50

51
        for _, model := range n.hostCapabilities.items {
159✔
52
                if _, ok := obsoleteCPUsx86[model]; ok {
157✔
53
                        continue
21✔
54
                }
55
                supportedCPUModels = append(supportedCPUModels, model)
115✔
56
        }
57

58
        return supportedCPUModels
23✔
59
}
60

61
func (n *NodeLabeller) getSupportedCpuFeatures() cpuFeatures {
25✔
62
        supportedCpuFeatures := make(cpuFeatures)
25✔
63

25✔
64
        for _, feature := range n.supportedFeatures {
202✔
65
                supportedCpuFeatures[feature] = true
177✔
66
        }
177✔
67

68
        return supportedCpuFeatures
25✔
69
}
70

71
func (n *NodeLabeller) GetHostCpuModel() hostCPUModel {
24✔
72
        return n.hostCPUModel
24✔
73
}
24✔
74

75
// loadDomCapabilities loads info about cpu models, which can host emulate
76
func (n *NodeLabeller) loadDomCapabilities() error {
38✔
77
        hostDomCapabilities, err := n.getDomCapabilities()
38✔
78
        if err != nil {
38✔
79
                return err
×
UNCOV
80
        }
×
81

82
        usableModels := make([]string, 0)
38✔
83
        for _, mode := range hostDomCapabilities.CPU.Mode {
161✔
84
                if mode.Name == v1.CPUModeHostModel {
161✔
85
                        if !n.arch.supportsHostModel() {
38✔
86
                                log.Log.Warningf("host-model cpu mode is not supported for %s architecture", n.arch.arch())
×
UNCOV
87
                                continue
×
88
                        }
89

90
                        n.cpuModelVendor = mode.Vendor.Name
38✔
91
                        if n.cpuModelVendor == "" {
43✔
92
                                n.cpuModelVendor = n.arch.defaultVendor()
5✔
93
                        }
5✔
94

95
                        if len(mode.Model) < 1 {
38✔
96
                                return fmt.Errorf("host model mode is expected to contain a model")
×
UNCOV
97
                        }
×
98
                        if len(mode.Model) > 1 {
38✔
99
                                log.Log.Warning("host model mode is expected to contain only one model")
×
UNCOV
100
                        }
×
101

102
                        hostCpuModel := mode.Model[0]
38✔
103
                        n.hostCPUModel.Name = hostCpuModel.Name
38✔
104
                        n.hostCPUModel.fallback = hostCpuModel.Fallback
38✔
105

38✔
106
                        for _, feature := range mode.Feature {
412✔
107
                                if feature.Policy == isRequired {
680✔
108
                                        n.hostCPUModel.requiredFeatures[feature.Name] = true
306✔
109
                                }
306✔
110
                        }
111
                }
112

113
                for _, model := range mode.Model {
1,030✔
114
                        if model.Usable == isUnusable || model.Usable == "" {
1,500✔
115
                                continue
593✔
116
                        }
117
                        usableModels = append(usableModels, model.Name)
314✔
118
                }
119
        }
120

121
        n.hostCapabilities.items = usableModels
38✔
122
        n.SEV = hostDomCapabilities.SEV
38✔
123
        n.SecureExecution = hostDomCapabilities.SecureExecution
38✔
124

38✔
125
        return nil
38✔
126
}
127

128
// loadHostSupportedFeatures loads supported features
129
func (n *NodeLabeller) loadHostSupportedFeatures() error {
33✔
130
        featuresFile := filepath.Join(n.volumePath, supportedFeaturesXml)
33✔
131

33✔
132
        hostFeatures := SupportedHostFeature{}
33✔
133
        err := n.getStructureFromXMLFile(featuresFile, &hostFeatures)
33✔
134
        if err != nil {
33✔
135
                return err
×
UNCOV
136
        }
×
137

138
        usableFeatures := make([]string, 0)
33✔
139
        for _, f := range hostFeatures.Feature {
420✔
140
                if n.arch.requirePolicy(f.Policy) {
596✔
141
                        usableFeatures = append(usableFeatures, f.Name)
209✔
142
                }
209✔
143
        }
144

145
        n.supportedFeatures = usableFeatures
33✔
146
        return nil
33✔
147
}
148

149
func (n *NodeLabeller) getDomCapabilities() (HostDomCapabilities, error) {
38✔
150
        domCapabilitiesFile := filepath.Join(n.volumePath, n.domCapabilitiesFileName)
38✔
151
        hostDomCapabilities := HostDomCapabilities{}
38✔
152
        err := n.getStructureFromXMLFile(domCapabilitiesFile, &hostDomCapabilities)
38✔
153
        if err != nil {
38✔
154
                return hostDomCapabilities, err
×
UNCOV
155
        }
×
156

157
        if hostDomCapabilities.SEV.Supported == isSupported && hostDomCapabilities.SEV.MaxESGuests > 0 {
68✔
158
                hostDomCapabilities.SEV.SupportedES = isSupported
30✔
159
                if hostDomCapabilities.LaunchSecurity.Supported == isSupported && slices.Contains(hostDomCapabilities.LaunchSecurity.SecTypes.Values, "sev-snp") {
59✔
160
                        hostDomCapabilities.SEV.SupportedSNP = isSupported
29✔
161
                } else {
30✔
162
                        hostDomCapabilities.SEV.SupportedSNP = isUnusable
1✔
163
                }
1✔
164
        } else {
8✔
165
                hostDomCapabilities.SEV.SupportedES = isUnusable
8✔
166
                hostDomCapabilities.SEV.SupportedSNP = isUnusable
8✔
167
        }
8✔
168

169
        return hostDomCapabilities, err
38✔
170
}
171

172
// GetStructureFromXMLFile load data from xml file and unmarshals them into given structure
173
// Given structure has to be pointer
174
func (n *NodeLabeller) getStructureFromXMLFile(path string, structure interface{}) error {
71✔
175
        rawFile, err := os.ReadFile(path)
71✔
176
        if err != nil {
71✔
UNCOV
177
                return err
×
UNCOV
178
        }
×
179

180
        n.logger.V(4).Infof("node-labeller - loading data from xml file: %#v", string(rawFile))
71✔
181

71✔
182
        return xml.Unmarshal(rawFile, structure)
71✔
183
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc