Parcourir la source

Add typed RestartPolicy

Signed-off-by: Michael Crosby <michael@docker.com>
Michael Crosby il y a 11 ans
Parent
commit
d9753ba20d
3 fichiers modifiés avec 52 ajouts et 6 suppressions
  1. 4 3
      daemon/container.go
  2. 9 2
      runconfig/hostconfig.go
  3. 39 1
      runconfig/parse.go

+ 4 - 3
daemon/container.go

@@ -501,6 +501,7 @@ func (container *Container) monitor(callback execdriver.StartCallback) error {
 		err       error
 		exitCode  int
 		failCount int
+		exit      bool
 
 		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 {
 			failCount++
 
-			if failCount == 100 {
-				container.requestedStop = true
+			if failCount == policy.MaximumRetryCount {
+				exit = true
 			}
 
 			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))
 		}
 
-		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)
 
 			time.Sleep(1 * time.Second)

+ 9 - 2
runconfig/hostconfig.go

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

+ 39 - 1
runconfig/parse.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"io/ioutil"
 	"path"
+	"strconv"
 	"strings"
 
 	"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)
 	}
 
+	restartPolicy, err := parseRestartPolicy(*flRestartPolicy)
+	if err != nil {
+		return nil, nil, cmd, err
+	}
+
 	config := &Config{
 		Hostname:        hostname,
 		Domainname:      domainname,
@@ -272,7 +278,7 @@ func parseRun(cmd *flag.FlagSet, args []string, sysInfo *sysinfo.SysInfo) (*Conf
 		Devices:         deviceMappings,
 		CapAdd:          flCapAdd.GetAll(),
 		CapDrop:         flCapDrop.GetAll(),
-		RestartPolicy:   *flRestartPolicy,
+		RestartPolicy:   restartPolicy,
 	}
 
 	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
 }
 
+// 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
 func parseDriverOpts(opts opts.ListOpts) (map[string][]string, error) {
 	out := make(map[string][]string, len(opts.GetAll()))