diff --git a/pkg/api/dryrunclient.go b/pkg/api/dryrunclient.go index 0fd989320..9580f2553 100644 --- a/pkg/api/dryrunclient.go +++ b/pkg/api/dryrunclient.go @@ -58,9 +58,10 @@ type DryRunKey struct{} // DryRunClient implements APIClient by delegating to implementation functions. This allows lazy init and per-method overrides type DryRunClient struct { - apiClient client.APIClient - execs sync.Map - resolver *imagetools.Resolver + apiClient client.APIClient + containers []moby.Container + execs sync.Map + resolver *imagetools.Resolver } type execDetails struct { @@ -79,9 +80,10 @@ func NewDryRunClient(apiClient client.APIClient, cli *command.DockerCli) (*DryRu return nil, err } return &DryRunClient{ - apiClient: apiClient, - execs: sync.Map{}, - resolver: imagetools.New(configFile), + apiClient: apiClient, + containers: []moby.Container{}, + execs: sync.Map{}, + resolver: imagetools.New(configFile), }, nil } @@ -99,15 +101,36 @@ func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, op func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string) (containerType.CreateResponse, error) { - return containerType.CreateResponse{ID: "dryRunId"}, nil + d.containers = append(d.containers, moby.Container{ + ID: containerName, + Names: []string{containerName}, + Labels: config.Labels, + HostConfig: struct { + NetworkMode string `json:",omitempty"` + }{}, + }) + return containerType.CreateResponse{ID: containerName}, nil } func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (moby.ContainerJSON, error) { containerJSON, err := d.apiClient.ContainerInspect(ctx, container) if err != nil { + id := "dryRunId" + for _, c := range d.containers { + if c.ID == container { + id = container + } + } return moby.ContainerJSON{ ContainerJSONBase: &moby.ContainerJSONBase{ - ID: "dryRunId", + ID: id, + Name: container, + State: &moby.ContainerState{ + Status: "running", // needed for --wait option + Health: &moby.Health{ + Status: moby.Healthy, // needed for healthcheck control + }, + }, }, Mounts: nil, Config: &containerType.Config{}, @@ -121,6 +144,21 @@ func (d *DryRunClient) ContainerKill(ctx context.Context, container, signal stri return nil } +func (d *DryRunClient) ContainerList(ctx context.Context, options moby.ContainerListOptions) ([]moby.Container, error) { + caller := getCallingFunction() + switch caller { + case "start": + return d.containers, nil + case "getContainers": + if len(d.containers) == 0 { + var err error + d.containers, err = d.apiClient.ContainerList(ctx, options) + return d.containers, err + } + } + return d.apiClient.ContainerList(ctx, options) +} + func (d *DryRunClient) ContainerPause(ctx context.Context, container string) error { return nil } @@ -246,7 +284,13 @@ func (d *DryRunClient) NetworkRemove(ctx context.Context, networkName string) er } func (d *DryRunClient) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) { - return volume.Volume{}, ErrNotImplemented + return volume.Volume{ + ClusterVolume: nil, + Driver: options.Driver, + Labels: options.Labels, + Name: options.Name, + Options: options.DriverOpts, + }, nil } func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, force bool) error { @@ -324,10 +368,6 @@ func (d *DryRunClient) ContainerInspectWithRaw(ctx context.Context, container st return d.apiClient.ContainerInspectWithRaw(ctx, container, getSize) } -func (d *DryRunClient) ContainerList(ctx context.Context, options moby.ContainerListOptions) ([]moby.Container, error) { - return d.apiClient.ContainerList(ctx, options) -} - func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options moby.ContainerLogsOptions) (io.ReadCloser, error) { return d.apiClient.ContainerLogs(ctx, container, options) } diff --git a/pkg/compose/up.go b/pkg/compose/up.go index d051e0deb..a90f0a19d 100644 --- a/pkg/compose/up.go +++ b/pkg/compose/up.go @@ -48,6 +48,10 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options if options.Start.Attach == nil { return err } + if s.dryRun { + fmt.Fprintln(s.stdout(), "end of 'compose up' output, interactive run is not supported in dry-run mode") + return err + } printer := newLogPrinter(options.Start.Attach)