Skip to content

Commit 7764535

Browse files
committed
feat: implement reproducible build and get cached image
1 parent 6cb1217 commit 7764535

File tree

4 files changed

+57
-11
lines changed

4 files changed

+57
-11
lines changed

envbuilder.go

+33-8
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,11 @@ func Run(ctx context.Context, options Options) error {
119119
options.WorkspaceFolder = f
120120
}
121121

122-
stageNumber := 1
122+
stageNumber := 0
123123
startStage := func(format string, args ...any) func(format string, args ...any) {
124124
now := time.Now()
125-
stageNum := stageNumber
126125
stageNumber++
126+
stageNum := stageNumber
127127
options.Logger(notcodersdk.LogLevelInfo, "#%d: %s", stageNum, fmt.Sprintf(format, args...))
128128

129129
return func(format string, args ...any) {
@@ -338,7 +338,7 @@ func Run(ctx context.Context, options Options) error {
338338

339339
HijackLogrus(func(entry *logrus.Entry) {
340340
for _, line := range strings.Split(entry.Message, "\r") {
341-
options.Logger(notcodersdk.LogLevelInfo, "#2: %s", color.HiBlackString(line))
341+
options.Logger(notcodersdk.LogLevelInfo, "#%d: %s", stageNumber, color.HiBlackString(line))
342342
}
343343
})
344344

@@ -474,7 +474,6 @@ func Run(ctx context.Context, options Options) error {
474474
cacheTTL = time.Hour * 24 * time.Duration(options.CacheTTLDays)
475475
}
476476

477-
endStage := startStage("🏗️ Building image...")
478477
// At this point we have all the context, we can now build!
479478
registryMirror := []string{}
480479
if val, ok := os.LookupEnv("KANIKO_REGISTRY_MIRROR"); ok {
@@ -492,7 +491,7 @@ func Run(ctx context.Context, options Options) error {
492491
RunStdout: stdoutWriter,
493492
RunStderr: stderrWriter,
494493
Destinations: destinations,
495-
NoPush: len(destinations) == 0,
494+
NoPush: !options.PushImage || len(destinations) == 0,
496495
CacheRunLayers: true,
497496
CacheCopyLayers: true,
498497
CompressedCaching: true,
@@ -523,15 +522,41 @@ func Run(ctx context.Context, options Options) error {
523522
RegistryMirrors: registryMirror,
524523
},
525524
SrcContext: buildParams.BuildContext,
525+
526+
// For cached image utilization, produce reproducible builds.
527+
Reproducible: options.PushImage,
528+
}
529+
530+
if options.GetCachedImage {
531+
endStage := startStage("🏗️ Building fake image...")
532+
image, err := executor.DoFakeBuild(opts)
533+
if err != nil {
534+
logrus.Infof("unable to build fake image: %s", err)
535+
os.Exit(1)
536+
}
537+
endStage("🏗️ Built fake image!")
538+
digest, err := image.Digest()
539+
if err != nil {
540+
return nil, xerrors.Errorf("image digest: %w", err)
541+
}
542+
543+
_, _ = fmt.Fprintf(os.Stdout, "%s@%s\n", options.CacheRepo, digest.String())
544+
os.Exit(0)
526545
}
546+
547+
endStage := startStage("🏗️ Building image...")
527548
image, err := executor.DoBuild(opts)
528549
if err != nil {
529550
return nil, xerrors.Errorf("do build: %w", err)
530551
}
531-
if err := executor.DoPush(image, opts); err != nil {
532-
return nil, xerrors.Errorf("do push: %w", err)
533-
}
534552
endStage("🏗️ Built image!")
553+
if options.PushImage {
554+
endStage = startStage("🏗️ Pushing image...")
555+
if err := executor.DoPush(image, opts); err != nil {
556+
return nil, xerrors.Errorf("do push: %w", err)
557+
}
558+
endStage("🏗️ Pushed image!")
559+
}
535560

536561
return image, err
537562
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ toolchain go1.22.3
66

77
// There are a few options we need added to Kaniko!
88
// See: https://github.com/GoogleContainerTools/kaniko/compare/main...coder:kaniko:main
9-
replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240524082248-9d0d55902c34
9+
replace github.com/GoogleContainerTools/kaniko => github.com/coder/kaniko v0.0.0-20240530135420-68a0b6735395
1010

1111
require (
1212
cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,8 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
121121
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
122122
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
123123
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
124-
github.com/coder/kaniko v0.0.0-20240524082248-9d0d55902c34 h1:Wm7sMNc1aTN5l0NerYHb3LZdQJVQp4QrW4v83N21sfc=
125-
github.com/coder/kaniko v0.0.0-20240524082248-9d0d55902c34/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM=
124+
github.com/coder/kaniko v0.0.0-20240530135420-68a0b6735395 h1:xXYQkWPtu9zyhGKP1wnFjPoH9wTQksyNAFnS4xZWdxA=
125+
github.com/coder/kaniko v0.0.0-20240530135420-68a0b6735395/go.mod h1:YMK7BlxerzLlMwihGxNWUaFoN9LXCij4P+w/8/fNlcM=
126126
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs=
127127
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc=
128128
github.com/coder/retry v1.5.1 h1:iWu8YnD8YqHs3XwqrqsjoBTAVqT9ml6z9ViJ2wlMiqc=

options.go

+21
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ type Options struct {
138138
// CoderAgentSubsystem is the Coder agent subsystems to report when forwarding
139139
// logs. The envbuilder subsystem is always included.
140140
CoderAgentSubsystem []string
141+
142+
// PushImage is a flag to determine if the image should be pushed to the
143+
// container registry. This option implies reproducible builds.
144+
PushImage bool
145+
// GetCachedImage is a flag to determine if the cached image is available,
146+
// and if it is, to return it.
147+
GetCachedImage bool
141148
}
142149

143150
const envPrefix = "ENVBUILDER_"
@@ -395,6 +402,20 @@ func (o *Options) CLI() serpent.OptionSet {
395402
Description: "Coder agent subsystems to report when forwarding logs. " +
396403
"The envbuilder subsystem is always included.",
397404
},
405+
{
406+
Flag: "push-image",
407+
Env: WithEnvPrefix("PUSH_IMAGE"),
408+
Value: serpent.BoolOf(&o.PushImage),
409+
Description: "Flag to determine if the image should be pushed to " +
410+
"the container registry. This option implies reproducible builds.",
411+
},
412+
{
413+
Flag: "get-cached-image",
414+
Env: WithEnvPrefix("GET_CACHED_IMAGE"),
415+
Value: serpent.BoolOf(&o.GetCachedImage),
416+
Description: "Flag to determine if the cached image is available, " +
417+
"and if it is, to return it.",
418+
},
398419
}
399420

400421
// Add options without the prefix for backward compatibility. These options

0 commit comments

Comments
 (0)