Skip to content

Commit

Permalink
Merge branch 'main' into run-extend
Browse files Browse the repository at this point in the history
  • Loading branch information
natalieparellano authored Jan 22, 2024
2 parents 7cf7e08 + a51140e commit b416335
Show file tree
Hide file tree
Showing 25 changed files with 334 additions and 29 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
golang.org/x/mod v0.14.0
golang.org/x/oauth2 v0.15.0
golang.org/x/sync v0.5.0
golang.org/x/sys v0.15.0
golang.org/x/term v0.15.0
golang.org/x/text v0.14.0
gopkg.in/yaml.v3 v3.0.1
Expand Down Expand Up @@ -113,7 +114,6 @@ require (
github.com/vbatts/tar-split v0.11.3 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/tools v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.31.0 // indirect
Expand Down
17 changes: 17 additions & 0 deletions internal/build/lifecycle_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
const (
defaultProcessType = "web"
overrideGID = 0
overrideUID = 0
sourceDateEpochEnv = "SOURCE_DATE_EPOCH"
)

Expand Down Expand Up @@ -334,6 +335,10 @@ func (l *LifecycleExecution) Create(ctx context.Context, buildCache, launchCache
flags = append(flags, "-gid", strconv.Itoa(l.opts.GID))
}

if l.opts.UID >= overrideUID {
flags = append(flags, "-uid", strconv.Itoa(l.opts.UID))
}

if l.opts.PreviousImage != "" {
if l.opts.Image == nil {
return errors.New("image can't be nil")
Expand Down Expand Up @@ -485,6 +490,10 @@ func (l *LifecycleExecution) Restore(ctx context.Context, buildCache Cache, kani
flags = append(flags, "-gid", strconv.Itoa(l.opts.GID))
}

if l.opts.UID >= overrideUID {
flags = append(flags, "-uid", strconv.Itoa(l.opts.UID))
}

// for kaniko
kanikoCacheBindOp := NullOp()
if l.platformAPI.AtLeast("0.12") {
Expand Down Expand Up @@ -581,6 +590,10 @@ func (l *LifecycleExecution) Analyze(ctx context.Context, buildCache, launchCach
flags = append(flags, "-gid", strconv.Itoa(l.opts.GID))
}

if l.opts.UID >= overrideUID {
flags = append(flags, "-uid", strconv.Itoa(l.opts.UID))
}

if l.opts.PreviousImage != "" {
if l.opts.Image == nil {
return errors.New("image can't be nil")
Expand Down Expand Up @@ -886,6 +899,10 @@ func (l *LifecycleExecution) Export(ctx context.Context, buildCache, launchCache
flags = append(flags, "-gid", strconv.Itoa(l.opts.GID))
}

if l.opts.UID >= overrideUID {
flags = append(flags, "-uid", strconv.Itoa(l.opts.UID))
}

cacheBindOp := NullOp()
switch buildCache.Type() {
case cache.Image:
Expand Down
100 changes: 100 additions & 0 deletions internal/build/lifecycle_execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1064,6 +1064,31 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
})
})

when("override UID", func() {
when("override UID is provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = 1001
})

it("configures the phase with the expected arguments", func() {
h.AssertIncludeAllExpectedPatterns(t,
configProvider.ContainerConfig().Cmd,
[]string{"-uid", "1001"},
)
})
})

when("override UID is not provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = -1
})

it("uid is not added to the expected arguments", func() {
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-uid")
})
})
})

when("-previous-image is used and builder is trusted", func() {
when("image is invalid", func() {
it("errors", func() {
Expand Down Expand Up @@ -1578,6 +1603,31 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
})
})
})

when("override UID", func() {
when("override UID is provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = 1001
})

it("configures the phase with the expected arguments", func() {
h.AssertIncludeAllExpectedPatterns(t,
configProvider.ContainerConfig().Cmd,
[]string{"-uid", "1001"},
)
})
})

when("override UID is not provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = -1
})

it("uid is not added to the expected arguments", func() {
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-uid")
})
})
})
})
})

Expand Down Expand Up @@ -1779,6 +1829,31 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
})
})

when("override UID", func() {
when("override UID is provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = 1001
})

it("configures the phase with the expected arguments", func() {
h.AssertIncludeAllExpectedPatterns(t,
configProvider.ContainerConfig().Cmd,
[]string{"-uid", "1001"},
)
})
})

when("override UID is not provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = -1
})

it("uid is not added to the expected arguments", func() {
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-uid")
})
})
})

when("--clear-cache", func() {
providedClearCache = true

Expand Down Expand Up @@ -2340,6 +2415,31 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
})
})

when("override UID", func() {
when("override UID is provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = 1001
})

it("configures the phase with the expected arguments", func() {
h.AssertIncludeAllExpectedPatterns(t,
configProvider.ContainerConfig().Cmd,
[]string{"-uid", "1001"},
)
})
})

when("override UID is not provided", func() {
lifecycleOps = append(lifecycleOps, func(options *build.LifecycleOptions) {
options.UID = -1
})

it("uid is not added to the expected arguments", func() {
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-uid")
})
})
})

when("interactive mode", func() {
lifecycleOps = append(lifecycleOps, func(opts *build.LifecycleOptions) {
opts.Interactive = true
Expand Down
1 change: 1 addition & 0 deletions internal/build/lifecycle_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ type LifecycleOptions struct {
FileFilter func(string) bool
Workspace string
GID int
UID int
PreviousImage string
ReportDestinationDir string
SBOMDestinationDir string
Expand Down
15 changes: 14 additions & 1 deletion internal/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type BuildFlags struct {
AdditionalTags []string
Workspace string
GID int
UID int
PreviousImage string
SBOMDestinationDir string
ReportDestinationDir string
Expand Down Expand Up @@ -143,6 +144,12 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
if cmd.Flags().Changed("gid") {
gid = flags.GID
}

var uid = -1
if cmd.Flags().Changed("uid") {
uid = flags.UID
}

dateTime, err := parseTime(flags.DateTime)
if err != nil {
return errors.Wrapf(err, "parsing creation time %s", flags.DateTime)
Expand Down Expand Up @@ -177,6 +184,7 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
Workspace: flags.Workspace,
LifecycleImage: lifecycleImage,
GroupID: gid,
UserID: uid,
PreviousImage: inputPreviousImage.Name(),
Interactive: flags.Interactive,
SBOMDestinationDir: flags.SBOMDestinationDir,
Expand Down Expand Up @@ -241,7 +249,7 @@ func buildCommandFlags(cmd *cobra.Command, buildFlags *BuildFlags, cfg config.Co
cmd.Flags().StringVar(&buildFlags.Network, "network", "", "Connect detect and build containers to network")
cmd.Flags().StringArrayVar(&buildFlags.PreBuildpacks, "pre-buildpack", []string{}, "Buildpacks to prepend to the groups in the builder's order")
cmd.Flags().StringArrayVar(&buildFlags.PostBuildpacks, "post-buildpack", []string{}, "Buildpacks to append to the groups in the builder's order")
cmd.Flags().BoolVar(&buildFlags.Publish, "publish", false, "Publish to registry")
cmd.Flags().BoolVar(&buildFlags.Publish, "publish", false, "Publish the application image directly to the container registry specified in <image-name>, instead of the daemon. The run image must also reside in the registry.")
cmd.Flags().StringVar(&buildFlags.DockerHost, "docker-host", "",
`Address to docker daemon that will be exposed to the build container.
If not set (or set to empty string) the standard socket location will be used.
Expand All @@ -257,6 +265,7 @@ This option may set DOCKER_HOST environment variable for the build container if
cmd.Flags().StringArrayVar(&buildFlags.Volumes, "volume", nil, "Mount host volume into the build container, in the form '<host path>:<target path>[:<options>]'.\n- 'host path': Name of the volume or absolute directory path to mount.\n- 'target path': The path where the file or directory is available in the container.\n- 'options' (default \"ro\"): An optional comma separated list of mount options.\n - \"ro\", volume contents are read-only.\n - \"rw\", volume contents are readable and writeable.\n - \"volume-opt=<key>=<value>\", can be specified more than once, takes a key-value pair consisting of the option name and its value."+stringArrayHelp("volume"))
cmd.Flags().StringVar(&buildFlags.Workspace, "workspace", "", "Location at which to mount the app dir in the build image")
cmd.Flags().IntVar(&buildFlags.GID, "gid", 0, `Override GID of user's group in the stack's build and run images. The provided value must be a positive number`)
cmd.Flags().IntVar(&buildFlags.UID, "uid", 0, `Override UID of user in the stack's build and run images. The provided value must be a positive number`)
cmd.Flags().StringVar(&buildFlags.PreviousImage, "previous-image", "", "Set previous image to a particular tag reference, digest reference, or (when performing a daemon build) image ID")
cmd.Flags().StringVar(&buildFlags.SBOMDestinationDir, "sbom-output-dir", "", "Path to export SBoM contents.\nOmitting the flag will yield no SBoM content.")
cmd.Flags().StringVar(&buildFlags.ReportDestinationDir, "report-output-dir", "", "Path to export build report.toml.\nOmitting the flag yield no report file.")
Expand Down Expand Up @@ -293,6 +302,10 @@ func validateBuildFlags(flags *BuildFlags, cfg config.Config, inputImageRef clie
return errors.New("gid flag must be in the range of 0-2147483647")
}

if flags.UID < 0 {
return errors.New("uid flag must be in the range of 0-2147483647")
}

if flags.Interactive && !cfg.Experimental {
return client.NewExperimentError("Interactive mode is currently experimental.")
}
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/builder_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
cmd.Flags().MarkHidden("buildpack-registry")
}
cmd.Flags().StringVarP(&flags.BuilderTomlPath, "config", "c", "", "Path to builder TOML file (required)")
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish to registry")
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish the builder directly to the container registry specified in <image-name>, instead of the daemon.")
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
cmd.Flags().BoolVar(&flags.Flatten, "flatten", false, "Flatten each composite buildpack into a single layer")
cmd.Flags().StringSliceVarP(&flags.FlattenExclude, "flatten-exclude", "e", nil, "Buildpacks to exclude from flattening, in the form of '<buildpack-id>@<buildpack-version>'")
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/buildpack_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func BuildpackPackage(logger logging.Logger, cfg config.Config, packager Buildpa

cmd.Flags().StringVarP(&flags.PackageTomlPath, "config", "c", "", "Path to package TOML config")
cmd.Flags().StringVarP(&flags.Format, "format", "f", "", `Format to save package as ("image" or "file")`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish to registry (applies to "--format=image" only)`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish the buildpack directly to the container registry specified in <name>, instead of the daemon (applies to "--format=image" only).`)
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
cmd.Flags().StringVarP(&flags.Path, "path", "p", "", "Path to the Buildpack that needs to be packaged")
cmd.Flags().StringVarP(&flags.BuildpackRegistry, "buildpack-registry", "r", "", "Buildpack Registry name")
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/create_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ Creating a custom builder allows you to control what buildpacks are used and wha
cmd.Flags().MarkHidden("buildpack-registry")
}
cmd.Flags().StringVarP(&flags.BuilderTomlPath, "config", "c", "", "Path to builder TOML file (required)")
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish to registry")
cmd.Flags().BoolVar(&flags.Publish, "publish", false, "Publish the builder directly to the container registry specified in <image-name>, instead of the daemon.")
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
return cmd
}
2 changes: 1 addition & 1 deletion internal/commands/extension_package.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ func ExtensionPackage(logger logging.Logger, cfg config.Config, packager Extensi
// flags will be added here
cmd.Flags().StringVarP(&flags.PackageTomlPath, "config", "c", "", "Path to package TOML config")
cmd.Flags().StringVarP(&flags.Format, "format", "f", "", `Format to save package as ("image" or "file")`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish to registry (applies to "--format=image" only)`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish the extension directly to the container registry specified in <name>, instead of the daemon (applies to "--format=image" only).`)
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
AddHelpFlag(cmd, "package")
return cmd
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/package_buildpack.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func PackageBuildpack(logger logging.Logger, cfg config.Config, packager Buildpa
cmd.Flags().StringVarP(&flags.PackageTomlPath, "config", "c", "", "Path to package TOML config (required)")

cmd.Flags().StringVarP(&flags.Format, "format", "f", "", `Format to save package as ("image" or "file")`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish to registry (applies to "--format=image" only)`)
cmd.Flags().BoolVar(&flags.Publish, "publish", false, `Publish the buildpack directly to the container registry specified in <name>, instead of the daemon (applies to "--format=image" only).`)
cmd.Flags().StringVar(&flags.Policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
cmd.Flags().StringVarP(&flags.BuildpackRegistry, "buildpack-registry", "r", "", "Buildpack Registry name")

Expand Down
2 changes: 1 addition & 1 deletion internal/commands/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func Rebase(logger logging.Logger, cfg config.Config, pack PackClient) *cobra.Co
}),
}

cmd.Flags().BoolVar(&opts.Publish, "publish", false, "Publish to registry")
cmd.Flags().BoolVar(&opts.Publish, "publish", false, "Publish the rebased application image directly to the container registry specified in <image-name>, instead of the daemon. The previous application image must also reside in the registry.")
cmd.Flags().StringVar(&opts.RunImage, "run-image", "", "Run image to use for rebasing")
cmd.Flags().StringVar(&policy, "pull-policy", "", "Pull policy to use. Accepted values are always, never, and if-not-present. The default is always")
cmd.Flags().StringVar(&opts.ReportDestinationDir, "report-output-dir", "", "Path to export build report.toml.\nOmitting the flag yield no report file.")
Expand Down
19 changes: 19 additions & 0 deletions internal/fakes/fake_access_checker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package fakes

type FakeAccessChecker struct {
RegistriesToFail []string
}

func NewFakeAccessChecker() *FakeAccessChecker {
return &FakeAccessChecker{}
}

func (f *FakeAccessChecker) Check(repo string) bool {
for _, toFail := range f.RegistriesToFail {
if toFail == repo {
return false
}
}

return true
}
7 changes: 6 additions & 1 deletion internal/inspectimage/info_display.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,12 +187,17 @@ func convertToDisplay(proc launch.Process, isDefault bool) ProcessDisplay {
case false:
shell = "bash"
}
var argsToUse []string
if len(proc.Command.Entries) > 1 {
argsToUse = proc.Command.Entries[1:]
}
argsToUse = append(argsToUse, proc.Args...)
result := ProcessDisplay{
Type: proc.Type,
Shell: shell,
Command: proc.Command.Entries[0],
Default: isDefault,
Args: proc.Args, // overridable args are supported for platform API >= 0.10 with buildpack API >= 0.9, but we can't determine the buildpack API from the metadata label (to be fixed in platform 0.11)
Args: argsToUse, // overridable args are supported for platform API >= 0.10 with buildpack API >= 0.9, but we can't determine the buildpack API from the metadata label (to be fixed in platform 0.11)
WorkDir: proc.WorkingDirectory,
}

Expand Down
6 changes: 5 additions & 1 deletion pkg/client/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ type BuildOptions struct {
// User's group id used to build the image
GroupID int

// User's user id used to build the image
UserID int

// A previous image to set to a particular tag reference, digest reference, or (when performing a daemon build) image ID;
PreviousImage string

Expand Down Expand Up @@ -337,7 +340,7 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
return errors.Wrapf(err, "invalid builder %s", style.Symbol(opts.Builder))
}

runImageName := c.resolveRunImage(opts.RunImage, imgRegistry, builderRef.Context().RegistryStr(), bldr.DefaultRunImage(), opts.AdditionalMirrors, opts.Publish)
runImageName := c.resolveRunImage(opts.RunImage, imgRegistry, builderRef.Context().RegistryStr(), bldr.DefaultRunImage(), opts.AdditionalMirrors, opts.Publish, c.accessChecker)

fetchOptions := image.FetchOptions{
Daemon: !opts.Publish,
Expand Down Expand Up @@ -539,6 +542,7 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
FileFilter: fileFilter,
Workspace: opts.Workspace,
GID: opts.GroupID,
UID: opts.UserID,
PreviousImage: opts.PreviousImage,
Interactive: opts.Interactive,
Termui: termui.NewTermui(imageName, ephemeralBuilder, runImageName),
Expand Down
Loading

0 comments on commit b416335

Please sign in to comment.