mirror of https://github.com/docker/docs.git
Rebased changes to return on first start's error
Signed-off-by: Michael Crosby <michael@docker.com>
This commit is contained in:
parent
ebf5d4657d
commit
2ec1b697c1
|
@ -1081,22 +1081,14 @@ func (container *Container) startLoggingToDisk() error {
|
||||||
func (container *Container) waitForStart() error {
|
func (container *Container) waitForStart() error {
|
||||||
container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
|
container.monitor = newContainerMonitor(container, container.hostConfig.RestartPolicy)
|
||||||
|
|
||||||
var (
|
// block until we either receive an error from the initial start of the container's
|
||||||
cErr = utils.Go(container.monitor.Start)
|
// process or until the process is running in the container
|
||||||
waitStart = make(chan struct{})
|
|
||||||
)
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
container.State.WaitRunning(-1 * time.Second)
|
|
||||||
close(waitStart)
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Start should not return until the process is actually running
|
|
||||||
select {
|
select {
|
||||||
case <-waitStart:
|
case <-container.monitor.startSignal:
|
||||||
case err := <-cErr:
|
case err := <-utils.Go(container.monitor.Start):
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ type containerMonitor struct {
|
||||||
// either because docker or the user asked for the container to be stopped
|
// either because docker or the user asked for the container to be stopped
|
||||||
shouldStop bool
|
shouldStop bool
|
||||||
|
|
||||||
|
// startSignal signals with the initial process has launched after calling Start
|
||||||
|
// on the monitor
|
||||||
|
startSignal chan struct{}
|
||||||
|
|
||||||
// stopChan is used to signal to the monitor whenever there is a wait for the
|
// stopChan is used to signal to the monitor whenever there is a wait for the
|
||||||
// next restart so that the timeIncrement is not honored and the user is not
|
// next restart so that the timeIncrement is not honored and the user is not
|
||||||
// left waiting for nothing to happen during this time
|
// left waiting for nothing to happen during this time
|
||||||
|
@ -48,12 +52,15 @@ type containerMonitor struct {
|
||||||
lastStartTime time.Time
|
lastStartTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newContainerMonitor returns an initialized containerMonitor for the provided container
|
||||||
|
// honoring the provided restart policy
|
||||||
func newContainerMonitor(container *Container, policy runconfig.RestartPolicy) *containerMonitor {
|
func newContainerMonitor(container *Container, policy runconfig.RestartPolicy) *containerMonitor {
|
||||||
return &containerMonitor{
|
return &containerMonitor{
|
||||||
container: container,
|
container: container,
|
||||||
restartPolicy: policy,
|
restartPolicy: policy,
|
||||||
timeIncrement: defaultTimeIncrement,
|
timeIncrement: defaultTimeIncrement,
|
||||||
stopChan: make(chan struct{}, 1),
|
stopChan: make(chan struct{}, 1),
|
||||||
|
startSignal: make(chan struct{}, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +126,14 @@ func (m *containerMonitor) Start() error {
|
||||||
m.lastStartTime = time.Now()
|
m.lastStartTime = time.Now()
|
||||||
|
|
||||||
if exitStatus, err = m.container.daemon.Run(m.container, pipes, m.callback); err != nil {
|
if exitStatus, err = m.container.daemon.Run(m.container, pipes, m.callback); err != nil {
|
||||||
|
// if we receive an internal error from the initial start of a container then lets
|
||||||
|
// return it instead of entering the restart loop
|
||||||
|
if m.container.RestartCount == 1 {
|
||||||
|
m.resetContainer()
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
utils.Errorf("Error running container: %s", err)
|
utils.Errorf("Error running container: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,6 +245,9 @@ func (m *containerMonitor) callback(command *execdriver.Command) {
|
||||||
|
|
||||||
m.container.State.SetRunning(command.Pid())
|
m.container.State.SetRunning(command.Pid())
|
||||||
|
|
||||||
|
// signal that the process has started
|
||||||
|
close(m.startSignal)
|
||||||
|
|
||||||
if err := m.container.ToDisk(); err != nil {
|
if err := m.container.ToDisk(); err != nil {
|
||||||
utils.Debugf("%s", err)
|
utils.Debugf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue