Skip to content
This repository was archived by the owner on Oct 11, 2023. It is now read-only.

Commit cdfec4b

Browse files
committed
add a timeout in case a system-container refuses to quit
Signed-off-by: Sven Dowideit <[email protected]>
1 parent 3b624d7 commit cdfec4b

File tree

7 files changed

+72
-20
lines changed

7 files changed

+72
-20
lines changed

cmd/power/power.go

Lines changed: 62 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ package power
22

33
import (
44
"errors"
5+
"fmt"
56
"os"
67
"path/filepath"
78
"strconv"
89
"strings"
910
"syscall"
11+
"time"
1012

1113
"golang.org/x/net/context"
1214

1315
"github.com/docker/engine-api/types"
1416
"github.com/docker/engine-api/types/container"
1517
"github.com/docker/engine-api/types/filters"
18+
"github.com/rancher/os/config"
1619
"github.com/rancher/os/log"
1720

1821
"github.com/rancher/os/docker"
@@ -76,21 +79,35 @@ func runDocker(name string) error {
7679
return err
7780
}
7881

79-
go func() {
80-
client.ContainerAttach(context.Background(), types.ContainerAttachOptions{
81-
ContainerID: powerContainer.ID,
82-
Stream: true,
83-
Stderr: true,
84-
Stdout: true,
85-
})
86-
}()
87-
8882
err = client.ContainerStart(context.Background(), powerContainer.ID)
8983
if err != nil {
9084
return err
9185
}
9286

93-
_, err = client.ContainerWait(context.Background(), powerContainer.ID)
87+
reader, err := client.ContainerLogs(context.Background(), types.ContainerLogsOptions{
88+
ContainerID: powerContainer.ID,
89+
ShowStderr: true,
90+
ShowStdout: true,
91+
Follow: true,
92+
})
93+
if err != nil {
94+
log.Fatal(err)
95+
}
96+
97+
for {
98+
p := make([]byte, 4096)
99+
n, err := reader.Read(p)
100+
if err != nil {
101+
log.Error(err)
102+
if n == 0 {
103+
reader.Close()
104+
break
105+
}
106+
}
107+
if n > 0 {
108+
fmt.Print(string(p))
109+
}
110+
}
94111

95112
if err != nil {
96113
log.Fatal(err)
@@ -126,13 +143,39 @@ func Halt() {
126143
}
127144

128145
func reboot(code uint) {
146+
cfg := config.LoadConfig()
147+
timeoutValue := cfg.Rancher.ShutdownTimeout
148+
if timeoutValue == 0 {
149+
timeoutValue = 60
150+
}
151+
if timeoutValue < 5 {
152+
timeoutValue = 5
153+
}
154+
log.Infof("Setting %s timeout to %d (cfg set to %d)", os.Args[0], timeoutValue, cfg.Rancher.ShutdownTimeout)
155+
156+
go func() {
157+
timeout := time.After(time.Duration(timeoutValue) * time.Second)
158+
tick := time.Tick(100 * time.Millisecond)
159+
// Keep trying until we're timed out or got a result or got an error
160+
for {
161+
select {
162+
// Got a timeout! fail with a timeout error
163+
case <-timeout:
164+
log.Errorf("Container shutdown taking too long, forcing %s.", os.Args[0])
165+
syscall.Sync()
166+
syscall.Reboot(int(code))
167+
case <-tick:
168+
fmt.Printf(".")
169+
}
170+
}
171+
}()
172+
129173
err := shutDownContainers()
130174
if err != nil {
131175
log.Error(err)
132176
}
133177

134178
syscall.Sync()
135-
136179
err = syscall.Reboot(int(code))
137180
if err != nil {
138181
log.Fatal(err)
@@ -206,13 +249,20 @@ func shutDownContainers() error {
206249
}
207250
}
208251

252+
// lets see what containers are still running and only wait on those
253+
containers, err = client.ContainerList(context.Background(), opts)
254+
if err != nil {
255+
return err
256+
}
257+
209258
var waitErrorStrings []string
210259

211-
for _, container := range containers {
260+
for idx, container := range containers {
212261
if container.ID == currentContainerID {
213262
continue
214263
}
215264
if container.Names[0] == "/console" {
265+
consoleContainerIdx = idx
216266
continue
217267
}
218268
log.Infof("Waiting %s : %s", container.Names[0], container.ID[:12])

cmd/power/shutdown.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ func Main() {
3131
}
3232
app.HideHelp = true
3333

34-
log.Infof("%s, %s", app.Usage, app.Version)
35-
fmt.Printf("%s, %s", app.Usage, app.Version)
36-
3734
app.Run(os.Args)
3835
}
3936

config/schema.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ var schema = `{
5252
"defaults": {"$ref": "#/definitions/defaults_config"},
5353
"resize_device": {"type": "string"},
5454
"sysctl": {"type": "object"},
55-
"restart_services": {"type": "array"}
55+
"restart_services": {"type": "array"},
56+
"shutdown_timeout": {"type": "int"}
5657
}
5758
},
5859

config/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ type RancherConfig struct {
130130
ResizeDevice string `yaml:"resize_device,omitempty"`
131131
Sysctl map[string]string `yaml:"sysctl,omitempty"`
132132
RestartServices []string `yaml:"restart_services,omitempty"`
133+
ShutdownTimeout int `yaml:"shutdown_timeout,omitempty"`
133134
}
134135

135136
type UpgradeConfig struct {

os-config.tpl.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
rancher:
2+
shutdown_timeout: 60
23
environment:
34
VERSION: {{.VERSION}}
45
SUFFIX: {{.SUFFIX}}

scripts/installer/kexec/Dockerfile.dapper

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ RUN echo "Acquire::http { Proxy \"$APTPROXY\"; };" >> /etc/apt/apt.conf.d/01prox
1010
&& apt-get install -yq build-essential autoconf libtool gawk alien fakeroot \
1111
zlib1g-dev uuid-dev libattr1-dev libblkid-dev libselinux-dev libudev-dev libdevmapper-dev \
1212
module-init-tools \
13-
parted lsscsi ksh curl git
13+
parted lsscsi ksh curl git wget
1414

1515
WORKDIR /source
1616

@@ -20,8 +20,9 @@ WORKDIR /source
2020
# && tar zxvf /source/build-linux-4.9.15-rancher-x86.tar.gz
2121

2222
# https://www.kernel.org/pub/linux/utils/kernel/kexec/
23-
ENV VERSION 2.0.14
24-
ADD https://www.kernel.org/pub/linux/utils/kernel/kexec/kexec-tools-$VERSION.tar.gz .
23+
ENV VERSION 2.0.15
24+
RUN wget https://www.kernel.org/pub/linux/utils/kernel/kexec/kexec-tools-$VERSION.tar.gz \
25+
&& tar zxvf kexec-tools-$VERSION.tar.gz
2526

2627
RUN zcat kexec-tools-$VERSION.tar.gz | tar xvf - \
2728
&& cd kexec-tools-$VERSION \

scripts/schema.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@
5050
"defaults": {"$ref": "#/definitions/defaults_config"},
5151
"resize_device": {"type": "string"},
5252
"sysctl": {"type": "object"},
53-
"restart_services": {"type": "array"}
53+
"restart_services": {"type": "array"},
54+
"shutdown_timeout": {"type": "int"}
5455
}
5556
},
5657

0 commit comments

Comments
 (0)