Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add dry-run support to create command #10413

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions pkg/api/dryrunclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"io"
"net"
"net/http"
"runtime"
"strings"
"sync"

Expand Down Expand Up @@ -84,6 +85,12 @@ func NewDryRunClient(apiClient client.APIClient, cli *command.DockerCli) (*DryRu
}, nil
}

func getCallingFunction() string {
pc, _, _, _ := runtime.Caller(2)
fullName := runtime.FuncForPC(pc).Name()
return fullName[strings.LastIndex(fullName, ".")+1:]
}

// All methods and functions which need to be overridden for dry run.

func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options moby.ContainerAttachOptions) (moby.HijackedResponse, error) {
Expand Down Expand Up @@ -162,7 +169,14 @@ func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options
}

func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (moby.ImageInspect, []byte, error) {
return moby.ImageInspect{ID: "dryRunId"}, nil, nil
caller := getCallingFunction()
switch caller {
case "pullServiceImage", "buildContainerVolumes":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like a fragile solution to distinguish usages, but I guess we don't have a better option :'(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but as we can't change the interface signature and we don't want to apply the same behaviour depending of the parent context, this was the first solution in my mind.
I can try to use a wrapper function to call ImageInspectWithRaw instead, wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder: would it make sense we pass the top-level command being ran as a Context.Value so it make it easier to distinguish usages?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not enough for example if you run the create command, the ImageInspectWithRaw function will be call multiple times, first to check if the image is present locally, so we want to get an error if the image doesn't exists to trigger a pull and after the pull (and this time we don't want to fail because we just faked the pull)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice... which seems to demonstrate some design issue to be fixed, as we should not require a second call after pull :P
anyway, go for it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the second call is here to very the pull was correctly done, kind of double check protection in some way

return moby.ImageInspect{ID: "dryRunId"}, nil, nil
default:
return d.apiClient.ImageInspectWithRaw(ctx, imageName)
}

}

func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options moby.ImagePullOptions) (io.ReadCloser, error) {
Expand Down Expand Up @@ -204,7 +218,10 @@ func (d *DryRunClient) NetworkConnect(ctx context.Context, networkName, containe
}

func (d *DryRunClient) NetworkCreate(ctx context.Context, name string, options moby.NetworkCreate) (moby.NetworkCreateResponse, error) {
return moby.NetworkCreateResponse{}, ErrNotImplemented
return moby.NetworkCreateResponse{
ID: name,
Warning: "",
}, nil
}

func (d *DryRunClient) NetworkDisconnect(ctx context.Context, networkName, container string, force bool) error {
Expand Down
10 changes: 10 additions & 0 deletions pkg/compose/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ func (s *composeService) build(ctx context.Context, project *types.Project, opti
return nil
}

//TODO:glours - condition to be removed when dry-run support of build will be implemented.
if s.dryRun {
builder := "buildkit"
if !buildkitEnabled {
builder = "legacy builder"
}
fmt.Printf("%sBuilding image %s with %s\n", api.DRYRUN_PREFIX, service.Image, builder)
return nil
}

if !buildkitEnabled {
service.Build.Args = service.Build.Args.OverrideBy(args)
id, err := s.doBuildClassic(ctx, service)
Expand Down