Skip to content

Commit 7b1ea68

Browse files
authored
Merge pull request #517 from jeremyje/fixwin
Windows Support: Fix Build Regressions, Tests Pass
2 parents cb8534b + 4181ece commit 7b1ea68

20 files changed

+322
-55
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ script:
3131
- BUILD_TAGS="disable_stackdriver_exporter" make test
3232
- make clean && ENABLE_JOURNALD=0 make
3333
- ENABLE_JOURNALD=0 make test
34+
- ENABLE_JOURNALD=0 make build-binaries

Makefile

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,12 @@ UPLOAD_PATH:=$(shell echo $(UPLOAD_PATH) | sed '$$s/\/*$$//')
3838
PKG:=k8s.io/node-problem-detector
3939

4040
# PKG_SOURCES are all the go source code.
41+
ifeq ($(OS),Windows_NT)
42+
PKG_SOURCES:=
43+
# TODO: File change detection does not work in Windows.
44+
else
4145
PKG_SOURCES:=$(shell find pkg cmd -name '*.go')
46+
endif
4247

4348
# PARALLEL specifies the number of parallel test nodes to run for e2e tests.
4449
PARALLEL?=3
@@ -74,6 +79,12 @@ BUILD_TAGS?=
7479
LINUX_BUILD_TAGS = $(BUILD_TAGS)
7580
WINDOWS_BUILD_TAGS = $(BUILD_TAGS)
7681

82+
ifeq ($(OS),Windows_NT)
83+
HOST_PLATFORM_BUILD_TAGS = $(WINDOWS_BUILD_TAGS)
84+
else
85+
HOST_PLATFORM_BUILD_TAGS = $(LINUX_BUILD_TAGS)
86+
endif
87+
7788
ifeq ($(ENABLE_JOURNALD), 1)
7889
# Enable journald build tag.
7990
LINUX_BUILD_TAGS := $(BUILD_TAGS) journald
@@ -91,9 +102,9 @@ else
91102
endif
92103

93104
vet:
94-
GO111MODULE=on go list -mod vendor -tags "$(LINUX_BUILD_TAGS)" ./... | \
105+
GO111MODULE=on go list -mod vendor -tags "$(HOST_PLATFORM_BUILD_TAGS)" ./... | \
95106
grep -v "./vendor/*" | \
96-
GO111MODULE=on xargs go vet -mod vendor -tags "$(LINUX_BUILD_TAGS)"
107+
GO111MODULE=on xargs go vet -mod vendor -tags "$(HOST_PLATFORM_BUILD_TAGS)"
97108

98109
fmt:
99110
find . -type f -name "*.go" | grep -v "./vendor/*" | xargs gofmt -s -w -l
@@ -109,7 +120,10 @@ ifeq ($(ENABLE_JOURNALD), 1)
109120
LINUX_AMD64_BINARIES += bin/linux_amd64/log-counter
110121
endif
111122

112-
windows-binaries: $(WINDOWS_AMD64_BINARIES) $(WINDOWS_AMD64_TEST_BINARIES)
123+
WINDOWS_BINARIES = $(WINDOWS_AMD64_BINARIES) $(WINDOWS_AMD64_TEST_BINARIES)
124+
LINUX_BINARIES = $(LINUX_AMD64_BINARIES) $(LINUX_AMD64_TEST_BINARIES)
125+
126+
windows-binaries: $(WINDOWS_BINARIES)
113127

114128
bin/windows_amd64/%.exe: $(PKG_SOURCES)
115129
ifeq ($(ENABLE_JOURNALD), 1)
@@ -191,10 +205,10 @@ endif
191205
cmd/healthchecker/health_checker.go
192206

193207
test: vet fmt
194-
GO111MODULE=on go test -mod vendor -timeout=1m -v -race -short -tags "$(LINUX_BUILD_TAGS)" ./...
208+
GO111MODULE=on go test -mod vendor -timeout=1m -v -race -short -tags "$(HOST_PLATFORM_BUILD_TAGS)" ./...
195209

196210
e2e-test: vet fmt build-tar
197-
GO111MODULE=on ginkgo -nodes=$(PARALLEL) -mod vendor -timeout=10m -v -tags "$(LINUX_BUILD_TAGS)" -stream \
211+
GO111MODULE=on ginkgo -nodes=$(PARALLEL) -mod vendor -timeout=10m -v -tags "$(HOST_PLATFORM_BUILD_TAGS)" -stream \
198212
./test/e2e/metriconly/... -- \
199213
-project=$(PROJECT) -zone=$(ZONE) \
200214
-image=$(VM_IMAGE) -image-family=$(IMAGE_FAMILY) -image-project=$(IMAGE_PROJECT) \
@@ -203,7 +217,7 @@ e2e-test: vet fmt build-tar
203217
-boskos-project-type=$(BOSKOS_PROJECT_TYPE) -job-name=$(JOB_NAME) \
204218
-artifacts-dir=$(ARTIFACTS)
205219

206-
build-binaries: ./bin/node-problem-detector ./bin/log-counter ./bin/health-checker
220+
build-binaries: ./bin/node-problem-detector ./bin/log-counter ./bin/health-checker $(WINDOWS_BINARIES) $(LINUX_BINARIES)
207221

208222
build-container: build-binaries Dockerfile
209223
docker build -t $(IMAGE) --build-arg BASEIMAGE=$(BASEIMAGE) --build-arg LOGCOUNTER=$(LOGCOUNTER) .

config/windows-containerd-monitor-filelog.json

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,18 @@
88
"logPath": "C:\\Program Files\\containerd\\containerd.log",
99
"lookback": "5m",
1010
"bufferSize": 10,
11-
"source": "docker-monitor",
11+
"source": "containerd",
1212
"conditions": [],
1313
"rules": [
1414
{
1515
"type": "temporary",
16-
"reason": "BadCNIConfig",
17-
"pattern": "failed to reload cni configuration.*"
16+
"reason": "MissingPigz",
17+
"pattern": "unpigz not found.*"
18+
},
19+
{
20+
"type": "temporary",
21+
"reason": "IncompatibleContainer",
22+
"pattern": ".*CreateComputeSystem.*"
1823
}
1924
]
2025
}

pkg/custompluginmonitor/plugin/plugin.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929

3030
"github.com/golang/glog"
3131
cpmtypes "k8s.io/node-problem-detector/pkg/custompluginmonitor/types"
32+
"k8s.io/node-problem-detector/pkg/util"
3233
"k8s.io/node-problem-detector/pkg/util/tomb"
3334
)
3435

@@ -147,12 +148,7 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
147148
}
148149
defer cancel()
149150

150-
// create a process group
151-
sysProcAttr := &syscall.SysProcAttr{
152-
Setpgid: true,
153-
}
154-
cmd := exec.Command(rule.Path, rule.Args...)
155-
cmd.SysProcAttr = sysProcAttr
151+
cmd := util.Exec(rule.Path, rule.Args...)
156152

157153
stdoutPipe, err := cmd.StdoutPipe()
158154
if err != nil {
@@ -172,6 +168,9 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
172168
waitChan := make(chan struct{})
173169
defer close(waitChan)
174170

171+
var m sync.Mutex
172+
timeout := false
173+
175174
go func() {
176175
select {
177176
case <-ctx.Done():
@@ -183,7 +182,12 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
183182
glog.Errorf("Error in cmd.Process check %q", rule.Path)
184183
break
185184
}
186-
err := syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
185+
186+
m.Lock()
187+
timeout = true
188+
m.Unlock()
189+
190+
err := util.Kill(cmd)
187191
if err != nil {
188192
glog.Errorf("Error in kill process %d, %v", cmd.Process.Pid, err)
189193
}
@@ -202,12 +206,12 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
202206

203207
wg.Add(2)
204208
go func() {
209+
defer wg.Done()
205210
stdout, stdoutErr = readFromReader(stdoutPipe, maxCustomPluginBufferBytes)
206-
wg.Done()
207211
}()
208212
go func() {
213+
defer wg.Done()
209214
stderr, stderrErr = readFromReader(stderrPipe, maxCustomPluginBufferBytes)
210-
wg.Done()
211215
}()
212216
// This will wait for the reads to complete. If the execution times out, the pipes
213217
// will be closed and the wait group unblocks.
@@ -234,7 +238,11 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
234238
output = string(stdout)
235239
output = strings.TrimSpace(output)
236240

237-
if cmd.ProcessState.Sys().(syscall.WaitStatus).Signaled() {
241+
m.Lock()
242+
cmdKilled := timeout
243+
m.Unlock()
244+
245+
if cmdKilled {
238246
output = fmt.Sprintf("Timeout when running plugin %q: state - %s. output - %q", rule.Path, cmd.ProcessState.String(), output)
239247
}
240248

@@ -257,6 +265,7 @@ func (p *Plugin) run(rule cpmtypes.CustomRule) (exitStatus cpmtypes.Status, outp
257265
}
258266
}
259267

268+
// Stop the plugin.
260269
func (p *Plugin) Stop() {
261270
p.tomb.Stop()
262271
glog.Info("Stop plugin execution")

pkg/custompluginmonitor/plugin/plugin_test.go

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package plugin
1818

1919
import (
20+
"runtime"
2021
"testing"
2122
"time"
2223

@@ -25,6 +26,13 @@ import (
2526

2627
func TestNewPluginRun(t *testing.T) {
2728
ruleTimeout := 1 * time.Second
29+
timeoutExitStatus := cpmtypes.Unknown
30+
ext := "sh"
31+
32+
if runtime.GOOS == "windows" {
33+
ext = "cmd"
34+
timeoutExitStatus = cpmtypes.NonOK
35+
}
2836

2937
utMetas := map[string]struct {
3038
Rule cpmtypes.CustomRule
@@ -33,30 +41,31 @@ func TestNewPluginRun(t *testing.T) {
3341
}{
3442
"ok": {
3543
Rule: cpmtypes.CustomRule{
36-
Path: "./test-data/ok.sh",
44+
Path: "./test-data/ok." + ext,
3745
Timeout: &ruleTimeout,
3846
},
3947
ExitStatus: cpmtypes.OK,
4048
Output: "OK",
4149
},
4250
"non-ok": {
4351
Rule: cpmtypes.CustomRule{
44-
Path: "./test-data/non-ok.sh",
52+
Path: "./test-data/non-ok." + ext,
4553
Timeout: &ruleTimeout,
4654
},
4755
ExitStatus: cpmtypes.NonOK,
4856
Output: "NonOK",
4957
},
5058
"unknown": {
5159
Rule: cpmtypes.CustomRule{
52-
Path: "./test-data/unknown.sh",
60+
Path: "./test-data/unknown." + ext,
5361
Timeout: &ruleTimeout,
5462
},
5563
ExitStatus: cpmtypes.Unknown,
5664
Output: "UNKNOWN",
5765
},
5866
"non executable": {
5967
Rule: cpmtypes.CustomRule{
68+
// Intentionally run .sh for Windows, this is meant to be not executable.
6069
Path: "./test-data/non-executable.sh",
6170
Timeout: &ruleTimeout,
6271
},
@@ -65,45 +74,48 @@ func TestNewPluginRun(t *testing.T) {
6574
},
6675
"longer than 80 stdout with ok exit status": {
6776
Rule: cpmtypes.CustomRule{
68-
Path: "./test-data/longer-than-80-stdout-with-ok-exit-status.sh",
77+
Path: "./test-data/longer-than-80-stdout-with-ok-exit-status." + ext,
6978
Timeout: &ruleTimeout,
7079
},
7180
ExitStatus: cpmtypes.OK,
7281
Output: "01234567890123456789012345678901234567890123456789012345678901234567890123456789",
7382
},
7483
"non defined exit status": {
7584
Rule: cpmtypes.CustomRule{
76-
Path: "./test-data/non-defined-exit-status.sh",
85+
Path: "./test-data/non-defined-exit-status." + ext,
7786
Timeout: &ruleTimeout,
7887
},
7988
ExitStatus: cpmtypes.Unknown,
8089
Output: "NON-DEFINED-EXIT-STATUS",
8190
},
8291
"sleep 3 second with ok exit status": {
8392
Rule: cpmtypes.CustomRule{
84-
Path: "./test-data/sleep-3-second-with-ok-exit-status.sh",
93+
Path: "./test-data/sleep-3-second-with-ok-exit-status." + ext,
8594
Timeout: &ruleTimeout,
8695
},
87-
ExitStatus: cpmtypes.Unknown,
88-
Output: `Timeout when running plugin "./test-data/sleep-3-second-with-ok-exit-status.sh": state - signal: killed. output - ""`,
96+
ExitStatus: timeoutExitStatus,
97+
Output: `Timeout when running plugin "./test-data/sleep-3-second-with-ok-exit-status.` + ext + `": state - signal: killed. output - ""`,
8998
},
9099
}
91100

92-
conf := cpmtypes.CustomPluginConfig{}
93-
(&conf).ApplyConfiguration()
94-
p := Plugin{config: conf}
95-
for desp, utMeta := range utMetas {
96-
gotExitStatus, gotOutput := p.run(utMeta.Rule)
97-
// cut at position max_output_length if expected output is longer than max_output_length bytes
98-
if len(utMeta.Output) > *p.config.PluginGlobalConfig.MaxOutputLength {
99-
utMeta.Output = utMeta.Output[:*p.config.PluginGlobalConfig.MaxOutputLength]
100-
}
101-
if gotExitStatus != utMeta.ExitStatus || gotOutput != utMeta.Output {
102-
t.Errorf("%s", desp)
103-
t.Errorf("Error in run plugin and get exit status and output for %q. "+
104-
"Got exit status: %v, Expected exit status: %v. "+
105-
"Got output: %q, Expected output: %q",
106-
utMeta.Rule.Path, gotExitStatus, utMeta.ExitStatus, gotOutput, utMeta.Output)
107-
}
101+
for k, v := range utMetas {
102+
desp := k
103+
utMeta := v
104+
t.Run(desp, func(t *testing.T) {
105+
conf := cpmtypes.CustomPluginConfig{}
106+
(&conf).ApplyConfiguration()
107+
p := Plugin{config: conf}
108+
gotExitStatus, gotOutput := p.run(utMeta.Rule)
109+
// cut at position max_output_length if expected output is longer than max_output_length bytes
110+
if len(utMeta.Output) > *p.config.PluginGlobalConfig.MaxOutputLength {
111+
utMeta.Output = utMeta.Output[:*p.config.PluginGlobalConfig.MaxOutputLength]
112+
}
113+
if gotExitStatus != utMeta.ExitStatus || gotOutput != utMeta.Output {
114+
t.Errorf("Error in run plugin and get exit status and output for %q. "+
115+
"Got exit status: %v, Expected exit status: %v. "+
116+
"Got output: %q, Expected output: %q",
117+
utMeta.Rule.Path, gotExitStatus, utMeta.ExitStatus, gotOutput, utMeta.Output)
118+
}
119+
})
108120
}
109121
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@echo off
2+
3+
echo 012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
4+
exit 0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@echo off
2+
3+
echo NON-DEFINED-EXIT-STATUS
4+
exit 100
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@echo off
2+
3+
echo NonOK
4+
exit 1
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@echo off
2+
3+
echo OK
4+
exit 0
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@echo off
2+
3+
ping 127.0.0.1 -n 3 > nul
4+
echo SLEEP 3S SECOND
5+
exit 0
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@echo off
2+
3+
echo UNKNOWN
4+
exit 3

0 commit comments

Comments
 (0)