mirror of
https://github.com/containers/podman.git
synced 2025-11-30 10:07:33 +08:00
Update vendor containers/(common,storage,buildah,image)
Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
143
vendor/github.com/containers/buildah/internal/parse/parse.go
generated
vendored
143
vendor/github.com/containers/buildah/internal/parse/parse.go
generated
vendored
@@ -33,6 +33,9 @@ const (
|
||||
BuildahCacheDir = "buildah-cache"
|
||||
// mount=type=cache allows users to lock a cache store while its being used by another build
|
||||
BuildahCacheLockfile = "buildah-cache-lockfile"
|
||||
// All the lockfiles are stored in a separate directory inside `BuildahCacheDir`
|
||||
// Example `/var/tmp/buildah-cache/<target>/buildah-cache-lockfile`
|
||||
BuildahCacheLockfileDir = "buildah-cache-lockfiles"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -184,10 +187,12 @@ func GetBindMount(ctx *types.SystemContext, args []string, contextDir string, st
|
||||
}
|
||||
|
||||
// GetCacheMount parses a single cache mount entry from the --mount flag.
|
||||
func GetCacheMount(args []string, store storage.Store, imageMountLabel string, additionalMountPoints map[string]internal.StageMountDetails) (specs.Mount, []string, error) {
|
||||
//
|
||||
// If this function succeeds and returns a non-nil lockfile.Locker, the caller must unlock it (when??).
|
||||
func GetCacheMount(args []string, store storage.Store, imageMountLabel string, additionalMountPoints map[string]internal.StageMountDetails) (specs.Mount, lockfile.Locker, error) {
|
||||
var err error
|
||||
var mode uint64
|
||||
lockedTargets := make([]string, 0)
|
||||
var buildahLockFilesDir string
|
||||
var (
|
||||
setDest bool
|
||||
setShared bool
|
||||
@@ -235,59 +240,59 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
sharing = kv[1]
|
||||
case "bind-propagation":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
newMount.Options = append(newMount.Options, kv[1])
|
||||
case "id":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
id = kv[1]
|
||||
case "from":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
fromStage = kv[1]
|
||||
case "target", "dst", "destination":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil {
|
||||
return newMount, lockedTargets, err
|
||||
return newMount, nil, err
|
||||
}
|
||||
newMount.Destination = kv[1]
|
||||
setDest = true
|
||||
case "src", "source":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
newMount.Source = kv[1]
|
||||
case "mode":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
mode, err = strconv.ParseUint(kv[1], 8, 32)
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to parse cache mode: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to parse cache mode: %w", err)
|
||||
}
|
||||
case "uid":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
uid, err = strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to parse cache uid: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to parse cache uid: %w", err)
|
||||
}
|
||||
case "gid":
|
||||
if len(kv) == 1 {
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadOptionArg)
|
||||
}
|
||||
gid, err = strconv.Atoi(kv[1])
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to parse cache gid: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to parse cache gid: %w", err)
|
||||
}
|
||||
default:
|
||||
return newMount, lockedTargets, fmt.Errorf("%v: %w", kv[0], errBadMntOption)
|
||||
return newMount, nil, fmt.Errorf("%v: %w", kv[0], errBadMntOption)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,7 +303,7 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
}
|
||||
|
||||
if !setDest {
|
||||
return newMount, lockedTargets, errBadVolDest
|
||||
return newMount, nil, errBadVolDest
|
||||
}
|
||||
|
||||
if fromStage != "" {
|
||||
@@ -315,7 +320,7 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
// Cache does not supports using image so if not stage found
|
||||
// return with error
|
||||
if mountPoint == "" {
|
||||
return newMount, lockedTargets, fmt.Errorf("no stage found with name %s", fromStage)
|
||||
return newMount, nil, fmt.Errorf("no stage found with name %s", fromStage)
|
||||
}
|
||||
// path should be /contextDir/specified path
|
||||
newMount.Source = filepath.Join(mountPoint, filepath.Clean(string(filepath.Separator)+newMount.Source))
|
||||
@@ -331,13 +336,15 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
// create cache on host if not present
|
||||
err = os.MkdirAll(cacheParent, os.FileMode(0755))
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to create build cache directory: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to create build cache directory: %w", err)
|
||||
}
|
||||
|
||||
if id != "" {
|
||||
newMount.Source = filepath.Join(cacheParent, filepath.Clean(id))
|
||||
buildahLockFilesDir = filepath.Join(BuildahCacheLockfileDir, filepath.Clean(id))
|
||||
} else {
|
||||
newMount.Source = filepath.Join(cacheParent, filepath.Clean(newMount.Destination))
|
||||
buildahLockFilesDir = filepath.Join(BuildahCacheLockfileDir, filepath.Clean(newMount.Destination))
|
||||
}
|
||||
idPair := idtools.IDPair{
|
||||
UID: uid,
|
||||
@@ -346,26 +353,40 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
//buildkit parity: change uid and gid if specified otheriwise keep `0`
|
||||
err = idtools.MkdirAllAndChownNew(newMount.Source, os.FileMode(mode), idPair)
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to change uid,gid of cache directory: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to change uid,gid of cache directory: %w", err)
|
||||
}
|
||||
|
||||
// create a subdirectory inside `cacheParent` just to store lockfiles
|
||||
buildahLockFilesDir = filepath.Join(cacheParent, buildahLockFilesDir)
|
||||
err = os.MkdirAll(buildahLockFilesDir, os.FileMode(0700))
|
||||
if err != nil {
|
||||
return newMount, nil, fmt.Errorf("unable to create build cache lockfiles directory: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var targetLock lockfile.Locker // = nil
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded && targetLock != nil {
|
||||
targetLock.Unlock()
|
||||
}
|
||||
}()
|
||||
switch sharing {
|
||||
case "locked":
|
||||
// lock parent cache
|
||||
lockfile, err := lockfile.GetLockfile(filepath.Join(newMount.Source, BuildahCacheLockfile))
|
||||
lockfile, err := lockfile.GetLockfile(filepath.Join(buildahLockFilesDir, BuildahCacheLockfile))
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, fmt.Errorf("unable to acquire lock when sharing mode is locked: %w", err)
|
||||
return newMount, nil, fmt.Errorf("unable to acquire lock when sharing mode is locked: %w", err)
|
||||
}
|
||||
// Will be unlocked after the RUN step is executed.
|
||||
lockfile.Lock()
|
||||
lockedTargets = append(lockedTargets, filepath.Join(newMount.Source, BuildahCacheLockfile))
|
||||
targetLock = lockfile
|
||||
case "shared":
|
||||
// do nothing since default is `shared`
|
||||
break
|
||||
default:
|
||||
// error out for unknown values
|
||||
return newMount, lockedTargets, fmt.Errorf("unrecognized value %q for field `sharing`: %w", sharing, err)
|
||||
return newMount, nil, fmt.Errorf("unrecognized value %q for field `sharing`: %w", sharing, err)
|
||||
}
|
||||
|
||||
// buildkit parity: default sharing should be shared
|
||||
@@ -383,11 +404,12 @@ func GetCacheMount(args []string, store storage.Store, imageMountLabel string, a
|
||||
|
||||
opts, err := parse.ValidateVolumeOpts(newMount.Options)
|
||||
if err != nil {
|
||||
return newMount, lockedTargets, err
|
||||
return newMount, nil, err
|
||||
}
|
||||
newMount.Options = opts
|
||||
|
||||
return newMount, lockedTargets, nil
|
||||
succeeded = true
|
||||
return newMount, targetLock, nil
|
||||
}
|
||||
|
||||
// ValidateVolumeMountHostDir validates the host path of buildah --volume
|
||||
@@ -474,19 +496,34 @@ func Volume(volume string) (specs.Mount, error) {
|
||||
return mount, nil
|
||||
}
|
||||
|
||||
// GetVolumes gets the volumes from --volume and --mount
|
||||
func GetVolumes(ctx *types.SystemContext, store storage.Store, volumes []string, mounts []string, contextDir string) ([]specs.Mount, []string, []string, error) {
|
||||
unifiedMounts, mountedImages, lockedTargets, err := getMounts(ctx, store, mounts, contextDir)
|
||||
if err != nil {
|
||||
return nil, mountedImages, lockedTargets, err
|
||||
// UnlockLockArray is a helper for cleaning up after GetVolumes and the like.
|
||||
func UnlockLockArray(locks []lockfile.Locker) {
|
||||
for _, lock := range locks {
|
||||
lock.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// GetVolumes gets the volumes from --volume and --mount
|
||||
//
|
||||
// If this function succeeds, the caller must unlock the returned lockfile.Lockers if any (when??).
|
||||
func GetVolumes(ctx *types.SystemContext, store storage.Store, volumes []string, mounts []string, contextDir string) ([]specs.Mount, []string, []lockfile.Locker, error) {
|
||||
unifiedMounts, mountedImages, targetLocks, err := getMounts(ctx, store, mounts, contextDir)
|
||||
if err != nil {
|
||||
return nil, mountedImages, nil, err
|
||||
}
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
UnlockLockArray(targetLocks)
|
||||
}
|
||||
}()
|
||||
volumeMounts, err := getVolumeMounts(volumes)
|
||||
if err != nil {
|
||||
return nil, mountedImages, lockedTargets, err
|
||||
return nil, mountedImages, nil, err
|
||||
}
|
||||
for dest, mount := range volumeMounts {
|
||||
if _, ok := unifiedMounts[dest]; ok {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%v: %w", dest, errDuplicateDest)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%v: %w", dest, errDuplicateDest)
|
||||
}
|
||||
unifiedMounts[dest] = mount
|
||||
}
|
||||
@@ -495,19 +532,28 @@ func GetVolumes(ctx *types.SystemContext, store storage.Store, volumes []string,
|
||||
for _, mount := range unifiedMounts {
|
||||
finalMounts = append(finalMounts, mount)
|
||||
}
|
||||
return finalMounts, mountedImages, lockedTargets, nil
|
||||
succeeded = true
|
||||
return finalMounts, mountedImages, targetLocks, nil
|
||||
}
|
||||
|
||||
// getMounts takes user-provided input from the --mount flag and creates OCI
|
||||
// spec mounts.
|
||||
// buildah run --mount type=bind,src=/etc/resolv.conf,target=/etc/resolv.conf ...
|
||||
// buildah run --mount type=tmpfs,target=/dev/shm ...
|
||||
func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, contextDir string) (map[string]specs.Mount, []string, []string, error) {
|
||||
//
|
||||
// If this function succeeds, the caller must unlock the returned lockfile.Lockers if any (when??).
|
||||
func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, contextDir string) (map[string]specs.Mount, []string, []lockfile.Locker, error) {
|
||||
// If `type` is not set default to "bind"
|
||||
mountType := TypeBind
|
||||
finalMounts := make(map[string]specs.Mount)
|
||||
mountedImages := make([]string, 0)
|
||||
lockedTargets := make([]string, 0)
|
||||
targetLocks := make([]lockfile.Locker, 0)
|
||||
succeeded := false
|
||||
defer func() {
|
||||
if !succeeded {
|
||||
UnlockLockArray(targetLocks)
|
||||
}
|
||||
}()
|
||||
|
||||
errInvalidSyntax := errors.New("incorrect mount format: should be --mount type=<bind|tmpfs>,[src=<host-dir>,]target=<ctr-dir>[,options]")
|
||||
|
||||
@@ -517,13 +563,13 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c
|
||||
for _, mount := range mounts {
|
||||
tokens := strings.Split(mount, ",")
|
||||
if len(tokens) < 2 {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%q: %w", mount, errInvalidSyntax)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%q: %w", mount, errInvalidSyntax)
|
||||
}
|
||||
for _, field := range tokens {
|
||||
if strings.HasPrefix(field, "type=") {
|
||||
kv := strings.Split(field, "=")
|
||||
if len(kv) != 2 {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%q: %w", mount, errInvalidSyntax)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%q: %w", mount, errInvalidSyntax)
|
||||
}
|
||||
mountType = kv[1]
|
||||
}
|
||||
@@ -532,38 +578,41 @@ func getMounts(ctx *types.SystemContext, store storage.Store, mounts []string, c
|
||||
case TypeBind:
|
||||
mount, image, err := GetBindMount(ctx, tokens, contextDir, store, "", nil)
|
||||
if err != nil {
|
||||
return nil, mountedImages, lockedTargets, err
|
||||
return nil, mountedImages, nil, err
|
||||
}
|
||||
if _, ok := finalMounts[mount.Destination]; ok {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
}
|
||||
finalMounts[mount.Destination] = mount
|
||||
mountedImages = append(mountedImages, image)
|
||||
case TypeCache:
|
||||
mount, lockedPaths, err := GetCacheMount(tokens, store, "", nil)
|
||||
lockedTargets = lockedPaths
|
||||
mount, tl, err := GetCacheMount(tokens, store, "", nil)
|
||||
if err != nil {
|
||||
return nil, mountedImages, lockedTargets, err
|
||||
return nil, mountedImages, nil, err
|
||||
}
|
||||
if tl != nil {
|
||||
targetLocks = append(targetLocks, tl)
|
||||
}
|
||||
if _, ok := finalMounts[mount.Destination]; ok {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
}
|
||||
finalMounts[mount.Destination] = mount
|
||||
case TypeTmpfs:
|
||||
mount, err := GetTmpfsMount(tokens)
|
||||
if err != nil {
|
||||
return nil, mountedImages, lockedTargets, err
|
||||
return nil, mountedImages, nil, err
|
||||
}
|
||||
if _, ok := finalMounts[mount.Destination]; ok {
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
return nil, mountedImages, nil, fmt.Errorf("%v: %w", mount.Destination, errDuplicateDest)
|
||||
}
|
||||
finalMounts[mount.Destination] = mount
|
||||
default:
|
||||
return nil, mountedImages, lockedTargets, fmt.Errorf("invalid filesystem type %q", mountType)
|
||||
return nil, mountedImages, nil, fmt.Errorf("invalid filesystem type %q", mountType)
|
||||
}
|
||||
}
|
||||
|
||||
return finalMounts, mountedImages, lockedTargets, nil
|
||||
succeeded = true
|
||||
return finalMounts, mountedImages, targetLocks, nil
|
||||
}
|
||||
|
||||
// GetTmpfsMount parses a single tmpfs mount entry from the --mount flag
|
||||
|
||||
Reference in New Issue
Block a user