Merge pull request #1247 from tonistiigi/dangling-naming

exporter: add canonical and dangling image naming
v0.7
Tõnis Tiigi 2019-11-12 10:02:04 -08:00 committed by GitHub
commit e486c1193f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 61 additions and 23 deletions

View File

@ -45,7 +45,7 @@ You don't need to read this document unless you want to use the full-featured st
- [Building a Dockerfile using external frontend:](#building-a-dockerfile-using-external-frontend)
- [Building a Dockerfile with experimental features like `RUN --mount=type=(bind|cache|tmpfs|secret|ssh)`](#building-a-dockerfile-with-experimental-features-like-run---mounttypebindcachetmpfssecretssh)
- [Output](#output)
- [Registry](#registry)
- [Image/Registry](#imageregistry)
- [Local directory](#local-directory)
- [Docker tarball](#docker-tarball)
- [OCI tarball](#oci-tarball)
@ -199,7 +199,7 @@ See [`frontend/dockerfile/docs/experimental.md`](frontend/dockerfile/docs/experi
By default, the build result and intermediate cache will only remain internally in BuildKit. An output needs to be specified to retrieve the result.
#### Registry
#### Image/Registry
```bash
buildctl build ... --output type=image,name=docker.io/username/image,push=true
@ -215,6 +215,17 @@ buildctl build ...\
--import-cache type=registry,ref=docker.io/username/image
```
Keys supported by image output:
* `name=[value]`: image name
* `push=true`: push after creating the image
* `push-by-digest=true`: push unnamed image
* `registry.insecure=true`: push to insecure HTTP registry
* `oci-mediatypes=true`: use OCI mediatypes in configuration JSON instead of Docker's
* `unpack=true`: unpack image after creation (for use with containerd)
* `dangling-name-prefix=[value]`: name image with `prefix@<digest>` , used for anonymous images
* `name-canonical=true`: add additional canonical name `name@<digest>`
If credentials are required, `buildctl` will attempt to read Docker configuration file `$DOCKER_CONFIG/config.json`.
`$DOCKER_CONFIG` defaults to `~/.docker`.

View File

@ -26,12 +26,14 @@ import (
)
const (
keyImageName = "name"
keyPush = "push"
keyPushByDigest = "push-by-digest"
keyInsecure = "registry.insecure"
keyUnpack = "unpack"
ociTypes = "oci-mediatypes"
keyImageName = "name"
keyPush = "push"
keyPushByDigest = "push-by-digest"
keyInsecure = "registry.insecure"
keyUnpack = "unpack"
keyDanglingPrefix = "dangling-name-prefix"
keyNameCanonical = "name-canonical"
ociTypes = "oci-mediatypes"
)
type Opt struct {
@ -111,6 +113,18 @@ func (e *imageExporter) Resolve(ctx context.Context, opt map[string]string) (exp
return nil, errors.Wrapf(err, "non-bool value specified for %s", k)
}
i.ociTypes = b
case keyDanglingPrefix:
i.danglingPrefix = v
case keyNameCanonical:
if v == "" {
i.nameCanonical = true
continue
}
b, err := strconv.ParseBool(v)
if err != nil {
return nil, errors.Wrapf(err, "non-bool value specified for %s", k)
}
i.nameCanonical = b
default:
if i.meta == nil {
i.meta = make(map[string][]byte)
@ -123,13 +137,15 @@ func (e *imageExporter) Resolve(ctx context.Context, opt map[string]string) (exp
type imageExporterInstance struct {
*imageExporter
targetName string
push bool
pushByDigest bool
unpack bool
insecure bool
ociTypes bool
meta map[string][]byte
targetName string
push bool
pushByDigest bool
unpack bool
insecure bool
ociTypes bool
nameCanonical bool
danglingPrefix string
meta map[string][]byte
}
func (e *imageExporterInstance) Name() string {
@ -165,24 +181,35 @@ func (e *imageExporterInstance) Export(ctx context.Context, src exporter.Source)
e.targetName = string(n)
}
nameCanonical := e.nameCanonical
if e.targetName == "" && e.danglingPrefix != "" {
e.targetName = e.danglingPrefix + "@" + desc.Digest.String()
nameCanonical = false
}
if e.targetName != "" {
targetNames := strings.Split(e.targetName, ",")
for _, targetName := range targetNames {
if e.opt.Images != nil {
tagDone := oneOffProgress(ctx, "naming to "+targetName)
img := images.Image{
Name: targetName,
Target: *desc,
CreatedAt: time.Now(),
}
sfx := []string{""}
if nameCanonical {
sfx = append(sfx, "@"+desc.Digest.String())
}
for _, sfx := range sfx {
img.Name = targetName + sfx
if _, err := e.opt.Images.Update(ctx, img); err != nil {
if !errdefs.IsNotFound(err) {
return nil, tagDone(err)
}
if _, err := e.opt.Images.Update(ctx, img); err != nil {
if !errdefs.IsNotFound(err) {
return nil, tagDone(err)
}
if _, err := e.opt.Images.Create(ctx, img); err != nil {
return nil, tagDone(err)
if _, err := e.opt.Images.Create(ctx, img); err != nil {
return nil, tagDone(err)
}
}
}
tagDone(nil)