Skip to content

Commit 06796b7

Browse files
committed
Use WMI to implement System API for better performance
1 parent f78ef3e commit 06796b7

File tree

1,399 files changed

+423359
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,399 files changed

+423359
-26
lines changed

pkg/os/system/api.go

+72-26
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package system
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"os/exec"
7-
"strings"
85

6+
"github.com/kubernetes-csi/csi-proxy/pkg/cim"
7+
"github.com/kubernetes-csi/csi-proxy/pkg/server/system/impl"
98
"github.com/kubernetes-csi/csi-proxy/pkg/utils"
9+
"github.com/microsoft/wmi/pkg/base/query"
10+
"github.com/microsoft/wmi/server2019/root/cimv2"
1011
)
1112

1213
// Implements the System OS API calls. All code here should be very simple
@@ -25,52 +26,97 @@ type ServiceInfo struct {
2526
Status uint32 `json:"Status"`
2627
}
2728

29+
var (
30+
startModeMappings = map[string]uint32{
31+
"Boot": impl.START_TYPE_BOOT,
32+
"System": impl.START_TYPE_SYSTEM,
33+
"Auto": impl.START_TYPE_AUTOMATIC,
34+
"Manual": impl.START_TYPE_MANUAL,
35+
"Disabled": impl.START_TYPE_DISABLED,
36+
}
37+
38+
statusMappings = map[string]uint32{
39+
"Unknown": impl.SERVICE_STATUS_UNKNOWN,
40+
"Stopped": impl.SERVICE_STATUS_STOPPED,
41+
"Start Pending": impl.SERVICE_STATUS_START_PENDING,
42+
"Stop Pending": impl.SERVICE_STATUS_STOP_PENDING,
43+
"Running": impl.SERVICE_STATUS_RUNNING,
44+
"Continue Pending": impl.SERVICE_STATUS_CONTINUE_PENDING,
45+
"Pause Pending": impl.SERVICE_STATUS_PAUSE_PENDING,
46+
"Paused": impl.SERVICE_STATUS_PAUSED,
47+
}
48+
)
49+
50+
func serviceStartModeToStartType(startMode string) uint32 {
51+
return startModeMappings[startMode]
52+
}
53+
54+
func serviceState(status string) uint32 {
55+
return statusMappings[status]
56+
}
57+
2858
type APIImplementor struct{}
2959

3060
func New() APIImplementor {
3161
return APIImplementor{}
3262
}
3363

3464
func (APIImplementor) GetBIOSSerialNumber() (string, error) {
35-
// Taken from Kubernetes vSphere cloud provider
36-
// https://github.com/kubernetes/kubernetes/blob/103e926604de6f79161b78af3e792d0ed282bc06/staging/src/k8s.io/legacy-cloud-providers/vsphere/vsphere_util_windows.go#L28
37-
result, err := exec.Command("wmic", "bios", "get", "serialnumber").Output()
65+
biosQuery := query.NewWmiQueryWithSelectList("CIM_BIOSElement", []string{"SerialNumber"})
66+
instances, err := cim.QueryInstances("", biosQuery)
3867
if err != nil {
3968
return "", err
4069
}
41-
lines := strings.FieldsFunc(string(result), func(r rune) bool {
42-
switch r {
43-
case '\n', '\r':
44-
return true
45-
default:
46-
return false
47-
}
48-
})
49-
if len(lines) != 2 {
50-
return "", fmt.Errorf("received unexpected value retrieving host uuid: %q", string(result))
70+
71+
bios, err := cimv2.NewCIM_BIOSElementEx1(instances[0])
72+
if err != nil {
73+
return "", fmt.Errorf("failed to get BIOS element: %w", err)
74+
}
75+
76+
sn, err := bios.GetPropertySerialNumber()
77+
if err != nil {
78+
return "", fmt.Errorf("failed to get BIOS serial number property: %w", err)
5179
}
52-
return lines[1], nil
80+
81+
return sn, nil
5382
}
5483

5584
func (APIImplementor) GetService(name string) (*ServiceInfo, error) {
56-
script := `Get-Service -Name $env:ServiceName | Select-Object DisplayName, Status, StartType | ` +
57-
`ConvertTo-JSON`
58-
cmdEnv := fmt.Sprintf("ServiceName=%s", name)
59-
out, err := utils.RunPowershellCmd(script, cmdEnv)
85+
serviceQuery := query.NewWmiQueryWithSelectList("Win32_Service", []string{"DisplayName", "State", "StartMode"}, "Name", name)
86+
instances, err := cim.QueryInstances("", serviceQuery)
6087
if err != nil {
61-
return nil, fmt.Errorf("error querying service name=%s. cmd: %s, output: %s, error: %v", name, script, string(out), err)
88+
return nil, err
6289
}
6390

64-
var serviceInfo ServiceInfo
65-
err = json.Unmarshal(out, &serviceInfo)
91+
service, err := cimv2.NewWin32_ServiceEx1(instances[0])
6692
if err != nil {
67-
return nil, err
93+
return nil, fmt.Errorf("failed to get service %s: %w", name, err)
94+
}
95+
96+
displayName, err := service.GetPropertyDisplayName()
97+
if err != nil {
98+
return nil, fmt.Errorf("failed to get displayName property of service %s: %w", name, err)
99+
}
100+
101+
state, err := service.GetPropertyState()
102+
if err != nil {
103+
return nil, fmt.Errorf("failed to get state property of service %s: %w", name, err)
104+
}
105+
106+
startMode, err := service.GetPropertyStartMode()
107+
if err != nil {
108+
return nil, fmt.Errorf("failed to get startMode property of service %s: %w", name, err)
68109
}
69110

70-
return &serviceInfo, nil
111+
return &ServiceInfo{
112+
DisplayName: displayName,
113+
StartType: serviceStartModeToStartType(startMode),
114+
Status: serviceState(state),
115+
}, nil
71116
}
72117

73118
func (APIImplementor) StartService(name string) error {
119+
// Note: both StartService and StopService are not implemented by WMI
74120
script := `Start-Service -Name $env:ServiceName`
75121
cmdEnv := fmt.Sprintf("ServiceName=%s", name)
76122
out, err := utils.RunPowershellCmd(script, cmdEnv)

vendor/github.com/beorn7/perks/quantile/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/cmpopts/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/internal/diff/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/internal/flags/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/internal/function/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-cmp/cmp/internal/value/.uuid

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)