Skip to content

Commit

Permalink
DockerDaemonTimeout: add
Browse files Browse the repository at this point in the history
Fixes #155
  • Loading branch information
langston-barrett committed May 31, 2016
1 parent 115a915 commit d19fbf7
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 56 deletions.
80 changes: 57 additions & 23 deletions checks/docker.go
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
package checks

import (
"fmt"
"os"
"regexp"
"strings"
"time"

"github.com/CiscoCloud/distributive/chkutil"
"github.com/CiscoCloud/distributive/dockerstatus"
"github.com/CiscoCloud/distributive/errutil"
"github.com/CiscoCloud/distributive/tabular"
log "github.com/Sirupsen/logrus"
"github.com/fsouza/go-dockerclient"
"os"
"regexp"
"strings"
)

/*
#### DockerImage
Description: Is this Docker image present?
Parameters:
- Name (string): Name of the image
- Name (string): Name of the image
Example parameters:
- "user/image", "ubuntu"
- "user/image", "ubuntu"
*/

type DockerImage struct{ name string }

func init() {
chkutil.Register("DockerImage", func() chkutil.Check {
return &DockerImage{}
})
chkutil.Register("DockerRunning", func() chkutil.Check {
return &DockerRunning{}
})
chkutil.Register("DockerRunningRegext", func() chkutil.Check {
return &DockerRunningRegexp{}
})
func init() {
chkutil.Register("DockerImage", func() chkutil.Check {
return &DockerImage{}
})
chkutil.Register("DockerRunning", func() chkutil.Check {
return &DockerRunning{}
})
chkutil.Register("DockerRunningRegext", func() chkutil.Check {
return &DockerRunningRegexp{}
})
}

func (chk DockerImage) New(params []string) (chkutil.Check, error) {
Expand Down Expand Up @@ -92,9 +95,9 @@ func (chk DockerImageRegexp) Status() (int, string, error) {
#### DockerRunning
Description: Is this Docker container running?
Parameters:
- Name (string): Name of the container
- Name (string): Name of the container
Example parameters:
- "user/container", "user/container:latest"
- "user/container", "user/container:latest"
*/

type DockerRunning struct{ name string }
Expand Down Expand Up @@ -150,11 +153,11 @@ func getRunningContainersAPI(endpoint string) (containers []string) {
Description: Works like DockerRunning, but fetches information from the Docker
API endpoint instead.
Parameters:
- Path (filepath): Path to Docker socket
- Name (string): Name of the container
- Path (filepath): Path to Docker socket
- Name (string): Name of the container
Example parameters:
- "/var/run/docker.sock", "/path/to/docker.sock"
- "user/container", "user/container:latest"
- "/var/run/docker.sock", "/path/to/docker.sock"
- "user/container", "user/container:latest"
*/

type DockerRunningAPI struct{ path, name string }
Expand Down Expand Up @@ -186,9 +189,9 @@ func (chk DockerRunningAPI) Status() (int, string, error) {
Description: Works like DockerRunning, but matches with a regexp instead of a
string.
Parameters:
- Regexp (regexp): Regexp to match names with
- Regexp (regexp): Regexp to match names with
Example parameters:
- "user/.+", "user/[cC](o){2,3}[nta]tai\w{2}r"
- "user/.+", "user/[cC](o){2,3}[nta]tai\w{2}r"
*/
type DockerRunningRegexp struct{ re *regexp.Regexp }

Expand All @@ -215,3 +218,34 @@ func (chk DockerRunningRegexp) Status() (int, string, error) {
msg := "Docker container not runnning"
return errutil.GenericError(msg, chk.re.String(), running)
}

/*
#### DockerDaemonTimeout
Description: Tests if the Docker Daemon responds within a given timeout.
Parameters:
- Timeout (time.Duration)
Example parameters:
- "5s"
- "2m"
*/
type DockerDaemonTimeout struct{ timeout time.Duration }

func (chk DockerDaemonTimeout) New(params []string) (chkutil.Check, error) {
if len(params) != 1 {
return chk, errutil.ParameterLengthError{1, params}
}
timeout, err := time.ParseDuration(params[0])
if err != nil {
return chk, errutil.ParameterTypeError{params[0], "time.Duration"}
}
chk.timeout = timeout
return chk, nil
}

func (chk DockerDaemonTimeout) Status() (int, string, error) {
err := dockerstatus.DaemonResponding(chk.timeout)
if err == nil {
return errutil.Success()
}
return 1, fmt.Sprintf("Docker daemon isn't responding: %v", err), nil
}
46 changes: 17 additions & 29 deletions checks/docker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import (
)

func TestDockerImage(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
t.Parallel()
validInputs := names
invalidInputs := notLengthOne
// inputs that should lead to success
Expand All @@ -22,10 +22,10 @@ func TestDockerImage(t *testing.T) {
}

func TestDockerImageRegexp(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
t.Parallel()
validInputs := [][]string{
{"name"}, {"test*"}, {`win\d{1}`},
}
Expand All @@ -41,10 +41,10 @@ func TestDockerImageRegexp(t *testing.T) {
}

func TestDockerRunning(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
t.Parallel()
validInputs := names
invalidInputs := notLengthOne
goodEggs := [][]string{}
Expand All @@ -55,36 +55,11 @@ func TestDockerRunning(t *testing.T) {
}
}

/*
func TestDockerRunningAPI(t *testing.T) {
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
t.Parallel()
validInputs := [][]string{
{"/var/run/docker.sock", "name"},
{"/var/run/docker.sock", "test"},
{"/var/run/docker.sock", "win"},
}
invalidInputs := notLengthOne
invalidInputs = append(invalidInputs, names...)
goodEggs := [][]string{}
badEggs := [][]string{
{"/var/run/docker.sock", "failme"},
{"/var/run/docker.sock", "fail"},
{"/var/run/docker.sock", "loser"},
}
testParameters(validInputs, invalidInputs, DockerRunningAPI{}, t)
testCheck(goodEggs, badEggs, DockerRunningAPI{}, t)
}
}
*/

func TestDockerRunningRegexp(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
t.Parallel()
validInputs := names
// TODO invalid regexps
invalidInputs := notLengthOne
Expand All @@ -95,3 +70,16 @@ func TestDockerRunningRegexp(t *testing.T) {
testCheck(goodEggs, badEggs, DockerRunning{}, t)
}
}

func TestDockerDaemonTimeout(t *testing.T) {
t.Parallel()
if testing.Short() {
t.Skip("Skipping docker tests in short mode")
} else {
validInputs := [][]string{{"5s"}, {"0m"}, {"1h"}}
invalidInputs := append(notLengthOne, []string{"1fail", "sec"})
badEggs := [][]string{{"0s"}, {".1μs"}}
testParameters(validInputs, invalidInputs, DockerDaemonTimeout{}, t)
testCheck([][]string{}, badEggs, DockerDaemonTimeout{}, t)
}
}
10 changes: 6 additions & 4 deletions chkutil/chkutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,13 @@ func CommandTimeout(cmd *exec.Cmd, timeout time.Duration) (string, error) {
case cmdOutput := <-out:
return cmdOutput.Out, cmdOutput.Err
case <-timedOut:
err := cmd.Process.Kill()
if err != nil {
return "", fmt.Errorf("Error while killing timed out process %v: %v", cmd, err)
if cmd != nil && cmd.Process != nil {
err := cmd.Process.Kill()
if err != nil {
return "", fmt.Errorf("Error while killing timed out process %v: %v", cmd, err)
}
}
return "", fmt.Errorf("Command timed out: %v", cmd)
return "", fmt.Errorf("cmd's Process pointer was nil: %v", cmd)
}
}

Expand Down
7 changes: 7 additions & 0 deletions dockerstatus/dockerstatus.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,10 @@ func RunningContainers() (containers []string, err error) {
}
return parseRunningContainers(string(out)), nil
}

// DaemonResponding checks to see if the Docker daemon responds to commands
// within the given timeout. If everything goes well, it returns nil.
func DaemonResponding(timeout time.Duration) error {
_, err := chkutil.CommandTimeout(exec.Command("docker", "ps"), timeout)
return err
}

0 comments on commit d19fbf7

Please sign in to comment.