1
1
package system
2
2
3
3
import (
4
- "encoding/json"
5
4
"fmt"
6
- "os/exec"
7
- "strings"
8
5
6
+ "github.com/kubernetes-csi/csi-proxy/pkg/cim"
7
+ "github.com/kubernetes-csi/csi-proxy/pkg/server/system/impl"
9
8
"github.com/kubernetes-csi/csi-proxy/pkg/utils"
9
+ "github.com/microsoft/wmi/pkg/base/query"
10
+ "github.com/microsoft/wmi/server2019/root/cimv2"
10
11
)
11
12
12
13
// Implements the System OS API calls. All code here should be very simple
@@ -25,52 +26,97 @@ type ServiceInfo struct {
25
26
Status uint32 `json:"Status"`
26
27
}
27
28
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
+
28
58
type APIImplementor struct {}
29
59
30
60
func New () APIImplementor {
31
61
return APIImplementor {}
32
62
}
33
63
34
64
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 )
38
67
if err != nil {
39
68
return "" , err
40
69
}
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 )
51
79
}
52
- return lines [1 ], nil
80
+
81
+ return sn , nil
53
82
}
54
83
55
84
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 )
60
87
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
62
89
}
63
90
64
- var serviceInfo ServiceInfo
65
- err = json .Unmarshal (out , & serviceInfo )
91
+ service , err := cimv2 .NewWin32_ServiceEx1 (instances [0 ])
66
92
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 )
68
109
}
69
110
70
- return & serviceInfo , nil
111
+ return & ServiceInfo {
112
+ DisplayName : displayName ,
113
+ StartType : serviceStartModeToStartType (startMode ),
114
+ Status : serviceState (state ),
115
+ }, nil
71
116
}
72
117
73
118
func (APIImplementor ) StartService (name string ) error {
119
+ // Note: both StartService and StopService are not implemented by WMI
74
120
script := `Start-Service -Name $env:ServiceName`
75
121
cmdEnv := fmt .Sprintf ("ServiceName=%s" , name )
76
122
out , err := utils .RunPowershellCmd (script , cmdEnv )
0 commit comments