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

kubevirt / kubevirt / 97e57f72-61f0-4714-92c3-0f67fdc669e1

01 Mar 2025 06:39AM UTC coverage: 71.521%. Remained the same
97e57f72-61f0-4714-92c3-0f67fdc669e1

push

prow

web-flow
Merge pull request #13973 from jschintag/arch-labeller

virt-handler/node-labeller: Move arch specific content into separate files

60 of 73 new or added lines in 6 files covered. (82.19%)

7 existing lines in 2 files now uncovered.

61881 of 86521 relevant lines covered (71.52%)

0.8 hits per line

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

82.98
/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 2021 Red Hat, Inc.
17
 *
18
 */
19

20
package nodelabeller
21

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

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

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

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

40
        supportedFeaturesXml = "supported_features.xml"
41
)
42

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

1✔
46
        if obsoleteCPUsx86 == nil {
1✔
47
                obsoleteCPUsx86 = util.DefaultObsoleteCPUModels
×
48
        }
×
49

50
        for _, model := range n.hostCapabilities.items {
2✔
51
                if _, ok := obsoleteCPUsx86[model]; ok {
2✔
52
                        continue
1✔
53
                }
54
                supportedCPUModels = append(supportedCPUModels, model)
1✔
55
        }
56

57
        return supportedCPUModels
1✔
58
}
59

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

1✔
63
        for _, feature := range n.supportedFeatures {
2✔
64
                supportedCpuFeatures[feature] = true
1✔
65
        }
1✔
66

67
        return supportedCpuFeatures
1✔
68
}
69

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

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

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

89
                        n.cpuModelVendor = mode.Vendor.Name
1✔
90
                        if n.cpuModelVendor == "" {
2✔
91
                                n.cpuModelVendor = n.arch.defaultVendor()
1✔
92
                        }
1✔
93

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

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

1✔
105
                        for _, feature := range mode.Feature {
2✔
106
                                if feature.Policy == isRequired {
2✔
107
                                        n.hostCPUModel.requiredFeatures[feature.Name] = true
1✔
108
                                }
1✔
109
                        }
110
                }
111

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

120
        n.hostCapabilities.items = usableModels
1✔
121
        n.SEV = hostDomCapabilities.SEV
1✔
122

1✔
123
        return nil
1✔
124
}
125

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

1✔
130
        hostFeatures := SupportedHostFeature{}
1✔
131
        err := n.getStructureFromXMLFile(featuresFile, &hostFeatures)
1✔
132
        if err != nil {
1✔
133
                return err
×
134
        }
×
135

136
        usableFeatures := make([]string, 0)
1✔
137
        for _, f := range hostFeatures.Feature {
2✔
138
                if n.arch.requirePolicy(f.Policy) {
2✔
139
                        usableFeatures = append(usableFeatures, f.Name)
1✔
140
                }
1✔
141
        }
142

143
        n.supportedFeatures = usableFeatures
1✔
144
        return nil
1✔
145
}
146

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

155
        if hostDomCapabilities.SEV.Supported == "yes" && hostDomCapabilities.SEV.MaxESGuests > 0 {
2✔
156
                hostDomCapabilities.SEV.SupportedES = "yes"
1✔
157
        } else {
2✔
158
                hostDomCapabilities.SEV.SupportedES = "no"
1✔
159
        }
1✔
160

161
        return hostDomCapabilities, err
1✔
162
}
163

164
// GetStructureFromXMLFile load data from xml file and unmarshals them into given structure
165
// Given structure has to be pointer
166
func (n *NodeLabeller) getStructureFromXMLFile(path string, structure interface{}) error {
1✔
167
        rawFile, err := os.ReadFile(path)
1✔
168
        if err != nil {
1✔
169
                return err
×
170
        }
×
171

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

1✔
174
        return xml.Unmarshal(rawFile, structure)
1✔
175
}
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