Skip to content

Commit

Permalink
Merge branch 'main' into implement-pack-create
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Bustamante <[email protected]>
  • Loading branch information
jjbustamante authored Feb 8, 2024
2 parents c7d4a14 + 5cbc93e commit e757d06
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 18 deletions.
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ require (
github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06
github.com/sclevine/spec v1.4.0
github.com/spf13/cobra v1.8.0
golang.org/x/crypto v0.18.0
golang.org/x/mod v0.14.0
golang.org/x/oauth2 v0.16.0
golang.org/x/crypto v0.19.0
golang.org/x/mod v0.15.0
golang.org/x/oauth2 v0.17.0
golang.org/x/sync v0.6.0
golang.org/x/sys v0.16.0
golang.org/x/term v0.16.0
golang.org/x/sys v0.17.0
golang.org/x/term v0.17.0
golang.org/x/text v0.14.0
gopkg.in/yaml.v3 v3.0.1
)
Expand Down Expand Up @@ -107,7 +107,7 @@ require (
github.com/src-d/gcfg v1.4.0 // indirect
github.com/vbatts/tar-split v0.11.5 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/net v0.21.0 // indirect
golang.org/x/tools v0.16.1 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.31.0 // indirect
Expand Down
24 changes: 12 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -480,15 +480,15 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
Expand All @@ -507,11 +507,11 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ=
golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -557,8 +557,8 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
Expand All @@ -569,8 +569,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE=
golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
Expand Down
6 changes: 6 additions & 0 deletions internal/build/fakes/fake_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,9 @@ func WithBuilder(builder *FakeBuilder) func(*build.LifecycleOptions) {
opts.Builder = builder
}
}

func WithMacAddresss(macAddresss string) func(*build.LifecycleOptions) {
return func(opts *build.LifecycleOptions) {
opts.MacAddress = macAddresss
}
}
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 {
Workspace string
GID int
UID int
MacAddress string
PreviousImage string
ReportDestinationDir string
SBOMDestinationDir string
Expand Down
5 changes: 5 additions & 0 deletions internal/build/phase_config_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ func NewPhaseConfigProvider(name string, lifecycleExec *LifecycleExecution, ops
provider.ctrConf.Image = lifecycleExec.opts.Builder.Name()
provider.ctrConf.Labels = map[string]string{"author": "pack"}

if lifecycleExec.opts.MacAddress != "" {
provider.ctrConf.MacAddress = lifecycleExec.opts.MacAddress
lifecycleExec.logger.Debugf("MAC Address: %s", style.Symbol(lifecycleExec.opts.MacAddress))
}

if lifecycleExec.os == "windows" {
provider.hostConf.Isolation = container.IsolationProcess
}
Expand Down
11 changes: 11 additions & 0 deletions internal/build/phase_config_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ func testPhaseConfigProvider(t *testing.T, when spec.G, it spec.S) {
})
})

when("mac address is set", func() {
it("should set MacAddress in LifecycleOptions", func() {
expectedMacAddress := "01:23:45:67:89:ab"
lifecycle := newTestLifecycleExec(t, false, "some-temp-dir", fakes.WithMacAddresss(expectedMacAddress))

phaseConfigProvider := build.NewPhaseConfigProvider("some-name", lifecycle)

h.AssertEq(t, phaseConfigProvider.ContainerConfig().MacAddress, expectedMacAddress)
})
})

when("building with interactive mode", func() {
it("returns a phase config provider with interactive args", func() {
handler := func(bodyChan <-chan container.WaitResponse, errChan <-chan error, reader io.Reader) error {
Expand Down
14 changes: 14 additions & 0 deletions internal/commands/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -49,6 +50,7 @@ type BuildFlags struct {
Workspace string
GID int
UID int
MacAddress string
PreviousImage string
SBOMDestinationDir string
ReportDestinationDir string
Expand All @@ -57,6 +59,8 @@ type BuildFlags struct {
PostBuildpacks []string
}

var macAddressRegex = regexp.MustCompile(`^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$`)

// Build an image from source code
func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cobra.Command {
var flags BuildFlags
Expand Down Expand Up @@ -185,6 +189,7 @@ func Build(logger logging.Logger, cfg config.Config, packClient PackClient) *cob
LifecycleImage: lifecycleImage,
GroupID: gid,
UserID: uid,
MacAddress: flags.MacAddress,
PreviousImage: inputPreviousImage.Name(),
Interactive: flags.Interactive,
SBOMDestinationDir: flags.SBOMDestinationDir,
Expand Down Expand Up @@ -266,6 +271,7 @@ This option may set DOCKER_HOST environment variable for the build container if
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.MacAddress, "mac-address", "", "MAC address to set for the build container network configuration")
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 @@ -306,6 +312,10 @@ func validateBuildFlags(flags *BuildFlags, cfg config.Config, inputImageRef clie
return errors.New("uid flag must be in the range of 0-2147483647")
}

if flags.MacAddress != "" && !isValidMacAddress(flags.MacAddress) {
return errors.New("invalid MAC address provided")
}

if flags.Interactive && !cfg.Experimental {
return client.NewExperimentError("Interactive mode is currently experimental.")
}
Expand Down Expand Up @@ -380,3 +390,7 @@ func parseProjectToml(appPath, descriptorPath string) (projectTypes.Descriptor,
descriptor, err := project.ReadProjectDescriptor(actualPath)
return descriptor, actualPath, err
}

func isValidMacAddress(macAddress string) bool {
return macAddressRegex.MatchString(macAddress)
}
40 changes: 40 additions & 0 deletions internal/commands/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,37 @@ builder = "my-builder"
})
})

when("mac-address flag is provided", func() {
when("mac-address is a valid value", func() {
it("should set MacAddress in BuildOptions", func() {
mockClient.EXPECT().
Build(gomock.Any(), EqBuildOptionsWithMacAddress("01:23:45:67:89:ab")).
Return(nil)

command.SetArgs([]string{"--builder", "my-builder", "image", "--mac-address", "01:23:45:67:89:ab"})
h.AssertNil(t, command.Execute())
})
})
when("mac-address is an invalid value", func() {
it("should throw an error", func() {
command.SetArgs([]string{"--builder", "my-builder", "image", "--mac-address", "invalid-mac"})
err := command.Execute()
h.AssertError(t, err, "invalid MAC address")
})
})
})

when("mac-address flag is not provided", func() {
it("should not set MacAddress in BuildOptions", func() {
mockClient.EXPECT().
Build(gomock.Any(), EqBuildOptionsWithMacAddress("")).
Return(nil)

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

when("previous-image flag is provided", func() {
when("image is invalid", func() {
it("error must be thrown", func() {
Expand Down Expand Up @@ -1076,6 +1107,15 @@ func EqBuildOptionsWithOverrideGroupID(gid int) gomock.Matcher {
}
}

func EqBuildOptionsWithMacAddress(macAddress string) gomock.Matcher {
return buildOptionsMatcher{
description: fmt.Sprintf("MacAddress=%s", macAddress),
equals: func(o client.BuildOptions) bool {
return o.MacAddress == macAddress
},
}
}

func EqBuildOptionsWithPreviousImage(prevImage string) gomock.Matcher {
return buildOptionsMatcher{
description: fmt.Sprintf("Previous image=%s", prevImage),
Expand Down
4 changes: 4 additions & 0 deletions pkg/client/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ type BuildOptions struct {
// Directory to output the report.toml metadata artifact
ReportDestinationDir string

// For storing the mac-address to later pass on docker config structure
MacAddress string

// Desired create time in the output image config
CreationTime *time.Time

Expand Down Expand Up @@ -543,6 +546,7 @@ func (c *Client) Build(ctx context.Context, opts BuildOptions) error {
Workspace: opts.Workspace,
GID: opts.GroupID,
UID: opts.UserID,
MacAddress: opts.MacAddress,
PreviousImage: opts.PreviousImage,
Interactive: opts.Interactive,
Termui: termui.NewTermui(imageName, ephemeralBuilder, runImageName),
Expand Down

0 comments on commit e757d06

Please sign in to comment.