Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
4d7ee1cd
Commit
4d7ee1cd
authored
May 21, 2019
by
ksubrmnn
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use system calls to manage Windows services
parent
e0fec1dc
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
414 additions
and
212 deletions
+414
-212
checks.go
cmd/kubeadm/app/preflight/checks.go
+2
-2
BUILD
pkg/util/initsystem/BUILD
+12
-5
initsystem.go
pkg/util/initsystem/initsystem.go
+0
-205
initsystem_unix.go
pkg/util/initsystem/initsystem_unix.go
+162
-0
initsystem_windows.go
pkg/util/initsystem/initsystem_windows.go
+238
-0
No files found.
cmd/kubeadm/app/preflight/checks.go
View file @
4d7ee1cd
...
...
@@ -143,8 +143,8 @@ func (sc ServiceCheck) Check() (warnings, errorList []error) {
if
!
initSystem
.
ServiceIsEnabled
(
sc
.
Service
)
{
warnings
=
append
(
warnings
,
errors
.
Errorf
(
"%s service is not enabled, please run '
systemctl enable %s.service
'"
,
sc
.
Service
,
sc
.
Service
))
errors
.
Errorf
(
"%s service is not enabled, please run '
%s
'"
,
sc
.
Service
,
initSystem
.
EnableCommand
(
sc
.
Service
)
))
}
if
sc
.
CheckIfActive
&&
!
initSystem
.
ServiceIsActive
(
sc
.
Service
)
{
...
...
pkg/util/initsystem/BUILD
View file @
4d7ee1cd
...
...
@@ -7,12 +7,19 @@ load(
go_library(
name = "go_default_library",
srcs = ["initsystem.go"],
importpath = "k8s.io/kubernetes/pkg/util/initsystem",
deps = [
"//vendor/golang.org/x/sys/windows/svc:go_default_library",
"//vendor/golang.org/x/sys/windows/svc/mgr:go_default_library",
srcs = [
"initsystem.go",
"initsystem_unix.go",
"initsystem_windows.go",
],
importpath = "k8s.io/kubernetes/pkg/util/initsystem",
deps = select({
"@io_bazel_rules_go//go/platform:windows": [
"//vendor/golang.org/x/sys/windows/svc:go_default_library",
"//vendor/golang.org/x/sys/windows/svc/mgr:go_default_library",
],
"//conditions:default": [],
}),
)
filegroup(
...
...
pkg/util/initsystem/initsystem.go
View file @
4d7ee1cd
...
...
@@ -16,12 +16,6 @@ limitations under the License.
package
initsystem
import
(
"fmt"
"os/exec"
"strings"
)
type
InitSystem
interface
{
// return a string describing how to enable a service
EnableCommand
(
service
string
)
string
...
...
@@ -44,202 +38,3 @@ type InitSystem interface {
// ServiceIsActive ensures the service is running, or attempting to run. (crash looping in the case of kubelet)
ServiceIsActive
(
service
string
)
bool
}
type
OpenRCInitSystem
struct
{}
func
(
openrc
OpenRCInitSystem
)
ServiceStart
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"start"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
func
(
openrc
OpenRCInitSystem
)
ServiceStop
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"stop"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
func
(
openrc
OpenRCInitSystem
)
ServiceRestart
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"restart"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
// openrc writes to stderr if a service is not found or not enabled
// this is in contrast to systemd which only writes to stdout.
// Hence, we use the Combinedoutput, and ignore the error.
func
(
openrc
OpenRCInitSystem
)
ServiceExists
(
service
string
)
bool
{
args
:=
[]
string
{
service
,
"status"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-service"
,
args
...
)
.
CombinedOutput
()
if
strings
.
Contains
(
string
(
outBytes
),
"does not exist"
)
{
return
false
}
return
true
}
func
(
openrc
OpenRCInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
args
:=
[]
string
{
"show"
,
"default"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-update"
,
args
...
)
.
Output
()
if
strings
.
Contains
(
string
(
outBytes
),
service
)
{
return
true
}
return
false
}
func
(
openrc
OpenRCInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
args
:=
[]
string
{
service
,
"status"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-service"
,
args
...
)
.
Output
()
if
strings
.
Contains
(
string
(
outBytes
),
"stopped"
)
{
return
false
}
return
true
}
func
(
openrc
OpenRCInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"rc-update add %s default"
,
service
)
}
type
SystemdInitSystem
struct
{}
func
(
sysd
SystemdInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"systemctl enable %s.service"
,
service
)
}
func
(
sysd
SystemdInitSystem
)
reloadSystemd
()
error
{
if
err
:=
exec
.
Command
(
"systemctl"
,
"daemon-reload"
)
.
Run
();
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to reload systemd: %v"
,
err
)
}
return
nil
}
func
(
sysd
SystemdInitSystem
)
ServiceStart
(
service
string
)
error
{
// Before we try to start any service, make sure that systemd is ready
if
err
:=
sysd
.
reloadSystemd
();
err
!=
nil
{
return
err
}
args
:=
[]
string
{
"start"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceRestart
(
service
string
)
error
{
// Before we try to restart any service, make sure that systemd is ready
if
err
:=
sysd
.
reloadSystemd
();
err
!=
nil
{
return
err
}
args
:=
[]
string
{
"restart"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceStop
(
service
string
)
error
{
args
:=
[]
string
{
"stop"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceExists
(
service
string
)
bool
{
args
:=
[]
string
{
"status"
,
service
}
outBytes
,
_
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Output
()
output
:=
string
(
outBytes
)
if
strings
.
Contains
(
output
,
"Loaded: not-found"
)
{
return
false
}
return
true
}
func
(
sysd
SystemdInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
args
:=
[]
string
{
"is-enabled"
,
service
}
err
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
if
err
!=
nil
{
return
false
}
return
true
}
// ServiceIsActive will check is the service is "active". In the case of
// crash looping services (kubelet in our case) status will return as
// "activating", so we will consider this active as well.
func
(
sysd
SystemdInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
args
:=
[]
string
{
"is-active"
,
service
}
// Ignoring error here, command returns non-0 if in "activating" status:
outBytes
,
_
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Output
()
output
:=
strings
.
TrimSpace
(
string
(
outBytes
))
if
output
==
"active"
||
output
==
"activating"
{
return
true
}
return
false
}
// WindowsInitSystem is the windows implementation of InitSystem
type
WindowsInitSystem
struct
{}
func
(
sysd
WindowsInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"Set-Service '%s' -StartupType Automatic"
,
service
)
}
func
(
sysd
WindowsInitSystem
)
ServiceStart
(
service
string
)
error
{
args
:=
[]
string
{
"Start-Service"
,
service
}
err
:=
exec
.
Command
(
"powershell"
,
args
...
)
.
Run
()
return
err
}
func
(
sysd
WindowsInitSystem
)
ServiceRestart
(
service
string
)
error
{
if
err
:=
sysd
.
ServiceStop
(
service
);
err
!=
nil
{
return
fmt
.
Errorf
(
"couldn't stop service: %v"
,
err
)
}
if
err
:=
sysd
.
ServiceStart
(
service
);
err
!=
nil
{
return
fmt
.
Errorf
(
"couldn't start service: %v"
,
err
)
}
return
nil
}
func
(
sysd
WindowsInitSystem
)
ServiceStop
(
service
string
)
error
{
args
:=
[]
string
{
"Stop-Service"
,
service
}
err
:=
exec
.
Command
(
"powershell"
,
args
...
)
.
Run
()
return
err
}
func
(
sysd
WindowsInitSystem
)
ServiceExists
(
service
string
)
bool
{
args
:=
[]
string
{
"Get-Service"
,
service
}
err
:=
exec
.
Command
(
"powershell"
,
args
...
)
.
Run
()
if
err
!=
nil
{
return
false
}
return
true
}
func
(
sysd
WindowsInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
args
:=
[]
string
{
"Get-Service"
,
service
+
"| select -property starttype"
}
outBytes
,
_
:=
exec
.
Command
(
"powershell"
,
args
...
)
.
Output
()
output
:=
strings
.
TrimSpace
(
string
(
outBytes
))
if
strings
.
Contains
(
output
,
"Automatic"
)
{
return
true
}
return
false
}
func
(
sysd
WindowsInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
args
:=
[]
string
{
"Get-Service"
,
service
+
"| select -property status"
}
outBytes
,
_
:=
exec
.
Command
(
"powershell"
,
args
...
)
.
Output
()
output
:=
strings
.
TrimSpace
(
string
(
outBytes
))
if
strings
.
Contains
(
output
,
"Running"
)
{
return
true
}
return
false
}
// GetInitSystem returns an InitSystem for the current system, or nil
// if we cannot detect a supported init system for pre-flight checks.
// This indicates we will skip init system checks, not an error.
func
GetInitSystem
()
(
InitSystem
,
error
)
{
// Assume existence of systemctl in path implies this is a systemd system:
_
,
err
:=
exec
.
LookPath
(
"systemctl"
)
if
err
==
nil
{
return
&
SystemdInitSystem
{},
nil
}
_
,
err
=
exec
.
LookPath
(
"openrc"
)
if
err
==
nil
{
return
&
OpenRCInitSystem
{},
nil
}
_
,
err
=
exec
.
LookPath
(
"wininit.exe"
)
if
err
==
nil
{
return
&
WindowsInitSystem
{},
nil
}
return
nil
,
fmt
.
Errorf
(
"no supported init system detected, skipping checking for services"
)
}
pkg/util/initsystem/initsystem_unix.go
0 → 100644
View file @
4d7ee1cd
// +build !windows
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
initsystem
import
(
"fmt"
"os/exec"
"strings"
)
type
OpenRCInitSystem
struct
{}
func
(
openrc
OpenRCInitSystem
)
ServiceStart
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"start"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
func
(
openrc
OpenRCInitSystem
)
ServiceStop
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"stop"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
func
(
openrc
OpenRCInitSystem
)
ServiceRestart
(
service
string
)
error
{
args
:=
[]
string
{
service
,
"restart"
}
return
exec
.
Command
(
"rc-service"
,
args
...
)
.
Run
()
}
// openrc writes to stderr if a service is not found or not enabled
// this is in contrast to systemd which only writes to stdout.
// Hence, we use the Combinedoutput, and ignore the error.
func
(
openrc
OpenRCInitSystem
)
ServiceExists
(
service
string
)
bool
{
args
:=
[]
string
{
service
,
"status"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-service"
,
args
...
)
.
CombinedOutput
()
if
strings
.
Contains
(
string
(
outBytes
),
"does not exist"
)
{
return
false
}
return
true
}
func
(
openrc
OpenRCInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
args
:=
[]
string
{
"show"
,
"default"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-update"
,
args
...
)
.
Output
()
if
strings
.
Contains
(
string
(
outBytes
),
service
)
{
return
true
}
return
false
}
func
(
openrc
OpenRCInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
args
:=
[]
string
{
service
,
"status"
}
outBytes
,
_
:=
exec
.
Command
(
"rc-service"
,
args
...
)
.
Output
()
if
strings
.
Contains
(
string
(
outBytes
),
"stopped"
)
{
return
false
}
return
true
}
func
(
openrc
OpenRCInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"rc-update add %s default"
,
service
)
}
type
SystemdInitSystem
struct
{}
func
(
sysd
SystemdInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"systemctl enable %s.service"
,
service
)
}
func
(
sysd
SystemdInitSystem
)
reloadSystemd
()
error
{
if
err
:=
exec
.
Command
(
"systemctl"
,
"daemon-reload"
)
.
Run
();
err
!=
nil
{
return
fmt
.
Errorf
(
"failed to reload systemd: %v"
,
err
)
}
return
nil
}
func
(
sysd
SystemdInitSystem
)
ServiceStart
(
service
string
)
error
{
// Before we try to start any service, make sure that systemd is ready
if
err
:=
sysd
.
reloadSystemd
();
err
!=
nil
{
return
err
}
args
:=
[]
string
{
"start"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceRestart
(
service
string
)
error
{
// Before we try to restart any service, make sure that systemd is ready
if
err
:=
sysd
.
reloadSystemd
();
err
!=
nil
{
return
err
}
args
:=
[]
string
{
"restart"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceStop
(
service
string
)
error
{
args
:=
[]
string
{
"stop"
,
service
}
return
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
}
func
(
sysd
SystemdInitSystem
)
ServiceExists
(
service
string
)
bool
{
args
:=
[]
string
{
"status"
,
service
}
outBytes
,
_
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Output
()
output
:=
string
(
outBytes
)
if
strings
.
Contains
(
output
,
"Loaded: not-found"
)
{
return
false
}
return
true
}
func
(
sysd
SystemdInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
args
:=
[]
string
{
"is-enabled"
,
service
}
err
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Run
()
if
err
!=
nil
{
return
false
}
return
true
}
// ServiceIsActive will check is the service is "active". In the case of
// crash looping services (kubelet in our case) status will return as
// "activating", so we will consider this active as well.
func
(
sysd
SystemdInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
args
:=
[]
string
{
"is-active"
,
service
}
// Ignoring error here, command returns non-0 if in "activating" status:
outBytes
,
_
:=
exec
.
Command
(
"systemctl"
,
args
...
)
.
Output
()
output
:=
strings
.
TrimSpace
(
string
(
outBytes
))
if
output
==
"active"
||
output
==
"activating"
{
return
true
}
return
false
}
// GetInitSystem returns an InitSystem for the current system, or nil
// if we cannot detect a supported init system.
// This indicates we will skip init system checks, not an error.
func
GetInitSystem
()
(
InitSystem
,
error
)
{
// Assume existence of systemctl in path implies this is a systemd system:
_
,
err
:=
exec
.
LookPath
(
"systemctl"
)
if
err
==
nil
{
return
&
SystemdInitSystem
{},
nil
}
_
,
err
=
exec
.
LookPath
(
"openrc"
)
if
err
==
nil
{
return
&
OpenRCInitSystem
{},
nil
}
return
nil
,
fmt
.
Errorf
(
"no supported init system detected, skipping checking for services"
)
}
pkg/util/initsystem/initsystem_windows.go
0 → 100644
View file @
4d7ee1cd
// +build windows
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
initsystem
import
(
"fmt"
"time"
"golang.org/x/sys/windows/svc"
"golang.org/x/sys/windows/svc/mgr"
)
// WindowsInitSystem is the windows implementation of InitSystem
type
WindowsInitSystem
struct
{}
func
(
sysd
WindowsInitSystem
)
EnableCommand
(
service
string
)
string
{
return
fmt
.
Sprintf
(
"Set-Service '%s' -StartupType Automatic"
,
service
)
}
// Following Windows documentation: https://docs.microsoft.com/en-us/windows/desktop/Services/starting-a-service
func
(
sysd
WindowsInitSystem
)
ServiceStart
(
service
string
)
error
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
err
}
defer
m
.
Disconnect
()
s
,
err
:=
m
.
OpenService
(
service
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not access service %s: %v"
,
service
,
err
)
}
defer
s
.
Close
()
// Check if service is already started
status
,
err
:=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not query service %s: %v"
,
service
,
err
)
}
if
status
.
State
!=
svc
.
Stopped
&&
status
.
State
!=
svc
.
StopPending
{
return
nil
}
timeout
:=
time
.
Now
()
.
Add
(
10
*
time
.
Second
)
for
status
.
State
!=
svc
.
Stopped
{
if
timeout
.
Before
(
time
.
Now
())
{
return
fmt
.
Errorf
(
"timeout waiting for %s service to stop"
,
service
)
}
time
.
Sleep
(
300
*
time
.
Millisecond
)
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not retrieve %s service status: %v"
,
service
,
err
)
}
}
// Start the service
err
=
s
.
Start
(
"is"
,
"manual-started"
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not start service %s: %v"
,
service
,
err
)
}
// Check that the start was successful
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not query service %s: %v"
,
service
,
err
)
}
timeout
=
time
.
Now
()
.
Add
(
10
*
time
.
Second
)
for
status
.
State
!=
svc
.
Running
{
if
timeout
.
Before
(
time
.
Now
())
{
return
fmt
.
Errorf
(
"timeout waiting for %s service to start"
,
service
)
}
time
.
Sleep
(
300
*
time
.
Millisecond
)
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not retrieve %s service status: %v"
,
service
,
err
)
}
}
return
nil
}
func
(
sysd
WindowsInitSystem
)
ServiceRestart
(
service
string
)
error
{
if
err
:=
sysd
.
ServiceStop
(
service
);
err
!=
nil
{
return
fmt
.
Errorf
(
"couldn't stop service %s: %v"
,
service
,
err
)
}
if
err
:=
sysd
.
ServiceStart
(
service
);
err
!=
nil
{
return
fmt
.
Errorf
(
"couldn't start service %s: %v"
,
service
,
err
)
}
return
nil
}
// Following Windows documentation: https://docs.microsoft.com/en-us/windows/desktop/Services/stopping-a-service
func
(
sysd
WindowsInitSystem
)
ServiceStop
(
service
string
)
error
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
err
}
defer
m
.
Disconnect
()
s
,
err
:=
m
.
OpenService
(
service
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not access service %s: %v"
,
service
,
err
)
}
defer
s
.
Close
()
// Check if service is already stopped
status
,
err
:=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not query service %s: %v"
,
service
,
err
)
}
if
status
.
State
==
svc
.
Stopped
{
return
nil
}
// If StopPending, check that service eventually stops
if
status
.
State
==
svc
.
StopPending
{
timeout
:=
time
.
Now
()
.
Add
(
10
*
time
.
Second
)
for
status
.
State
!=
svc
.
Stopped
{
if
timeout
.
Before
(
time
.
Now
())
{
return
fmt
.
Errorf
(
"timeout waiting for %s service to stop"
,
service
)
}
time
.
Sleep
(
300
*
time
.
Millisecond
)
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not retrieve %s service status: %v"
,
service
,
err
)
}
}
return
nil
}
// Stop the service
status
,
err
=
s
.
Control
(
svc
.
Stop
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not stop service %s: %v"
,
service
,
err
)
}
// Check that the stop was successful
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not query service %s: %v"
,
service
,
err
)
}
timeout
:=
time
.
Now
()
.
Add
(
10
*
time
.
Second
)
for
status
.
State
!=
svc
.
Stopped
{
if
timeout
.
Before
(
time
.
Now
())
{
return
fmt
.
Errorf
(
"timeout waiting for %s service to stop"
,
service
)
}
time
.
Sleep
(
300
*
time
.
Millisecond
)
status
,
err
=
s
.
Query
()
if
err
!=
nil
{
return
fmt
.
Errorf
(
"could not retrieve %s service status: %v"
,
service
,
err
)
}
}
return
nil
}
func
(
sysd
WindowsInitSystem
)
ServiceExists
(
service
string
)
bool
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
false
}
defer
m
.
Disconnect
()
s
,
err
:=
m
.
OpenService
(
service
)
if
err
!=
nil
{
return
false
}
defer
s
.
Close
()
return
true
}
func
(
sysd
WindowsInitSystem
)
ServiceIsEnabled
(
service
string
)
bool
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
false
}
defer
m
.
Disconnect
()
s
,
err
:=
m
.
OpenService
(
service
)
if
err
!=
nil
{
return
false
}
defer
s
.
Close
()
c
,
err
:=
s
.
Config
()
if
err
!=
nil
{
return
false
}
return
c
.
StartType
!=
mgr
.
StartDisabled
}
func
(
sysd
WindowsInitSystem
)
ServiceIsActive
(
service
string
)
bool
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
false
}
defer
m
.
Disconnect
()
s
,
err
:=
m
.
OpenService
(
service
)
if
err
!=
nil
{
return
false
}
defer
s
.
Close
()
status
,
err
:=
s
.
Query
()
if
err
!=
nil
{
return
false
}
return
status
.
State
==
svc
.
Running
}
// GetInitSystem returns an InitSystem for the current system, or nil
// if we cannot detect a supported init system.
// This indicates we will skip init system checks, not an error.
func
GetInitSystem
()
(
InitSystem
,
error
)
{
m
,
err
:=
mgr
.
Connect
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"no supported init system detected: %v"
,
err
)
}
defer
m
.
Disconnect
()
return
&
WindowsInitSystem
{},
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment