Skip to content

Commit 42e3d11

Browse files
authored
Make container startup timeout configurable (#65)
* make container startup timeout configurable Signed-off-by: James Lamb <[email protected]> * address linter warnings Signed-off-by: James Lamb <[email protected]> * simplify Signed-off-by: James Lamb <[email protected]> * use a different, less segfault-y path to pass configuration Signed-off-by: James Lamb <[email protected]> * remove startupTimeout from the Container class Signed-off-by: James Lamb <[email protected]> * more simplifications Signed-off-by: James Lamb <[email protected]> * add tests Signed-off-by: James Lamb <[email protected]> * revert tests Signed-off-by: James Lamb <[email protected]> * revert one more test thing Signed-off-by: James Lamb <[email protected]> --------- Signed-off-by: James Lamb <[email protected]>
1 parent ed10893 commit 42e3d11

File tree

6 files changed

+39
-32
lines changed

6 files changed

+39
-32
lines changed

cmd/validate.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,5 @@ func init() {
8686
rootCmd.AddCommand(validateCmd)
8787
validateCmd.PersistentFlags().String("file", "", "Path or URL of a manifest to validate against.")
8888
validateCmd.PersistentFlags().Bool("debug", false, "Keep container running on failure for debugging.")
89-
89+
validateCmd.PersistentFlags().Int("startup-timeout", 10, "Maximum time (in seconds) to wait for the container to start up.")
9090
}

internal/container/container.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type ContainerInfo struct {
3737
}
3838

3939
type ContainerInterface interface {
40-
Start() error
40+
Start(timeoutSeconds int) error
4141
Remove() error
4242
Status() (*ContainerInfo, error)
4343
Exec(command ...string) (string, error)

internal/container/docker.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ type DockerContainer struct {
2222
Volumes []canaryv1.Volume
2323
RunOptions []string
2424
runCommand string
25+
StartupTimeout int
2526
}
2627

2728
// Start a container
28-
func (c *DockerContainer) Start() error {
29+
func (c *DockerContainer) Start(timeoutSeconds int) error {
2930

3031
commandArgs := []string{"run", "-d"}
3132

@@ -78,12 +79,12 @@ func (c *DockerContainer) Start() error {
7879
if info.State.Running {
7980
break
8081
}
81-
if time.Since(startTime) > (time.Second * 10) {
82+
if time.Since(startTime) > (time.Second * time.Duration(timeoutSeconds)) {
8283
err := c.Remove()
8384
if err != nil {
8485
return err
8586
}
86-
return errors.New("container failed to start after 10 seconds")
87+
return fmt.Errorf("container failed to start after %d seconds", timeoutSeconds)
8788
}
8889
time.Sleep(time.Second)
8990
}

internal/container/docker_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func TestDockerContainer(t *testing.T) {
3939
}
4040
c := New("nginx", env, ports, volumes, nil, nil)
4141

42-
err := c.Start()
42+
err := c.Start(10)
4343

4444
defer func() {
4545
err := c.Remove()
@@ -71,7 +71,7 @@ func TestDockerContainer(t *testing.T) {
7171
func TestDockerContainerRemoves(t *testing.T) {
7272
c := New("nginx", nil, nil, nil, nil, nil)
7373

74-
err := c.Start()
74+
err := c.Start(10)
7575
if err != nil {
7676
t.Errorf("Failed to start container: %s", err.Error())
7777
return

internal/validator/tui.go

+15-14
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,20 @@ import (
2828
)
2929

3030
type model struct {
31-
sub chan checkResult
32-
container container.ContainerInterface
33-
containerStarted bool
34-
results []checkResult
35-
allChecksPassed bool
36-
spinner spinner.Model
37-
progress progress.Model
38-
debug bool
39-
image string
40-
validator *canaryv1.Validator
41-
configPath string
42-
err error
43-
tty bool
31+
sub chan checkResult
32+
container container.ContainerInterface
33+
containerStarted bool
34+
containerStartupTimeout int
35+
results []checkResult
36+
allChecksPassed bool
37+
spinner spinner.Model
38+
progress progress.Model
39+
debug bool
40+
image string
41+
validator *canaryv1.Validator
42+
configPath string
43+
err error
44+
tty bool
4445
}
4546

4647
func (m model) Init() tea.Cmd {
@@ -133,7 +134,7 @@ func handleConfigLoaded(m model, msg configLoaded) (model, tea.Cmd) {
133134
if !m.tty {
134135
commands = append(commands, tea.Printf("Starting container"))
135136
}
136-
commands = append(commands, startContainer(m.image, m.validator))
137+
commands = append(commands, startContainer(m.image, m.validator, m.containerStartupTimeout))
137138
return m, tea.Batch(commands...)
138139
}
139140

internal/validator/validator.go

+16-11
Original file line numberDiff line numberDiff line change
@@ -69,16 +69,21 @@ func Validate(image string, configPath string, cmd *cobra.Command, debug bool) (
6969
tty = bufio.NewReader(os.Stdin)
7070
isTty = false
7171
}
72+
startupTimeout, err := cmd.Flags().GetInt("startup-timeout")
73+
if err != nil {
74+
return false, err
75+
}
7276
m := model{
73-
sub: make(chan checkResult),
74-
configPath: configPath,
75-
containerStarted: false,
76-
spinner: spinner.New(),
77-
progress: progress.New(progress.WithSolidFill("#f2e63a")),
78-
allChecksPassed: true,
79-
debug: debug,
80-
image: image,
81-
tty: isTty,
77+
sub: make(chan checkResult),
78+
configPath: configPath,
79+
containerStarted: false,
80+
containerStartupTimeout: startupTimeout,
81+
spinner: spinner.New(),
82+
progress: progress.New(progress.WithSolidFill("#f2e63a")),
83+
allChecksPassed: true,
84+
debug: debug,
85+
image: image,
86+
tty: isTty,
8287
}
8388
p := tea.NewProgram(m, tea.WithInput(tty), tea.WithOutput(cmd.OutOrStderr()))
8489
out, err := p.Run()
@@ -123,10 +128,10 @@ func loadConfig(filePath string) tea.Cmd {
123128
}
124129
}
125130

126-
func startContainer(image string, validator *canaryv1.Validator) tea.Cmd {
131+
func startContainer(image string, validator *canaryv1.Validator, startupTimeout int) tea.Cmd {
127132
return func() tea.Msg {
128133
container := container.New(image, validator.Env, validator.Ports, validator.Volumes, validator.Command, validator.DockerRunOptions)
129-
err := container.Start()
134+
err := container.Start(startupTimeout)
130135
if err != nil {
131136
return containerFailed{Error: err}
132137
}

0 commit comments

Comments
 (0)