Skip to content
This repository was archived by the owner on Jun 3, 2025. It is now read-only.

Commit 38c05ba

Browse files
author
priyawadhwa
authored
Merge pull request #744 from chhsia0/layout-path
Added `--oci-layout-path` flag to save image in OCI layout.
2 parents 1d3cf8a + ea1a927 commit 38c05ba

21 files changed

Lines changed: 1287 additions & 18 deletions

File tree

Gopkg.lock

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gopkg.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ required = [
3737

3838
[[constraint]]
3939
name = "github.com/google/go-containerregistry"
40-
revision = "273af77a08b28b49cc2cff2dd8ae50a5094dac74"
40+
revision = "31e00cede111067bae48bfc2cbfc522b0b36207f"
4141

4242
[[override]]
4343
name = "k8s.io/apimachinery"

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ _If you are interested in contributing to kaniko, see [DEVELOPMENT.md](DEVELOPME
4444
- [--insecure](#--insecure)
4545
- [--insecure-pull](#--insecure-pull)
4646
- [--no-push](#--no-push)
47+
- [--oci-layout-path](#--oci-layout-path)
4748
- [--reproducible](#--reproducible)
4849
- [--single-snapshot](#--single-snapshot)
4950
- [--snapshotMode](#--snapshotmode)
@@ -374,6 +375,19 @@ will write the digest to that file, which is picked up by
374375
Kubernetes automatically as the `{{.state.terminated.message}}`
375376
of the container.
376377

378+
#### --oci-layout-path
379+
380+
Set this flag to specify a directory in the container where the OCI image
381+
layout of a built image will be placed. This can be used to automatically
382+
track the exact image built by Kaniko.
383+
384+
For example, to surface the image digest built in a
385+
[Tekton task](https://github.com/tektoncd/pipeline/blob/v0.6.0/docs/resources.md#surfacing-the-image-digest-built-in-a-task),
386+
this flag should be set to match the image resource `outputImageDir`.
387+
388+
_Note: Depending on the built image, the media type of the image manifest might be either
389+
`application/vnd.oci.image.manifest.v1+json` or `application/vnd.docker.distribution.manifest.v2+json``._
390+
377391
#### --insecure-registry
378392

379393
Set this flag to use plain HTTP requests when accessing a registry. It is supposed to be used for testing purposes only and should not be used in production!

cmd/executor/cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ func addKanikoOptionsFlags(cmd *cobra.Command) {
129129
RootCmd.PersistentFlags().StringVarP(&opts.CacheRepo, "cache-repo", "", "", "Specify a repository to use as a cache, otherwise one will be inferred from the destination provided")
130130
RootCmd.PersistentFlags().StringVarP(&opts.CacheDir, "cache-dir", "", "/cache", "Specify a local directory to use as a cache.")
131131
RootCmd.PersistentFlags().StringVarP(&opts.DigestFile, "digest-file", "", "", "Specify a file to save the digest of the built image to.")
132+
RootCmd.PersistentFlags().StringVarP(&opts.OCILayoutPath, "oci-layout-path", "", "", "Path to save the OCI image layout of the built image.")
132133
RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image")
133134
RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end")
134135
RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout in hours. Defaults to two weeks.")

pkg/config/options.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type KanikoOptions struct {
3737
Target string
3838
CacheRepo string
3939
DigestFile string
40+
OCILayoutPath string
4041
Destinations multiArg
4142
BuildArgs multiArg
4243
Insecure bool

pkg/executor/push.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import (
3434
"github.com/google/go-containerregistry/pkg/name"
3535
"github.com/google/go-containerregistry/pkg/v1"
3636
"github.com/google/go-containerregistry/pkg/v1/empty"
37+
"github.com/google/go-containerregistry/pkg/v1/layout"
3738
"github.com/google/go-containerregistry/pkg/v1/mutate"
3839
"github.com/google/go-containerregistry/pkg/v1/remote"
3940
"github.com/google/go-containerregistry/pkg/v1/tarball"
@@ -101,6 +102,16 @@ func DoPush(image v1.Image, opts *config.KanikoOptions) error {
101102
}
102103
}
103104

105+
if opts.OCILayoutPath != "" {
106+
path, err := layout.Write(opts.OCILayoutPath, empty.Index)
107+
if err != nil {
108+
return errors.Wrap(err, "writing empty layout")
109+
}
110+
if err := path.AppendImage(image); err != nil {
111+
return errors.Wrap(err, "appending image")
112+
}
113+
}
114+
104115
destRefs := []name.Tag{}
105116
for _, destination := range opts.Destinations {
106117
destRef, err := name.NewTag(destination, name.WeakValidation)

pkg/executor/push_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@ import (
2323
"os"
2424
"testing"
2525

26+
"github.com/GoogleContainerTools/kaniko/pkg/config"
2627
"github.com/GoogleContainerTools/kaniko/testutil"
28+
"github.com/google/go-containerregistry/pkg/v1/layout"
29+
"github.com/google/go-containerregistry/pkg/v1/random"
30+
"github.com/google/go-containerregistry/pkg/v1/validate"
2731
)
2832

2933
func TestHeaderAdded(t *testing.T) {
@@ -69,3 +73,49 @@ func (m *mockRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
6973
ua := r.UserAgent()
7074
return &http.Response{Body: ioutil.NopCloser(bytes.NewBufferString(ua))}, nil
7175
}
76+
77+
func TestOCILayoutPath(t *testing.T) {
78+
tmpDir, err := ioutil.TempDir("", "")
79+
if err != nil {
80+
t.Fatalf("could not create temp dir: %s", err)
81+
}
82+
defer os.RemoveAll(tmpDir)
83+
84+
image, err := random.Image(1024, 4)
85+
if err != nil {
86+
t.Fatalf("could not create image: %s", err)
87+
}
88+
89+
digest, err := image.Digest()
90+
if err != nil {
91+
t.Fatalf("could not get image digest: %s", err)
92+
}
93+
94+
want, err := image.Manifest()
95+
if err != nil {
96+
t.Fatalf("could not get image manifest: %s", err)
97+
}
98+
99+
opts := config.KanikoOptions{
100+
NoPush: true,
101+
OCILayoutPath: tmpDir,
102+
}
103+
104+
if err := DoPush(image, &opts); err != nil {
105+
t.Fatalf("could not push image: %s", err)
106+
}
107+
108+
layoutIndex, err := layout.ImageIndexFromPath(tmpDir)
109+
if err != nil {
110+
t.Fatalf("could not get index from layout: %s", err)
111+
}
112+
testutil.CheckError(t, false, validate.Index(layoutIndex))
113+
114+
layoutImage, err := layoutIndex.Image(digest)
115+
if err != nil {
116+
t.Fatalf("could not get image from layout: %s", err)
117+
}
118+
119+
got, err := layoutImage.Manifest()
120+
testutil.CheckErrorAndDeepEqual(t, false, err, want, got)
121+
}

vendor/github.com/google/go-containerregistry/pkg/v1/layout/blob.go

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-containerregistry/pkg/v1/layout/doc.go

Lines changed: 19 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/google/go-containerregistry/pkg/v1/layout/image.go

Lines changed: 131 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)