Add typed RestartPolicy

Signed-off-by: Michael Crosby <michael@docker.com>
This commit is contained in:
Michael Crosby 2014-08-04 16:14:43 -07:00
parent e0a076d486
commit d9753ba20d
3 changed files with 52 additions and 6 deletions

View File

@ -501,6 +501,7 @@ func (container *Container) monitor(callback execdriver.StartCallback) error {
err error err error
exitCode int exitCode int
failCount int failCount int
exit bool
policy = container.hostConfig.RestartPolicy policy = container.hostConfig.RestartPolicy
) )
@ -522,8 +523,8 @@ func (container *Container) monitor(callback execdriver.StartCallback) error {
if exitCode, err = container.daemon.Run(container, pipes, callback); err != nil { if exitCode, err = container.daemon.Run(container, pipes, callback); err != nil {
failCount++ failCount++
if failCount == 100 { if failCount == policy.MaximumRetryCount {
container.requestedStop = true exit = true
} }
utils.Errorf("Error running container: %s", err) utils.Errorf("Error running container: %s", err)
@ -561,7 +562,7 @@ func (container *Container) monitor(callback execdriver.StartCallback) error {
container.daemon.srv.LogEvent("die", container.ID, container.daemon.repositories.ImageName(container.Image)) container.daemon.srv.LogEvent("die", container.ID, container.daemon.repositories.ImageName(container.Image))
} }
if (policy == "always" || (policy == "on-failure" && exitCode != 0)) && !container.requestedStop { if (policy.Name == "always" || (policy.Name == "on-failure" && exitCode != 0)) && !container.requestedStop || !exit {
container.command.Cmd = copyCmd(&container.command.Cmd) container.command.Cmd = copyCmd(&container.command.Cmd)
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)

View File

@ -25,6 +25,11 @@ type DeviceMapping struct {
CgroupPermissions string CgroupPermissions string
} }
type RestartPolicy struct {
Name string
MaximumRetryCount int
}
type HostConfig struct { type HostConfig struct {
Binds []string Binds []string
ContainerIDFile string ContainerIDFile string
@ -40,7 +45,7 @@ type HostConfig struct {
NetworkMode NetworkMode NetworkMode NetworkMode
CapAdd []string CapAdd []string
CapDrop []string CapDrop []string
RestartPolicy string RestartPolicy RestartPolicy
} }
func ContainerHostConfigFromJob(job *engine.Job) *HostConfig { func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
@ -49,11 +54,12 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
Privileged: job.GetenvBool("Privileged"), Privileged: job.GetenvBool("Privileged"),
PublishAllPorts: job.GetenvBool("PublishAllPorts"), PublishAllPorts: job.GetenvBool("PublishAllPorts"),
NetworkMode: NetworkMode(job.Getenv("NetworkMode")), NetworkMode: NetworkMode(job.Getenv("NetworkMode")),
RestartPolicy: job.Getenv("RestartPolicy"),
} }
job.GetenvJson("LxcConf", &hostConfig.LxcConf) job.GetenvJson("LxcConf", &hostConfig.LxcConf)
job.GetenvJson("PortBindings", &hostConfig.PortBindings) job.GetenvJson("PortBindings", &hostConfig.PortBindings)
job.GetenvJson("Devices", &hostConfig.Devices) job.GetenvJson("Devices", &hostConfig.Devices)
job.GetenvJson("RestartPolicy", &hostConfig.RestartPolicy)
if Binds := job.GetenvList("Binds"); Binds != nil { if Binds := job.GetenvList("Binds"); Binds != nil {
hostConfig.Binds = Binds hostConfig.Binds = Binds
} }
@ -75,5 +81,6 @@ func ContainerHostConfigFromJob(job *engine.Job) *HostConfig {
if CapDrop := job.GetenvList("CapDrop"); CapDrop != nil { if CapDrop := job.GetenvList("CapDrop"); CapDrop != nil {
hostConfig.CapDrop = CapDrop hostConfig.CapDrop = CapDrop
} }
return hostConfig return hostConfig
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"path" "path"
"strconv"
"strings" "strings"
"github.com/docker/docker/nat" "github.com/docker/docker/nat"
@ -234,6 +235,11 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err) return nil, nil, cmd, fmt.Errorf("--net: invalid net mode: %v", err)
} }
restartPolicy, err := parseRestartPolicy(*flRestartPolicy)
if err != nil {
return nil, nil, cmd, err
}
config := &Config{ config := &Config{
Hostname: hostname, Hostname: hostname,
Domainname: domainname, Domainname: domainname,
@ -272,7 +278,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
Devices: deviceMappings, Devices: deviceMappings,
CapAdd: flCapAdd.GetAll(), CapAdd: flCapAdd.GetAll(),
CapDrop: flCapDrop.GetAll(), CapDrop: flCapDrop.GetAll(),
RestartPolicy: *flRestartPolicy, RestartPolicy: restartPolicy,
} }
if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit { if sysInfo != nil && flMemory > 0 && !sysInfo.SwapLimit {
@ -287,6 +293,38 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
return config, hostConfig, cmd, nil return config, hostConfig, cmd, nil
} }
// parseRestartPolicy returns the parsed policy or an error indicating what is incorrect
func parseRestartPolicy(policy string) (RestartPolicy, error) {
p := RestartPolicy{}
if policy == "" {
return p, nil
}
var (
parts = strings.Split(policy, ":")
name = parts[0]
)
switch name {
case "no", "on-failure", "always":
p.Name = name
if len(parts) == 2 {
count, err := strconv.Atoi(parts[1])
if err != nil {
return p, err
}
p.MaximumRetryCount = count
}
default:
return p, fmt.Errorf("invalid restart policy %s", name)
}
return p, nil
}
// options will come in the format of name.key=value or name.option // options will come in the format of name.key=value or name.option
func parseDriverOpts(opts opts.ListOpts) (map[string][]string, error) { func parseDriverOpts(opts opts.ListOpts) (map[string][]string, error) {
out := make(map[string][]string, len(opts.GetAll())) out := make(map[string][]string, len(opts.GetAll()))