-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Driver.Prestart method #2054
Changes from 2 commits
ee17940
50934da
750d597
bbcc27e
6702813
aaa70ab
5ad7eea
630812b
decee19
904543e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,6 +91,10 @@ const ( | |
|
||
type DockerDriver struct { | ||
DriverContext | ||
|
||
imageID string | ||
waitClient *docker.Client | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You don't have to pass this as it is a shared variable that is initialized once per client There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tangent: Hm, should I be using the waitClient for image downloading? |
||
driverConfig *DockerDriverConfig | ||
} | ||
|
||
type DockerDriverAuth struct { | ||
|
@@ -339,46 +343,57 @@ func (d *DockerDriver) Abilities() DriverAbilities { | |
} | ||
} | ||
|
||
func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { | ||
func (d *DockerDriver) Prestart(ctx *ExecContext, task *structs.Task) error { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you emit a message for when it downloads an image? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can't believe I missed that in this PR! Added (inside the createImage method so it's not emitted if the image already exists). |
||
// Set environment variables. | ||
d.taskEnv.SetAllocDir(allocdir.SharedAllocContainerPath). | ||
SetTaskLocalDir(allocdir.TaskLocalContainerPath).SetSecretsDir(allocdir.TaskSecretsContainerPath).Build() | ||
|
||
driverConfig, err := NewDockerDriverConfig(task, d.taskEnv) | ||
if err != nil { | ||
return nil, err | ||
return err | ||
} | ||
|
||
cleanupImage := d.config.ReadBoolDefault("docker.cleanup.image", true) | ||
|
||
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName] | ||
if !ok { | ||
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) | ||
return fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. taskDir is a variable in the task_runner now. Pass it through the context? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's in the next PR |
||
} | ||
|
||
// Initialize docker API clients | ||
client, waitClient, err := d.dockerClients() | ||
if err != nil { | ||
return nil, fmt.Errorf("Failed to connect to docker daemon: %s", err) | ||
return fmt.Errorf("Failed to connect to docker daemon: %s", err) | ||
} | ||
|
||
if err := d.createImage(driverConfig, client, taskDir); err != nil { | ||
return nil, err | ||
return err | ||
} | ||
|
||
image := driverConfig.ImageName | ||
// Now that we have the image we can get the image id | ||
dockerImage, err := client.InspectImage(image) | ||
if err != nil { | ||
d.logger.Printf("[ERR] driver.docker: failed getting image id for %s: %s", image, err) | ||
return nil, fmt.Errorf("Failed to determine image id for `%s`: %s", image, err) | ||
return fmt.Errorf("Failed to determine image id for `%s`: %s", image, err) | ||
} | ||
d.logger.Printf("[DEBUG] driver.docker: identified image %s as %s", image, dockerImage.ID) | ||
|
||
// Set state needed by Start() | ||
d.imageID = dockerImage.ID | ||
d.waitClient = waitClient | ||
d.driverConfig = driverConfig | ||
return nil | ||
} | ||
|
||
func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle, error) { | ||
bin, err := discover.NomadExecutable() | ||
if err != nil { | ||
return nil, fmt.Errorf("unable to find the nomad binary: %v", err) | ||
} | ||
|
||
taskDir, ok := ctx.AllocDir.TaskDirs[d.DriverContext.taskName] | ||
if !ok { | ||
return nil, fmt.Errorf("Could not find task directory for task: %v", d.DriverContext.taskName) | ||
} | ||
pluginLogFile := filepath.Join(taskDir, fmt.Sprintf("%s-executor.out", task.Name)) | ||
pluginConfig := &plugin.ClientConfig{ | ||
Cmd: exec.Command(bin, "executor", pluginLogFile), | ||
|
@@ -404,9 +419,9 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
|
||
// Only launch syslog server if we're going to use it! | ||
syslogAddr := "" | ||
if runtime.GOOS == "darwin" && len(driverConfig.Logging) == 0 { | ||
if runtime.GOOS == "darwin" && len(d.driverConfig.Logging) == 0 { | ||
d.logger.Printf("[DEBUG] driver.docker: disabling syslog driver as Docker for Mac workaround") | ||
} else if len(driverConfig.Logging) == 0 || driverConfig.Logging[0].Type == "syslog" { | ||
} else if len(d.driverConfig.Logging) == 0 || d.driverConfig.Logging[0].Type == "syslog" { | ||
ss, err := exec.LaunchSyslogServer() | ||
if err != nil { | ||
pluginClient.Kill() | ||
|
@@ -415,11 +430,11 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
syslogAddr = ss.Addr | ||
} | ||
|
||
config, err := d.createContainerConfig(ctx, task, driverConfig, syslogAddr) | ||
config, err := d.createContainerConfig(ctx, task, d.driverConfig, syslogAddr) | ||
if err != nil { | ||
d.logger.Printf("[ERR] driver.docker: failed to create container configuration for image %s: %s", image, err) | ||
d.logger.Printf("[ERR] driver.docker: failed to create container configuration for image %s: %s", d.imageID, err) | ||
pluginClient.Kill() | ||
return nil, fmt.Errorf("Failed to create container configuration for image %s: %s", image, err) | ||
return nil, fmt.Errorf("Failed to create container configuration for image %s: %s", d.imageID, err) | ||
} | ||
|
||
container, rerr := d.createContainer(config) | ||
|
@@ -432,17 +447,17 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
|
||
d.logger.Printf("[INFO] driver.docker: created container %s", container.ID) | ||
|
||
cleanupImage := d.config.ReadBoolDefault("docker.cleanup.image", true) | ||
|
||
// We don't need to start the container if the container is already running | ||
// since we don't create containers which are already present on the host | ||
// and are running | ||
if !container.State.Running { | ||
// Start the container | ||
err := d.startContainer(container) | ||
if err != nil { | ||
if err := client.StartContainer(container.ID, container.HostConfig); err != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did you change from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yikes. No clue. Thanks for catching this. Fixed. |
||
d.logger.Printf("[ERR] driver.docker: failed to start container %s: %s", container.ID, err) | ||
pluginClient.Kill() | ||
err.Err = fmt.Sprintf("Failed to start container %s: %s", container.ID, err) | ||
return nil, err | ||
return nil, fmt.Errorf("Failed to start container %s: %s", container.ID, err) | ||
} | ||
d.logger.Printf("[INFO] driver.docker: started container %s", container.ID) | ||
} else { | ||
|
@@ -454,12 +469,12 @@ func (d *DockerDriver) Start(ctx *ExecContext, task *structs.Task) (DriverHandle | |
maxKill := d.DriverContext.config.MaxKillTimeout | ||
h := &DockerHandle{ | ||
client: client, | ||
waitClient: waitClient, | ||
waitClient: d.waitClient, | ||
executor: exec, | ||
pluginClient: pluginClient, | ||
cleanupImage: cleanupImage, | ||
logger: d.logger, | ||
imageID: dockerImage.ID, | ||
imageID: d.imageID, | ||
containerID: container.ID, | ||
version: d.config.Version, | ||
killTimeout: GetKillTimeout(task.KillTimeout, maxKill), | ||
|
@@ -935,6 +950,7 @@ func (d *DockerDriver) pullImage(driverConfig *DockerDriverConfig, client *docke | |
} | ||
} | ||
|
||
d.emitEvent("Downloading image") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call; fixed. |
||
err := client.PullImage(pullOptions, authOptions) | ||
if err != nil { | ||
d.logger.Printf("[ERR] driver.docker: failed pulling container %s:%s: %s", repo, tag, err) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to
DriverMsg
as theemitEvent
function can be used generically by the driver?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any thoughts on what I should change the
TaskInitializing
const to? All of the other consts are verbs, but I don't think it'd be confusing to just have a "Driver" message type.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Driver" is fine with me