dockerfile: expose cache sharing options
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>docker-18.09
parent
ccbf185006
commit
cdcab49bfc
|
@ -467,7 +467,11 @@ func dispatchRun(d *dispatchState, c *instructions.RunCommand, proxy *llb.ProxyE
|
||||||
opt = append(opt, llb.WithProxy(*proxy))
|
opt = append(opt, llb.WithProxy(*proxy))
|
||||||
}
|
}
|
||||||
|
|
||||||
opt = append(opt, dispatchRunMounts(d, c, sources, dopt)...)
|
runMounts, err := dispatchRunMounts(d, c, sources, dopt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opt = append(opt, runMounts...)
|
||||||
|
|
||||||
d.state = d.state.Run(opt...).Root()
|
d.state = d.state.Run(opt...).Root()
|
||||||
return commitToHistory(&d.image, "RUN "+runCommandString(args, d.buildArgs), true, &d.state)
|
return commitToHistory(&d.image, "RUN "+runCommandString(args, d.buildArgs), true, &d.state)
|
||||||
|
|
|
@ -11,6 +11,6 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption {
|
func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) {
|
||||||
return nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/moby/buildkit/client/llb"
|
"github.com/moby/buildkit/client/llb"
|
||||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool {
|
func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState, allDispatchStates []*dispatchState) bool {
|
||||||
|
@ -40,7 +41,7 @@ func detectRunMount(cmd *command, dispatchStatesByName map[string]*dispatchState
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) []llb.RunOption {
|
func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*dispatchState, opt dispatchOpt) ([]llb.RunOption, error) {
|
||||||
var out []llb.RunOption
|
var out []llb.RunOption
|
||||||
mounts := instructions.GetMounts(c)
|
mounts := instructions.GetMounts(c)
|
||||||
|
|
||||||
|
@ -61,14 +62,25 @@ func dispatchRunMounts(d *dispatchState, c *instructions.RunCommand, sources []*
|
||||||
mountOpts = append(mountOpts, llb.Readonly)
|
mountOpts = append(mountOpts, llb.Readonly)
|
||||||
}
|
}
|
||||||
if mount.Type == instructions.MountTypeCache {
|
if mount.Type == instructions.MountTypeCache {
|
||||||
mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID, llb.CacheMountShared))
|
sharing := llb.CacheMountShared
|
||||||
|
if mount.CacheSharing == instructions.MountSharingPrivate {
|
||||||
|
sharing = llb.CacheMountPrivate
|
||||||
|
}
|
||||||
|
if mount.CacheSharing == instructions.MountSharingLocked {
|
||||||
|
sharing = llb.CacheMountLocked
|
||||||
|
}
|
||||||
|
mountOpts = append(mountOpts, llb.AsPersistentCacheDir(opt.cacheIDNamespace+"/"+mount.CacheID, sharing))
|
||||||
|
}
|
||||||
|
target := path.Join("/", mount.Target)
|
||||||
|
if target == "/" {
|
||||||
|
return nil, errors.Errorf("invalid mount target %q", mount.Target)
|
||||||
}
|
}
|
||||||
if src := path.Join("/", mount.Source); src != "/" {
|
if src := path.Join("/", mount.Source); src != "/" {
|
||||||
mountOpts = append(mountOpts, llb.SourcePath(src))
|
mountOpts = append(mountOpts, llb.SourcePath(src))
|
||||||
}
|
}
|
||||||
out = append(out, llb.AddMount(path.Join("/", mount.Target), st, mountOpts...))
|
out = append(out, llb.AddMount(target, st, mountOpts...))
|
||||||
|
|
||||||
d.ctxPaths[path.Join("/", filepath.ToSlash(mount.Source))] = struct{}{}
|
d.ctxPaths[path.Join("/", filepath.ToSlash(mount.Source))] = struct{}{}
|
||||||
}
|
}
|
||||||
return out
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,16 @@ var allowedMountTypes = map[string]struct{}{
|
||||||
MountTypeTmpfs: {},
|
MountTypeTmpfs: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MountSharingShared = "shared"
|
||||||
|
const MountSharingPrivate = "private"
|
||||||
|
const MountSharingLocked = "locked"
|
||||||
|
|
||||||
|
var allowedSharingTypes = map[string]struct{}{
|
||||||
|
MountSharingShared: {},
|
||||||
|
MountSharingPrivate: {},
|
||||||
|
MountSharingLocked: {},
|
||||||
|
}
|
||||||
|
|
||||||
type mountsKeyT string
|
type mountsKeyT string
|
||||||
|
|
||||||
var mountsKey = mountsKeyT("dockerfile/run/mounts")
|
var mountsKey = mountsKeyT("dockerfile/run/mounts")
|
||||||
|
@ -76,12 +86,13 @@ type mountState struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mount struct {
|
type Mount struct {
|
||||||
Type string
|
Type string
|
||||||
From string
|
From string
|
||||||
Source string
|
Source string
|
||||||
Target string
|
Target string
|
||||||
ReadOnly bool
|
ReadOnly bool
|
||||||
CacheID string
|
CacheID string
|
||||||
|
CacheSharing string
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseMount(value string) (*Mount, error) {
|
func parseMount(value string) (*Mount, error) {
|
||||||
|
@ -120,7 +131,7 @@ func parseMount(value string) (*Mount, error) {
|
||||||
switch key {
|
switch key {
|
||||||
case "type":
|
case "type":
|
||||||
if !isValidMountType(strings.ToLower(value)) {
|
if !isValidMountType(strings.ToLower(value)) {
|
||||||
return nil, errors.Errorf("invalid mount type %q", value)
|
return nil, errors.Errorf("unsupported mount type %q", value)
|
||||||
}
|
}
|
||||||
m.Type = strings.ToLower(value)
|
m.Type = strings.ToLower(value)
|
||||||
case "from":
|
case "from":
|
||||||
|
@ -144,6 +155,11 @@ func parseMount(value string) (*Mount, error) {
|
||||||
roAuto = false
|
roAuto = false
|
||||||
case "id":
|
case "id":
|
||||||
m.CacheID = value
|
m.CacheID = value
|
||||||
|
case "sharing":
|
||||||
|
if _, ok := allowedSharingTypes[strings.ToLower(value)]; !ok {
|
||||||
|
return nil, errors.Errorf("unsupported sharing value %q", value)
|
||||||
|
}
|
||||||
|
m.CacheSharing = strings.ToLower(value)
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
|
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
|
||||||
}
|
}
|
||||||
|
@ -157,5 +173,9 @@ func parseMount(value string) (*Mount, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.CacheSharing != "" && m.Type != MountTypeCache {
|
||||||
|
return nil, errors.Errorf("invalid cache sharing set for %v mount", m.Type)
|
||||||
|
}
|
||||||
|
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue