feat: specify create time for image built with buildpacks (#1685)

* specify the image created time

* add build-timestamp config

* fix trailing white space
This commit is contained in:
Will Li 2023-04-28 15:14:51 +08:00 committed by GitHub
parent 46076a581d
commit cd0dbfd300
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 22 deletions

View File

@ -27,6 +27,7 @@ NAME
SYNOPSIS
{{rootCmdUse}} build [-r|--registry] [--builder] [--builder-image] [--push]
[--platform] [-p|--path] [-c|--confirm] [-v|--verbose]
[--build-timestamp]
DESCRIPTION
@ -64,7 +65,7 @@ EXAMPLES
`,
SuggestFor: []string{"biuld", "buidl", "built"},
PreRunE: bindEnv("image", "path", "builder", "registry", "confirm", "push", "builder-image", "platform", "verbose"),
PreRunE: bindEnv("image", "path", "builder", "registry", "confirm", "push", "builder-image", "platform", "verbose", "build-timestamp"),
RunE: func(cmd *cobra.Command, args []string) error {
return runBuild(cmd, args, newClient)
},
@ -105,6 +106,7 @@ EXAMPLES
"Specify a custom builder image for use by the builder other than its default. ($FUNC_BUILDER_IMAGE)")
cmd.Flags().StringP("image", "i", f.Image,
"Full image name in the form [registry]/[namespace]/[name]:[tag] (optional). This option takes precedence over --registry ($FUNC_IMAGE)")
cmd.Flags().BoolP("build-timestamp", "", false, "Use the actual time as the created time for the docker image. This is only useful for buildpacks builder.")
// Static Flags:
// Options which have static defaults only (not globally configurable nor
@ -171,7 +173,9 @@ func runBuild(cmd *cobra.Command, _ []string, newClient ClientFactory) (err erro
if f.Build.Builder == builders.Pack {
builder = buildpacks.NewBuilder(
buildpacks.WithName(builders.Pack),
buildpacks.WithVerbose(cfg.Verbose))
buildpacks.WithVerbose(cfg.Verbose),
buildpacks.WithTimestamp(cfg.WithTimestamp),
)
} else if f.Build.Builder == builders.S2I {
builder = s2i.NewBuilder(
s2i.WithName(builders.S2I),
@ -220,6 +224,10 @@ type buildConfig struct {
// Push the resulting image to the registry after building.
Push bool
// Build with the current timestamp as the created time for docker image.
// This is only useful for buildpacks builder.
WithTimestamp bool
}
// newBuildConfig gathers options into a single build request.
@ -231,11 +239,12 @@ func newBuildConfig() buildConfig {
Registry: registry(), // deferred defaulting
Verbose: viper.GetBool("verbose"),
},
BuilderImage: viper.GetString("builder-image"),
Image: viper.GetString("image"),
Path: viper.GetString("path"),
Platform: viper.GetString("platform"),
Push: viper.GetBool("push"),
BuilderImage: viper.GetString("builder-image"),
Image: viper.GetString("image"),
Path: viper.GetString("path"),
Platform: viper.GetString("platform"),
Push: viper.GetBool("push"),
WithTimestamp: viper.GetBool("build-timestamp"),
}
}

View File

@ -32,7 +32,7 @@ SYNOPSIS
{{rootCmdUse}} deploy [-R|--remote] [-r|--registry] [-i|--image] [-n|--namespace]
[-e|env] [-g|--git-url] [-t|git-branch] [-d|--git-dir]
[-b|--build] [--builder] [--builder-image] [-p|--push]
[--platform] [-c|--confirm] [-v|--verbose]
[--platform] [-c|--confirm] [-v|--verbose] [--build-timestamp]
DESCRIPTION
@ -116,7 +116,7 @@ EXAMPLES
`,
SuggestFor: []string{"delpoy", "deplyo"},
PreRunE: bindEnv("confirm", "env", "git-url", "git-branch", "git-dir", "remote", "build", "builder", "builder-image", "image", "registry", "push", "platform", "namespace", "path", "verbose", "pvc-size"),
PreRunE: bindEnv("confirm", "env", "git-url", "git-branch", "git-dir", "remote", "build", "builder", "builder-image", "image", "registry", "push", "platform", "namespace", "path", "verbose", "pvc-size", "build-timestamp"),
RunE: func(cmd *cobra.Command, args []string) error {
return runDeploy(cmd, newClient)
},
@ -178,6 +178,7 @@ EXAMPLES
"Push the function image to registry before deploying. ($FUNC_PUSH)")
cmd.Flags().String("platform", "",
"Optionally specify a specific platform to build for (e.g. linux/amd64). ($FUNC_PLATFORM)")
cmd.Flags().BoolP("build-timestamp", "", false, "Use the actual time as the created time for the docker image. This is only useful for buildpacks builder.")
// Oft-shared flags:
addConfirmFlag(cmd, cfg.Confirm)
@ -240,7 +241,9 @@ func runDeploy(cmd *cobra.Command, newClient ClientFactory) (err error) {
if f.Build.Builder == builders.Pack {
builder = buildpacks.NewBuilder(
buildpacks.WithName(builders.Pack),
buildpacks.WithVerbose(cfg.Verbose))
buildpacks.WithVerbose(cfg.Verbose),
buildpacks.WithTimestamp(cfg.WithTimestamp),
)
} else if f.Build.Builder == builders.S2I {
builder = s2i.NewBuilder(
s2i.WithName(builders.S2I),
@ -374,21 +377,26 @@ type deployConfig struct {
// PVCSize configures the PVC size used by the pipeline if --remote flag is set.
PVCSize string
// Build with the current timestamp as the created time for docker image.
// This is only useful for buildpacks builder.
WithTimestamp bool
}
// newDeployConfig creates a buildConfig populated from command flags and
// environment variables; in that precedence.
func newDeployConfig(cmd *cobra.Command) (c deployConfig) {
c = deployConfig{
buildConfig: newBuildConfig(),
Build: viper.GetString("build"),
Env: viper.GetStringSlice("env"),
GitBranch: viper.GetString("git-branch"),
GitDir: viper.GetString("git-dir"),
GitURL: viper.GetString("git-url"),
Namespace: viper.GetString("namespace"),
Remote: viper.GetBool("remote"),
PVCSize: viper.GetString("pvc-size"),
buildConfig: newBuildConfig(),
Build: viper.GetString("build"),
Env: viper.GetStringSlice("env"),
GitBranch: viper.GetString("git-branch"),
GitDir: viper.GetString("git-dir"),
GitURL: viper.GetString("git-url"),
Namespace: viper.GetString("namespace"),
Remote: viper.GetBool("remote"),
PVCSize: viper.GetString("pvc-size"),
WithTimestamp: viper.GetBool("build-timestamp"),
}
// NOTE: .Env should be viper.GetStringSlice, but this returns unparsed
// results and appears to be an open issue since 2017:

View File

@ -7,6 +7,7 @@ import (
"io"
"runtime"
"strings"
"time"
"github.com/Masterminds/semver"
pack "github.com/buildpacks/pack/pkg/client"
@ -50,9 +51,10 @@ type Builder struct {
name string
verbose bool
// in non-verbose mode contains std[err,out], so it can be printed on error
outBuff bytes.Buffer
logger logging.Logger
impl Impl
outBuff bytes.Buffer
logger logging.Logger
impl Impl
withTimestamp bool
}
// Impl allows for the underlying implementation to be mocked for tests.
@ -97,6 +99,12 @@ func WithImpl(i Impl) Option {
}
}
func WithTimestamp(v bool) Option {
return func(b *Builder) {
b.withTimestamp = v
}
}
var DefaultLifecycleImage = "quay.io/boson/lifecycle@sha256:f53fea9ec9188b92cab0b8a298ff852d76a6c2aaf56f968a08637e13de0e0c59"
// Build the Function at path.
@ -119,6 +127,10 @@ func (b *Builder) Build(ctx context.Context, f fn.Function) (err error) {
Volumes []string
}{Network: "", Volumes: nil},
}
if b.withTimestamp {
now := time.Now()
opts.CreationTime = &now
}
if opts.Env, err = fn.Interpolate(f.Build.BuildEnvs); err != nil {
return err
}