Skip to content

Commit

Permalink
Changes build opt name to lifecycle-docker-host
Browse files Browse the repository at this point in the history
- Previous name docker-host was confusing (Issue: 1093) and the name is best left for an eventual equivalent to `docker --host` https://docs.docker.com/engine/reference/commandline/cli/#:~:text=host%20value
- Validate mutual excluson of publish and lifecycle-docker-host

Signed-off-by: Micah Young <[email protected]>
  • Loading branch information
Micah Young committed Mar 15, 2021
1 parent 11b0a1f commit 6d11343
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 78 deletions.
44 changes: 22 additions & 22 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ type BuildOptions struct {
// built atop.
RunImage string

// Address of docker daemon exposed to build container
// e.g. tcp://example.com:1234, unix:///run/user/1000/podman/podman.sock
DockerHost string
// Address of docker daemon exposed to lifecycle in the build container
// e.g. host-socket, inherit, tcp://example.com:1234, unix:///run/user/1000/podman/podman.sock
LifecycleDockerHost string

// Used to determine a run-image mirror if Run Image is empty.
// Used in combination with Builder metadata to determine to the the 'best' mirror.
Expand Down Expand Up @@ -284,25 +284,25 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
}

lifecycleOpts := build.LifecycleOptions{
AppPath: appPath,
Image: imageRef,
Builder: ephemeralBuilder,
RunImage: runImageName,
ClearCache: opts.ClearCache,
Publish: opts.Publish,
DockerHost: opts.DockerHost,
UseCreator: false,
TrustBuilder: opts.TrustBuilder,
LifecycleImage: ephemeralBuilder.Name(),
HTTPProxy: proxyConfig.HTTPProxy,
HTTPSProxy: proxyConfig.HTTPSProxy,
NoProxy: proxyConfig.NoProxy,
Network: opts.ContainerConfig.Network,
AdditionalTags: opts.AdditionalTags,
Volumes: processedVolumes,
DefaultProcessType: opts.DefaultProcessType,
FileFilter: fileFilter,
CacheImage: opts.CacheImage,
AppPath: appPath,
Image: imageRef,
Builder: ephemeralBuilder,
RunImage: runImageName,
ClearCache: opts.ClearCache,
Publish: opts.Publish,
UseCreator: false,
TrustBuilder: opts.TrustBuilder,
HTTPProxy: proxyConfig.HTTPProxy,
HTTPSProxy: proxyConfig.HTTPSProxy,
NoProxy: proxyConfig.NoProxy,
Network: opts.ContainerConfig.Network,
AdditionalTags: opts.AdditionalTags,
Volumes: processedVolumes,
DefaultProcessType: opts.DefaultProcessType,
FileFilter: fileFilter,
CacheImage: opts.CacheImage,
LifecycleImage: ephemeralBuilder.Name(),
LifecycleDockerHost: opts.LifecycleDockerHost,
}

lifecycleVersion := ephemeralBuilder.LifecycleDescriptor().Info.Version
Expand Down
6 changes: 3 additions & 3 deletions internal/build/lifecycle_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (l *LifecycleExecution) Run(ctx context.Context, phaseFactoryCreator PhaseF
}

l.logger.Info(style.Step("ANALYZING"))
if err := l.Analyze(ctx, l.opts.Image.String(), l.opts.Network, l.opts.Publish, l.opts.DockerHost, l.opts.ClearCache, buildCache, phaseFactory); err != nil {
if err := l.Analyze(ctx, l.opts.Image.String(), l.opts.Network, l.opts.Publish, l.opts.LifecycleDockerHost, l.opts.ClearCache, buildCache, phaseFactory); err != nil {
return err
}

Expand All @@ -150,10 +150,10 @@ func (l *LifecycleExecution) Run(ctx context.Context, phaseFactoryCreator PhaseF
}

l.logger.Info(style.Step("EXPORTING"))
return l.Export(ctx, l.opts.Image.String(), l.opts.RunImage, l.opts.Publish, l.opts.DockerHost, l.opts.Network, buildCache, launchCache, l.opts.AdditionalTags, phaseFactory)
return l.Export(ctx, l.opts.Image.String(), l.opts.RunImage, l.opts.Publish, l.opts.LifecycleDockerHost, l.opts.Network, buildCache, launchCache, l.opts.AdditionalTags, phaseFactory)
}

return l.Create(ctx, l.opts.Publish, l.opts.DockerHost, l.opts.ClearCache, l.opts.RunImage, l.opts.Image.String(), l.opts.Network, buildCache, launchCache, l.opts.AdditionalTags, l.opts.Volumes, phaseFactory)
return l.Create(ctx, l.opts.Publish, l.opts.LifecycleDockerHost, l.opts.ClearCache, l.opts.RunImage, l.opts.Image.String(), l.opts.Network, buildCache, launchCache, l.opts.AdditionalTags, l.opts.Volumes, phaseFactory)
}

func (l *LifecycleExecution) Cleanup() error {
Expand Down
14 changes: 7 additions & 7 deletions internal/build/lifecycle_execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertSliceContains(t, configProvider.HostConfig().Binds, "/var/run/docker.sock:/var/run/docker.sock")
})

it("configures the phase with daemon access with tcp docker-host", func() {
it("configures the phase with daemon access with tcp lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand All @@ -563,7 +563,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertSliceContains(t, configProvider.ContainerConfig().Env, "DOCKER_HOST=tcp://localhost:1234")
})

it("configures the phase with daemon access with alternative unix socket docker-host", func() {
it("configures the phase with daemon access with alternative unix socket lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand All @@ -577,7 +577,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertSliceContains(t, configProvider.HostConfig().Binds, "/home/user/docker.sock:/var/run/docker.sock")
})

it("configures the phase with daemon access with alternative windows pipe docker-host", func() {
it("configures the phase with daemon access with alternative windows pipe lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand Down Expand Up @@ -608,7 +608,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
os.Unsetenv("DOCKER_HOST")
}
})
it("configures the phase with daemon access with inherited docker-host", func() {
it("configures the phase with daemon access with inherited lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand All @@ -623,7 +623,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
})
})

it("configures the phase with daemon access with docker-host with unknown protocol", func() {
it("configures the phase with daemon access with lifecycle-docker-host with unknown protocol", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()
err := lifecycle.Create(context.Background(), false, `withoutprotocol`, false, "test", "test", "test", fakeBuildCache, fakeLaunchCache, []string{}, []string{}, fakePhaseFactory)
Expand Down Expand Up @@ -1041,7 +1041,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertSliceContains(t, configProvider.HostConfig().Binds, "/var/run/docker.sock:/var/run/docker.sock")
})

it("configures the phase with daemon access with TCP docker-host", func() {
it("configures the phase with daemon access with TCP lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand Down Expand Up @@ -1667,7 +1667,7 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertSliceContains(t, configProvider.HostConfig().Binds, "/var/run/docker.sock:/var/run/docker.sock")
})

it("configures the phase with daemon access with tcp docker-host", func() {
it("configures the phase with daemon access with tcp lifecycle-docker-host", func() {
lifecycle := newTestLifecycleExec(t, false)
fakePhaseFactory := fakes.NewFakePhaseFactory()

Expand Down
38 changes: 19 additions & 19 deletions internal/build/lifecycle_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,25 @@ func init() {
}

type LifecycleOptions struct {
AppPath string
Image name.Reference
Builder Builder
LifecycleImage string
RunImage string
ClearCache bool
Publish bool
TrustBuilder bool
UseCreator bool
DockerHost string
CacheImage string
HTTPProxy string
HTTPSProxy string
NoProxy string
Network string
AdditionalTags []string
Volumes []string
DefaultProcessType string
FileFilter func(string) bool
AppPath string
Image name.Reference
Builder Builder
RunImage string
ClearCache bool
Publish bool
TrustBuilder bool
UseCreator bool
CacheImage string
LifecycleImage string
LifecycleDockerHost string
HTTPProxy string
HTTPSProxy string
NoProxy string
Network string
AdditionalTags []string
Volumes []string
DefaultProcessType string
FileFilter func(string) bool
}

func NewLifecycleExecutor(logger logging.Logger, docker client.CommonAPIClient) *LifecycleExecutor {
Expand Down
3 changes: 2 additions & 1 deletion internal/build/phase_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) {
})
})

when("with TCP docker-host", func() {
when("with TCP lifecycle-docker-host", func() {
it.Before(func() {
h.SkipIf(t, runtime.GOOS != "linux", "Skipped on non-linux")
})
Expand Down Expand Up @@ -379,6 +379,7 @@ func testPhase(t *testing.T, when spec.G, it spec.S) {
build.WithArgs("registry", repoName),
build.WithRegistryAccess(authConfig),
build.WithNetwork("host"),
build.WithDaemonAccess("host-socket"),
)
phase := phaseFactory.New(configProvider)
assertRunSucceeds(t, phase, &outBuf, &errBuf)
Expand Down
56 changes: 30 additions & 26 deletions internal/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,25 @@ import (
)

type BuildFlags struct {
Publish bool
ClearCache bool
TrustBuilder bool
DockerHost string
CacheImage string
AppPath string
Builder string
Registry string
RunImage string
Policy string
Network string
DescriptorPath string
DefaultProcessType string
LifecycleImage string
Env []string
EnvFiles []string
Buildpacks []string
Volumes []string
AdditionalTags []string
Publish bool
ClearCache bool
TrustBuilder bool
CacheImage string
AppPath string
Builder string
Registry string
RunImage string
Policy string
Network string
DescriptorPath string
DefaultProcessType string
LifecycleImage string
LifecycleDockerHost string
Env []string
EnvFiles []string
Buildpacks []string
Volumes []string
AdditionalTags []string
}

// Build an image from source code
Expand Down Expand Up @@ -118,7 +118,6 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
Env: env,
Image: imageName,
Publish: flags.Publish,
DockerHost: flags.DockerHost,
PullPolicy: pullPolicy,
ClearCache: flags.ClearCache,
TrustBuilder: trustBuilder,
Expand All @@ -132,6 +131,7 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
ProjectDescriptor: descriptor,
CacheImage: flags.CacheImage,
LifecycleImage: lifecycleImage,
LifecycleDockerHost: flags.LifecycleDockerHost,
}); err != nil {
return errors.Wrap(err, "failed to build")
}
Expand All @@ -156,13 +156,13 @@ func buildCommandFlags(cmd *cobra.Command, buildFlags *BuildFlags, cfg config.Co
cmd.Flags().StringArrayVar(&buildFlags.EnvFiles, "env-file", []string{}, "Build-time environment variables file\nOne variable per line, of the form 'VAR=VALUE' or 'VAR'\nWhen using latter value-less form, value will be taken from current\n environment at the time this command is executed\nNOTE: These are NOT available at image runtime.\"")
cmd.Flags().StringVar(&buildFlags.Network, "network", "", "Connect detect and build containers to network")
cmd.Flags().BoolVar(&buildFlags.Publish, "publish", false, "Publish to registry")
cmd.Flags().StringVar(&buildFlags.DockerHost, "docker-host", "host-socket",
`Address to docker daemon that will be exposed to the build container.
If not set (or set to 'host-socket') the standard socket location will be used.
Special value 'inherit' may be used in which case DOCKER_HOST environment variable will be used.
This option may set DOCKER_HOST environment variable for the build container if needed.
`)
cmd.Flags().StringVar(&buildFlags.LifecycleImage, "lifecycle-image", cfg.LifecycleImage, `Custom lifecycle image to use for analysis, restore, and export when builder is untrusted.`)
cmd.Flags().StringVar(&buildFlags.LifecycleDockerHost, "lifecycle-docker-host", "host-socket",
`Address to docker daemon to expose for lifecycle in the build container.
Default value 'host-socket' will bind-mount the daemon socket from the host daemon.
Special value 'inherit' will use the DOCKER_HOST environment variable from pack.
Otherwise, values will be passed through to the DOCKER_HOST environment variable for the build container.
`)
cmd.Flags().StringVar(&buildFlags.Policy, "pull-policy", "", `Pull policy to use. Accepted values are always, never, and if-not-present. (default "always")`)
cmd.Flags().StringVarP(&buildFlags.Registry, "buildpack-registry", "r", cfg.DefaultRegistryName, "Buildpack Registry by name")
cmd.Flags().StringVar(&buildFlags.RunImage, "run-image", "", "Run image (defaults to default stack's run image)")
Expand All @@ -185,6 +185,10 @@ func validateBuildFlags(flags *BuildFlags, cfg config.Config, packClient PackCli
return errors.New("cache-image flag requires the publish flag")
}

if flags.LifecycleDockerHost != "host-socket" && flags.Publish {
return errors.New("lifecycle-docker-host is not allowed when publishing to registry")
}

return nil
}

Expand Down
39 changes: 39 additions & 0 deletions internal/commands/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,36 @@ func testBuildCommand(t *testing.T, when spec.G, it spec.S) {
})
})

when("a lifecycle-docker-host is given", func() {
when("--publish is used", func() {
it("errors", func() {
command.SetArgs([]string{"--lifecycle-docker-host", "unix://foo", "--publish", "--builder", "my-builder", "image"})
err := command.Execute()
h.AssertError(t, err, "lifecycle-docker-host is not allowed when publishing to registry")
})
})
when("--publish is not used", func() {
it("sets the host", func() {
mockClient.EXPECT().
Build(gomock.Any(), EqBuildOptionsWithLifecycleDockerHost("unix://foo")).
Return(nil)

command.SetArgs([]string{"--lifecycle-docker-host", "unix://foo", "--builder", "my-builder", "image"})
h.AssertNil(t, command.Execute())
})
})
when("unset", func() {
it("sets the default host option", func() {
mockClient.EXPECT().
Build(gomock.Any(), EqBuildOptionsWithLifecycleDockerHost("host-socket")).
Return(nil)

command.SetArgs([]string{"--builder", "my-builder", "image"})
h.AssertNil(t, command.Execute())
})
})
})

when("a valid lifecycle-image is provided", func() {
when("only the image repo is provided", func() {
it("uses the provided lifecycle-image and parses it correctly", func() {
Expand Down Expand Up @@ -749,6 +779,15 @@ func EqBuildOptionsWithEnv(env map[string]string) gomock.Matcher {
}
}

func EqBuildOptionsWithLifecycleDockerHost(lifecycleDockerHost string) gomock.Matcher {
return buildOptionsMatcher{
description: fmt.Sprintf("LifecycleDockerHost=%s", lifecycleDockerHost),
equals: func(o pack.BuildOptions) bool {
return reflect.DeepEqual(o.LifecycleDockerHost, lifecycleDockerHost)
},
}
}

type buildOptionsMatcher struct {
equals func(pack.BuildOptions) bool
description string
Expand Down

0 comments on commit 6d11343

Please sign in to comment.