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

Enable GID override in Build #1041

Closed
wants to merge 1 commit into from
Closed
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
10 changes: 7 additions & 3 deletions build.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ type BuildOptions struct {

// ProjectDescriptor describes the project and any configuration specific to the project
ProjectDescriptor project.Descriptor

// TBD
GroupID config.GroupID
}

// ProxyConfig specifies proxy setting to be set as environment variables in a container.
Expand Down Expand Up @@ -241,7 +244,7 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
buildEnvs[k] = v
}

ephemeralBuilder, err := c.createEphemeralBuilder(rawBuilderImage, buildEnvs, order, fetchedBPs)
ephemeralBuilder, err := c.createEphemeralBuilder(rawBuilderImage, buildEnvs, order, fetchedBPs, opts)
if err != nil {
return err
}
Expand Down Expand Up @@ -803,9 +806,10 @@ func ensureBPSupport(bpPath string) (err error) {
return nil
}

func (c *Client) createEphemeralBuilder(rawBuilderImage imgutil.Image, env map[string]string, order dist.Order, buildpacks []dist.Buildpack) (*builder.Builder, error) {
func (c *Client) createEphemeralBuilder(rawBuilderImage imgutil.Image, env map[string]string, order dist.Order, buildpacks []dist.Buildpack, opts BuildOptions) (*builder.Builder, error) {
origBuilderName := rawBuilderImage.Name()
bldr, err := builder.New(rawBuilderImage, fmt.Sprintf("pack.local/builder/%x:latest", randString(10)))
name := fmt.Sprintf("pack.local/builder/%x:latest", randString(10))
bldr, err := builder.New(rawBuilderImage, name, opts.GroupID)
if err != nil {
return nil, errors.Wrapf(err, "invalid builder %s", style.Symbol(origBuilderName))
}
Expand Down
26 changes: 26 additions & 0 deletions config/gid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package config

import (
"strconv"

"github.com/pkg/errors"
)

type GroupID struct {
ID string
FlagProvided bool
}

func (gid *GroupID) GetID(sGID string) (int, error) {
if gid.FlagProvided {
id, err := strconv.Atoi(gid.ID)

if err != nil {
return 0, errors.Errorf("invalid gid %s", gid.ID)
}

return id, nil
}

return strconv.Atoi(sGID)
}
2 changes: 1 addition & 1 deletion create_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func (c *Client) createBaseBuilder(ctx context.Context, opts CreateBuilderOption
}

c.logger.Debugf("Creating builder %s from build-image %s", style.Symbol(opts.BuilderName), style.Symbol(baseImage.Name()))
bldr, err := builder.New(baseImage, opts.BuilderName)
bldr, err := builder.New(baseImage, opts.BuilderName, config.GroupID{})
if err != nil {
return nil, errors.Wrap(err, "invalid build-image")
}
Expand Down
19 changes: 12 additions & 7 deletions internal/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"github.com/pkg/errors"

"github.com/buildpacks/pack/builder"
"github.com/buildpacks/pack/config"
"github.com/buildpacks/pack/internal/archive"
"github.com/buildpacks/pack/internal/dist"
"github.com/buildpacks/pack/internal/layer"
"github.com/buildpacks/pack/internal/stack"
Expand Down Expand Up @@ -76,20 +78,21 @@ func FromImage(img imgutil.Image) (*Builder, error) {
} else if !ok {
return nil, fmt.Errorf("builder %s missing label %s -- try recreating builder", style.Symbol(img.Name()), style.Symbol(metadataLabel))
}
return constructBuilder(img, "", metadata)
return constructBuilder(img, "", metadata, config.GroupID{})
}

// New constructs a new builder from a base image
func New(baseImage imgutil.Image, name string) (*Builder, error) {
func New(baseImage imgutil.Image, name string, gid config.GroupID) (*Builder, error) {
var metadata Metadata
if _, err := dist.GetLabel(baseImage, metadataLabel, &metadata); err != nil {
return nil, errors.Wrapf(err, "getting label %s", metadataLabel)
}
return constructBuilder(baseImage, name, metadata)
return constructBuilder(baseImage, name, metadata, gid)
}

func constructBuilder(img imgutil.Image, newName string, metadata Metadata) (*Builder, error) {
func constructBuilder(img imgutil.Image, newName string, metadata Metadata, gid config.GroupID) (*Builder, error) {
imageOS, err := img.OS()

if err != nil {
return nil, errors.Wrap(err, "getting image OS")
}
Expand All @@ -107,6 +110,8 @@ func constructBuilder(img imgutil.Image, newName string, metadata Metadata) (*Bu
env: map[string]string{},
}

bldr.uid, bldr.gid, err = userAndGroupIDs(img, gid)

if err := addImgLabelsToBuildr(bldr); err != nil {
return nil, errors.Wrap(err, "adding image labels to builder")
}
Expand All @@ -130,7 +135,6 @@ func constructLifecycleDescriptor(metadata Metadata) LifecycleDescriptor {

func addImgLabelsToBuildr(bldr *Builder) error {
var err error
bldr.uid, bldr.gid, err = userAndGroupIDs(bldr.image)
if err != nil {
return err
}
Expand Down Expand Up @@ -490,7 +494,7 @@ func validateBuildpacks(stackID string, mixins []string, lifecycleDescriptor Lif
return nil
}

func userAndGroupIDs(img imgutil.Image) (int, int, error) {
func userAndGroupIDs(img imgutil.Image, groupID config.GroupID) (int, int, error) {
sUID, err := img.Env(EnvUID)
if err != nil {
return 0, 0, errors.Wrap(err, "reading builder env variables")
Expand All @@ -511,7 +515,8 @@ func userAndGroupIDs(img imgutil.Image) (int, int, error) {
return 0, 0, fmt.Errorf("failed to parse %s, value %s should be an integer", style.Symbol(EnvUID), style.Symbol(sUID))
}

gid, err = strconv.Atoi(sGID)
gid, err = groupID.GetID(sGID)

if err != nil {
return 0, 0, fmt.Errorf("failed to parse %s, value %s should be an integer", style.Symbol(EnvGID), style.Symbol(sGID))
}
Expand Down
8 changes: 8 additions & 0 deletions internal/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ type BuildFlags struct {
Network string
DescriptorPath string
DefaultProcessType string
GroupID string
Env []string
EnvFiles []string
Buildpacks []string
Expand Down Expand Up @@ -97,6 +98,11 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
return errors.Wrapf(err, "parsing pull policy %s", flags.Policy)
}

var gid = pubcfg.GroupID{
FlagProvided: flags.GroupID != "",
ID: flags.GroupID,
}

if err := packClient.Build(cmd.Context(), pack.BuildOptions{
AppPath: flags.AppPath,
Builder: flags.Builder,
Expand All @@ -119,6 +125,7 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
ProjectDescriptorBaseDir: filepath.Dir(actualDescriptorPath),
ProjectDescriptor: descriptor,
CacheImage: flags.CacheImage,
GroupID: gid,
}); err != nil {
return errors.Wrap(err, "failed to build")
}
Expand Down Expand Up @@ -152,6 +159,7 @@ func buildCommandFlags(cmd *cobra.Command, buildFlags *BuildFlags, cfg config.Co
cmd.Flags().StringVar(&buildFlags.Policy, "pull-policy", "", `Pull policy to use. Accepted values are always, never, and if-not-present. (default "always")`)
cmd.Flags().StringSliceVarP(&buildFlags.AdditionalTags, "tag", "t", nil, "Additional tags to push the output image to."+multiValueHelp("tag"))
cmd.Flags().StringVar(&buildFlags.CacheImage, "cache-image", "", `Cache build layers in remote registry. Requires --publish`)
cmd.Flags().StringVar(&buildFlags.GroupID, "gid", "", "Set group '0' as the owner of the contents in '/workspace/' within the app image")
}

func validateBuildFlags(flags *BuildFlags, cfg config.Config, packClient PackClient, logger logging.Logger) error {
Expand Down