Co-authored-by: Paweł Gronowski <pawel.gronowski@docker.com>
Signed-off-by: Paweł Gronowski <pawel.gronowski@docker.com>
| ... | ... |
@@ -32,14 +32,14 @@ type copyBackend interface {
|
| 32 | 32 |
|
| 33 | 33 |
// stateBackend includes functions to implement to provide container state lifecycle functionality. |
| 34 | 34 |
type stateBackend interface {
|
| 35 |
- ContainerCreate(config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 35 |
+ ContainerCreate(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 36 | 36 |
ContainerKill(name string, signal string) error |
| 37 | 37 |
ContainerPause(name string) error |
| 38 | 38 |
ContainerRename(oldName, newName string) error |
| 39 | 39 |
ContainerResize(name string, height, width int) error |
| 40 | 40 |
ContainerRestart(ctx context.Context, name string, options container.StopOptions) error |
| 41 | 41 |
ContainerRm(name string, config *types.ContainerRmConfig) error |
| 42 |
- ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 42 |
+ ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 43 | 43 |
ContainerStop(ctx context.Context, name string, options container.StopOptions) error |
| 44 | 44 |
ContainerUnpause(name string) error |
| 45 | 45 |
ContainerUpdate(name string, hostConfig *container.HostConfig) (container.ContainerUpdateOKBody, error) |
| ... | ... |
@@ -54,7 +54,7 @@ type monitorBackend interface {
|
| 54 | 54 |
ContainerStats(ctx context.Context, name string, config *backend.ContainerStatsConfig) error |
| 55 | 55 |
ContainerTop(name string, psArgs string) (*container.ContainerTopOKBody, error) |
| 56 | 56 |
|
| 57 |
- Containers(config *types.ContainerListOptions) ([]*types.Container, error) |
|
| 57 |
+ Containers(ctx context.Context, config *types.ContainerListOptions) ([]*types.Container, error) |
|
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 | 60 |
// attachBackend includes function to implement to provide container attaching functionality. |
| ... | ... |
@@ -68,7 +68,7 @@ type systemBackend interface {
|
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 | 70 |
type commitBackend interface {
|
| 71 |
- CreateImageFromContainer(name string, config *backend.CreateImageConfig) (imageID string, err error) |
|
| 71 |
+ CreateImageFromContainer(ctx context.Context, name string, config *backend.CreateImageConfig) (imageID string, err error) |
|
| 72 | 72 |
} |
| 73 | 73 |
|
| 74 | 74 |
// Backend is all the methods that need to be implemented to provide container specific functionality. |
| ... | ... |
@@ -58,7 +58,7 @@ func (s *containerRouter) postCommit(ctx context.Context, w http.ResponseWriter, |
| 58 | 58 |
Changes: r.Form["changes"], |
| 59 | 59 |
} |
| 60 | 60 |
|
| 61 |
- imgID, err := s.backend.CreateImageFromContainer(r.Form.Get("container"), commitCfg)
|
|
| 61 |
+ imgID, err := s.backend.CreateImageFromContainer(ctx, r.Form.Get("container"), commitCfg)
|
|
| 62 | 62 |
if err != nil {
|
| 63 | 63 |
return err |
| 64 | 64 |
} |
| ... | ... |
@@ -91,7 +91,7 @@ func (s *containerRouter) getContainersJSON(ctx context.Context, w http.Response |
| 91 | 91 |
config.Limit = limit |
| 92 | 92 |
} |
| 93 | 93 |
|
| 94 |
- containers, err := s.backend.Containers(config) |
|
| 94 |
+ containers, err := s.backend.Containers(ctx, config) |
|
| 95 | 95 |
if err != nil {
|
| 96 | 96 |
return err |
| 97 | 97 |
} |
| ... | ... |
@@ -214,7 +214,7 @@ func (s *containerRouter) postContainersStart(ctx context.Context, w http.Respon |
| 214 | 214 |
|
| 215 | 215 |
checkpoint := r.Form.Get("checkpoint")
|
| 216 | 216 |
checkpointDir := r.Form.Get("checkpoint-dir")
|
| 217 |
- if err := s.backend.ContainerStart(vars["name"], hostConfig, checkpoint, checkpointDir); err != nil {
|
|
| 217 |
+ if err := s.backend.ContainerStart(ctx, vars["name"], hostConfig, checkpoint, checkpointDir); err != nil {
|
|
| 218 | 218 |
return err |
| 219 | 219 |
} |
| 220 | 220 |
|
| ... | ... |
@@ -578,7 +578,7 @@ func (s *containerRouter) postContainersCreate(ctx context.Context, w http.Respo |
| 578 | 578 |
hostConfig.PidsLimit = nil |
| 579 | 579 |
} |
| 580 | 580 |
|
| 581 |
- ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
|
|
| 581 |
+ ccr, err := s.backend.ContainerCreate(ctx, types.ContainerCreateConfig{
|
|
| 582 | 582 |
Name: name, |
| 583 | 583 |
Config: config, |
| 584 | 584 |
HostConfig: hostConfig, |
| ... | ... |
@@ -31,7 +31,7 @@ type imageBackend interface {
|
| 31 | 31 |
|
| 32 | 32 |
type importExportBackend interface {
|
| 33 | 33 |
LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error |
| 34 |
- ImportImage(src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error |
|
| 34 |
+ ImportImage(ctx context.Context, src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error |
|
| 35 | 35 |
ExportImage(ctx context.Context, names []string, outStream io.Writer) error |
| 36 | 36 |
} |
| 37 | 37 |
|
| ... | ... |
@@ -68,7 +68,7 @@ func (ir *imageRouter) postImagesCreate(ctx context.Context, w http.ResponseWrit |
| 68 | 68 |
progressErr = ir.backend.PullImage(ctx, img, tag, platform, metaHeaders, authConfig, output) |
| 69 | 69 |
} else { // import
|
| 70 | 70 |
src := r.Form.Get("fromSrc")
|
| 71 |
- progressErr = ir.backend.ImportImage(src, repo, platform, tag, message, r.Body, output, r.Form["changes"]) |
|
| 71 |
+ progressErr = ir.backend.ImportImage(ctx, src, repo, platform, tag, message, r.Body, output, r.Form["changes"]) |
|
| 72 | 72 |
} |
| 73 | 73 |
if progressErr != nil {
|
| 74 | 74 |
if !output.Flushed() {
|
| ... | ... |
@@ -12,7 +12,7 @@ import ( |
| 12 | 12 |
type Backend interface {
|
| 13 | 13 |
Init(req types.InitRequest) (string, error) |
| 14 | 14 |
Join(req types.JoinRequest) error |
| 15 |
- Leave(force bool) error |
|
| 15 |
+ Leave(ctx context.Context, force bool) error |
|
| 16 | 16 |
Inspect() (types.Swarm, error) |
| 17 | 17 |
Update(uint64, types.Spec, types.UpdateFlags) error |
| 18 | 18 |
GetUnlockKey() (string, error) |
| ... | ... |
@@ -56,7 +56,7 @@ func (sr *swarmRouter) leaveCluster(ctx context.Context, w http.ResponseWriter, |
| 56 | 56 |
} |
| 57 | 57 |
|
| 58 | 58 |
force := httputils.BoolValue(r, "force") |
| 59 |
- return sr.backend.Leave(force) |
|
| 59 |
+ return sr.backend.Leave(ctx, force) |
|
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 | 62 |
func (sr *swarmRouter) inspectCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -60,13 +60,13 @@ type ExecBackend interface {
|
| 60 | 60 |
// ContainerAttachRaw attaches to container. |
| 61 | 61 |
ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout, stderr io.Writer, stream bool, attached chan struct{}) error
|
| 62 | 62 |
// ContainerCreateIgnoreImagesArgsEscaped creates a new Docker container and returns potential warnings |
| 63 |
- ContainerCreateIgnoreImagesArgsEscaped(config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 63 |
+ ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 64 | 64 |
// ContainerRm removes a container specified by `id`. |
| 65 | 65 |
ContainerRm(name string, config *types.ContainerRmConfig) error |
| 66 | 66 |
// ContainerKill stops the container execution abruptly. |
| 67 | 67 |
ContainerKill(containerID string, sig string) error |
| 68 | 68 |
// ContainerStart starts a new container |
| 69 |
- ContainerStart(containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 69 |
+ ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 70 | 70 |
// ContainerWait stops processing until the given container is stopped. |
| 71 | 71 |
ContainerWait(ctx context.Context, name string, condition containerpkg.WaitCondition) (<-chan containerpkg.StateStatus, error) |
| 72 | 72 |
} |
| ... | ... |
@@ -80,7 +80,7 @@ type Result struct {
|
| 80 | 80 |
// ImageCacheBuilder represents a generator for stateful image cache. |
| 81 | 81 |
type ImageCacheBuilder interface {
|
| 82 | 82 |
// MakeImageCache creates a stateful image cache. |
| 83 |
- MakeImageCache(cacheFrom []string) ImageCache |
|
| 83 |
+ MakeImageCache(ctx context.Context, cacheFrom []string) (ImageCache, error) |
|
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 | 86 |
// ImageCache abstracts an image cache. |
| ... | ... |
@@ -95,7 +95,7 @@ func (bm *BuildManager) Build(ctx context.Context, config backend.BuildConfig) ( |
| 95 | 95 |
if err != nil {
|
| 96 | 96 |
return nil, err |
| 97 | 97 |
} |
| 98 |
- return b.build(source, dockerfile) |
|
| 98 |
+ return b.build(ctx, source, dockerfile) |
|
| 99 | 99 |
} |
| 100 | 100 |
|
| 101 | 101 |
// builderOptions are the dependencies required by the builder |
| ... | ... |
@@ -136,6 +136,11 @@ func newBuilder(clientCtx context.Context, options builderOptions) (*Builder, er |
| 136 | 136 |
config = new(types.ImageBuildOptions) |
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 |
+ imageProber, err := newImageProber(clientCtx, options.Backend, config.CacheFrom, config.NoCache) |
|
| 140 |
+ if err != nil {
|
|
| 141 |
+ return nil, err |
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 139 | 144 |
b := &Builder{
|
| 140 | 145 |
clientCtx: clientCtx, |
| 141 | 146 |
options: config, |
| ... | ... |
@@ -147,7 +152,7 @@ func newBuilder(clientCtx context.Context, options builderOptions) (*Builder, er |
| 147 | 147 |
idMapping: options.IDMapping, |
| 148 | 148 |
imageSources: newImageSources(clientCtx, options), |
| 149 | 149 |
pathCache: options.PathCache, |
| 150 |
- imageProber: newImageProber(options.Backend, config.CacheFrom, config.NoCache), |
|
| 150 |
+ imageProber: imageProber, |
|
| 151 | 151 |
containerManager: newContainerManager(options.Backend), |
| 152 | 152 |
} |
| 153 | 153 |
|
| ... | ... |
@@ -181,7 +186,7 @@ func buildLabelOptions(labels map[string]string, stages []instructions.Stage) {
|
| 181 | 181 |
|
| 182 | 182 |
// Build runs the Dockerfile builder by parsing the Dockerfile and executing |
| 183 | 183 |
// the instructions from the file. |
| 184 |
-func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*builder.Result, error) {
|
|
| 184 |
+func (b *Builder) build(ctx context.Context, source builder.Source, dockerfile *parser.Result) (*builder.Result, error) {
|
|
| 185 | 185 |
defer b.imageSources.Unmount() |
| 186 | 186 |
|
| 187 | 187 |
stages, metaArgs, err := instructions.Parse(dockerfile.AST) |
| ... | ... |
@@ -205,7 +210,7 @@ func (b *Builder) build(source builder.Source, dockerfile *parser.Result) (*buil |
| 205 | 205 |
buildLabelOptions(b.options.Labels, stages) |
| 206 | 206 |
|
| 207 | 207 |
dockerfile.PrintWarnings(b.Stderr) |
| 208 |
- dispatchState, err := b.dispatchDockerfileWithCancellation(stages, metaArgs, dockerfile.EscapeToken, source) |
|
| 208 |
+ dispatchState, err := b.dispatchDockerfileWithCancellation(ctx, stages, metaArgs, dockerfile.EscapeToken, source) |
|
| 209 | 209 |
if err != nil {
|
| 210 | 210 |
return nil, err |
| 211 | 211 |
} |
| ... | ... |
@@ -244,7 +249,7 @@ func printCommand(out io.Writer, currentCommandIndex int, totalCommands int, cmd |
| 244 | 244 |
return currentCommandIndex + 1 |
| 245 | 245 |
} |
| 246 | 246 |
|
| 247 |
-func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions.Stage, metaArgs []instructions.ArgCommand, escapeToken rune, source builder.Source) (*dispatchState, error) {
|
|
| 247 |
+func (b *Builder) dispatchDockerfileWithCancellation(ctx context.Context, parseResult []instructions.Stage, metaArgs []instructions.ArgCommand, escapeToken rune, source builder.Source) (*dispatchState, error) {
|
|
| 248 | 248 |
dispatchRequest := dispatchRequest{}
|
| 249 | 249 |
buildArgs := NewBuildArgs(b.options.BuildArgs) |
| 250 | 250 |
totalCommands := len(metaArgs) + len(parseResult) |
| ... | ... |
@@ -272,7 +277,7 @@ func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions. |
| 272 | 272 |
dispatchRequest = newDispatchRequest(b, escapeToken, source, buildArgs, stagesResults) |
| 273 | 273 |
|
| 274 | 274 |
currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, stage.SourceCode) |
| 275 |
- if err := initializeStage(dispatchRequest, &stage); err != nil {
|
|
| 275 |
+ if err := initializeStage(ctx, dispatchRequest, &stage); err != nil {
|
|
| 276 | 276 |
return nil, err |
| 277 | 277 |
} |
| 278 | 278 |
dispatchRequest.state.updateRunConfig() |
| ... | ... |
@@ -290,7 +295,7 @@ func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions. |
| 290 | 290 |
|
| 291 | 291 |
currentCommandIndex = printCommand(b.Stdout, currentCommandIndex, totalCommands, cmd) |
| 292 | 292 |
|
| 293 |
- if err := dispatch(dispatchRequest, cmd); err != nil {
|
|
| 293 |
+ if err := dispatch(ctx, dispatchRequest, cmd); err != nil {
|
|
| 294 | 294 |
return nil, err |
| 295 | 295 |
} |
| 296 | 296 |
dispatchRequest.state.updateRunConfig() |
| ... | ... |
@@ -317,7 +322,7 @@ func (b *Builder) dispatchDockerfileWithCancellation(parseResult []instructions. |
| 317 | 317 |
// coming from the query parameter of the same name. |
| 318 | 318 |
// |
| 319 | 319 |
// TODO: Remove? |
| 320 |
-func BuildFromConfig(config *container.Config, changes []string, os string) (*container.Config, error) {
|
|
| 320 |
+func BuildFromConfig(ctx context.Context, config *container.Config, changes []string, os string) (*container.Config, error) {
|
|
| 321 | 321 |
if len(changes) == 0 {
|
| 322 | 322 |
return config, nil |
| 323 | 323 |
} |
| ... | ... |
@@ -327,7 +332,7 @@ func BuildFromConfig(config *container.Config, changes []string, os string) (*co |
| 327 | 327 |
return nil, errdefs.InvalidParameter(err) |
| 328 | 328 |
} |
| 329 | 329 |
|
| 330 |
- b, err := newBuilder(context.Background(), builderOptions{
|
|
| 330 |
+ b, err := newBuilder(ctx, builderOptions{
|
|
| 331 | 331 |
Options: &types.ImageBuildOptions{NoCache: true},
|
| 332 | 332 |
}) |
| 333 | 333 |
if err != nil {
|
| ... | ... |
@@ -360,7 +365,7 @@ func BuildFromConfig(config *container.Config, changes []string, os string) (*co |
| 360 | 360 |
dispatchRequest.state.imageID = config.Image |
| 361 | 361 |
dispatchRequest.state.operatingSystem = os |
| 362 | 362 |
for _, cmd := range commands {
|
| 363 |
- err := dispatch(dispatchRequest, cmd) |
|
| 363 |
+ err := dispatch(ctx, dispatchRequest, cmd) |
|
| 364 | 364 |
if err != nil {
|
| 365 | 365 |
return nil, errdefs.InvalidParameter(err) |
| 366 | 366 |
} |
| ... | ... |
@@ -28,8 +28,8 @@ func newContainerManager(docker builder.ExecBackend) *containerManager {
|
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 | 30 |
// Create a container |
| 31 |
-func (c *containerManager) Create(runConfig *container.Config, hostConfig *container.HostConfig) (container.CreateResponse, error) {
|
|
| 32 |
- container, err := c.backend.ContainerCreateIgnoreImagesArgsEscaped(types.ContainerCreateConfig{
|
|
| 31 |
+func (c *containerManager) Create(ctx context.Context, runConfig *container.Config, hostConfig *container.HostConfig) (container.CreateResponse, error) {
|
|
| 32 |
+ container, err := c.backend.ContainerCreateIgnoreImagesArgsEscaped(ctx, types.ContainerCreateConfig{
|
|
| 33 | 33 |
Config: runConfig, |
| 34 | 34 |
HostConfig: hostConfig, |
| 35 | 35 |
}) |
| ... | ... |
@@ -69,7 +69,7 @@ func (c *containerManager) Run(ctx context.Context, cID string, stdout, stderr i |
| 69 | 69 |
} |
| 70 | 70 |
}() |
| 71 | 71 |
|
| 72 |
- if err := c.backend.ContainerStart(cID, nil, "", ""); err != nil {
|
|
| 72 |
+ if err := c.backend.ContainerStart(ctx, cID, nil, "", ""); err != nil {
|
|
| 73 | 73 |
close(finished) |
| 74 | 74 |
logCancellationError(cancelErrCh, "error from ContainerStart: "+err.Error()) |
| 75 | 75 |
return err |
| ... | ... |
@@ -9,6 +9,7 @@ package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 9 | 9 |
|
| 10 | 10 |
import ( |
| 11 | 11 |
"bytes" |
| 12 |
+ "context" |
|
| 12 | 13 |
"fmt" |
| 13 | 14 |
"runtime" |
| 14 | 15 |
"sort" |
| ... | ... |
@@ -35,7 +36,7 @@ import ( |
| 35 | 35 |
// |
| 36 | 36 |
// Sets the environment variable foo to bar, also makes interpolation |
| 37 | 37 |
// in the dockerfile available from the next statement on via ${foo}.
|
| 38 |
-func dispatchEnv(d dispatchRequest, c *instructions.EnvCommand) error {
|
|
| 38 |
+func dispatchEnv(ctx context.Context, d dispatchRequest, c *instructions.EnvCommand) error {
|
|
| 39 | 39 |
runConfig := d.state.runConfig |
| 40 | 40 |
commitMessage := bytes.NewBufferString("ENV")
|
| 41 | 41 |
for _, e := range c.Env {
|
| ... | ... |
@@ -57,21 +58,21 @@ func dispatchEnv(d dispatchRequest, c *instructions.EnvCommand) error {
|
| 57 | 57 |
runConfig.Env = append(runConfig.Env, newVar) |
| 58 | 58 |
} |
| 59 | 59 |
} |
| 60 |
- return d.builder.commit(d.state, commitMessage.String()) |
|
| 60 |
+ return d.builder.commit(ctx, d.state, commitMessage.String()) |
|
| 61 | 61 |
} |
| 62 | 62 |
|
| 63 | 63 |
// MAINTAINER some text <maybe@an.email.address> |
| 64 | 64 |
// |
| 65 | 65 |
// Sets the maintainer metadata. |
| 66 |
-func dispatchMaintainer(d dispatchRequest, c *instructions.MaintainerCommand) error {
|
|
| 66 |
+func dispatchMaintainer(ctx context.Context, d dispatchRequest, c *instructions.MaintainerCommand) error {
|
|
| 67 | 67 |
d.state.maintainer = c.Maintainer |
| 68 |
- return d.builder.commit(d.state, "MAINTAINER "+c.Maintainer) |
|
| 68 |
+ return d.builder.commit(ctx, d.state, "MAINTAINER "+c.Maintainer) |
|
| 69 | 69 |
} |
| 70 | 70 |
|
| 71 | 71 |
// LABEL some json data describing the image |
| 72 | 72 |
// |
| 73 | 73 |
// Sets the Label variable foo to bar, |
| 74 |
-func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
|
|
| 74 |
+func dispatchLabel(ctx context.Context, d dispatchRequest, c *instructions.LabelCommand) error {
|
|
| 75 | 75 |
if d.state.runConfig.Labels == nil {
|
| 76 | 76 |
d.state.runConfig.Labels = make(map[string]string) |
| 77 | 77 |
} |
| ... | ... |
@@ -80,14 +81,14 @@ func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
|
| 80 | 80 |
d.state.runConfig.Labels[v.Key] = v.Value |
| 81 | 81 |
commitStr += " " + v.String() |
| 82 | 82 |
} |
| 83 |
- return d.builder.commit(d.state, commitStr) |
|
| 83 |
+ return d.builder.commit(ctx, d.state, commitStr) |
|
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 | 86 |
// ADD foo /path |
| 87 | 87 |
// |
| 88 | 88 |
// Add the file 'foo' to '/path'. Tarball and Remote URL (http, https) handling |
| 89 | 89 |
// exist here. If you do not wish to have this automatic handling, use COPY. |
| 90 |
-func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
|
| 90 |
+func dispatchAdd(ctx context.Context, d dispatchRequest, c *instructions.AddCommand) error {
|
|
| 91 | 91 |
if c.Chmod != "" {
|
| 92 | 92 |
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
| 93 | 93 |
} |
| ... | ... |
@@ -102,13 +103,13 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
| 102 | 102 |
copyInstruction.chownStr = c.Chown |
| 103 | 103 |
copyInstruction.allowLocalDecompression = true |
| 104 | 104 |
|
| 105 |
- return d.builder.performCopy(d, copyInstruction) |
|
| 105 |
+ return d.builder.performCopy(ctx, d, copyInstruction) |
|
| 106 | 106 |
} |
| 107 | 107 |
|
| 108 | 108 |
// COPY foo /path |
| 109 | 109 |
// |
| 110 | 110 |
// Same as 'ADD' but without the tar and remote url handling. |
| 111 |
-func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
|
|
| 111 |
+func dispatchCopy(ctx context.Context, d dispatchRequest, c *instructions.CopyCommand) error {
|
|
| 112 | 112 |
if c.Chmod != "" {
|
| 113 | 113 |
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
| 114 | 114 |
} |
| ... | ... |
@@ -130,7 +131,7 @@ func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
|
| 130 | 130 |
if c.From != "" && copyInstruction.chownStr == "" {
|
| 131 | 131 |
copyInstruction.preserveOwnership = true |
| 132 | 132 |
} |
| 133 |
- return d.builder.performCopy(d, copyInstruction) |
|
| 133 |
+ return d.builder.performCopy(ctx, d, copyInstruction) |
|
| 134 | 134 |
} |
| 135 | 135 |
|
| 136 | 136 |
func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error) {
|
| ... | ... |
@@ -152,8 +153,11 @@ func (d *dispatchRequest) getImageMount(imageRefOrID string) (*imageMount, error |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 | 154 |
// FROM [--platform=platform] imagename[:tag | @digest] [AS build-stage-name] |
| 155 |
-func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
|
|
| 156 |
- d.builder.imageProber.Reset() |
|
| 155 |
+func initializeStage(ctx context.Context, d dispatchRequest, cmd *instructions.Stage) error {
|
|
| 156 |
+ err := d.builder.imageProber.Reset(ctx) |
|
| 157 |
+ if err != nil {
|
|
| 158 |
+ return err |
|
| 159 |
+ } |
|
| 157 | 160 |
|
| 158 | 161 |
var platform *specs.Platform |
| 159 | 162 |
if v := cmd.Platform; v != "" {
|
| ... | ... |
@@ -180,12 +184,12 @@ func initializeStage(d dispatchRequest, cmd *instructions.Stage) error {
|
| 180 | 180 |
if len(state.runConfig.OnBuild) > 0 {
|
| 181 | 181 |
triggers := state.runConfig.OnBuild |
| 182 | 182 |
state.runConfig.OnBuild = nil |
| 183 |
- return dispatchTriggeredOnBuild(d, triggers) |
|
| 183 |
+ return dispatchTriggeredOnBuild(ctx, d, triggers) |
|
| 184 | 184 |
} |
| 185 | 185 |
return nil |
| 186 | 186 |
} |
| 187 | 187 |
|
| 188 |
-func dispatchTriggeredOnBuild(d dispatchRequest, triggers []string) error {
|
|
| 188 |
+func dispatchTriggeredOnBuild(ctx context.Context, d dispatchRequest, triggers []string) error {
|
|
| 189 | 189 |
fmt.Fprintf(d.builder.Stdout, "# Executing %d build trigger", len(triggers)) |
| 190 | 190 |
if len(triggers) > 1 {
|
| 191 | 191 |
fmt.Fprint(d.builder.Stdout, "s") |
| ... | ... |
@@ -208,7 +212,7 @@ func dispatchTriggeredOnBuild(d dispatchRequest, triggers []string) error {
|
| 208 | 208 |
} |
| 209 | 209 |
return err |
| 210 | 210 |
} |
| 211 |
- err = dispatch(d, cmd) |
|
| 211 |
+ err = dispatch(ctx, d, cmd) |
|
| 212 | 212 |
if err != nil {
|
| 213 | 213 |
return err |
| 214 | 214 |
} |
| ... | ... |
@@ -276,15 +280,15 @@ func (d *dispatchRequest) getFromImage(shlex *shell.Lex, basename string, platfo |
| 276 | 276 |
return d.getImageOrStage(name, platform) |
| 277 | 277 |
} |
| 278 | 278 |
|
| 279 |
-func dispatchOnbuild(d dispatchRequest, c *instructions.OnbuildCommand) error {
|
|
| 279 |
+func dispatchOnbuild(ctx context.Context, d dispatchRequest, c *instructions.OnbuildCommand) error {
|
|
| 280 | 280 |
d.state.runConfig.OnBuild = append(d.state.runConfig.OnBuild, c.Expression) |
| 281 |
- return d.builder.commit(d.state, "ONBUILD "+c.Expression) |
|
| 281 |
+ return d.builder.commit(ctx, d.state, "ONBUILD "+c.Expression) |
|
| 282 | 282 |
} |
| 283 | 283 |
|
| 284 | 284 |
// WORKDIR /tmp |
| 285 | 285 |
// |
| 286 | 286 |
// Set the working directory for future RUN/CMD/etc statements. |
| 287 |
-func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
|
|
| 287 |
+func dispatchWorkdir(ctx context.Context, d dispatchRequest, c *instructions.WorkdirCommand) error {
|
|
| 288 | 288 |
runConfig := d.state.runConfig |
| 289 | 289 |
var err error |
| 290 | 290 |
runConfig.WorkingDir, err = normalizeWorkdir(d.state.operatingSystem, runConfig.WorkingDir, c.Path) |
| ... | ... |
@@ -305,7 +309,7 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
|
| 305 | 305 |
comment := "WORKDIR " + runConfig.WorkingDir |
| 306 | 306 |
runConfigWithCommentCmd := copyRunConfig(runConfig, withCmdCommentString(comment, d.state.operatingSystem)) |
| 307 | 307 |
|
| 308 |
- containerID, err := d.builder.probeAndCreate(d.state, runConfigWithCommentCmd) |
|
| 308 |
+ containerID, err := d.builder.probeAndCreate(ctx, d.state, runConfigWithCommentCmd) |
|
| 309 | 309 |
if err != nil || containerID == "" {
|
| 310 | 310 |
return err |
| 311 | 311 |
} |
| ... | ... |
@@ -326,7 +330,7 @@ func dispatchWorkdir(d dispatchRequest, c *instructions.WorkdirCommand) error {
|
| 326 | 326 |
// RUN echo hi # sh -c echo hi (Linux and LCOW) |
| 327 | 327 |
// RUN echo hi # cmd /S /C echo hi (Windows) |
| 328 | 328 |
// RUN [ "echo", "hi" ] # echo hi |
| 329 |
-func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
|
|
| 329 |
+func dispatchRun(ctx context.Context, d dispatchRequest, c *instructions.RunCommand) error {
|
|
| 330 | 330 |
if !system.IsOSSupported(d.state.operatingSystem) {
|
| 331 | 331 |
return system.ErrNotSupportedOperatingSystem |
| 332 | 332 |
} |
| ... | ... |
@@ -360,7 +364,7 @@ func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
|
| 360 | 360 |
withEntrypointOverride(saveCmd, strslice.StrSlice{""}),
|
| 361 | 361 |
withoutHealthcheck()) |
| 362 | 362 |
|
| 363 |
- cID, err := d.builder.create(runConfig) |
|
| 363 |
+ cID, err := d.builder.create(ctx, runConfig) |
|
| 364 | 364 |
if err != nil {
|
| 365 | 365 |
return err |
| 366 | 366 |
} |
| ... | ... |
@@ -420,7 +424,7 @@ func prependEnvOnCmd(buildArgs *BuildArgs, buildArgVars []string, cmd strslice.S |
| 420 | 420 |
// |
| 421 | 421 |
// Set the default command to run in the container (which may be empty). |
| 422 | 422 |
// Argument handling is the same as RUN. |
| 423 |
-func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
|
|
| 423 |
+func dispatchCmd(ctx context.Context, d dispatchRequest, c *instructions.CmdCommand) error {
|
|
| 424 | 424 |
runConfig := d.state.runConfig |
| 425 | 425 |
cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String()) |
| 426 | 426 |
|
| ... | ... |
@@ -436,7 +440,7 @@ func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
|
| 436 | 436 |
runConfig.Cmd = cmd |
| 437 | 437 |
runConfig.ArgsEscaped = argsEscaped |
| 438 | 438 |
|
| 439 |
- if err := d.builder.commit(d.state, fmt.Sprintf("CMD %q", cmd)); err != nil {
|
|
| 439 |
+ if err := d.builder.commit(ctx, d.state, fmt.Sprintf("CMD %q", cmd)); err != nil {
|
|
| 440 | 440 |
return err |
| 441 | 441 |
} |
| 442 | 442 |
if len(c.ShellDependantCmdLine.CmdLine) != 0 {
|
| ... | ... |
@@ -450,7 +454,7 @@ func dispatchCmd(d dispatchRequest, c *instructions.CmdCommand) error {
|
| 450 | 450 |
// |
| 451 | 451 |
// Set the default healthcheck command to run in the container (which may be empty). |
| 452 | 452 |
// Argument handling is the same as RUN. |
| 453 |
-func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) error {
|
|
| 453 |
+func dispatchHealthcheck(ctx context.Context, d dispatchRequest, c *instructions.HealthCheckCommand) error {
|
|
| 454 | 454 |
runConfig := d.state.runConfig |
| 455 | 455 |
if runConfig.Healthcheck != nil {
|
| 456 | 456 |
oldCmd := runConfig.Healthcheck.Test |
| ... | ... |
@@ -459,7 +463,7 @@ func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) |
| 459 | 459 |
} |
| 460 | 460 |
} |
| 461 | 461 |
runConfig.Healthcheck = c.Health |
| 462 |
- return d.builder.commit(d.state, fmt.Sprintf("HEALTHCHECK %q", runConfig.Healthcheck))
|
|
| 462 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("HEALTHCHECK %q", runConfig.Healthcheck))
|
|
| 463 | 463 |
} |
| 464 | 464 |
|
| 465 | 465 |
// ENTRYPOINT /usr/sbin/nginx |
| ... | ... |
@@ -469,7 +473,7 @@ func dispatchHealthcheck(d dispatchRequest, c *instructions.HealthCheckCommand) |
| 469 | 469 |
// |
| 470 | 470 |
// Handles command processing similar to CMD and RUN, only req.runConfig.Entrypoint |
| 471 | 471 |
// is initialized at newBuilder time instead of through argument parsing. |
| 472 |
-func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) error {
|
|
| 472 |
+func dispatchEntrypoint(ctx context.Context, d dispatchRequest, c *instructions.EntrypointCommand) error {
|
|
| 473 | 473 |
runConfig := d.state.runConfig |
| 474 | 474 |
cmd, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, runConfig, d.state.operatingSystem, c.Name(), c.String()) |
| 475 | 475 |
|
| ... | ... |
@@ -491,14 +495,14 @@ func dispatchEntrypoint(d dispatchRequest, c *instructions.EntrypointCommand) er |
| 491 | 491 |
runConfig.Cmd = nil |
| 492 | 492 |
} |
| 493 | 493 |
|
| 494 |
- return d.builder.commit(d.state, fmt.Sprintf("ENTRYPOINT %q", runConfig.Entrypoint))
|
|
| 494 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("ENTRYPOINT %q", runConfig.Entrypoint))
|
|
| 495 | 495 |
} |
| 496 | 496 |
|
| 497 | 497 |
// EXPOSE 6667/tcp 7000/tcp |
| 498 | 498 |
// |
| 499 | 499 |
// Expose ports for links and port mappings. This all ends up in |
| 500 | 500 |
// req.runConfig.ExposedPorts for runconfig. |
| 501 |
-func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []string) error {
|
|
| 501 |
+func dispatchExpose(ctx context.Context, d dispatchRequest, c *instructions.ExposeCommand, envs []string) error {
|
|
| 502 | 502 |
// custom multi word expansion |
| 503 | 503 |
// expose $FOO with FOO="80 443" is expanded as EXPOSE [80,443]. This is the only command supporting word to words expansion |
| 504 | 504 |
// so the word processing has been de-generalized |
| ... | ... |
@@ -524,22 +528,22 @@ func dispatchExpose(d dispatchRequest, c *instructions.ExposeCommand, envs []str |
| 524 | 524 |
d.state.runConfig.ExposedPorts[p] = struct{}{}
|
| 525 | 525 |
} |
| 526 | 526 |
|
| 527 |
- return d.builder.commit(d.state, "EXPOSE "+strings.Join(c.Ports, " ")) |
|
| 527 |
+ return d.builder.commit(ctx, d.state, "EXPOSE "+strings.Join(c.Ports, " ")) |
|
| 528 | 528 |
} |
| 529 | 529 |
|
| 530 | 530 |
// USER foo |
| 531 | 531 |
// |
| 532 | 532 |
// Set the user to 'foo' for future commands and when running the |
| 533 | 533 |
// ENTRYPOINT/CMD at container run time. |
| 534 |
-func dispatchUser(d dispatchRequest, c *instructions.UserCommand) error {
|
|
| 534 |
+func dispatchUser(ctx context.Context, d dispatchRequest, c *instructions.UserCommand) error {
|
|
| 535 | 535 |
d.state.runConfig.User = c.User |
| 536 |
- return d.builder.commit(d.state, fmt.Sprintf("USER %v", c.User))
|
|
| 536 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("USER %v", c.User))
|
|
| 537 | 537 |
} |
| 538 | 538 |
|
| 539 | 539 |
// VOLUME /foo |
| 540 | 540 |
// |
| 541 | 541 |
// Expose the volume /foo for use. Will also accept the JSON array form. |
| 542 |
-func dispatchVolume(d dispatchRequest, c *instructions.VolumeCommand) error {
|
|
| 542 |
+func dispatchVolume(ctx context.Context, d dispatchRequest, c *instructions.VolumeCommand) error {
|
|
| 543 | 543 |
if d.state.runConfig.Volumes == nil {
|
| 544 | 544 |
d.state.runConfig.Volumes = map[string]struct{}{}
|
| 545 | 545 |
} |
| ... | ... |
@@ -549,19 +553,19 @@ func dispatchVolume(d dispatchRequest, c *instructions.VolumeCommand) error {
|
| 549 | 549 |
} |
| 550 | 550 |
d.state.runConfig.Volumes[v] = struct{}{}
|
| 551 | 551 |
} |
| 552 |
- return d.builder.commit(d.state, fmt.Sprintf("VOLUME %v", c.Volumes))
|
|
| 552 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("VOLUME %v", c.Volumes))
|
|
| 553 | 553 |
} |
| 554 | 554 |
|
| 555 | 555 |
// STOPSIGNAL signal |
| 556 | 556 |
// |
| 557 | 557 |
// Set the signal that will be used to kill the container. |
| 558 |
-func dispatchStopSignal(d dispatchRequest, c *instructions.StopSignalCommand) error {
|
|
| 558 |
+func dispatchStopSignal(ctx context.Context, d dispatchRequest, c *instructions.StopSignalCommand) error {
|
|
| 559 | 559 |
_, err := signal.ParseSignal(c.Signal) |
| 560 | 560 |
if err != nil {
|
| 561 | 561 |
return errdefs.InvalidParameter(err) |
| 562 | 562 |
} |
| 563 | 563 |
d.state.runConfig.StopSignal = c.Signal |
| 564 |
- return d.builder.commit(d.state, fmt.Sprintf("STOPSIGNAL %v", c.Signal))
|
|
| 564 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("STOPSIGNAL %v", c.Signal))
|
|
| 565 | 565 |
} |
| 566 | 566 |
|
| 567 | 567 |
// ARG name[=value] |
| ... | ... |
@@ -569,7 +573,7 @@ func dispatchStopSignal(d dispatchRequest, c *instructions.StopSignalCommand) er |
| 569 | 569 |
// Adds the variable foo to the trusted list of variables that can be passed |
| 570 | 570 |
// to builder using the --build-arg flag for expansion/substitution or passing to 'run'. |
| 571 | 571 |
// Dockerfile author may optionally set a default value of this variable. |
| 572 |
-func dispatchArg(d dispatchRequest, c *instructions.ArgCommand) error {
|
|
| 572 |
+func dispatchArg(ctx context.Context, d dispatchRequest, c *instructions.ArgCommand) error {
|
|
| 573 | 573 |
var commitStr strings.Builder |
| 574 | 574 |
commitStr.WriteString("ARG ")
|
| 575 | 575 |
for i, arg := range c.Args {
|
| ... | ... |
@@ -584,13 +588,13 @@ func dispatchArg(d dispatchRequest, c *instructions.ArgCommand) error {
|
| 584 | 584 |
d.state.buildArgs.AddArg(arg.Key, arg.Value) |
| 585 | 585 |
} |
| 586 | 586 |
|
| 587 |
- return d.builder.commit(d.state, commitStr.String()) |
|
| 587 |
+ return d.builder.commit(ctx, d.state, commitStr.String()) |
|
| 588 | 588 |
} |
| 589 | 589 |
|
| 590 | 590 |
// SHELL powershell -command |
| 591 | 591 |
// |
| 592 | 592 |
// Set the non-default shell to use. |
| 593 |
-func dispatchShell(d dispatchRequest, c *instructions.ShellCommand) error {
|
|
| 593 |
+func dispatchShell(ctx context.Context, d dispatchRequest, c *instructions.ShellCommand) error {
|
|
| 594 | 594 |
d.state.runConfig.Shell = c.Shell |
| 595 |
- return d.builder.commit(d.state, fmt.Sprintf("SHELL %v", d.state.runConfig.Shell))
|
|
| 595 |
+ return d.builder.commit(ctx, d.state, fmt.Sprintf("SHELL %v", d.state.runConfig.Shell))
|
|
| 596 | 596 |
} |
| ... | ... |
@@ -23,10 +23,15 @@ import ( |
| 23 | 23 |
is "gotest.tools/v3/assert/cmp" |
| 24 | 24 |
) |
| 25 | 25 |
|
| 26 |
-func newBuilderWithMockBackend() *Builder {
|
|
| 26 |
+func newBuilderWithMockBackend(t *testing.T) *Builder {
|
|
| 27 |
+ t.Helper() |
|
| 27 | 28 |
mockBackend := &MockBackend{}
|
| 28 | 29 |
opts := &types.ImageBuildOptions{}
|
| 29 | 30 |
ctx := context.Background() |
| 31 |
+ |
|
| 32 |
+ imageProber, err := newImageProber(ctx, mockBackend, nil, false) |
|
| 33 |
+ assert.NilError(t, err, "Could not create image prober") |
|
| 34 |
+ |
|
| 30 | 35 |
b := &Builder{
|
| 31 | 36 |
options: opts, |
| 32 | 37 |
docker: mockBackend, |
| ... | ... |
@@ -37,14 +42,14 @@ func newBuilderWithMockBackend() *Builder {
|
| 37 | 37 |
Options: opts, |
| 38 | 38 |
Backend: mockBackend, |
| 39 | 39 |
}), |
| 40 |
- imageProber: newImageProber(mockBackend, nil, false), |
|
| 40 |
+ imageProber: imageProber, |
|
| 41 | 41 |
containerManager: newContainerManager(mockBackend), |
| 42 | 42 |
} |
| 43 | 43 |
return b |
| 44 | 44 |
} |
| 45 | 45 |
|
| 46 | 46 |
func TestEnv2Variables(t *testing.T) {
|
| 47 |
- b := newBuilderWithMockBackend() |
|
| 47 |
+ b := newBuilderWithMockBackend(t) |
|
| 48 | 48 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 49 | 49 |
envCommand := &instructions.EnvCommand{
|
| 50 | 50 |
Env: instructions.KeyValuePairs{
|
| ... | ... |
@@ -52,7 +57,7 @@ func TestEnv2Variables(t *testing.T) {
|
| 52 | 52 |
instructions.KeyValuePair{Key: "var2", Value: "val2"},
|
| 53 | 53 |
}, |
| 54 | 54 |
} |
| 55 |
- err := dispatch(sb, envCommand) |
|
| 55 |
+ err := dispatch(context.TODO(), sb, envCommand) |
|
| 56 | 56 |
assert.NilError(t, err) |
| 57 | 57 |
|
| 58 | 58 |
expected := []string{
|
| ... | ... |
@@ -63,7 +68,7 @@ func TestEnv2Variables(t *testing.T) {
|
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 | 65 |
func TestEnvValueWithExistingRunConfigEnv(t *testing.T) {
|
| 66 |
- b := newBuilderWithMockBackend() |
|
| 66 |
+ b := newBuilderWithMockBackend(t) |
|
| 67 | 67 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 68 | 68 |
sb.state.runConfig.Env = []string{"var1=old", "var2=fromenv"}
|
| 69 | 69 |
envCommand := &instructions.EnvCommand{
|
| ... | ... |
@@ -71,7 +76,7 @@ func TestEnvValueWithExistingRunConfigEnv(t *testing.T) {
|
| 71 | 71 |
instructions.KeyValuePair{Key: "var1", Value: "val1"},
|
| 72 | 72 |
}, |
| 73 | 73 |
} |
| 74 |
- err := dispatch(sb, envCommand) |
|
| 74 |
+ err := dispatch(context.TODO(), sb, envCommand) |
|
| 75 | 75 |
assert.NilError(t, err) |
| 76 | 76 |
expected := []string{
|
| 77 | 77 |
"var1=val1", |
| ... | ... |
@@ -82,10 +87,10 @@ func TestEnvValueWithExistingRunConfigEnv(t *testing.T) {
|
| 82 | 82 |
|
| 83 | 83 |
func TestMaintainer(t *testing.T) {
|
| 84 | 84 |
maintainerEntry := "Some Maintainer <maintainer@example.com>" |
| 85 |
- b := newBuilderWithMockBackend() |
|
| 85 |
+ b := newBuilderWithMockBackend(t) |
|
| 86 | 86 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 87 | 87 |
cmd := &instructions.MaintainerCommand{Maintainer: maintainerEntry}
|
| 88 |
- err := dispatch(sb, cmd) |
|
| 88 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 89 | 89 |
assert.NilError(t, err) |
| 90 | 90 |
assert.Check(t, is.Equal(maintainerEntry, sb.state.maintainer)) |
| 91 | 91 |
} |
| ... | ... |
@@ -94,14 +99,14 @@ func TestLabel(t *testing.T) {
|
| 94 | 94 |
labelName := "label" |
| 95 | 95 |
labelValue := "value" |
| 96 | 96 |
|
| 97 |
- b := newBuilderWithMockBackend() |
|
| 97 |
+ b := newBuilderWithMockBackend(t) |
|
| 98 | 98 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 99 | 99 |
cmd := &instructions.LabelCommand{
|
| 100 | 100 |
Labels: instructions.KeyValuePairs{
|
| 101 | 101 |
instructions.KeyValuePair{Key: labelName, Value: labelValue},
|
| 102 | 102 |
}, |
| 103 | 103 |
} |
| 104 |
- err := dispatch(sb, cmd) |
|
| 104 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 105 | 105 |
assert.NilError(t, err) |
| 106 | 106 |
|
| 107 | 107 |
assert.Assert(t, is.Contains(sb.state.runConfig.Labels, labelName)) |
| ... | ... |
@@ -109,12 +114,12 @@ func TestLabel(t *testing.T) {
|
| 109 | 109 |
} |
| 110 | 110 |
|
| 111 | 111 |
func TestFromScratch(t *testing.T) {
|
| 112 |
- b := newBuilderWithMockBackend() |
|
| 112 |
+ b := newBuilderWithMockBackend(t) |
|
| 113 | 113 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 114 | 114 |
cmd := &instructions.Stage{
|
| 115 | 115 |
BaseName: "scratch", |
| 116 | 116 |
} |
| 117 |
- err := initializeStage(sb, cmd) |
|
| 117 |
+ err := initializeStage(context.TODO(), sb, cmd) |
|
| 118 | 118 |
|
| 119 | 119 |
if runtime.GOOS == "windows" {
|
| 120 | 120 |
assert.Check(t, is.Error(err, "Windows does not support FROM scratch")) |
| ... | ... |
@@ -135,7 +140,7 @@ func TestFromWithArg(t *testing.T) {
|
| 135 | 135 |
assert.Check(t, is.Equal("alpine"+tag, name))
|
| 136 | 136 |
return &mockImage{id: "expectedthisid"}, nil, nil
|
| 137 | 137 |
} |
| 138 |
- b := newBuilderWithMockBackend() |
|
| 138 |
+ b := newBuilderWithMockBackend(t) |
|
| 139 | 139 |
b.docker.(*MockBackend).getImageFunc = getImage |
| 140 | 140 |
args := NewBuildArgs(make(map[string]*string)) |
| 141 | 141 |
|
| ... | ... |
@@ -151,7 +156,7 @@ func TestFromWithArg(t *testing.T) {
|
| 151 | 151 |
|
| 152 | 152 |
sb := newDispatchRequest(b, '\\', nil, args, newStagesBuildResults()) |
| 153 | 153 |
assert.NilError(t, err) |
| 154 |
- err = initializeStage(sb, cmd) |
|
| 154 |
+ err = initializeStage(context.TODO(), sb, cmd) |
|
| 155 | 155 |
assert.NilError(t, err) |
| 156 | 156 |
|
| 157 | 157 |
assert.Check(t, is.Equal(expected, sb.state.imageID)) |
| ... | ... |
@@ -161,7 +166,7 @@ func TestFromWithArg(t *testing.T) {
|
| 161 | 161 |
} |
| 162 | 162 |
|
| 163 | 163 |
func TestFromWithArgButBuildArgsNotGiven(t *testing.T) {
|
| 164 |
- b := newBuilderWithMockBackend() |
|
| 164 |
+ b := newBuilderWithMockBackend(t) |
|
| 165 | 165 |
args := NewBuildArgs(make(map[string]*string)) |
| 166 | 166 |
|
| 167 | 167 |
metaArg := instructions.ArgCommand{}
|
| ... | ... |
@@ -172,7 +177,7 @@ func TestFromWithArgButBuildArgsNotGiven(t *testing.T) {
|
| 172 | 172 |
|
| 173 | 173 |
sb := newDispatchRequest(b, '\\', nil, args, newStagesBuildResults()) |
| 174 | 174 |
assert.NilError(t, err) |
| 175 |
- err = initializeStage(sb, cmd) |
|
| 175 |
+ err = initializeStage(context.TODO(), sb, cmd) |
|
| 176 | 176 |
assert.Error(t, err, "base name (${THETAG}) should not be blank")
|
| 177 | 177 |
} |
| 178 | 178 |
|
| ... | ... |
@@ -183,7 +188,7 @@ func TestFromWithUndefinedArg(t *testing.T) {
|
| 183 | 183 |
assert.Check(t, is.Equal("alpine", name))
|
| 184 | 184 |
return &mockImage{id: "expectedthisid"}, nil, nil
|
| 185 | 185 |
} |
| 186 |
- b := newBuilderWithMockBackend() |
|
| 186 |
+ b := newBuilderWithMockBackend(t) |
|
| 187 | 187 |
b.docker.(*MockBackend).getImageFunc = getImage |
| 188 | 188 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 189 | 189 |
|
| ... | ... |
@@ -192,41 +197,41 @@ func TestFromWithUndefinedArg(t *testing.T) {
|
| 192 | 192 |
cmd := &instructions.Stage{
|
| 193 | 193 |
BaseName: "alpine${THETAG}",
|
| 194 | 194 |
} |
| 195 |
- err := initializeStage(sb, cmd) |
|
| 195 |
+ err := initializeStage(context.TODO(), sb, cmd) |
|
| 196 | 196 |
assert.NilError(t, err) |
| 197 | 197 |
assert.Check(t, is.Equal(expected, sb.state.imageID)) |
| 198 | 198 |
} |
| 199 | 199 |
|
| 200 | 200 |
func TestFromMultiStageWithNamedStage(t *testing.T) {
|
| 201 |
- b := newBuilderWithMockBackend() |
|
| 201 |
+ b := newBuilderWithMockBackend(t) |
|
| 202 | 202 |
firstFrom := &instructions.Stage{BaseName: "someimg", Name: "base"}
|
| 203 | 203 |
secondFrom := &instructions.Stage{BaseName: "base"}
|
| 204 | 204 |
previousResults := newStagesBuildResults() |
| 205 | 205 |
firstSB := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), previousResults) |
| 206 | 206 |
secondSB := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), previousResults) |
| 207 |
- err := initializeStage(firstSB, firstFrom) |
|
| 207 |
+ err := initializeStage(context.TODO(), firstSB, firstFrom) |
|
| 208 | 208 |
assert.NilError(t, err) |
| 209 | 209 |
assert.Check(t, firstSB.state.hasFromImage()) |
| 210 | 210 |
previousResults.indexed["base"] = firstSB.state.runConfig |
| 211 | 211 |
previousResults.flat = append(previousResults.flat, firstSB.state.runConfig) |
| 212 |
- err = initializeStage(secondSB, secondFrom) |
|
| 212 |
+ err = initializeStage(context.TODO(), secondSB, secondFrom) |
|
| 213 | 213 |
assert.NilError(t, err) |
| 214 | 214 |
assert.Check(t, secondSB.state.hasFromImage()) |
| 215 | 215 |
} |
| 216 | 216 |
|
| 217 | 217 |
func TestOnbuild(t *testing.T) {
|
| 218 |
- b := newBuilderWithMockBackend() |
|
| 218 |
+ b := newBuilderWithMockBackend(t) |
|
| 219 | 219 |
sb := newDispatchRequest(b, '\\', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 220 | 220 |
cmd := &instructions.OnbuildCommand{
|
| 221 | 221 |
Expression: "ADD . /app/src", |
| 222 | 222 |
} |
| 223 |
- err := dispatch(sb, cmd) |
|
| 223 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 224 | 224 |
assert.NilError(t, err) |
| 225 | 225 |
assert.Check(t, is.Equal("ADD . /app/src", sb.state.runConfig.OnBuild[0]))
|
| 226 | 226 |
} |
| 227 | 227 |
|
| 228 | 228 |
func TestWorkdir(t *testing.T) {
|
| 229 |
- b := newBuilderWithMockBackend() |
|
| 229 |
+ b := newBuilderWithMockBackend(t) |
|
| 230 | 230 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 231 | 231 |
sb.state.baseImage = &mockImage{}
|
| 232 | 232 |
workingDir := "/app" |
| ... | ... |
@@ -237,13 +242,13 @@ func TestWorkdir(t *testing.T) {
|
| 237 | 237 |
Path: workingDir, |
| 238 | 238 |
} |
| 239 | 239 |
|
| 240 |
- err := dispatch(sb, cmd) |
|
| 240 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 241 | 241 |
assert.NilError(t, err) |
| 242 | 242 |
assert.Check(t, is.Equal(workingDir, sb.state.runConfig.WorkingDir)) |
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 | 245 |
func TestCmd(t *testing.T) {
|
| 246 |
- b := newBuilderWithMockBackend() |
|
| 246 |
+ b := newBuilderWithMockBackend(t) |
|
| 247 | 247 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 248 | 248 |
sb.state.baseImage = &mockImage{}
|
| 249 | 249 |
command := "./executable" |
| ... | ... |
@@ -254,7 +259,7 @@ func TestCmd(t *testing.T) {
|
| 254 | 254 |
PrependShell: true, |
| 255 | 255 |
}, |
| 256 | 256 |
} |
| 257 |
- err := dispatch(sb, cmd) |
|
| 257 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 258 | 258 |
assert.NilError(t, err) |
| 259 | 259 |
|
| 260 | 260 |
var expectedCommand strslice.StrSlice |
| ... | ... |
@@ -269,14 +274,14 @@ func TestCmd(t *testing.T) {
|
| 269 | 269 |
} |
| 270 | 270 |
|
| 271 | 271 |
func TestHealthcheckNone(t *testing.T) {
|
| 272 |
- b := newBuilderWithMockBackend() |
|
| 272 |
+ b := newBuilderWithMockBackend(t) |
|
| 273 | 273 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 274 | 274 |
cmd := &instructions.HealthCheckCommand{
|
| 275 | 275 |
Health: &container.HealthConfig{
|
| 276 | 276 |
Test: []string{"NONE"},
|
| 277 | 277 |
}, |
| 278 | 278 |
} |
| 279 |
- err := dispatch(sb, cmd) |
|
| 279 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 280 | 280 |
assert.NilError(t, err) |
| 281 | 281 |
|
| 282 | 282 |
assert.Assert(t, sb.state.runConfig.Healthcheck != nil) |
| ... | ... |
@@ -284,7 +289,7 @@ func TestHealthcheckNone(t *testing.T) {
|
| 284 | 284 |
} |
| 285 | 285 |
|
| 286 | 286 |
func TestHealthcheckCmd(t *testing.T) {
|
| 287 |
- b := newBuilderWithMockBackend() |
|
| 287 |
+ b := newBuilderWithMockBackend(t) |
|
| 288 | 288 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 289 | 289 |
expectedTest := []string{"CMD-SHELL", "curl -f http://localhost/ || exit 1"}
|
| 290 | 290 |
cmd := &instructions.HealthCheckCommand{
|
| ... | ... |
@@ -292,7 +297,7 @@ func TestHealthcheckCmd(t *testing.T) {
|
| 292 | 292 |
Test: expectedTest, |
| 293 | 293 |
}, |
| 294 | 294 |
} |
| 295 |
- err := dispatch(sb, cmd) |
|
| 295 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 296 | 296 |
assert.NilError(t, err) |
| 297 | 297 |
|
| 298 | 298 |
assert.Assert(t, sb.state.runConfig.Healthcheck != nil) |
| ... | ... |
@@ -300,7 +305,7 @@ func TestHealthcheckCmd(t *testing.T) {
|
| 300 | 300 |
} |
| 301 | 301 |
|
| 302 | 302 |
func TestEntrypoint(t *testing.T) {
|
| 303 |
- b := newBuilderWithMockBackend() |
|
| 303 |
+ b := newBuilderWithMockBackend(t) |
|
| 304 | 304 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 305 | 305 |
sb.state.baseImage = &mockImage{}
|
| 306 | 306 |
entrypointCmd := "/usr/sbin/nginx" |
| ... | ... |
@@ -311,7 +316,7 @@ func TestEntrypoint(t *testing.T) {
|
| 311 | 311 |
PrependShell: true, |
| 312 | 312 |
}, |
| 313 | 313 |
} |
| 314 |
- err := dispatch(sb, cmd) |
|
| 314 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 315 | 315 |
assert.NilError(t, err) |
| 316 | 316 |
assert.Assert(t, sb.state.runConfig.Entrypoint != nil) |
| 317 | 317 |
|
| ... | ... |
@@ -325,14 +330,14 @@ func TestEntrypoint(t *testing.T) {
|
| 325 | 325 |
} |
| 326 | 326 |
|
| 327 | 327 |
func TestExpose(t *testing.T) {
|
| 328 |
- b := newBuilderWithMockBackend() |
|
| 328 |
+ b := newBuilderWithMockBackend(t) |
|
| 329 | 329 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 330 | 330 |
|
| 331 | 331 |
exposedPort := "80" |
| 332 | 332 |
cmd := &instructions.ExposeCommand{
|
| 333 | 333 |
Ports: []string{exposedPort},
|
| 334 | 334 |
} |
| 335 |
- err := dispatch(sb, cmd) |
|
| 335 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 336 | 336 |
assert.NilError(t, err) |
| 337 | 337 |
|
| 338 | 338 |
assert.Assert(t, sb.state.runConfig.ExposedPorts != nil) |
| ... | ... |
@@ -344,19 +349,19 @@ func TestExpose(t *testing.T) {
|
| 344 | 344 |
} |
| 345 | 345 |
|
| 346 | 346 |
func TestUser(t *testing.T) {
|
| 347 |
- b := newBuilderWithMockBackend() |
|
| 347 |
+ b := newBuilderWithMockBackend(t) |
|
| 348 | 348 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 349 | 349 |
|
| 350 | 350 |
cmd := &instructions.UserCommand{
|
| 351 | 351 |
User: "test", |
| 352 | 352 |
} |
| 353 |
- err := dispatch(sb, cmd) |
|
| 353 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 354 | 354 |
assert.NilError(t, err) |
| 355 | 355 |
assert.Check(t, is.Equal("test", sb.state.runConfig.User))
|
| 356 | 356 |
} |
| 357 | 357 |
|
| 358 | 358 |
func TestVolume(t *testing.T) {
|
| 359 |
- b := newBuilderWithMockBackend() |
|
| 359 |
+ b := newBuilderWithMockBackend(t) |
|
| 360 | 360 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 361 | 361 |
|
| 362 | 362 |
exposedVolume := "/foo" |
| ... | ... |
@@ -364,7 +369,7 @@ func TestVolume(t *testing.T) {
|
| 364 | 364 |
cmd := &instructions.VolumeCommand{
|
| 365 | 365 |
Volumes: []string{exposedVolume},
|
| 366 | 366 |
} |
| 367 |
- err := dispatch(sb, cmd) |
|
| 367 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 368 | 368 |
assert.NilError(t, err) |
| 369 | 369 |
assert.Assert(t, sb.state.runConfig.Volumes != nil) |
| 370 | 370 |
assert.Check(t, is.Len(sb.state.runConfig.Volumes, 1)) |
| ... | ... |
@@ -376,7 +381,7 @@ func TestStopSignal(t *testing.T) {
|
| 376 | 376 |
t.Skip("Windows does not support stopsignal")
|
| 377 | 377 |
return |
| 378 | 378 |
} |
| 379 |
- b := newBuilderWithMockBackend() |
|
| 379 |
+ b := newBuilderWithMockBackend(t) |
|
| 380 | 380 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 381 | 381 |
sb.state.baseImage = &mockImage{}
|
| 382 | 382 |
signal := "SIGKILL" |
| ... | ... |
@@ -384,19 +389,19 @@ func TestStopSignal(t *testing.T) {
|
| 384 | 384 |
cmd := &instructions.StopSignalCommand{
|
| 385 | 385 |
Signal: signal, |
| 386 | 386 |
} |
| 387 |
- err := dispatch(sb, cmd) |
|
| 387 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 388 | 388 |
assert.NilError(t, err) |
| 389 | 389 |
assert.Check(t, is.Equal(signal, sb.state.runConfig.StopSignal)) |
| 390 | 390 |
} |
| 391 | 391 |
|
| 392 | 392 |
func TestArg(t *testing.T) {
|
| 393 |
- b := newBuilderWithMockBackend() |
|
| 393 |
+ b := newBuilderWithMockBackend(t) |
|
| 394 | 394 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 395 | 395 |
|
| 396 | 396 |
argName := "foo" |
| 397 | 397 |
argVal := "bar" |
| 398 | 398 |
cmd := &instructions.ArgCommand{Args: []instructions.KeyValuePairOptional{{Key: argName, Value: &argVal}}}
|
| 399 |
- err := dispatch(sb, cmd) |
|
| 399 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 400 | 400 |
assert.NilError(t, err) |
| 401 | 401 |
|
| 402 | 402 |
expected := map[string]string{argName: argVal}
|
| ... | ... |
@@ -404,13 +409,13 @@ func TestArg(t *testing.T) {
|
| 404 | 404 |
} |
| 405 | 405 |
|
| 406 | 406 |
func TestShell(t *testing.T) {
|
| 407 |
- b := newBuilderWithMockBackend() |
|
| 407 |
+ b := newBuilderWithMockBackend(t) |
|
| 408 | 408 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 409 | 409 |
|
| 410 | 410 |
shellCmd := "powershell" |
| 411 | 411 |
cmd := &instructions.ShellCommand{Shell: strslice.StrSlice{shellCmd}}
|
| 412 | 412 |
|
| 413 |
- err := dispatch(sb, cmd) |
|
| 413 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 414 | 414 |
assert.NilError(t, err) |
| 415 | 415 |
|
| 416 | 416 |
expectedShell := strslice.StrSlice([]string{shellCmd})
|
| ... | ... |
@@ -430,7 +435,7 @@ func TestPrependEnvOnCmd(t *testing.T) {
|
| 430 | 430 |
} |
| 431 | 431 |
|
| 432 | 432 |
func TestRunWithBuildArgs(t *testing.T) {
|
| 433 |
- b := newBuilderWithMockBackend() |
|
| 433 |
+ b := newBuilderWithMockBackend(t) |
|
| 434 | 434 |
args := NewBuildArgs(make(map[string]*string)) |
| 435 | 435 |
args.argsFromOptions["HTTP_PROXY"] = strPtr("FOO")
|
| 436 | 436 |
b.disableCommit = false |
| ... | ... |
@@ -462,7 +467,11 @@ func TestRunWithBuildArgs(t *testing.T) {
|
| 462 | 462 |
mockBackend.makeImageCacheFunc = func(_ []string) builder.ImageCache {
|
| 463 | 463 |
return imageCache |
| 464 | 464 |
} |
| 465 |
- b.imageProber = newImageProber(mockBackend, nil, false) |
|
| 465 |
+ |
|
| 466 |
+ imageProber, err := newImageProber(context.TODO(), mockBackend, nil, false) |
|
| 467 |
+ assert.NilError(t, err, "Could not create image prober") |
|
| 468 |
+ b.imageProber = imageProber |
|
| 469 |
+ |
|
| 466 | 470 |
mockBackend.getImageFunc = func(_ string) (builder.Image, builder.ROLayer, error) {
|
| 467 | 471 |
return &mockImage{
|
| 468 | 472 |
id: "abcdef", |
| ... | ... |
@@ -484,7 +493,7 @@ func TestRunWithBuildArgs(t *testing.T) {
|
| 484 | 484 |
return "", nil |
| 485 | 485 |
} |
| 486 | 486 |
from := &instructions.Stage{BaseName: "abcdef"}
|
| 487 |
- err := initializeStage(sb, from) |
|
| 487 |
+ err = initializeStage(context.TODO(), sb, from) |
|
| 488 | 488 |
assert.NilError(t, err) |
| 489 | 489 |
sb.state.buildArgs.AddArg("one", strPtr("two"))
|
| 490 | 490 |
|
| ... | ... |
@@ -504,14 +513,14 @@ func TestRunWithBuildArgs(t *testing.T) {
|
| 504 | 504 |
runinst.CmdLine = strslice.StrSlice{"echo foo"}
|
| 505 | 505 |
runinst.PrependShell = true |
| 506 | 506 |
|
| 507 |
- assert.NilError(t, dispatch(sb, runinst)) |
|
| 507 |
+ assert.NilError(t, dispatch(context.TODO(), sb, runinst)) |
|
| 508 | 508 |
|
| 509 | 509 |
// Check that runConfig.Cmd has not been modified by run |
| 510 | 510 |
assert.Check(t, is.DeepEqual(origCmd, sb.state.runConfig.Cmd)) |
| 511 | 511 |
} |
| 512 | 512 |
|
| 513 | 513 |
func TestRunIgnoresHealthcheck(t *testing.T) {
|
| 514 |
- b := newBuilderWithMockBackend() |
|
| 514 |
+ b := newBuilderWithMockBackend(t) |
|
| 515 | 515 |
args := NewBuildArgs(make(map[string]*string)) |
| 516 | 516 |
sb := newDispatchRequest(b, '`', nil, args, newStagesBuildResults()) |
| 517 | 517 |
b.disableCommit = false |
| ... | ... |
@@ -528,7 +537,10 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
|
| 528 | 528 |
mockBackend.makeImageCacheFunc = func(_ []string) builder.ImageCache {
|
| 529 | 529 |
return imageCache |
| 530 | 530 |
} |
| 531 |
- b.imageProber = newImageProber(mockBackend, nil, false) |
|
| 531 |
+ imageProber, err := newImageProber(context.TODO(), mockBackend, nil, false) |
|
| 532 |
+ assert.NilError(t, err, "Could not create image prober") |
|
| 533 |
+ |
|
| 534 |
+ b.imageProber = imageProber |
|
| 532 | 535 |
mockBackend.getImageFunc = func(_ string) (builder.Image, builder.ROLayer, error) {
|
| 533 | 536 |
return &mockImage{
|
| 534 | 537 |
id: "abcdef", |
| ... | ... |
@@ -542,7 +554,7 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
|
| 542 | 542 |
return "", nil |
| 543 | 543 |
} |
| 544 | 544 |
from := &instructions.Stage{BaseName: "abcdef"}
|
| 545 |
- err := initializeStage(sb, from) |
|
| 545 |
+ err = initializeStage(context.TODO(), sb, from) |
|
| 546 | 546 |
assert.NilError(t, err) |
| 547 | 547 |
|
| 548 | 548 |
expectedTest := []string{"CMD-SHELL", "curl -f http://localhost/ || exit 1"}
|
| ... | ... |
@@ -559,7 +571,7 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
|
| 559 | 559 |
assert.NilError(t, err) |
| 560 | 560 |
cmd := healthint.(*instructions.HealthCheckCommand) |
| 561 | 561 |
|
| 562 |
- assert.NilError(t, dispatch(sb, cmd)) |
|
| 562 |
+ assert.NilError(t, dispatch(context.TODO(), sb, cmd)) |
|
| 563 | 563 |
assert.Assert(t, sb.state.runConfig.Healthcheck != nil) |
| 564 | 564 |
|
| 565 | 565 |
mockBackend.containerCreateFunc = func(config types.ContainerCreateConfig) (container.CreateResponse, error) {
|
| ... | ... |
@@ -574,12 +586,12 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
|
| 574 | 574 |
run := runint.(*instructions.RunCommand) |
| 575 | 575 |
run.PrependShell = true |
| 576 | 576 |
|
| 577 |
- assert.NilError(t, dispatch(sb, run)) |
|
| 577 |
+ assert.NilError(t, dispatch(context.TODO(), sb, run)) |
|
| 578 | 578 |
assert.Check(t, is.DeepEqual(expectedTest, sb.state.runConfig.Healthcheck.Test)) |
| 579 | 579 |
} |
| 580 | 580 |
|
| 581 | 581 |
func TestDispatchUnsupportedOptions(t *testing.T) {
|
| 582 |
- b := newBuilderWithMockBackend() |
|
| 582 |
+ b := newBuilderWithMockBackend(t) |
|
| 583 | 583 |
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 584 | 584 |
sb.state.baseImage = &mockImage{}
|
| 585 | 585 |
sb.state.operatingSystem = runtime.GOOS |
| ... | ... |
@@ -592,7 +604,7 @@ func TestDispatchUnsupportedOptions(t *testing.T) {
|
| 592 | 592 |
}, |
| 593 | 593 |
Chmod: "0655", |
| 594 | 594 |
} |
| 595 |
- err := dispatch(sb, cmd) |
|
| 595 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 596 | 596 |
assert.Error(t, err, "the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled") |
| 597 | 597 |
}) |
| 598 | 598 |
|
| ... | ... |
@@ -604,7 +616,7 @@ func TestDispatchUnsupportedOptions(t *testing.T) {
|
| 604 | 604 |
}, |
| 605 | 605 |
Chmod: "0655", |
| 606 | 606 |
} |
| 607 |
- err := dispatch(sb, cmd) |
|
| 607 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 608 | 608 |
assert.Error(t, err, "the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled") |
| 609 | 609 |
}) |
| 610 | 610 |
|
| ... | ... |
@@ -618,7 +630,7 @@ func TestDispatchUnsupportedOptions(t *testing.T) {
|
| 618 | 618 |
// one or more of these flags will be supported in future |
| 619 | 619 |
for _, f := range []string{"mount", "network", "security", "any-flag"} {
|
| 620 | 620 |
cmd.FlagsUsed = []string{f}
|
| 621 |
- err := dispatch(sb, cmd) |
|
| 621 |
+ err := dispatch(context.TODO(), sb, cmd) |
|
| 622 | 622 |
assert.Error(t, err, fmt.Sprintf("the --%s option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled", f))
|
| 623 | 623 |
} |
| 624 | 624 |
}) |
| ... | ... |
@@ -20,6 +20,7 @@ |
| 20 | 20 |
package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 21 | 21 |
|
| 22 | 22 |
import ( |
| 23 |
+ "context" |
|
| 23 | 24 |
"reflect" |
| 24 | 25 |
"strconv" |
| 25 | 26 |
"strings" |
| ... | ... |
@@ -34,7 +35,7 @@ import ( |
| 34 | 34 |
"github.com/pkg/errors" |
| 35 | 35 |
) |
| 36 | 36 |
|
| 37 |
-func dispatch(d dispatchRequest, cmd instructions.Command) (err error) {
|
|
| 37 |
+func dispatch(ctx context.Context, d dispatchRequest, cmd instructions.Command) (err error) {
|
|
| 38 | 38 |
if c, ok := cmd.(instructions.PlatformSpecific); ok {
|
| 39 | 39 |
err := c.CheckPlatform(d.state.operatingSystem) |
| 40 | 40 |
if err != nil {
|
| ... | ... |
@@ -65,39 +66,39 @@ func dispatch(d dispatchRequest, cmd instructions.Command) (err error) {
|
| 65 | 65 |
}() |
| 66 | 66 |
switch c := cmd.(type) {
|
| 67 | 67 |
case *instructions.EnvCommand: |
| 68 |
- return dispatchEnv(d, c) |
|
| 68 |
+ return dispatchEnv(ctx, d, c) |
|
| 69 | 69 |
case *instructions.MaintainerCommand: |
| 70 |
- return dispatchMaintainer(d, c) |
|
| 70 |
+ return dispatchMaintainer(ctx, d, c) |
|
| 71 | 71 |
case *instructions.LabelCommand: |
| 72 |
- return dispatchLabel(d, c) |
|
| 72 |
+ return dispatchLabel(ctx, d, c) |
|
| 73 | 73 |
case *instructions.AddCommand: |
| 74 |
- return dispatchAdd(d, c) |
|
| 74 |
+ return dispatchAdd(ctx, d, c) |
|
| 75 | 75 |
case *instructions.CopyCommand: |
| 76 |
- return dispatchCopy(d, c) |
|
| 76 |
+ return dispatchCopy(ctx, d, c) |
|
| 77 | 77 |
case *instructions.OnbuildCommand: |
| 78 |
- return dispatchOnbuild(d, c) |
|
| 78 |
+ return dispatchOnbuild(ctx, d, c) |
|
| 79 | 79 |
case *instructions.WorkdirCommand: |
| 80 |
- return dispatchWorkdir(d, c) |
|
| 80 |
+ return dispatchWorkdir(ctx, d, c) |
|
| 81 | 81 |
case *instructions.RunCommand: |
| 82 |
- return dispatchRun(d, c) |
|
| 82 |
+ return dispatchRun(ctx, d, c) |
|
| 83 | 83 |
case *instructions.CmdCommand: |
| 84 |
- return dispatchCmd(d, c) |
|
| 84 |
+ return dispatchCmd(ctx, d, c) |
|
| 85 | 85 |
case *instructions.HealthCheckCommand: |
| 86 |
- return dispatchHealthcheck(d, c) |
|
| 86 |
+ return dispatchHealthcheck(ctx, d, c) |
|
| 87 | 87 |
case *instructions.EntrypointCommand: |
| 88 |
- return dispatchEntrypoint(d, c) |
|
| 88 |
+ return dispatchEntrypoint(ctx, d, c) |
|
| 89 | 89 |
case *instructions.ExposeCommand: |
| 90 |
- return dispatchExpose(d, c, envs) |
|
| 90 |
+ return dispatchExpose(ctx, d, c, envs) |
|
| 91 | 91 |
case *instructions.UserCommand: |
| 92 |
- return dispatchUser(d, c) |
|
| 92 |
+ return dispatchUser(ctx, d, c) |
|
| 93 | 93 |
case *instructions.VolumeCommand: |
| 94 |
- return dispatchVolume(d, c) |
|
| 94 |
+ return dispatchVolume(ctx, d, c) |
|
| 95 | 95 |
case *instructions.StopSignalCommand: |
| 96 |
- return dispatchStopSignal(d, c) |
|
| 96 |
+ return dispatchStopSignal(ctx, d, c) |
|
| 97 | 97 |
case *instructions.ArgCommand: |
| 98 |
- return dispatchArg(d, c) |
|
| 98 |
+ return dispatchArg(ctx, d, c) |
|
| 99 | 99 |
case *instructions.ShellCommand: |
| 100 |
- return dispatchShell(d, c) |
|
| 100 |
+ return dispatchShell(ctx, d, c) |
|
| 101 | 101 |
} |
| 102 | 102 |
return errors.Errorf("unsupported command type: %v", reflect.TypeOf(cmd))
|
| 103 | 103 |
} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"os" |
| 5 | 6 |
"runtime" |
| 6 | 7 |
"testing" |
| ... | ... |
@@ -127,9 +128,9 @@ func TestDispatch(t *testing.T) {
|
| 127 | 127 |
} |
| 128 | 128 |
}() |
| 129 | 129 |
|
| 130 |
- b := newBuilderWithMockBackend() |
|
| 130 |
+ b := newBuilderWithMockBackend(t) |
|
| 131 | 131 |
sb := newDispatchRequest(b, '`', buildContext, NewBuildArgs(make(map[string]*string)), newStagesBuildResults()) |
| 132 |
- err = dispatch(sb, tc.cmd) |
|
| 132 |
+ err = dispatch(context.TODO(), sb, tc.cmd) |
|
| 133 | 133 |
assert.Check(t, is.ErrorContains(err, tc.expectedError)) |
| 134 | 134 |
}) |
| 135 | 135 |
} |
| ... | ... |
@@ -1,6 +1,8 @@ |
| 1 | 1 |
package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 5 |
+ |
|
| 4 | 6 |
"github.com/docker/docker/api/types/container" |
| 5 | 7 |
"github.com/docker/docker/builder" |
| 6 | 8 |
"github.com/sirupsen/logrus" |
| ... | ... |
@@ -9,30 +11,42 @@ import ( |
| 9 | 9 |
// ImageProber exposes an Image cache to the Builder. It supports resetting a |
| 10 | 10 |
// cache. |
| 11 | 11 |
type ImageProber interface {
|
| 12 |
- Reset() |
|
| 12 |
+ Reset(ctx context.Context) error |
|
| 13 | 13 |
Probe(parentID string, runConfig *container.Config) (string, error) |
| 14 | 14 |
} |
| 15 | 15 |
|
| 16 |
+type resetFunc func(context.Context) (builder.ImageCache, error) |
|
| 17 |
+ |
|
| 16 | 18 |
type imageProber struct {
|
| 17 | 19 |
cache builder.ImageCache |
| 18 |
- reset func() builder.ImageCache |
|
| 20 |
+ reset resetFunc |
|
| 19 | 21 |
cacheBusted bool |
| 20 | 22 |
} |
| 21 | 23 |
|
| 22 |
-func newImageProber(cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, noCache bool) ImageProber {
|
|
| 24 |
+func newImageProber(ctx context.Context, cacheBuilder builder.ImageCacheBuilder, cacheFrom []string, noCache bool) (ImageProber, error) {
|
|
| 23 | 25 |
if noCache {
|
| 24 |
- return &nopProber{}
|
|
| 26 |
+ return &nopProber{}, nil
|
|
| 27 |
+ } |
|
| 28 |
+ |
|
| 29 |
+ reset := func(ctx context.Context) (builder.ImageCache, error) {
|
|
| 30 |
+ return cacheBuilder.MakeImageCache(ctx, cacheFrom) |
|
| 25 | 31 |
} |
| 26 | 32 |
|
| 27 |
- reset := func() builder.ImageCache {
|
|
| 28 |
- return cacheBuilder.MakeImageCache(cacheFrom) |
|
| 33 |
+ cache, err := reset(ctx) |
|
| 34 |
+ if err != nil {
|
|
| 35 |
+ return nil, err |
|
| 29 | 36 |
} |
| 30 |
- return &imageProber{cache: reset(), reset: reset}
|
|
| 37 |
+ return &imageProber{cache: cache, reset: reset}, nil
|
|
| 31 | 38 |
} |
| 32 | 39 |
|
| 33 |
-func (c *imageProber) Reset() {
|
|
| 34 |
- c.cache = c.reset() |
|
| 40 |
+func (c *imageProber) Reset(ctx context.Context) error {
|
|
| 41 |
+ newCache, err := c.reset(ctx) |
|
| 42 |
+ if err != nil {
|
|
| 43 |
+ return err |
|
| 44 |
+ } |
|
| 45 |
+ c.cache = newCache |
|
| 35 | 46 |
c.cacheBusted = false |
| 47 |
+ return nil |
|
| 36 | 48 |
} |
| 37 | 49 |
|
| 38 | 50 |
// Probe checks if cache match can be found for current build instruction. |
| ... | ... |
@@ -56,7 +70,9 @@ func (c *imageProber) Probe(parentID string, runConfig *container.Config) (strin |
| 56 | 56 |
|
| 57 | 57 |
type nopProber struct{}
|
| 58 | 58 |
|
| 59 |
-func (c *nopProber) Reset() {}
|
|
| 59 |
+func (c *nopProber) Reset(ctx context.Context) error {
|
|
| 60 |
+ return nil |
|
| 61 |
+} |
|
| 60 | 62 |
|
| 61 | 63 |
func (c *nopProber) Probe(_ string, _ *container.Config) (string, error) {
|
| 62 | 64 |
return "", nil |
| ... | ... |
@@ -4,6 +4,7 @@ package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 4 | 4 |
// non-contiguous functionality. Please read the comments. |
| 5 | 5 |
|
| 6 | 6 |
import ( |
| 7 |
+ "context" |
|
| 7 | 8 |
"crypto/sha256" |
| 8 | 9 |
"encoding/hex" |
| 9 | 10 |
"fmt" |
| ... | ... |
@@ -27,7 +28,7 @@ func (b *Builder) getArchiver() *archive.Archiver {
|
| 27 | 27 |
return chrootarchive.NewArchiver(b.idMapping) |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
-func (b *Builder) commit(dispatchState *dispatchState, comment string) error {
|
|
| 30 |
+func (b *Builder) commit(ctx context.Context, dispatchState *dispatchState, comment string) error {
|
|
| 31 | 31 |
if b.disableCommit {
|
| 32 | 32 |
return nil |
| 33 | 33 |
} |
| ... | ... |
@@ -36,7 +37,7 @@ func (b *Builder) commit(dispatchState *dispatchState, comment string) error {
|
| 36 | 36 |
} |
| 37 | 37 |
|
| 38 | 38 |
runConfigWithCommentCmd := copyRunConfig(dispatchState.runConfig, withCmdComment(comment, dispatchState.operatingSystem)) |
| 39 |
- id, err := b.probeAndCreate(dispatchState, runConfigWithCommentCmd) |
|
| 39 |
+ id, err := b.probeAndCreate(ctx, dispatchState, runConfigWithCommentCmd) |
|
| 40 | 40 |
if err != nil || id == "" {
|
| 41 | 41 |
return err |
| 42 | 42 |
} |
| ... | ... |
@@ -107,7 +108,7 @@ func (b *Builder) exportImage(state *dispatchState, layer builder.RWLayer, paren |
| 107 | 107 |
return nil |
| 108 | 108 |
} |
| 109 | 109 |
|
| 110 |
-func (b *Builder) performCopy(req dispatchRequest, inst copyInstruction) error {
|
|
| 110 |
+func (b *Builder) performCopy(ctx context.Context, req dispatchRequest, inst copyInstruction) error {
|
|
| 111 | 111 |
state := req.state |
| 112 | 112 |
srcHash := getSourceHashFromInfos(inst.infos) |
| 113 | 113 |
|
| ... | ... |
@@ -147,7 +148,7 @@ func (b *Builder) performCopy(req dispatchRequest, inst copyInstruction) error {
|
| 147 | 147 |
// translated (if necessary because of user namespaces), and replace |
| 148 | 148 |
// the root pair with the chown pair for copy operations |
| 149 | 149 |
if inst.chownStr != "" {
|
| 150 |
- identity, err = parseChownFlag(b, state, inst.chownStr, destInfo.root, b.idMapping) |
|
| 150 |
+ identity, err = parseChownFlag(ctx, b, state, inst.chownStr, destInfo.root, b.idMapping) |
|
| 151 | 151 |
if err != nil {
|
| 152 | 152 |
if b.options.Platform != "windows" {
|
| 153 | 153 |
return errors.Wrapf(err, "unable to convert uid/gid chown string to host mapping") |
| ... | ... |
@@ -331,18 +332,18 @@ func (b *Builder) probeCache(dispatchState *dispatchState, runConfig *container. |
| 331 | 331 |
|
| 332 | 332 |
var defaultLogConfig = container.LogConfig{Type: "none"}
|
| 333 | 333 |
|
| 334 |
-func (b *Builder) probeAndCreate(dispatchState *dispatchState, runConfig *container.Config) (string, error) {
|
|
| 334 |
+func (b *Builder) probeAndCreate(ctx context.Context, dispatchState *dispatchState, runConfig *container.Config) (string, error) {
|
|
| 335 | 335 |
if hit, err := b.probeCache(dispatchState, runConfig); err != nil || hit {
|
| 336 | 336 |
return "", err |
| 337 | 337 |
} |
| 338 |
- return b.create(runConfig) |
|
| 338 |
+ return b.create(ctx, runConfig) |
|
| 339 | 339 |
} |
| 340 | 340 |
|
| 341 |
-func (b *Builder) create(runConfig *container.Config) (string, error) {
|
|
| 341 |
+func (b *Builder) create(ctx context.Context, runConfig *container.Config) (string, error) {
|
|
| 342 | 342 |
logrus.Debugf("[BUILDER] Command to be executed: %v", runConfig.Cmd)
|
| 343 | 343 |
|
| 344 | 344 |
hostConfig := hostConfigFromOptions(b.options) |
| 345 |
- container, err := b.containerManager.Create(runConfig, hostConfig) |
|
| 345 |
+ container, err := b.containerManager.Create(ctx, runConfig, hostConfig) |
|
| 346 | 346 |
if err != nil {
|
| 347 | 347 |
return "", err |
| 348 | 348 |
} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"path/filepath" |
| 5 | 6 |
"strconv" |
| 6 | 7 |
"strings" |
| ... | ... |
@@ -11,7 +12,7 @@ import ( |
| 11 | 11 |
"github.com/pkg/errors" |
| 12 | 12 |
) |
| 13 | 13 |
|
| 14 |
-func parseChownFlag(builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) {
|
|
| 14 |
+func parseChownFlag(ctx context.Context, builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) {
|
|
| 15 | 15 |
var userStr, grpStr string |
| 16 | 16 |
parts := strings.Split(chown, ":") |
| 17 | 17 |
if len(parts) > 2 {
|
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"os" |
| 5 | 6 |
"path/filepath" |
| 6 | 7 |
"testing" |
| ... | ... |
@@ -115,7 +116,7 @@ othergrp:x:6666: |
| 115 | 115 |
}, |
| 116 | 116 |
} {
|
| 117 | 117 |
t.Run(testcase.name, func(t *testing.T) {
|
| 118 |
- idPair, err := parseChownFlag(testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) |
|
| 118 |
+ idPair, err := parseChownFlag(context.TODO(), testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) |
|
| 119 | 119 |
assert.NilError(t, err, "Failed to parse chown flag: %q", testcase.chownStr) |
| 120 | 120 |
assert.Check(t, is.DeepEqual(testcase.expected, idPair), "chown flag mapping failure") |
| 121 | 121 |
}) |
| ... | ... |
@@ -156,7 +157,7 @@ othergrp:x:6666: |
| 156 | 156 |
}, |
| 157 | 157 |
} {
|
| 158 | 158 |
t.Run(testcase.name, func(t *testing.T) {
|
| 159 |
- _, err := parseChownFlag(testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) |
|
| 159 |
+ _, err := parseChownFlag(context.TODO(), testcase.builder, testcase.state, testcase.chownStr, contextDir, testcase.idMapping) |
|
| 160 | 160 |
assert.Check(t, is.Error(err, testcase.descr), "Expected error string doesn't match") |
| 161 | 161 |
}) |
| 162 | 162 |
} |
| ... | ... |
@@ -2,6 +2,7 @@ package dockerfile // import "github.com/docker/docker/builder/dockerfile" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"bytes" |
| 5 |
+ "context" |
|
| 5 | 6 |
"os" |
| 6 | 7 |
"path/filepath" |
| 7 | 8 |
"strings" |
| ... | ... |
@@ -14,15 +15,15 @@ import ( |
| 14 | 14 |
"golang.org/x/sys/windows" |
| 15 | 15 |
) |
| 16 | 16 |
|
| 17 |
-func parseChownFlag(builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) {
|
|
| 17 |
+func parseChownFlag(ctx context.Context, builder *Builder, state *dispatchState, chown, ctrRootPath string, identityMapping idtools.IdentityMapping) (idtools.Identity, error) {
|
|
| 18 | 18 |
if builder.options.Platform == "windows" {
|
| 19 |
- return getAccountIdentity(builder, chown, ctrRootPath, state) |
|
| 19 |
+ return getAccountIdentity(ctx, builder, chown, ctrRootPath, state) |
|
| 20 | 20 |
} |
| 21 | 21 |
|
| 22 | 22 |
return identityMapping.RootPair(), nil |
| 23 | 23 |
} |
| 24 | 24 |
|
| 25 |
-func getAccountIdentity(builder *Builder, accountName string, ctrRootPath string, state *dispatchState) (idtools.Identity, error) {
|
|
| 25 |
+func getAccountIdentity(ctx context.Context, builder *Builder, accountName string, ctrRootPath string, state *dispatchState) (idtools.Identity, error) {
|
|
| 26 | 26 |
// If this is potentially a string SID then attempt to convert it to verify |
| 27 | 27 |
// this, otherwise continue looking for the account. |
| 28 | 28 |
if strings.HasPrefix(accountName, "S-") || strings.HasPrefix(accountName, "s-") {
|
| ... | ... |
@@ -51,10 +52,10 @@ func getAccountIdentity(builder *Builder, accountName string, ctrRootPath string |
| 51 | 51 |
|
| 52 | 52 |
// All other lookups failed, so therefore determine if the account in |
| 53 | 53 |
// question exists in the container and if so, obtain its SID. |
| 54 |
- return lookupNTAccount(builder, accountName, state) |
|
| 54 |
+ return lookupNTAccount(ctx, builder, accountName, state) |
|
| 55 | 55 |
} |
| 56 | 56 |
|
| 57 |
-func lookupNTAccount(builder *Builder, accountName string, state *dispatchState) (idtools.Identity, error) {
|
|
| 57 |
+func lookupNTAccount(ctx context.Context, builder *Builder, accountName string, state *dispatchState) (idtools.Identity, error) {
|
|
| 58 | 58 |
|
| 59 | 59 |
source, _ := filepath.Split(os.Args[0]) |
| 60 | 60 |
|
| ... | ... |
@@ -81,7 +82,7 @@ func lookupNTAccount(builder *Builder, accountName string, state *dispatchState) |
| 81 | 81 |
}, |
| 82 | 82 |
} |
| 83 | 83 |
|
| 84 |
- container, err := builder.containerManager.Create(runConfig, hostConfig) |
|
| 84 |
+ container, err := builder.containerManager.Create(ctx, runConfig, hostConfig) |
|
| 85 | 85 |
if err != nil {
|
| 86 | 86 |
return idtools.Identity{}, err
|
| 87 | 87 |
} |
| ... | ... |
@@ -27,7 +27,7 @@ func (m *MockBackend) ContainerAttachRaw(cID string, stdin io.ReadCloser, stdout |
| 27 | 27 |
return nil |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
-func (m *MockBackend) ContainerCreateIgnoreImagesArgsEscaped(config types.ContainerCreateConfig) (container.CreateResponse, error) {
|
|
| 30 |
+func (m *MockBackend) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error) {
|
|
| 31 | 31 |
if m.containerCreateFunc != nil {
|
| 32 | 32 |
return m.containerCreateFunc(config) |
| 33 | 33 |
} |
| ... | ... |
@@ -49,7 +49,7 @@ func (m *MockBackend) ContainerKill(containerID string, sig string) error {
|
| 49 | 49 |
return nil |
| 50 | 50 |
} |
| 51 | 51 |
|
| 52 |
-func (m *MockBackend) ContainerStart(containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error {
|
|
| 52 |
+func (m *MockBackend) ContainerStart(ctx context.Context, containerID string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error {
|
|
| 53 | 53 |
return nil |
| 54 | 54 |
} |
| 55 | 55 |
|
| ... | ... |
@@ -73,11 +73,11 @@ func (m *MockBackend) GetImageAndReleasableLayer(ctx context.Context, refOrID st |
| 73 | 73 |
return &mockImage{id: "theid"}, &mockLayer{}, nil
|
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
-func (m *MockBackend) MakeImageCache(cacheFrom []string) builder.ImageCache {
|
|
| 76 |
+func (m *MockBackend) MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error) {
|
|
| 77 | 77 |
if m.makeImageCacheFunc != nil {
|
| 78 |
- return m.makeImageCacheFunc(cacheFrom) |
|
| 78 |
+ return m.makeImageCacheFunc(cacheFrom), nil |
|
| 79 | 79 |
} |
| 80 |
- return nil |
|
| 80 |
+ return nil, nil |
|
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 | 83 |
func (m *MockBackend) CreateImage(config []byte, parent string) (builder.Image, error) {
|
| ... | ... |
@@ -252,7 +252,7 @@ func (cli *DaemonCli) start(opts *daemonOptions) (err error) {
|
| 252 | 252 |
|
| 253 | 253 |
// notify systemd that we're shutting down |
| 254 | 254 |
notifyStopping() |
| 255 |
- shutdownDaemon(d) |
|
| 255 |
+ shutdownDaemon(ctx, d) |
|
| 256 | 256 |
|
| 257 | 257 |
// Stop notification processing and any background processes |
| 258 | 258 |
cancel() |
| ... | ... |
@@ -359,11 +359,11 @@ func (cli *DaemonCli) stop() {
|
| 359 | 359 |
// shutdownDaemon just wraps daemon.Shutdown() to handle a timeout in case |
| 360 | 360 |
// d.Shutdown() is waiting too long to kill container or worst it's |
| 361 | 361 |
// blocked there |
| 362 |
-func shutdownDaemon(d *daemon.Daemon) {
|
|
| 362 |
+func shutdownDaemon(ctx context.Context, d *daemon.Daemon) {
|
|
| 363 | 363 |
shutdownTimeout := d.ShutdownTimeout() |
| 364 | 364 |
ch := make(chan struct{})
|
| 365 | 365 |
go func() {
|
| 366 |
- d.Shutdown() |
|
| 366 |
+ d.Shutdown(ctx) |
|
| 367 | 367 |
close(ch) |
| 368 | 368 |
}() |
| 369 | 369 |
if shutdownTimeout < 0 {
|
| ... | ... |
@@ -37,8 +37,8 @@ type Backend interface {
|
| 37 | 37 |
FindNetwork(idName string) (libnetwork.Network, error) |
| 38 | 38 |
SetupIngress(clustertypes.NetworkCreateRequest, string) (<-chan struct{}, error)
|
| 39 | 39 |
ReleaseIngress() (<-chan struct{}, error)
|
| 40 |
- CreateManagedContainer(config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 41 |
- ContainerStart(name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 40 |
+ CreateManagedContainer(ctx context.Context, config types.ContainerCreateConfig) (container.CreateResponse, error) |
|
| 41 |
+ ContainerStart(ctx context.Context, name string, hostConfig *container.HostConfig, checkpoint string, checkpointDir string) error |
|
| 42 | 42 |
ContainerStop(ctx context.Context, name string, config container.StopOptions) error |
| 43 | 43 |
ContainerLogs(ctx context.Context, name string, config *types.ContainerLogsOptions) (msgs <-chan *backend.LogMessage, tty bool, err error) |
| 44 | 44 |
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error |
| ... | ... |
@@ -53,7 +53,7 @@ type Backend interface {
|
| 53 | 53 |
SetContainerSecretReferences(name string, refs []*swarm.SecretReference) error |
| 54 | 54 |
SetContainerConfigReferences(name string, refs []*swarm.ConfigReference) error |
| 55 | 55 |
SystemInfo() *types.Info |
| 56 |
- Containers(config *types.ContainerListOptions) ([]*types.Container, error) |
|
| 56 |
+ Containers(ctx context.Context, config *types.ContainerListOptions) ([]*types.Container, error) |
|
| 57 | 57 |
SetNetworkBootstrapKeys([]*networktypes.EncryptionKey) error |
| 58 | 58 |
DaemonJoinsCluster(provider cluster.Provider) |
| 59 | 59 |
DaemonLeavesCluster() |
| ... | ... |
@@ -290,7 +290,7 @@ func (c *containerAdapter) waitForDetach(ctx context.Context) error {
|
| 290 | 290 |
func (c *containerAdapter) create(ctx context.Context) error {
|
| 291 | 291 |
var cr containertypes.CreateResponse |
| 292 | 292 |
var err error |
| 293 |
- if cr, err = c.backend.CreateManagedContainer(types.ContainerCreateConfig{
|
|
| 293 |
+ if cr, err = c.backend.CreateManagedContainer(ctx, types.ContainerCreateConfig{
|
|
| 294 | 294 |
Name: c.container.name(), |
| 295 | 295 |
Config: c.container.config(), |
| 296 | 296 |
HostConfig: c.container.hostConfig(c.dependencies.Volumes()), |
| ... | ... |
@@ -357,7 +357,7 @@ func (c *containerAdapter) start(ctx context.Context) error {
|
| 357 | 357 |
return err |
| 358 | 358 |
} |
| 359 | 359 |
|
| 360 |
- return c.backend.ContainerStart(c.container.name(), nil, "", "") |
|
| 360 |
+ return c.backend.ContainerStart(ctx, c.container.name(), nil, "", "") |
|
| 361 | 361 |
} |
| 362 | 362 |
|
| 363 | 363 |
func (c *containerAdapter) inspect(ctx context.Context) (types.ContainerJSON, error) {
|
| ... | ... |
@@ -356,7 +356,7 @@ func (c *Cluster) UnlockSwarm(req types.UnlockRequest) error {
|
| 356 | 356 |
} |
| 357 | 357 |
|
| 358 | 358 |
// Leave shuts down Cluster and removes current state. |
| 359 |
-func (c *Cluster) Leave(force bool) error {
|
|
| 359 |
+func (c *Cluster) Leave(ctx context.Context, force bool) error {
|
|
| 360 | 360 |
c.controlMutex.Lock() |
| 361 | 361 |
defer c.controlMutex.Unlock() |
| 362 | 362 |
|
| ... | ... |
@@ -408,7 +408,7 @@ func (c *Cluster) Leave(force bool) error {
|
| 408 | 408 |
c.mu.Unlock() |
| 409 | 409 |
|
| 410 | 410 |
if nodeID := state.NodeID(); nodeID != "" {
|
| 411 |
- nodeContainers, err := c.listContainerForNode(nodeID) |
|
| 411 |
+ nodeContainers, err := c.listContainerForNode(ctx, nodeID) |
|
| 412 | 412 |
if err != nil {
|
| 413 | 413 |
return err |
| 414 | 414 |
} |
| ... | ... |
@@ -604,11 +604,11 @@ func initClusterSpec(node *swarmnode.Node, spec types.Spec) error {
|
| 604 | 604 |
return ctx.Err() |
| 605 | 605 |
} |
| 606 | 606 |
|
| 607 |
-func (c *Cluster) listContainerForNode(nodeID string) ([]string, error) {
|
|
| 607 |
+func (c *Cluster) listContainerForNode(ctx context.Context, nodeID string) ([]string, error) {
|
|
| 608 | 608 |
var ids []string |
| 609 | 609 |
filters := filters.NewArgs() |
| 610 | 610 |
filters.Add("label", fmt.Sprintf("com.docker.swarm.node.id=%s", nodeID))
|
| 611 |
- containers, err := c.config.Backend.Containers(&apitypes.ContainerListOptions{
|
|
| 611 |
+ containers, err := c.config.Backend.Containers(ctx, &apitypes.ContainerListOptions{
|
|
| 612 | 612 |
Filters: filters, |
| 613 | 613 |
}) |
| 614 | 614 |
if err != nil {
|
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package daemon // import "github.com/docker/docker/daemon" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"fmt" |
| 5 | 6 |
"runtime" |
| 6 | 7 |
"strings" |
| ... | ... |
@@ -116,7 +117,7 @@ func merge(userConf, imageConf *containertypes.Config) error {
|
| 116 | 116 |
// CreateImageFromContainer creates a new image from a container. The container |
| 117 | 117 |
// config will be updated by applying the change set to the custom config, then |
| 118 | 118 |
// applying that config over the existing container config. |
| 119 |
-func (daemon *Daemon) CreateImageFromContainer(name string, c *backend.CreateImageConfig) (string, error) {
|
|
| 119 |
+func (daemon *Daemon) CreateImageFromContainer(ctx context.Context, name string, c *backend.CreateImageConfig) (string, error) {
|
|
| 120 | 120 |
start := time.Now() |
| 121 | 121 |
container, err := daemon.GetContainer(name) |
| 122 | 122 |
if err != nil {
|
| ... | ... |
@@ -146,7 +147,7 @@ func (daemon *Daemon) CreateImageFromContainer(name string, c *backend.CreateIma |
| 146 | 146 |
if c.Config == nil {
|
| 147 | 147 |
c.Config = container.Config |
| 148 | 148 |
} |
| 149 |
- newConfig, err := dockerfile.BuildFromConfig(c.Config, c.Changes, container.OS) |
|
| 149 |
+ newConfig, err := dockerfile.BuildFromConfig(ctx, c.Config, c.Changes, container.OS) |
|
| 150 | 150 |
if err != nil {
|
| 151 | 151 |
return "", err |
| 152 | 152 |
} |
| ... | ... |
@@ -1,10 +1,12 @@ |
| 1 | 1 |
package containerd |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 5 |
+ |
|
| 4 | 6 |
"github.com/docker/docker/builder" |
| 5 | 7 |
) |
| 6 | 8 |
|
| 7 | 9 |
// MakeImageCache creates a stateful image cache. |
| 8 |
-func (i *ImageService) MakeImageCache(cacheFrom []string) builder.ImageCache {
|
|
| 10 |
+func (i *ImageService) MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error) {
|
|
| 9 | 11 |
panic("not implemented")
|
| 10 | 12 |
} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package containerd |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"errors" |
| 5 | 6 |
"io" |
| 6 | 7 |
|
| ... | ... |
@@ -12,6 +13,6 @@ import ( |
| 12 | 12 |
// inConfig (if src is "-"), or from a URI specified in src. Progress output is |
| 13 | 13 |
// written to outStream. Repository and tag names can optionally be given in |
| 14 | 14 |
// the repo and tag arguments, respectively. |
| 15 |
-func (i *ImageService) ImportImage(src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error {
|
|
| 15 |
+func (i *ImageService) ImportImage(ctx context.Context, src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error {
|
|
| 16 | 16 |
return errdefs.NotImplemented(errors.New("not implemented"))
|
| 17 | 17 |
} |
| ... | ... |
@@ -33,31 +33,30 @@ type createOpts struct {
|
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 | 35 |
// CreateManagedContainer creates a container that is managed by a Service |
| 36 |
-func (daemon *Daemon) CreateManagedContainer(params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 37 |
- return daemon.containerCreate(createOpts{
|
|
| 36 |
+func (daemon *Daemon) CreateManagedContainer(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 37 |
+ return daemon.containerCreate(ctx, createOpts{
|
|
| 38 | 38 |
params: params, |
| 39 | 39 |
managed: true, |
| 40 | 40 |
}) |
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 | 43 |
// ContainerCreate creates a regular container |
| 44 |
-func (daemon *Daemon) ContainerCreate(params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 45 |
- return daemon.containerCreate(createOpts{
|
|
| 44 |
+func (daemon *Daemon) ContainerCreate(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 45 |
+ return daemon.containerCreate(ctx, createOpts{
|
|
| 46 | 46 |
params: params, |
| 47 | 47 |
}) |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 | 50 |
// ContainerCreateIgnoreImagesArgsEscaped creates a regular container. This is called from the builder RUN case |
| 51 | 51 |
// and ensures that we do not take the images ArgsEscaped |
| 52 |
-func (daemon *Daemon) ContainerCreateIgnoreImagesArgsEscaped(params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 53 |
- return daemon.containerCreate(createOpts{
|
|
| 52 |
+func (daemon *Daemon) ContainerCreateIgnoreImagesArgsEscaped(ctx context.Context, params types.ContainerCreateConfig) (containertypes.CreateResponse, error) {
|
|
| 53 |
+ return daemon.containerCreate(ctx, createOpts{
|
|
| 54 | 54 |
params: params, |
| 55 | 55 |
ignoreImagesArgsEscaped: true, |
| 56 | 56 |
}) |
| 57 | 57 |
} |
| 58 | 58 |
|
| 59 |
-func (daemon *Daemon) containerCreate(opts createOpts) (containertypes.CreateResponse, error) {
|
|
| 60 |
- ctx := context.TODO() |
|
| 59 |
+func (daemon *Daemon) containerCreate(ctx context.Context, opts createOpts) (containertypes.CreateResponse, error) {
|
|
| 61 | 60 |
start := time.Now() |
| 62 | 61 |
if opts.params.Config == nil {
|
| 63 | 62 |
return containertypes.CreateResponse{}, errdefs.InvalidParameter(errors.New("Config cannot be empty in order to create a container"))
|
| ... | ... |
@@ -100,7 +99,7 @@ func (daemon *Daemon) containerCreate(opts createOpts) (containertypes.CreateRes |
| 100 | 100 |
return containertypes.CreateResponse{Warnings: warnings}, errdefs.InvalidParameter(err)
|
| 101 | 101 |
} |
| 102 | 102 |
|
| 103 |
- ctr, err := daemon.create(opts) |
|
| 103 |
+ ctr, err := daemon.create(ctx, opts) |
|
| 104 | 104 |
if err != nil {
|
| 105 | 105 |
return containertypes.CreateResponse{Warnings: warnings}, err
|
| 106 | 106 |
} |
| ... | ... |
@@ -114,8 +113,7 @@ func (daemon *Daemon) containerCreate(opts createOpts) (containertypes.CreateRes |
| 114 | 114 |
} |
| 115 | 115 |
|
| 116 | 116 |
// Create creates a new container from the given configuration with a given name. |
| 117 |
-func (daemon *Daemon) create(opts createOpts) (retC *container.Container, retErr error) {
|
|
| 118 |
- ctx := context.TODO() |
|
| 117 |
+func (daemon *Daemon) create(ctx context.Context, opts createOpts) (retC *container.Container, retErr error) {
|
|
| 119 | 118 |
var ( |
| 120 | 119 |
ctr *container.Container |
| 121 | 120 |
img *image.Image |
| ... | ... |
@@ -526,7 +526,7 @@ func (daemon *Daemon) restore() error {
|
| 526 | 526 |
if err := daemon.prepareMountPoints(c); err != nil {
|
| 527 | 527 |
log.WithError(err).Error("failed to prepare mount points for container")
|
| 528 | 528 |
} |
| 529 |
- if err := daemon.containerStart(c, "", "", true); err != nil {
|
|
| 529 |
+ if err := daemon.containerStart(context.Background(), c, "", "", true); err != nil {
|
|
| 530 | 530 |
log.WithError(err).Error("failed to start container")
|
| 531 | 531 |
} |
| 532 | 532 |
close(chNotify) |
| ... | ... |
@@ -617,7 +617,7 @@ func (daemon *Daemon) RestartSwarmContainers() {
|
| 617 | 617 |
return |
| 618 | 618 |
} |
| 619 | 619 |
|
| 620 |
- if err := daemon.containerStart(c, "", "", true); err != nil {
|
|
| 620 |
+ if err := daemon.containerStart(ctx, c, "", "", true); err != nil {
|
|
| 621 | 621 |
logrus.WithField("container", c.ID).WithError(err).Error("failed to start swarm container")
|
| 622 | 622 |
} |
| 623 | 623 |
|
| ... | ... |
@@ -775,7 +775,8 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S |
| 775 | 775 |
// initialization |
| 776 | 776 |
defer func() {
|
| 777 | 777 |
if err != nil {
|
| 778 |
- if err := d.Shutdown(); err != nil {
|
|
| 778 |
+ // Use a fresh context here. Passed context could be cancelled. |
|
| 779 |
+ if err := d.Shutdown(context.Background()); err != nil {
|
|
| 779 | 780 |
logrus.Error(err) |
| 780 | 781 |
} |
| 781 | 782 |
} |
| ... | ... |
@@ -1193,17 +1194,17 @@ func (daemon *Daemon) ShutdownTimeout() int {
|
| 1193 | 1193 |
} |
| 1194 | 1194 |
|
| 1195 | 1195 |
// Shutdown stops the daemon. |
| 1196 |
-func (daemon *Daemon) Shutdown() error {
|
|
| 1196 |
+func (daemon *Daemon) Shutdown(ctx context.Context) error {
|
|
| 1197 | 1197 |
daemon.shutdown = true |
| 1198 | 1198 |
// Keep mounts and networking running on daemon shutdown if |
| 1199 | 1199 |
// we are to keep containers running and restore them. |
| 1200 | 1200 |
|
| 1201 | 1201 |
if daemon.configStore.LiveRestoreEnabled && daemon.containers != nil {
|
| 1202 | 1202 |
// check if there are any running containers, if none we should do some cleanup |
| 1203 |
- if ls, err := daemon.Containers(&types.ContainerListOptions{}); len(ls) != 0 || err != nil {
|
|
| 1203 |
+ if ls, err := daemon.Containers(ctx, &types.ContainerListOptions{}); len(ls) != 0 || err != nil {
|
|
| 1204 | 1204 |
// metrics plugins still need some cleanup |
| 1205 | 1205 |
daemon.cleanupMetricsPlugins() |
| 1206 |
- return nil |
|
| 1206 |
+ return err |
|
| 1207 | 1207 |
} |
| 1208 | 1208 |
} |
| 1209 | 1209 |
|
| ... | ... |
@@ -14,7 +14,7 @@ import ( |
| 14 | 14 |
func (daemon *Daemon) ContainerDiskUsage(ctx context.Context) ([]*types.Container, error) {
|
| 15 | 15 |
ch := daemon.usage.DoChan("ContainerDiskUsage", func() (interface{}, error) {
|
| 16 | 16 |
// Retrieve container list |
| 17 |
- containers, err := daemon.Containers(&types.ContainerListOptions{
|
|
| 17 |
+ containers, err := daemon.Containers(context.TODO(), &types.ContainerListOptions{
|
|
| 18 | 18 |
Size: true, |
| 19 | 19 |
All: true, |
| 20 | 20 |
}) |
| ... | ... |
@@ -37,7 +37,7 @@ type ImageService interface {
|
| 37 | 37 |
CountImages() int |
| 38 | 38 |
ImageDiskUsage(ctx context.Context) ([]*types.ImageSummary, error) |
| 39 | 39 |
ImagesPrune(ctx context.Context, pruneFilters filters.Args) (*types.ImagesPruneReport, error) |
| 40 |
- ImportImage(src string, repository string, platform *v1.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error |
|
| 40 |
+ ImportImage(ctx context.Context, src string, repository string, platform *v1.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error |
|
| 41 | 41 |
TagImage(imageName, repository, tag string) (string, error) |
| 42 | 42 |
TagImageWithReference(imageID image.ID, newTag reference.Named) error |
| 43 | 43 |
GetImage(ctx context.Context, refOrID string, options imagetype.GetImageOpts) (*image.Image, error) |
| ... | ... |
@@ -62,7 +62,7 @@ type ImageService interface {
|
| 62 | 62 |
|
| 63 | 63 |
// Build |
| 64 | 64 |
|
| 65 |
- MakeImageCache(sourceRefs []string) builder.ImageCache |
|
| 65 |
+ MakeImageCache(ctx context.Context, cacheFrom []string) (builder.ImageCache, error) |
|
| 66 | 66 |
CommitBuildStep(c backend.CommitConfig) (image.ID, error) |
| 67 | 67 |
|
| 68 | 68 |
// Other |
| ... | ... |
@@ -6,14 +6,14 @@ import ( |
| 6 | 6 |
imagetypes "github.com/docker/docker/api/types/image" |
| 7 | 7 |
"github.com/docker/docker/builder" |
| 8 | 8 |
"github.com/docker/docker/image/cache" |
| 9 |
+ "github.com/pkg/errors" |
|
| 9 | 10 |
"github.com/sirupsen/logrus" |
| 10 | 11 |
) |
| 11 | 12 |
|
| 12 | 13 |
// MakeImageCache creates a stateful image cache. |
| 13 |
-func (i *ImageService) MakeImageCache(sourceRefs []string) builder.ImageCache {
|
|
| 14 |
- ctx := context.TODO() |
|
| 14 |
+func (i *ImageService) MakeImageCache(ctx context.Context, sourceRefs []string) (builder.ImageCache, error) {
|
|
| 15 | 15 |
if len(sourceRefs) == 0 {
|
| 16 |
- return cache.NewLocal(i.imageStore) |
|
| 16 |
+ return cache.NewLocal(i.imageStore), nil |
|
| 17 | 17 |
} |
| 18 | 18 |
|
| 19 | 19 |
cache := cache.New(i.imageStore) |
| ... | ... |
@@ -21,11 +21,14 @@ func (i *ImageService) MakeImageCache(sourceRefs []string) builder.ImageCache {
|
| 21 | 21 |
for _, ref := range sourceRefs {
|
| 22 | 22 |
img, err := i.GetImage(ctx, ref, imagetypes.GetImageOpts{})
|
| 23 | 23 |
if err != nil {
|
| 24 |
+ if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
|
|
| 25 |
+ return nil, err |
|
| 26 |
+ } |
|
| 24 | 27 |
logrus.Warnf("Could not look up %s for cache resolution, skipping: %+v", ref, err)
|
| 25 | 28 |
continue |
| 26 | 29 |
} |
| 27 | 30 |
cache.Populate(img) |
| 28 | 31 |
} |
| 29 | 32 |
|
| 30 |
- return cache |
|
| 33 |
+ return cache, nil |
|
| 31 | 34 |
} |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package images // import "github.com/docker/docker/daemon/images" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"encoding/json" |
| 5 | 6 |
"io" |
| 6 | 7 |
"net/http" |
| ... | ... |
@@ -29,7 +30,7 @@ import ( |
| 29 | 29 |
// inConfig (if src is "-"), or from a URI specified in src. Progress output is |
| 30 | 30 |
// written to outStream. Repository and tag names can optionally be given in |
| 31 | 31 |
// the repo and tag arguments, respectively. |
| 32 |
-func (i *ImageService) ImportImage(src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error {
|
|
| 32 |
+func (i *ImageService) ImportImage(ctx context.Context, src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error {
|
|
| 33 | 33 |
var ( |
| 34 | 34 |
rc io.ReadCloser |
| 35 | 35 |
resp *http.Response |
| ... | ... |
@@ -62,7 +63,7 @@ func (i *ImageService) ImportImage(src string, repository string, platform *spec |
| 62 | 62 |
if !system.IsOSSupported(platform.OS) {
|
| 63 | 63 |
return errdefs.InvalidParameter(system.ErrNotSupportedOperatingSystem) |
| 64 | 64 |
} |
| 65 |
- config, err := dockerfile.BuildFromConfig(&container.Config{}, changes, platform.OS)
|
|
| 65 |
+ config, err := dockerfile.BuildFromConfig(ctx, &container.Config{}, changes, platform.OS)
|
|
| 66 | 66 |
if err != nil {
|
| 67 | 67 |
return err |
| 68 | 68 |
} |
| ... | ... |
@@ -42,7 +42,7 @@ type iterationAction int |
| 42 | 42 |
|
| 43 | 43 |
// containerReducer represents a reducer for a container. |
| 44 | 44 |
// Returns the object to serialize by the api. |
| 45 |
-type containerReducer func(*container.Snapshot, *listContext) (*types.Container, error) |
|
| 45 |
+type containerReducer func(context.Context, *container.Snapshot, *listContext) (*types.Container, error) |
|
| 46 | 46 |
|
| 47 | 47 |
const ( |
| 48 | 48 |
// includeContainer is the action to include a container in the reducer. |
| ... | ... |
@@ -106,8 +106,8 @@ func (r byCreatedDescending) Less(i, j int) bool {
|
| 106 | 106 |
} |
| 107 | 107 |
|
| 108 | 108 |
// Containers returns the list of containers to show given the user's filtering. |
| 109 |
-func (daemon *Daemon) Containers(config *types.ContainerListOptions) ([]*types.Container, error) {
|
|
| 110 |
- return daemon.reduceContainers(config, daemon.refreshImage) |
|
| 109 |
+func (daemon *Daemon) Containers(ctx context.Context, config *types.ContainerListOptions) ([]*types.Container, error) {
|
|
| 110 |
+ return daemon.reduceContainers(ctx, config, daemon.refreshImage) |
|
| 111 | 111 |
} |
| 112 | 112 |
|
| 113 | 113 |
func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listContext) ([]container.Snapshot, error) {
|
| ... | ... |
@@ -177,7 +177,7 @@ func (daemon *Daemon) filterByNameIDMatches(view *container.View, filter *listCo |
| 177 | 177 |
} |
| 178 | 178 |
|
| 179 | 179 |
// reduceContainers parses the user's filtering options and generates the list of containers to return based on a reducer. |
| 180 |
-func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reducer containerReducer) ([]*types.Container, error) {
|
|
| 180 |
+func (daemon *Daemon) reduceContainers(ctx context.Context, config *types.ContainerListOptions, reducer containerReducer) ([]*types.Container, error) {
|
|
| 181 | 181 |
if err := config.Filters.Validate(acceptedPsFilterTags); err != nil {
|
| 182 | 182 |
return nil, err |
| 183 | 183 |
} |
| ... | ... |
@@ -187,7 +187,7 @@ func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reduc |
| 187 | 187 |
containers = []*types.Container{}
|
| 188 | 188 |
) |
| 189 | 189 |
|
| 190 |
- filter, err := daemon.foldFilter(view, config) |
|
| 190 |
+ filter, err := daemon.foldFilter(ctx, view, config) |
|
| 191 | 191 |
if err != nil {
|
| 192 | 192 |
return nil, err |
| 193 | 193 |
} |
| ... | ... |
@@ -201,7 +201,7 @@ func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reduc |
| 201 | 201 |
} |
| 202 | 202 |
|
| 203 | 203 |
for i := range containerList {
|
| 204 |
- t, err := daemon.reducePsContainer(&containerList[i], filter, reducer) |
|
| 204 |
+ t, err := daemon.reducePsContainer(ctx, &containerList[i], filter, reducer) |
|
| 205 | 205 |
if err != nil {
|
| 206 | 206 |
if err != errStopIteration {
|
| 207 | 207 |
return nil, err |
| ... | ... |
@@ -218,7 +218,7 @@ func (daemon *Daemon) reduceContainers(config *types.ContainerListOptions, reduc |
| 218 | 218 |
} |
| 219 | 219 |
|
| 220 | 220 |
// reducePsContainer is the basic representation for a container as expected by the ps command. |
| 221 |
-func (daemon *Daemon) reducePsContainer(container *container.Snapshot, filter *listContext, reducer containerReducer) (*types.Container, error) {
|
|
| 221 |
+func (daemon *Daemon) reducePsContainer(ctx context.Context, container *container.Snapshot, filter *listContext, reducer containerReducer) (*types.Container, error) {
|
|
| 222 | 222 |
// filter containers to return |
| 223 | 223 |
switch includeContainerInList(container, filter) {
|
| 224 | 224 |
case excludeContainer: |
| ... | ... |
@@ -228,7 +228,7 @@ func (daemon *Daemon) reducePsContainer(container *container.Snapshot, filter *l |
| 228 | 228 |
} |
| 229 | 229 |
|
| 230 | 230 |
// transform internal container struct into api structs |
| 231 |
- newC, err := reducer(container, filter) |
|
| 231 |
+ newC, err := reducer(ctx, container, filter) |
|
| 232 | 232 |
if err != nil {
|
| 233 | 233 |
return nil, err |
| 234 | 234 |
} |
| ... | ... |
@@ -243,8 +243,7 @@ func (daemon *Daemon) reducePsContainer(container *container.Snapshot, filter *l |
| 243 | 243 |
} |
| 244 | 244 |
|
| 245 | 245 |
// foldFilter generates the container filter based on the user's filtering options. |
| 246 |
-func (daemon *Daemon) foldFilter(view *container.View, config *types.ContainerListOptions) (*listContext, error) {
|
|
| 247 |
- ctx := context.TODO() |
|
| 246 |
+func (daemon *Daemon) foldFilter(ctx context.Context, view *container.View, config *types.ContainerListOptions) (*listContext, error) {
|
|
| 248 | 247 |
psFilters := config.Filters |
| 249 | 248 |
|
| 250 | 249 |
var filtExited []int |
| ... | ... |
@@ -580,8 +579,7 @@ func includeContainerInList(container *container.Snapshot, filter *listContext) |
| 580 | 580 |
} |
| 581 | 581 |
|
| 582 | 582 |
// refreshImage checks if the Image ref still points to the correct ID, and updates the ref to the actual ID when it doesn't |
| 583 |
-func (daemon *Daemon) refreshImage(s *container.Snapshot, filter *listContext) (*types.Container, error) {
|
|
| 584 |
- ctx := context.TODO() |
|
| 583 |
+func (daemon *Daemon) refreshImage(ctx context.Context, s *container.Snapshot, filter *listContext) (*types.Container, error) {
|
|
| 585 | 584 |
c := s.Container |
| 586 | 585 |
tmpImage := s.Image // keep the original ref if still valid (hasn't changed) |
| 587 | 586 |
if tmpImage != s.ImageID {
|
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package daemon |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"os" |
| 5 | 6 |
"path/filepath" |
| 6 | 7 |
"testing" |
| ... | ... |
@@ -88,7 +89,7 @@ func TestListInvalidFilter(t *testing.T) {
|
| 88 | 88 |
|
| 89 | 89 |
f := filters.NewArgs(filters.Arg("invalid", "foo"))
|
| 90 | 90 |
|
| 91 |
- _, err = d.Containers(&types.ContainerListOptions{
|
|
| 91 |
+ _, err = d.Containers(context.Background(), &types.ContainerListOptions{
|
|
| 92 | 92 |
Filters: f, |
| 93 | 93 |
}) |
| 94 | 94 |
assert.Assert(t, is.Error(err, "invalid filter 'invalid'")) |
| ... | ... |
@@ -109,7 +110,7 @@ func TestNameFilter(t *testing.T) {
|
| 109 | 109 |
|
| 110 | 110 |
// moby/moby #37453 - ^ regex not working due to prefix slash |
| 111 | 111 |
// not being stripped |
| 112 |
- containerList, err := d.Containers(&types.ContainerListOptions{
|
|
| 112 |
+ containerList, err := d.Containers(context.Background(), &types.ContainerListOptions{
|
|
| 113 | 113 |
Filters: filters.NewArgs(filters.Arg("name", "^a")),
|
| 114 | 114 |
}) |
| 115 | 115 |
assert.NilError(t, err) |
| ... | ... |
@@ -118,7 +119,7 @@ func TestNameFilter(t *testing.T) {
|
| 118 | 118 |
assert.Assert(t, containerListContainsName(containerList, two.Name)) |
| 119 | 119 |
|
| 120 | 120 |
// Same as above but with slash prefix should produce the same result |
| 121 |
- containerListWithPrefix, err := d.Containers(&types.ContainerListOptions{
|
|
| 121 |
+ containerListWithPrefix, err := d.Containers(context.Background(), &types.ContainerListOptions{
|
|
| 122 | 122 |
Filters: filters.NewArgs(filters.Arg("name", "^/a")),
|
| 123 | 123 |
}) |
| 124 | 124 |
assert.NilError(t, err) |
| ... | ... |
@@ -127,7 +128,7 @@ func TestNameFilter(t *testing.T) {
|
| 127 | 127 |
assert.Assert(t, containerListContainsName(containerListWithPrefix, two.Name)) |
| 128 | 128 |
|
| 129 | 129 |
// Same as above but make sure it works for exact names |
| 130 |
- containerList, err = d.Containers(&types.ContainerListOptions{
|
|
| 130 |
+ containerList, err = d.Containers(context.Background(), &types.ContainerListOptions{
|
|
| 131 | 131 |
Filters: filters.NewArgs(filters.Arg("name", "b1")),
|
| 132 | 132 |
}) |
| 133 | 133 |
assert.NilError(t, err) |
| ... | ... |
@@ -135,7 +136,7 @@ func TestNameFilter(t *testing.T) {
|
| 135 | 135 |
assert.Assert(t, containerListContainsName(containerList, three.Name)) |
| 136 | 136 |
|
| 137 | 137 |
// Same as above but with slash prefix should produce the same result |
| 138 |
- containerListWithPrefix, err = d.Containers(&types.ContainerListOptions{
|
|
| 138 |
+ containerListWithPrefix, err = d.Containers(context.Background(), &types.ContainerListOptions{
|
|
| 139 | 139 |
Filters: filters.NewArgs(filters.Arg("name", "/b1")),
|
| 140 | 140 |
}) |
| 141 | 141 |
assert.NilError(t, err) |
| ... | ... |
@@ -111,7 +111,7 @@ func (daemon *Daemon) handleContainerExit(c *container.Container, e *libcontaine |
| 111 | 111 |
// But containerStart will use daemon.netController segment. |
| 112 | 112 |
// So to avoid panic at startup process, here must wait util daemon restore done. |
| 113 | 113 |
daemon.waitForStartupDone() |
| 114 |
- if err = daemon.containerStart(c, "", "", false); err != nil {
|
|
| 114 |
+ if err = daemon.containerStart(context.Background(), c, "", "", false); err != nil {
|
|
| 115 | 115 |
logrus.Debugf("failed to restart container: %+v", err)
|
| 116 | 116 |
} |
| 117 | 117 |
} |
| ... | ... |
@@ -1007,7 +1007,7 @@ func WithUser(c *container.Container) coci.SpecOpts {
|
| 1007 | 1007 |
} |
| 1008 | 1008 |
} |
| 1009 | 1009 |
|
| 1010 |
-func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, err error) {
|
|
| 1010 |
+func (daemon *Daemon) createSpec(ctx context.Context, c *container.Container) (retSpec *specs.Spec, err error) {
|
|
| 1011 | 1011 |
var ( |
| 1012 | 1012 |
opts []coci.SpecOpts |
| 1013 | 1013 |
s = oci.DefaultSpec() |
| ... | ... |
@@ -1052,7 +1052,7 @@ func (daemon *Daemon) createSpec(c *container.Container) (retSpec *specs.Spec, e |
| 1052 | 1052 |
snapshotKey = c.ID |
| 1053 | 1053 |
} |
| 1054 | 1054 |
|
| 1055 |
- return &s, coci.ApplyOpts(context.Background(), nil, &containers.Container{
|
|
| 1055 |
+ return &s, coci.ApplyOpts(ctx, nil, &containers.Container{
|
|
| 1056 | 1056 |
ID: c.ID, |
| 1057 | 1057 |
Snapshotter: snapshotter, |
| 1058 | 1058 |
SnapshotKey: snapshotKey, |
| ... | ... |
@@ -1,6 +1,7 @@ |
| 1 | 1 |
package daemon // import "github.com/docker/docker/daemon" |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
+ "context" |
|
| 4 | 5 |
"os" |
| 5 | 6 |
"path/filepath" |
| 6 | 7 |
"testing" |
| ... | ... |
@@ -73,7 +74,7 @@ func TestTmpfsDevShmNoDupMount(t *testing.T) {
|
| 73 | 73 |
d := setupFakeDaemon(t, c) |
| 74 | 74 |
defer cleanupFakeContainer(c) |
| 75 | 75 |
|
| 76 |
- _, err := d.createSpec(c) |
|
| 76 |
+ _, err := d.createSpec(context.TODO(), c) |
|
| 77 | 77 |
assert.Check(t, err) |
| 78 | 78 |
} |
| 79 | 79 |
|
| ... | ... |
@@ -92,7 +93,7 @@ func TestIpcPrivateVsReadonly(t *testing.T) {
|
| 92 | 92 |
d := setupFakeDaemon(t, c) |
| 93 | 93 |
defer cleanupFakeContainer(c) |
| 94 | 94 |
|
| 95 |
- s, err := d.createSpec(c) |
|
| 95 |
+ s, err := d.createSpec(context.TODO(), c) |
|
| 96 | 96 |
assert.Check(t, err) |
| 97 | 97 |
|
| 98 | 98 |
// Find the /dev/shm mount in ms, check it does not have ro |
| ... | ... |
@@ -122,7 +123,7 @@ func TestSysctlOverride(t *testing.T) {
|
| 122 | 122 |
defer cleanupFakeContainer(c) |
| 123 | 123 |
|
| 124 | 124 |
// Ensure that the implicit sysctl is set correctly. |
| 125 |
- s, err := d.createSpec(c) |
|
| 125 |
+ s, err := d.createSpec(context.TODO(), c) |
|
| 126 | 126 |
assert.NilError(t, err) |
| 127 | 127 |
assert.Equal(t, s.Hostname, "foobar") |
| 128 | 128 |
assert.Equal(t, s.Linux.Sysctl["kernel.domainname"], c.Config.Domainname) |
| ... | ... |
@@ -138,7 +139,7 @@ func TestSysctlOverride(t *testing.T) {
|
| 138 | 138 |
assert.Assert(t, c.HostConfig.Sysctls["kernel.domainname"] != c.Config.Domainname) |
| 139 | 139 |
c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"] = "1024" |
| 140 | 140 |
|
| 141 |
- s, err = d.createSpec(c) |
|
| 141 |
+ s, err = d.createSpec(context.TODO(), c) |
|
| 142 | 142 |
assert.NilError(t, err) |
| 143 | 143 |
assert.Equal(t, s.Hostname, "foobar") |
| 144 | 144 |
assert.Equal(t, s.Linux.Sysctl["kernel.domainname"], c.HostConfig.Sysctls["kernel.domainname"]) |
| ... | ... |
@@ -146,7 +147,7 @@ func TestSysctlOverride(t *testing.T) {
|
| 146 | 146 |
|
| 147 | 147 |
// Ensure the ping_group_range is not set on a daemon with user-namespaces enabled |
| 148 | 148 |
d.configStore.RemappedRoot = "dummy:dummy" |
| 149 |
- s, err = d.createSpec(c) |
|
| 149 |
+ s, err = d.createSpec(context.TODO(), c) |
|
| 150 | 150 |
assert.NilError(t, err) |
| 151 | 151 |
_, ok := s.Linux.Sysctl["net.ipv4.ping_group_range"] |
| 152 | 152 |
assert.Assert(t, !ok) |
| ... | ... |
@@ -154,7 +155,7 @@ func TestSysctlOverride(t *testing.T) {
|
| 154 | 154 |
// Ensure the ping_group_range is set on a container in "host" userns mode |
| 155 | 155 |
// on a daemon with user-namespaces enabled |
| 156 | 156 |
c.HostConfig.UsernsMode = "host" |
| 157 |
- s, err = d.createSpec(c) |
|
| 157 |
+ s, err = d.createSpec(context.TODO(), c) |
|
| 158 | 158 |
assert.NilError(t, err) |
| 159 | 159 |
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "0 2147483647") |
| 160 | 160 |
} |
| ... | ... |
@@ -174,7 +175,7 @@ func TestSysctlOverrideHost(t *testing.T) {
|
| 174 | 174 |
defer cleanupFakeContainer(c) |
| 175 | 175 |
|
| 176 | 176 |
// Ensure that the implicit sysctl is not set |
| 177 |
- s, err := d.createSpec(c) |
|
| 177 |
+ s, err := d.createSpec(context.TODO(), c) |
|
| 178 | 178 |
assert.NilError(t, err) |
| 179 | 179 |
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], "") |
| 180 | 180 |
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ping_group_range"], "") |
| ... | ... |
@@ -182,7 +183,7 @@ func TestSysctlOverrideHost(t *testing.T) {
|
| 182 | 182 |
// Set an explicit sysctl. |
| 183 | 183 |
c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"] = "1024" |
| 184 | 184 |
|
| 185 |
- s, err = d.createSpec(c) |
|
| 185 |
+ s, err = d.createSpec(context.TODO(), c) |
|
| 186 | 186 |
assert.NilError(t, err) |
| 187 | 187 |
assert.Equal(t, s.Linux.Sysctl["net.ipv4.ip_unprivileged_port_start"], c.HostConfig.Sysctls["net.ipv4.ip_unprivileged_port_start"]) |
| 188 | 188 |
} |
| ... | ... |
@@ -26,8 +26,7 @@ const ( |
| 26 | 26 |
credentialSpecFileLocation = "CredentialSpecs" |
| 27 | 27 |
) |
| 28 | 28 |
|
| 29 |
-func (daemon *Daemon) createSpec(c *container.Container) (*specs.Spec, error) {
|
|
| 30 |
- ctx := context.TODO() |
|
| 29 |
+func (daemon *Daemon) createSpec(ctx context.Context, c *container.Container) (*specs.Spec, error) {
|
|
| 31 | 30 |
img, err := daemon.imageService.GetImage(ctx, string(c.ImageID), imagetypes.GetImageOpts{})
|
| 32 | 31 |
if err != nil {
|
| 33 | 32 |
return nil, err |
| ... | ... |
@@ -61,7 +61,7 @@ func (daemon *Daemon) containerRestart(ctx context.Context, container *container |
| 61 | 61 |
} |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
- if err := daemon.containerStart(container, "", "", true); err != nil {
|
|
| 64 |
+ if err := daemon.containerStart(ctx, container, "", "", true); err != nil {
|
|
| 65 | 65 |
return err |
| 66 | 66 |
} |
| 67 | 67 |
|
| ... | ... |
@@ -15,7 +15,7 @@ import ( |
| 15 | 15 |
) |
| 16 | 16 |
|
| 17 | 17 |
// ContainerStart starts a container. |
| 18 |
-func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
|
|
| 18 |
+func (daemon *Daemon) ContainerStart(ctx context.Context, name string, hostConfig *containertypes.HostConfig, checkpoint string, checkpointDir string) error {
|
|
| 19 | 19 |
if checkpoint != "" && !daemon.HasExperimental() {
|
| 20 | 20 |
return errdefs.InvalidParameter(errors.New("checkpoint is only supported in experimental mode"))
|
| 21 | 21 |
} |
| ... | ... |
@@ -92,14 +92,14 @@ func (daemon *Daemon) ContainerStart(name string, hostConfig *containertypes.Hos |
| 92 | 92 |
return errdefs.InvalidParameter(err) |
| 93 | 93 |
} |
| 94 | 94 |
} |
| 95 |
- return daemon.containerStart(ctr, checkpoint, checkpointDir, true) |
|
| 95 |
+ return daemon.containerStart(ctx, ctr, checkpoint, checkpointDir, true) |
|
| 96 | 96 |
} |
| 97 | 97 |
|
| 98 | 98 |
// containerStart prepares the container to run by setting up everything the |
| 99 | 99 |
// container needs, such as storage and networking, as well as links |
| 100 | 100 |
// between containers. The container is left waiting for a signal to |
| 101 | 101 |
// begin running. |
| 102 |
-func (daemon *Daemon) containerStart(container *container.Container, checkpoint string, checkpointDir string, resetRestartManager bool) (err error) {
|
|
| 102 |
+func (daemon *Daemon) containerStart(ctx context.Context, container *container.Container, checkpoint string, checkpointDir string, resetRestartManager bool) (err error) {
|
|
| 103 | 103 |
start := time.Now() |
| 104 | 104 |
container.Lock() |
| 105 | 105 |
defer container.Unlock() |
| ... | ... |
@@ -151,7 +151,7 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint |
| 151 | 151 |
return err |
| 152 | 152 |
} |
| 153 | 153 |
|
| 154 |
- spec, err := daemon.createSpec(container) |
|
| 154 |
+ spec, err := daemon.createSpec(ctx, container) |
|
| 155 | 155 |
if err != nil {
|
| 156 | 156 |
return errdefs.System(err) |
| 157 | 157 |
} |
| ... | ... |
@@ -177,8 +177,6 @@ func (daemon *Daemon) containerStart(container *container.Container, checkpoint |
| 177 | 177 |
return err |
| 178 | 178 |
} |
| 179 | 179 |
|
| 180 |
- ctx := context.TODO() |
|
| 181 |
- |
|
| 182 | 180 |
ctr, err := libcontainerd.ReplaceContainer(ctx, daemon.containerd, container.ID, spec, shim, createOptions) |
| 183 | 181 |
if err != nil {
|
| 184 | 182 |
return translateContainerdStartErr(container.Path, container.SetExitCode, err) |