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

Support Platform APIs 0.5, 0.6 #1051

Merged
merged 9 commits into from
Jun 15, 2021
2 changes: 1 addition & 1 deletion acceptance/testdata/pack_fixtures/report_output.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Pack:

Default Lifecycle Version: 0.11.3

Supported Platform APIs: 0.3, 0.4
Supported Platform APIs: 0.3, 0.4, 0.5, 0.6

Config:
default-builder-image = "{{ .DefaultBuilder }}"
Expand Down
4 changes: 2 additions & 2 deletions doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import (
// This example shows the basic usage of the package: Create a client,
// call a configuration object, call the client's Build function.
func Example_build() {
//create a context object
// create a context object
context := context.Background()

//initialize a pack client
// initialize a pack client
client, err := pack.NewClient()
if err != nil {
panic(err)
Expand Down
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3 h1:DywqrEscRX7O2phNjkT0L6lhHKGBoMLCNX+XcAe7t6s=
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
12 changes: 6 additions & 6 deletions internal/build/container_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func copyDirWindows(ctx context.Context, ctrClient client.CommonAPIClient, conta
"cmd",
"/c",

//xcopy args
// xcopy args
// e - recursively create subdirectories
// h - copy hidden and system files
// b - copy symlinks, do not dereference
Expand Down Expand Up @@ -185,10 +185,10 @@ func createReader(src, dst string, uid, gid int, includeRoot bool, fileFilter fu
return archive.ReadZipAsTar(src, dst, uid, gid, -1, false, fileFilter), nil
}

//EnsureVolumeAccess grants full access permissions to volumes for UID/GID-based user
//When UID/GID are 0 it grants explicit full access to BUILTIN\Administrators and any other UID/GID grants full access to BUILTIN\Users
//Changing permissions on volumes through stopped containers does not work on Docker for Windows so we start the container and make change using icacls
//See: https://github.com/moby/moby/issues/40771
// EnsureVolumeAccess grants full access permissions to volumes for UID/GID-based user
// When UID/GID are 0 it grants explicit full access to BUILTIN\Administrators and any other UID/GID grants full access to BUILTIN\Users
// Changing permissions on volumes through stopped containers does not work on Docker for Windows so we start the container and make change using icacls
// See: https://github.com/moby/moby/issues/40771
func EnsureVolumeAccess(uid, gid int, os string, volumeNames ...string) ContainerOperation {
return func(ctrClient client.CommonAPIClient, ctx context.Context, containerID string, stdout, stderr io.Writer) error {
if os != "windows" {
Expand All @@ -210,7 +210,7 @@ func EnsureVolumeAccess(uid, gid int, os string, volumeNames ...string) Containe
cmd += "&&"
}

//icacls args
// icacls args
// /grant - add new permissions instead of replacing
// (OI) - object inherit
// (CI) - container inherit
Expand Down
3 changes: 2 additions & 1 deletion internal/build/lifecycle_execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ func (l *LifecycleExecution) Build(ctx context.Context, networkMode string, volu
}

func determineDefaultProcessType(platformAPI *api.Version, providedValue string) string {
shouldSetForceDefault := platformAPI.Compare(api.MustParse("0.4")) >= 0
shouldSetForceDefault := platformAPI.Compare(api.MustParse("0.4")) >= 0 &&
platformAPI.Compare(api.MustParse("0.6")) < 0
if providedValue == "" && shouldSetForceDefault {
return defaultProcessType
}
Expand Down
83 changes: 82 additions & 1 deletion internal/build/lifecycle_execution_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,12 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
api.MustParse("0.3"),
api.MustParse("0.4"),
api.MustParse("0.5"),
api.MustParse("0.6"),
}))
h.AssertNil(t, err)

lifecycleExec := newTestLifecycleExec(t, false, fakes.WithBuilder(fakeBuilder))
h.AssertEq(t, lifecycleExec.PlatformAPI().String(), "0.4")
h.AssertEq(t, lifecycleExec.PlatformAPI().String(), "0.6")
})
})

Expand Down Expand Up @@ -566,6 +567,26 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertIncludeAllExpectedPatterns(t, configProvider.ContainerConfig().Cmd, []string{"-process-type", "web"})
})
})

when("platform >= 0.6", func() {
when("no user provided process type is present", func() {
it("doesn't provide 'web' as default process type", func() {
fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithSupportedPlatformAPIs([]*api.Version{api.MustParse("0.6")}))
h.AssertNil(t, err)
lifecycle := newTestLifecycleExec(t, true, fakes.WithBuilder(fakeBuilder))
fakePhaseFactory := fakes.NewFakePhaseFactory()

err = lifecycle.Export(context.Background(), "test", "test", true, "", "test", fakeBuildCache, fakeLaunchCache, []string{}, fakePhaseFactory)
h.AssertNil(t, err)

lastCallIndex := len(fakePhaseFactory.NewCalledWithProvider) - 1
h.AssertNotEq(t, lastCallIndex, -1)

configProvider := fakePhaseFactory.NewCalledWithProvider[lastCallIndex]
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-process-type")
})
})
})
})

when("publish is false", func() {
Expand Down Expand Up @@ -755,6 +776,26 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertIncludeAllExpectedPatterns(t, configProvider.ContainerConfig().Cmd, []string{"-process-type", "web"})
})
})

when("platform >= 0.6", func() {
when("no user provided process type is present", func() {
it("doesn't provide 'web' as default process type", func() {
fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithSupportedPlatformAPIs([]*api.Version{api.MustParse("0.6")}))
h.AssertNil(t, err)
lifecycle := newTestLifecycleExec(t, true, fakes.WithBuilder(fakeBuilder))
fakePhaseFactory := fakes.NewFakePhaseFactory()

err = lifecycle.Export(context.Background(), "test", "test", false, "", "test", fakeBuildCache, fakeLaunchCache, []string{}, fakePhaseFactory)
h.AssertNil(t, err)

lastCallIndex := len(fakePhaseFactory.NewCalledWithProvider) - 1
h.AssertNotEq(t, lastCallIndex, -1)

configProvider := fakePhaseFactory.NewCalledWithProvider[lastCallIndex]
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-process-type")
})
})
})
})

when("override GID", func() {
Expand Down Expand Up @@ -1819,6 +1860,26 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertIncludeAllExpectedPatterns(t, configProvider.ContainerConfig().Cmd, []string{"-process-type", "web"})
})
})

when("platform >= 0.6", func() {
when("no user provided process type is present", func() {
it("doesn't provide 'web' as default process type", func() {
fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithSupportedPlatformAPIs([]*api.Version{api.MustParse("0.6")}))
h.AssertNil(t, err)
lifecycle := newTestLifecycleExec(t, true, fakes.WithBuilder(fakeBuilder))
fakePhaseFactory := fakes.NewFakePhaseFactory()

err = lifecycle.Export(context.Background(), "test", "test", true, "", "test", fakeBuildCache, fakeLaunchCache, []string{}, fakePhaseFactory)
h.AssertNil(t, err)

lastCallIndex := len(fakePhaseFactory.NewCalledWithProvider) - 1
h.AssertNotEq(t, lastCallIndex, -1)

configProvider := fakePhaseFactory.NewCalledWithProvider[lastCallIndex]
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-process-type")
})
})
})
})

when("publish is false", func() {
Expand Down Expand Up @@ -2004,6 +2065,26 @@ func testLifecycleExecution(t *testing.T, when spec.G, it spec.S) {
h.AssertIncludeAllExpectedPatterns(t, configProvider.ContainerConfig().Cmd, []string{"-process-type", "web"})
})
})

when("platform >= 0.6", func() {
when("no user provided process type is present", func() {
it("doesn't provide 'web' as default process type", func() {
fakeBuilder, err := fakes.NewFakeBuilder(fakes.WithSupportedPlatformAPIs([]*api.Version{api.MustParse("0.6")}))
h.AssertNil(t, err)
lifecycle := newTestLifecycleExec(t, true, fakes.WithBuilder(fakeBuilder))
fakePhaseFactory := fakes.NewFakePhaseFactory()

err = lifecycle.Export(context.Background(), "test", "test", false, "", "test", fakeBuildCache, fakeLaunchCache, []string{}, fakePhaseFactory)
h.AssertNil(t, err)

lastCallIndex := len(fakePhaseFactory.NewCalledWithProvider) - 1
h.AssertNotEq(t, lastCallIndex, -1)

configProvider := fakePhaseFactory.NewCalledWithProvider[lastCallIndex]
h.AssertSliceNotContains(t, configProvider.ContainerConfig().Cmd, "-process-type")
})
})
})
})

when("override GID", func() {
Expand Down
2 changes: 2 additions & 0 deletions internal/build/lifecycle_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ var (
SupportedPlatformAPIVersions = builder.APISet{
api.MustParse("0.3"),
api.MustParse("0.4"),
api.MustParse("0.5"),
api.MustParse("0.6"),
}
)

Expand Down
2 changes: 1 addition & 1 deletion internal/commands/buildpack_new_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func testBuildpackNewCommand(t *testing.T, when spec.G, it spec.S) {
when("BuildpackNew#Execute", func() {
it("uses the args to generate artifacts", func() {
mockClient.EXPECT().NewBuildpack(gomock.Any(), pack.NewBuildpackOptions{
API: "0.4",
API: "0.6",
ID: "example/some-cnb",
Path: filepath.Join(tmpDir, "some-cnb"),
Version: "1.0.0",
Expand Down
4 changes: 2 additions & 2 deletions internal/commands/config_experimental_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ func testConfigExperimental(t *testing.T, when spec.G, it spec.S) {
it("returns error if invalid value provided", func() {
cmd.SetArgs([]string{"disable-me"})
h.AssertError(t, cmd.Execute(), fmt.Sprintf("invalid value %s provided", style.Symbol("disable-me")))
//output := outBuf.String()
//h.AssertContains(t, output, "Experimental features disabled.")
// output := outBuf.String()
// h.AssertContains(t, output, "Experimental features disabled.")
cfg, err := config.Read(configPath)
h.AssertNil(t, err)
h.AssertEq(t, cfg.Experimental, false)
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/config_registries_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func ConfigRegistriesDefault(logger logging.Logger, cfg config.Config, cfgPath s
}
logger.Infof("Successfully unset default registry %s", style.Symbol(oldRegistry))
logger.Infof("Default registry has been set to %s", style.Symbol(config.OfficialRegistryName))
case len(args) == 0: //list
case len(args) == 0: // list
if cfg.DefaultRegistryName == "" {
cfg.DefaultRegistryName = config.OfficialRegistryName
}
Expand Down
2 changes: 1 addition & 1 deletion internal/commands/config_run_image_mirrors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func testConfigRunImageMirrorsCommand(t *testing.T, when spec.G, it spec.S) {
cfg, err := config.Read(configPath)
h.AssertNil(t, err)
h.AssertEq(t, cfg, testCfg)
//This ensures that there are no dups
// This ensures that there are no dups
h.AssertEq(t, len(cfg.RunImages[0].Mirrors), 2)
})
})
Expand Down
2 changes: 1 addition & 1 deletion internal/dist/buildpack_descriptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type BuildpackDescriptor struct {
}

func (b *BuildpackDescriptor) EscapedID() string {
return strings.Replace(b.Info.ID, "/", "_", -1)
return strings.ReplaceAll(b.Info.ID, "/", "_")
}

func (b *BuildpackDescriptor) EnsureStackSupport(stackID string, providedMixins []string, validateRunStageMixins bool) error {
Expand Down
2 changes: 1 addition & 1 deletion internal/image/fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func (w *colorizedWriter) Write(p []byte) (n int, err error) {
">": style.ProgressBar,
}
for pattern, colorize := range colorizers {
msg = strings.Replace(msg, pattern, colorize(pattern), -1)
msg = strings.ReplaceAll(msg, pattern, colorize(pattern))
}
return w.writer.Write([]byte(msg))
}
18 changes: 9 additions & 9 deletions internal/paths/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ func FilterReservedNames(p string) string {
"prn": "p_r_n",
}
for k, v := range reservedNameConversions {
p = strings.Replace(p, k, v, -1)
p = strings.ReplaceAll(p, k, v)
}

return p
}

//WindowsDir is equivalent to path.Dir or filepath.Dir but always for Windows paths
//reproduced because Windows implementation is not exported
// WindowsDir is equivalent to path.Dir or filepath.Dir but always for Windows paths
// reproduced because Windows implementation is not exported
func WindowsDir(p string) string {
pathElements := strings.Split(p, `\`)

Expand All @@ -106,16 +106,16 @@ func WindowsDir(p string) string {
return dirName
}

//WindowsBasename is equivalent to path.Basename or filepath.Basename but always for Windows paths
//reproduced because Windows implementation is not exported
// WindowsBasename is equivalent to path.Basename or filepath.Basename but always for Windows paths
// reproduced because Windows implementation is not exported
func WindowsBasename(p string) string {
pathElements := strings.Split(p, `\`)

return pathElements[len(pathElements)-1]
}

//WindowsToSlash is equivalent to path.ToSlash or filepath.ToSlash but always for Windows paths
//reproduced because Windows implementation is not exported
// WindowsToSlash is equivalent to path.ToSlash or filepath.ToSlash but always for Windows paths
// reproduced because Windows implementation is not exported
func WindowsToSlash(p string) string {
slashPath := strings.ReplaceAll(p, `\`, "/") // convert slashes
if len(slashPath) < 2 {
Expand All @@ -125,8 +125,8 @@ func WindowsToSlash(p string) string {
return slashPath[2:] // strip volume
}

//WindowsPathSID returns the appropriate SID for a given UID and GID
//This the basic logic for path permissions in Pack and Lifecycle
// WindowsPathSID returns the appropriate SID for a given UID and GID
// This the basic logic for path permissions in Pack and Lifecycle
func WindowsPathSID(uid, gid int) string {
if uid == 0 && gid == 0 {
return "S-1-5-32-544" // BUILTIN\Administrators
Expand Down
2 changes: 1 addition & 1 deletion testhelpers/tar_assertions.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func isGzipped(reader io.Reader) (headerBytes []byte, isGzipped bool, err error)
return magicHeader, false, err
}
// This assertion is based on https://stackoverflow.com/a/28332019. It checks whether the two header bytes of
//the file match the expected headers for a gzip file; the first one is 0x1f and the second is 0x8b
// the file match the expected headers for a gzip file; the first one is 0x1f and the second is 0x8b
return magicHeader, bytes.Equal(magicHeader, gzipMagicHeader), nil
}

Expand Down