mirror of
https://github.com/containers/podman.git
synced 2025-07-27 02:12:48 +08:00
Merge pull request #17274 from giuseppe/idmap-rootfs
libpod: support idmap for --rootfs
This commit is contained in:
docs/source/markdown/options
go.modgo.sumlibpod
container_config.gocontainer_internal.gocontainer_internal_common.gocontainer_internal_test.gooptions.goruntime.go
pkg
test/system
vendor
github.com/containers/storage
modules.txt@ -21,3 +21,12 @@ finishes executing, similar to a tmpfs mount point being unmounted.
|
||||
|
||||
Note: On **SELinux** systems, the rootfs needs the correct label, which is by default
|
||||
**unconfined_u:object_r:container_file_t:s0**.
|
||||
|
||||
The `idmap` option if specified, creates an idmapped mount to the target user
|
||||
namespace in the container.
|
||||
The idmap option supports a custom mapping that can be different than the user
|
||||
namespace used by the container. The mapping can be specified after the idmap
|
||||
option like: `idmap=uids=0-1-10#10-11-10;gids=0-100-10`. For each triplet, the
|
||||
first value is the start of the backing file system IDs that are mapped to the
|
||||
second value on the host. The length of this mapping is given in the third value.
|
||||
Multiple ranges are separated with #.
|
||||
|
4
go.mod
4
go.mod
@ -80,7 +80,7 @@ require (
|
||||
github.com/chzyer/readline v1.5.1 // indirect
|
||||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/containerd/containerd v1.6.15 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.13.0 // indirect
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.1 // indirect
|
||||
github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
|
||||
github.com/coreos/go-oidc/v3 v3.5.0 // indirect
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f // indirect
|
||||
@ -177,3 +177,5 @@ require (
|
||||
)
|
||||
|
||||
replace github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
|
||||
|
||||
replace github.com/containers/storage => github.com/containers/storage v1.45.3-0.20230131031022-998b8bf212eb
|
||||
|
23
go.sum
23
go.sum
@ -55,8 +55,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
@ -68,7 +66,6 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
|
||||
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
|
||||
github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
|
||||
@ -81,9 +78,7 @@ github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2
|
||||
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
|
||||
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
|
||||
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
|
||||
github.com/Microsoft/hcsshim v0.8.22/go.mod h1:91uVCVzvX2QD16sMCenoxxXo6L1wJnLMX2PSufFMtF0=
|
||||
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
|
||||
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
github.com/Microsoft/hcsshim v0.9.6 h1:VwnDOgLeoi2du6dAznfmspNqTiwczvjv4K7NxuY9jsY=
|
||||
github.com/Microsoft/hcsshim v0.9.6/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
|
||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||
@ -238,10 +233,8 @@ github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFY
|
||||
github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.9.0/go.mod h1:aE5PCyhFMwR8sbrErO5eM2GcvkyXTTJremG883D4qF0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.12.0/go.mod h1:AIQ59TewBFJ4GOPEQXujcrJ/EKxh5xXZegW1rkR1P/M=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.13.0 h1:fD7AwuVV+B40p0d9qVkH/Au1qhp8hn/HWJHIYjpEcfw=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.13.0/go.mod h1:m+9VaGJGlhCnrcEUod8mYumTmRgblwd3rC5UCEh2Yp0=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.1 h1:n9M2GDSWM96pyipFTA0DaU+zdtzi3Iwsnj/rIHr1yFM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.1/go.mod h1:uPtMw6ucGJYwImjhxk/oghZmfElF/841u86wReNggNk=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
|
||||
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
|
||||
@ -283,10 +276,8 @@ github.com/containers/ocicrypt v1.1.7 h1:thhNr4fu2ltyGz8aMx8u48Ae0Pnbip3ePP9/mzk
|
||||
github.com/containers/ocicrypt v1.1.7/go.mod h1:7CAhjcj2H8AYp5YvEie7oVSK2AhBY8NscCYRawuDNtw=
|
||||
github.com/containers/psgo v1.8.0 h1:2loGekmGAxM9ir5OsXWEfGwFxorMPYnc6gEDsGFQvhY=
|
||||
github.com/containers/psgo v1.8.0/go.mod h1:T8ZxnX3Ur4RvnhxFJ7t8xJ1F48RhiZB4rSrOaR/qGHc=
|
||||
github.com/containers/storage v1.37.0/go.mod h1:kqeJeS0b7DO2ZT1nVWs0XufrmPFbgV3c+Q/45RlH6r4=
|
||||
github.com/containers/storage v1.43.0/go.mod h1:uZ147thiIFGdVTjMmIw19knttQnUCl3y9zjreHrg11s=
|
||||
github.com/containers/storage v1.45.3 h1:GbtTvTtp3GW2/tcFg5VhgHXcYMwVn2KfZKiHjf9FAOM=
|
||||
github.com/containers/storage v1.45.3/go.mod h1:OdRUYHrq1HP6iAo79VxqtYuJzC5j4eA2I60jKOoCT7g=
|
||||
github.com/containers/storage v1.45.3-0.20230131031022-998b8bf212eb h1:1N+upIrgGtvmLKJArMkVbHrGXmkSS8qADIP3RFwoJoI=
|
||||
github.com/containers/storage v1.45.3-0.20230131031022-998b8bf212eb/go.mod h1:ikiIaFiVqg3QAtJWkh/VKQSdSlYE963sxwgHY5rIDu4=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
|
||||
@ -706,9 +697,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.7/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
|
||||
github.com/klauspost/compress v1.15.12/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
|
||||
github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw=
|
||||
github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
@ -877,7 +865,6 @@ github.com/opencontainers/runtime-tools v0.9.1-0.20221014010322-58c91d646d86/go.
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opencontainers/selinux v1.8.5/go.mod h1:HTvjPFoGMbpQsG886e3lQwnsRWtE4TC1OF3OUvG9FAo=
|
||||
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
|
||||
github.com/opencontainers/selinux v1.10.2 h1:NFy2xCsjn7+WspbfZkUd5zyVeisV7VFbPSP96+8/ha4=
|
||||
@ -1056,7 +1043,6 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
|
||||
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
@ -1391,7 +1377,6 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210820121016-41cdb8703e55/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -116,6 +116,8 @@ type ContainerRootFSConfig struct {
|
||||
Rootfs string `json:"rootfs,omitempty"`
|
||||
// RootfsOverlay tells if rootfs has to be mounted as an overlay
|
||||
RootfsOverlay bool `json:"rootfs_overlay,omitempty"`
|
||||
// RootfsMapping specifies if there are mappings to apply to the rootfs.
|
||||
RootfsMapping *string `json:"rootfs_mapping,omitempty"`
|
||||
// ShmDir is the path to be mounted on /dev/shm in container.
|
||||
// If not set manually at creation time, Libpod will create a tmpfs
|
||||
// with the size specified in ShmSize and populate this with the path of
|
||||
|
@ -35,6 +35,7 @@ import (
|
||||
"github.com/containers/podman/v4/pkg/util"
|
||||
"github.com/containers/storage"
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idmap"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/lockfile"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
@ -370,9 +371,6 @@ func (c *Container) syncContainer() error {
|
||||
}
|
||||
|
||||
func (c *Container) setupStorageMapping(dest, from *storage.IDMappingOptions) {
|
||||
if c.config.Rootfs != "" {
|
||||
return
|
||||
}
|
||||
*dest = *from
|
||||
// If we are creating a container inside a pod, we always want to inherit the
|
||||
// userns settings from the infra container. So clear the auto userns settings
|
||||
@ -1525,9 +1523,34 @@ func (c *Container) mountStorage() (_ string, deferredErr error) {
|
||||
// We need to mount the container before volumes - to ensure the copyup
|
||||
// works properly.
|
||||
mountPoint := c.config.Rootfs
|
||||
|
||||
if c.config.RootfsMapping != nil {
|
||||
uidMappings, gidMappings, err := parseIDMapMountOption(c.config.IDMappings, *c.config.RootfsMapping, false)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
pid, cleanupFunc, err := idmap.CreateUsernsProcess(util.RuntimeSpecToIDtools(uidMappings), util.RuntimeSpecToIDtools(gidMappings))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
if err := idmap.CreateIDMappedMount(c.config.Rootfs, c.config.Rootfs, pid); err != nil {
|
||||
return "", fmt.Errorf("failed to create idmapped mount: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if deferredErr != nil {
|
||||
if err := unix.Unmount(c.config.Rootfs, 0); err != nil {
|
||||
logrus.Errorf("Unmounting idmapped rootfs for container %s after mount error: %v", c.ID(), err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// Check if overlay has to be created on top of Rootfs
|
||||
if c.config.RootfsOverlay {
|
||||
overlayDest := c.runtime.RunRoot()
|
||||
overlayDest := c.runtime.GraphRoot()
|
||||
contentDir, err := overlay.GenerateStructure(overlayDest, c.ID(), "rootfs", c.RootUID(), c.RootGID())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("rootfs-overlay: failed to create TempDir in the %s directory: %w", overlayDest, err)
|
||||
@ -1795,6 +1818,11 @@ func (c *Container) cleanupStorage() error {
|
||||
cleanupErr = err
|
||||
}
|
||||
}
|
||||
if c.config.RootfsMapping != nil {
|
||||
if err := unix.Unmount(c.config.Rootfs, 0); err != nil {
|
||||
logrus.Errorf("Unmounting idmapped rootfs for container %s after mount error: %v", c.ID(), err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, containerMount := range c.config.Mounts {
|
||||
if err := c.unmountSHM(containerMount); err != nil {
|
||||
|
@ -74,7 +74,7 @@ func parseOptionIDs(option string) ([]idtools.IDMap, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func parseIDMapMountOption(idMappings stypes.IDMappingOptions, option string) ([]spec.LinuxIDMapping, []spec.LinuxIDMapping, error) {
|
||||
func parseIDMapMountOption(idMappings stypes.IDMappingOptions, option string, invert bool) ([]spec.LinuxIDMapping, []spec.LinuxIDMapping, error) {
|
||||
uidMap := idMappings.UIDMap
|
||||
gidMap := idMappings.GIDMap
|
||||
if strings.HasPrefix(option, "idmap=") {
|
||||
@ -101,17 +101,33 @@ func parseIDMapMountOption(idMappings stypes.IDMappingOptions, option string) ([
|
||||
uidMappings := make([]spec.LinuxIDMapping, len(uidMap))
|
||||
gidMappings := make([]spec.LinuxIDMapping, len(gidMap))
|
||||
for i, uidmap := range uidMap {
|
||||
uidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(uidmap.ContainerID),
|
||||
ContainerID: uint32(uidmap.HostID),
|
||||
Size: uint32(uidmap.Size),
|
||||
if invert {
|
||||
uidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(uidmap.ContainerID),
|
||||
ContainerID: uint32(uidmap.HostID),
|
||||
Size: uint32(uidmap.Size),
|
||||
}
|
||||
} else {
|
||||
uidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(uidmap.HostID),
|
||||
ContainerID: uint32(uidmap.ContainerID),
|
||||
Size: uint32(uidmap.Size),
|
||||
}
|
||||
}
|
||||
}
|
||||
for i, gidmap := range gidMap {
|
||||
gidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(gidmap.ContainerID),
|
||||
ContainerID: uint32(gidmap.HostID),
|
||||
Size: uint32(gidmap.Size),
|
||||
if invert {
|
||||
gidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(gidmap.ContainerID),
|
||||
ContainerID: uint32(gidmap.HostID),
|
||||
Size: uint32(gidmap.Size),
|
||||
}
|
||||
} else {
|
||||
gidMappings[i] = spec.LinuxIDMapping{
|
||||
HostID: uint32(gidmap.HostID),
|
||||
ContainerID: uint32(gidmap.ContainerID),
|
||||
Size: uint32(gidmap.Size),
|
||||
}
|
||||
}
|
||||
}
|
||||
return uidMappings, gidMappings, nil
|
||||
@ -288,7 +304,7 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) {
|
||||
for _, o := range m.Options {
|
||||
if o == "idmap" || strings.HasPrefix(o, "idmap=") {
|
||||
var err error
|
||||
m.UIDMappings, m.GIDMappings, err = parseIDMapMountOption(c.config.IDMappings, o)
|
||||
m.UIDMappings, m.GIDMappings, err = parseIDMapMountOption(c.config.IDMappings, o, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ func TestParseIDMapMountOption(t *testing.T) {
|
||||
UIDMap: uidMap,
|
||||
GIDMap: gidMap,
|
||||
}
|
||||
uids, gids, err := parseIDMapMountOption(options, "idmap")
|
||||
uids, gids, err := parseIDMapMountOption(options, "idmap", true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, len(uids), 1)
|
||||
assert.Equal(t, len(gids), 1)
|
||||
@ -78,7 +78,7 @@ func TestParseIDMapMountOption(t *testing.T) {
|
||||
assert.Equal(t, gids[0].HostID, uint32(0))
|
||||
assert.Equal(t, gids[0].Size, uint32(10000))
|
||||
|
||||
uids, gids, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10")
|
||||
uids, gids, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10", true)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, len(uids), 2)
|
||||
assert.Equal(t, len(gids), 1)
|
||||
@ -95,19 +95,19 @@ func TestParseIDMapMountOption(t *testing.T) {
|
||||
assert.Equal(t, gids[0].HostID, uint32(0))
|
||||
assert.Equal(t, gids[0].Size, uint32(10))
|
||||
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10;foobar=bar")
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10;foobar=bar", true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0-12")
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0-12", true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0-12--12")
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0-12--12", true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#-1-12-12")
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#-1-12-12", true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0--12-0")
|
||||
_, _, err = parseIDMapMountOption(options, "idmap=uids=0-1-10#10-11-10;gids=0-3-10#0--12-0", true)
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
|
@ -1334,7 +1334,7 @@ func WithCommand(command []string) CtrCreateOption {
|
||||
|
||||
// WithRootFS sets the rootfs for the container.
|
||||
// This creates a container from a directory on disk and not an image.
|
||||
func WithRootFS(rootfs string, overlay bool) CtrCreateOption {
|
||||
func WithRootFS(rootfs string, overlay bool, mapping *string) CtrCreateOption {
|
||||
return func(ctr *Container) error {
|
||||
if ctr.valid {
|
||||
return define.ErrCtrFinalized
|
||||
@ -1344,6 +1344,7 @@ func WithRootFS(rootfs string, overlay bool) CtrCreateOption {
|
||||
}
|
||||
ctr.config.Rootfs = rootfs
|
||||
ctr.config.RootfsOverlay = overlay
|
||||
ctr.config.RootfsMapping = mapping
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -973,6 +973,14 @@ func (r *Runtime) RunRoot() string {
|
||||
return r.store.RunRoot()
|
||||
}
|
||||
|
||||
// GraphRoot retrieves the current c/storage directory in use by Libpod.
|
||||
func (r *Runtime) GraphRoot() string {
|
||||
if r.store == nil {
|
||||
return ""
|
||||
}
|
||||
return r.store.GraphRoot()
|
||||
}
|
||||
|
||||
// GetName retrieves the name associated with a given full ID.
|
||||
// This works for both containers and pods, and does not distinguish between the
|
||||
// two.
|
||||
|
@ -118,7 +118,7 @@ func MakeContainer(ctx context.Context, rt *libpod.Runtime, s *specgen.SpecGener
|
||||
}
|
||||
|
||||
if s.Rootfs != "" {
|
||||
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
|
||||
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay, s.RootfsMapping))
|
||||
}
|
||||
|
||||
newImage, resolvedImageName, imageData, err := getImageFromSpec(ctx, rt, s)
|
||||
@ -513,7 +513,7 @@ func createContainerOptions(rt *libpod.Runtime, s *specgen.SpecGenerator, pod *l
|
||||
options = append(options, libpod.WithShmSize(*s.ShmSize))
|
||||
}
|
||||
if s.Rootfs != "" {
|
||||
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay))
|
||||
options = append(options, libpod.WithRootFS(s.Rootfs, s.RootfsOverlay, s.RootfsMapping))
|
||||
}
|
||||
// Default used if not overridden on command line
|
||||
|
||||
|
@ -238,6 +238,8 @@ type ContainerStorageConfig struct {
|
||||
Rootfs string `json:"rootfs,omitempty"`
|
||||
// RootfsOverlay tells if rootfs is actually an overlay on top of base path
|
||||
RootfsOverlay bool `json:"rootfs_overlay,omitempty"`
|
||||
// RootfsMapping specifies if there are mappings to apply to the rootfs.
|
||||
RootfsMapping *string `json:"rootfs_mapping,omitempty"`
|
||||
// ImageVolumeMode indicates how image volumes will be created.
|
||||
// Supported modes are "ignore" (do not create), "tmpfs" (create as
|
||||
// tmpfs), and "anonymous" (create as anonymous volumes).
|
||||
@ -600,9 +602,15 @@ func NewSpecGenerator(arg string, rootfs bool) *SpecGenerator {
|
||||
csc.Rootfs = arg
|
||||
// check if rootfs should use overlay
|
||||
lastColonIndex := strings.LastIndex(csc.Rootfs, ":")
|
||||
if lastColonIndex != -1 && lastColonIndex+1 < len(csc.Rootfs) && csc.Rootfs[lastColonIndex+1:] == "O" {
|
||||
csc.RootfsOverlay = true
|
||||
csc.Rootfs = csc.Rootfs[:lastColonIndex]
|
||||
if lastColonIndex != -1 {
|
||||
lastPart := csc.Rootfs[lastColonIndex+1:]
|
||||
if lastPart == "O" {
|
||||
csc.RootfsOverlay = true
|
||||
csc.Rootfs = csc.Rootfs[:lastColonIndex]
|
||||
} else if lastPart == "idmap" || strings.HasPrefix(lastPart, "idmap=") {
|
||||
csc.RootfsMapping = &lastPart
|
||||
csc.Rootfs = csc.Rootfs[:lastColonIndex]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
csc.Image = arg
|
||||
|
@ -7,19 +7,31 @@ import (
|
||||
)
|
||||
|
||||
func TestNewSpecGeneratorWithRootfs(t *testing.T) {
|
||||
idmap := "idmap"
|
||||
idmapMappings := "idmap=uids=1-1-2000"
|
||||
tests := []struct {
|
||||
rootfs string
|
||||
expectedRootfsOverlay bool
|
||||
expectedRootfs string
|
||||
expectedMapping *string
|
||||
}{
|
||||
{"/root/a:b:O", true, "/root/a:b"},
|
||||
{"/root/a:b/c:O", true, "/root/a:b/c"},
|
||||
{"/root/a:b/c:", false, "/root/a:b/c:"},
|
||||
{"/root/a/b", false, "/root/a/b"},
|
||||
{"/root/a:b:O", true, "/root/a:b", nil},
|
||||
{"/root/a:b/c:O", true, "/root/a:b/c", nil},
|
||||
{"/root/a:b/c:", false, "/root/a:b/c:", nil},
|
||||
{"/root/a/b", false, "/root/a/b", nil},
|
||||
{"/root/a:b/c:idmap", false, "/root/a:b/c", &idmap},
|
||||
{"/root/a:b/c:idmap=uids=1-1-2000", false, "/root/a:b/c", &idmapMappings},
|
||||
}
|
||||
for _, args := range tests {
|
||||
val := NewSpecGenerator(args.rootfs, true)
|
||||
|
||||
assert.Equal(t, val.RootfsOverlay, args.expectedRootfsOverlay)
|
||||
assert.Equal(t, val.Rootfs, args.expectedRootfs)
|
||||
if args.expectedMapping == nil {
|
||||
assert.Nil(t, val.RootfsMapping)
|
||||
} else {
|
||||
assert.NotNil(t, val.RootfsMapping)
|
||||
assert.Equal(t, *val.RootfsMapping, *args.expectedMapping)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -502,6 +502,19 @@ func IDtoolsToRuntimeSpec(idMaps []idtools.IDMap) (convertedIDMap []specs.LinuxI
|
||||
return convertedIDMap
|
||||
}
|
||||
|
||||
// RuntimeSpecToIDtoolsTo converts runtime spec to the one of the idtools ID mapping
|
||||
func RuntimeSpecToIDtools(idMaps []specs.LinuxIDMapping) (convertedIDMap []idtools.IDMap) {
|
||||
for _, idmap := range idMaps {
|
||||
tempIDMap := idtools.IDMap{
|
||||
ContainerID: int(idmap.ContainerID),
|
||||
HostID: int(idmap.HostID),
|
||||
Size: int(idmap.Size),
|
||||
}
|
||||
convertedIDMap = append(convertedIDMap, tempIDMap)
|
||||
}
|
||||
return convertedIDMap
|
||||
}
|
||||
|
||||
func LookupUser(name string) (*user.User, error) {
|
||||
// Assume UID lookup first, if it fails look up by username
|
||||
if u, err := user.LookupId(name); err == nil {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/opencontainers/runtime-spec/specs-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@ -88,3 +89,30 @@ func TestParseInputTime(t *testing.T) {
|
||||
|
||||
assert.Equal(t, expected, tm)
|
||||
}
|
||||
|
||||
func TestConvertMappings(t *testing.T) {
|
||||
start := []specs.LinuxIDMapping{
|
||||
{
|
||||
ContainerID: 1,
|
||||
HostID: 2,
|
||||
Size: 3,
|
||||
},
|
||||
{
|
||||
ContainerID: 4,
|
||||
HostID: 5,
|
||||
Size: 6,
|
||||
},
|
||||
}
|
||||
|
||||
converted := RuntimeSpecToIDtools(start)
|
||||
|
||||
convertedBack := IDtoolsToRuntimeSpec(converted)
|
||||
|
||||
assert.Equal(t, len(start), len(convertedBack))
|
||||
|
||||
for i := range start {
|
||||
assert.Equal(t, start[i].ContainerID, convertedBack[i].ContainerID)
|
||||
assert.Equal(t, start[i].HostID, convertedBack[i].HostID)
|
||||
assert.Equal(t, start[i].Size, convertedBack[i].Size)
|
||||
}
|
||||
}
|
||||
|
@ -1021,4 +1021,38 @@ EOF
|
||||
run_podman run --net=host --cgroupns=host --rm $IMAGE sh -c "grep ' / /sys/fs/cgroup ' /proc/self/mountinfo | tail -n 1 | grep '/sys/fs/cgroup ro'"
|
||||
}
|
||||
|
||||
@test "podman run - rootfs with idmapped mounts" {
|
||||
skip_if_rootless "idmapped mounts work only with root for now"
|
||||
|
||||
skip_if_remote "userns=auto is set on the server"
|
||||
|
||||
egrep -q "^containers:" /etc/subuid || skip "no IDs allocated for user 'containers'"
|
||||
|
||||
# check if the underlying file system supports idmapped mounts
|
||||
check_dir=$PODMAN_TMPDIR/idmap-check
|
||||
mkdir $check_dir
|
||||
run_podman '?' run --rm --uidmap=0:1000:10000 --rootfs $check_dir:idmap true
|
||||
if [[ "$output" == *"failed to create idmapped mount: invalid argument"* ]]; then
|
||||
skip "idmapped mounts not supported"
|
||||
fi
|
||||
|
||||
run_podman image mount $IMAGE
|
||||
src="$output"
|
||||
|
||||
# we cannot use idmap on top of overlay, so we need a copy
|
||||
romount=$PODMAN_TMPDIR/rootfs
|
||||
cp -ar "$src" "$romount"
|
||||
|
||||
run_podman image unmount $IMAGE
|
||||
|
||||
run_podman run --rm --uidmap=0:1000:10000 --rootfs $romount:idmap stat -c %u:%g /bin
|
||||
is "$output" "0:0"
|
||||
|
||||
run_podman run --uidmap=0:1000:10000 --rm --rootfs "$romount:idmap=uids=0-1001-10000;gids=0-1002-10000" stat -c %u:%g /bin
|
||||
is "$output" "1:2"
|
||||
|
||||
rm -rf $romount
|
||||
}
|
||||
|
||||
|
||||
# vim: filetype=sh
|
||||
|
9
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
9
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
@ -78,6 +78,8 @@ fedora_testing_task: &fedora_testing
|
||||
TEST_DRIVER: "fuse-overlay"
|
||||
- env:
|
||||
TEST_DRIVER: "fuse-overlay-whiteout"
|
||||
- env:
|
||||
TEST_DRIVER: "btrfs"
|
||||
|
||||
# Separate scripts for separate outputs, makes debugging easier.
|
||||
setup_script: '${CIRRUS_WORKING_DIR}/${SCRIPT_BASE}/setup.sh |& ${_TIMESTAMP}'
|
||||
@ -90,6 +92,7 @@ fedora_testing_task: &fedora_testing
|
||||
journal_log_script: '${_JOURNALCMD} || true'
|
||||
|
||||
|
||||
# aufs was dropped between 20.04 and 22.04, can't test it
|
||||
ubuntu_testing_task: &ubuntu_testing
|
||||
<<: *fedora_testing
|
||||
alias: ubuntu_testing
|
||||
@ -102,6 +105,12 @@ ubuntu_testing_task: &ubuntu_testing
|
||||
TEST_DRIVER: "vfs"
|
||||
- env:
|
||||
TEST_DRIVER: "overlay"
|
||||
- env:
|
||||
TEST_DRIVER: "fuse-overlay"
|
||||
- env:
|
||||
TEST_DRIVER: "fuse-overlay-whiteout"
|
||||
- env:
|
||||
TEST_DRIVER: "btrfs"
|
||||
|
||||
|
||||
lint_task:
|
||||
|
42
vendor/github.com/containers/storage/Makefile
generated
vendored
42
vendor/github.com/containers/storage/Makefile
generated
vendored
@ -3,25 +3,19 @@ export GOPROXY=https://proxy.golang.org
|
||||
|
||||
.PHONY: \
|
||||
all \
|
||||
binary \
|
||||
clean \
|
||||
cross \
|
||||
default \
|
||||
docs \
|
||||
gccgo \
|
||||
help \
|
||||
install.tools \
|
||||
local-binary \
|
||||
local-cross \
|
||||
local-gccgo \
|
||||
local-test \
|
||||
local-test-integration \
|
||||
local-test-unit \
|
||||
local-validate \
|
||||
lint \
|
||||
test \
|
||||
test-integration \
|
||||
test-unit \
|
||||
validate \
|
||||
vendor
|
||||
|
||||
PACKAGE := github.com/containers/storage
|
||||
@ -40,14 +34,12 @@ ifeq ($(shell $(GO) help mod >/dev/null 2>&1 && echo true), true)
|
||||
MOD_VENDOR=-mod=vendor
|
||||
endif
|
||||
|
||||
RUNINVM := vagrant/runinvm.sh
|
||||
|
||||
default all: local-binary docs local-validate local-cross local-gccgo test-unit test-integration ## validate all checks, build and cross-build\nbinaries and docs, run tests in a VM
|
||||
default all: local-binary docs local-validate local-cross ## validate all checks, build and cross-build\nbinaries and docs
|
||||
|
||||
clean: ## remove all built files
|
||||
$(RM) -f containers-storage containers-storage.* docs/*.1 docs/*.5
|
||||
|
||||
sources := $(wildcard *.go cmd/containers-storage/*.go drivers/*.go drivers/*/*.go pkg/*/*.go pkg/*/*/*.go)
|
||||
sources := $(wildcard *.go cmd/containers-storage/*.go drivers/*.go drivers/*/*.go internal/*/*.go pkg/*/*.go pkg/*/*/*.go types/*.go)
|
||||
containers-storage: $(sources) ## build using gc on the host
|
||||
$(GO) build $(MOD_VENDOR) -compiler gc $(BUILDFLAGS) ./cmd/containers-storage
|
||||
|
||||
@ -56,10 +48,10 @@ codespell:
|
||||
|
||||
binary local-binary: containers-storage
|
||||
|
||||
local-gccgo: ## build using gccgo on the host
|
||||
local-gccgo gccgo: ## build using gccgo on the host
|
||||
GCCGO=$(PWD)/hack/gccgo-wrapper.sh $(GO) build $(MOD_VENDOR) -compiler gccgo $(BUILDFLAGS) -o containers-storage.gccgo ./cmd/containers-storage
|
||||
|
||||
local-cross: ## cross build the binaries for arm, darwin, and freebsd
|
||||
local-cross cross: ## cross build the binaries for arm, darwin, and freebsd
|
||||
@for target in linux/amd64 linux/386 linux/arm linux/arm64 linux/ppc64 linux/ppc64le linux/s390x linux/mips linux/mipsle linux/mips64 linux/mips64le darwin/amd64 windows/amd64 freebsd/amd64 freebsd/arm64 ; do \
|
||||
os=`echo $${target} | cut -f1 -d/` ; \
|
||||
arch=`echo $${target} | cut -f2 -d/` ; \
|
||||
@ -68,37 +60,21 @@ local-cross: ## cross build the binaries for arm, darwin, and freebsd
|
||||
env CGO_ENABLED=0 GOOS=$${os} GOARCH=$${arch} $(GO) build $(MOD_VENDOR) -compiler gc -tags "$(NATIVETAGS) $(TAGS)" $(FLAGS) -o containers-storage.$${suffix} ./cmd/containers-storage || exit 1 ; \
|
||||
done
|
||||
|
||||
cross: ## cross build the binaries for arm, darwin, and\nfreebsd using VMs
|
||||
$(RUNINVM) $(MAKE) local-$@
|
||||
|
||||
docs: install.tools ## build the docs on the host
|
||||
$(MAKE) -C docs docs
|
||||
|
||||
gccgo: ## build using gccgo using VMs
|
||||
$(RUNINVM) $(MAKE) local-$@
|
||||
local-test: local-binary local-test-unit local-test-integration ## build the binaries and run the tests
|
||||
|
||||
test: local-binary ## build the binaries and run the tests using VMs
|
||||
$(RUNINVM) $(MAKE) local-binary local-cross local-test-unit local-test-integration
|
||||
|
||||
local-test-unit: local-binary ## run the unit tests on the host (requires\nsuperuser privileges)
|
||||
local-test-unit test-unit: local-binary ## run the unit tests on the host (requires\nsuperuser privileges)
|
||||
@$(GO) test $(MOD_VENDOR) $(BUILDFLAGS) $(TESTFLAGS) $(shell $(GO) list ./... | grep -v ^$(PACKAGE)/vendor)
|
||||
|
||||
test-unit: local-binary ## run the unit tests using VMs
|
||||
$(RUNINVM) $(MAKE) local-$@
|
||||
|
||||
local-test-integration: local-binary ## run the integration tests on the host (requires\nsuperuser privileges)
|
||||
local-test-integration test-integration: local-binary ## run the integration tests on the host (requires\nsuperuser privileges)
|
||||
@cd tests; ./test_runner.bash
|
||||
|
||||
test-integration: local-binary ## run the integration tests using VMs
|
||||
$(RUNINVM) $(MAKE) local-$@
|
||||
|
||||
local-validate: install.tools ## validate DCO and gofmt on the host
|
||||
local-validate validate: install.tools ## validate DCO and gofmt on the host
|
||||
@./hack/git-validation.sh
|
||||
@./hack/gofmt.sh
|
||||
|
||||
validate: ## validate DCO, gofmt, ./pkg/ isolation, golint,\ngo vet and vendor using VMs
|
||||
$(RUNINVM) $(MAKE) local-$@
|
||||
|
||||
install.tools:
|
||||
$(MAKE) -C tests/tools
|
||||
|
||||
|
2
vendor/github.com/containers/storage/VERSION
generated
vendored
2
vendor/github.com/containers/storage/VERSION
generated
vendored
@ -1 +1 @@
|
||||
1.45.3
|
||||
1.45.3-dev
|
||||
|
2
vendor/github.com/containers/storage/containers.go
generated
vendored
2
vendor/github.com/containers/storage/containers.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
||||
"github.com/containers/storage/pkg/stringid"
|
||||
"github.com/containers/storage/pkg/truncindex"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type containerLocations uint8
|
||||
@ -420,6 +421,7 @@ func (r *containerStore) GarbageCollect() error {
|
||||
}
|
||||
|
||||
// Otherwise remove datadir
|
||||
logrus.Debugf("removing %q", filepath.Join(r.dir, id))
|
||||
moreErr := os.RemoveAll(filepath.Join(r.dir, id))
|
||||
// Propagate first error
|
||||
if moreErr != nil && err == nil {
|
||||
|
7
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
7
vendor/github.com/containers/storage/drivers/overlay/check.go
generated
vendored
@ -12,6 +12,7 @@ import (
|
||||
"syscall"
|
||||
|
||||
"github.com/containers/storage/pkg/archive"
|
||||
"github.com/containers/storage/pkg/idmap"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/ioutils"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
@ -243,20 +244,20 @@ func supportsIdmappedLowerLayers(home string) (bool, error) {
|
||||
_ = idtools.MkdirAs(upperDir, 0700, 0, 0)
|
||||
_ = idtools.MkdirAs(workDir, 0700, 0, 0)
|
||||
|
||||
idmap := []idtools.IDMap{
|
||||
mapping := []idtools.IDMap{
|
||||
{
|
||||
ContainerID: 0,
|
||||
HostID: 0,
|
||||
Size: 1,
|
||||
},
|
||||
}
|
||||
pid, cleanupFunc, err := createUsernsProcess(idmap, idmap)
|
||||
pid, cleanupFunc, err := idmap.CreateUsernsProcess(mapping, mapping)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer cleanupFunc()
|
||||
|
||||
if err := createIDMappedMount(lowerDir, lowerMappedDir, int(pid)); err != nil {
|
||||
if err := idmap.CreateIDMappedMount(lowerDir, lowerMappedDir, int(pid)); err != nil {
|
||||
return false, fmt.Errorf("create mapped mount: %w", err)
|
||||
}
|
||||
defer unix.Unmount(lowerMappedDir, unix.MNT_DETACH)
|
||||
|
5
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
5
vendor/github.com/containers/storage/drivers/overlay/overlay.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
||||
"github.com/containers/storage/pkg/chrootarchive"
|
||||
"github.com/containers/storage/pkg/directory"
|
||||
"github.com/containers/storage/pkg/fsutils"
|
||||
"github.com/containers/storage/pkg/idmap"
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
"github.com/containers/storage/pkg/mount"
|
||||
"github.com/containers/storage/pkg/parsers"
|
||||
@ -1511,7 +1512,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
return "", err
|
||||
}
|
||||
|
||||
pid, cleanupFunc, err := createUsernsProcess(options.UidMaps, options.GidMaps)
|
||||
pid, cleanupFunc, err := idmap.CreateUsernsProcess(options.UidMaps, options.GidMaps)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -1528,7 +1529,7 @@ func (d *Driver) get(id string, disableShifting bool, options graphdriver.MountO
|
||||
if !found {
|
||||
root = filepath.Join(mappedRoot, fmt.Sprintf("%d", c))
|
||||
c++
|
||||
if err := createIDMappedMount(mappedMountSrc, root, int(pid)); err != nil {
|
||||
if err := idmap.CreateIDMappedMount(mappedMountSrc, root, int(pid)); err != nil {
|
||||
return "", fmt.Errorf("create mapped mount for %q on %q: %w", mappedMountSrc, root, err)
|
||||
}
|
||||
idMappedMounts[mappedMountSrc] = root
|
||||
|
39
vendor/github.com/containers/storage/images.go
generated
vendored
39
vendor/github.com/containers/storage/images.go
generated
vendored
@ -14,6 +14,7 @@ import (
|
||||
"github.com/containers/storage/pkg/stringutils"
|
||||
"github.com/containers/storage/pkg/truncindex"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -152,6 +153,9 @@ type rwImageStore interface {
|
||||
addMappedTopLayer(id, layer string) error
|
||||
removeMappedTopLayer(id, layer string) error
|
||||
|
||||
// Clean up unreferenced per-image data.
|
||||
GarbageCollect() error
|
||||
|
||||
// Wipe removes records of all images.
|
||||
Wipe() error
|
||||
}
|
||||
@ -396,6 +400,41 @@ func (r *imageStore) Images() ([]Image, error) {
|
||||
return images, nil
|
||||
}
|
||||
|
||||
// This looks for datadirs in the store directory that are not referenced
|
||||
// by the json file and removes it. These can happen in the case of unclean
|
||||
// shutdowns.
|
||||
// Requires startReading or startWriting.
|
||||
func (r *imageStore) GarbageCollect() error {
|
||||
entries, err := os.ReadDir(r.dir)
|
||||
if err != nil {
|
||||
// Unexpected, don't try any GC
|
||||
return err
|
||||
}
|
||||
|
||||
for _, entry := range entries {
|
||||
id := entry.Name()
|
||||
// Does it look like a datadir directory?
|
||||
if !entry.IsDir() || !nameLooksLikeID(id) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Should the id be there?
|
||||
if r.byid[id] != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// Otherwise remove datadir
|
||||
logrus.Debugf("removing %q", filepath.Join(r.dir, id))
|
||||
moreErr := os.RemoveAll(filepath.Join(r.dir, id))
|
||||
// Propagate first error
|
||||
if moreErr != nil && err == nil {
|
||||
err = moreErr
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *imageStore) imagespath() string {
|
||||
return filepath.Join(r.dir, "images.json")
|
||||
}
|
||||
|
3
vendor/github.com/containers/storage/layers.go
generated
vendored
3
vendor/github.com/containers/storage/layers.go
generated
vendored
@ -678,10 +678,13 @@ func (r *layerStore) GarbageCollect() error {
|
||||
|
||||
// Remove layer and any related data of unreferenced id
|
||||
if err := r.driver.Remove(id); err != nil {
|
||||
logrus.Debugf("removing driver layer %q", id)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("removing %q", r.tspath(id))
|
||||
os.Remove(r.tspath(id))
|
||||
logrus.Debugf("removing %q", r.datadir(id))
|
||||
os.RemoveAll(r.datadir(id))
|
||||
}
|
||||
return nil
|
||||
|
10
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go → vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go
generated
vendored
10
vendor/github.com/containers/storage/drivers/overlay/idmapped_utils.go → vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go
generated
vendored
@ -1,7 +1,7 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package overlay
|
||||
package idmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -77,9 +77,9 @@ func mountSetAttr(dfd int, path string, flags uint, attr *attr, size uint) (err
|
||||
return
|
||||
}
|
||||
|
||||
// createIDMappedMount creates a IDMapped bind mount from SOURCE to TARGET using the user namespace
|
||||
// CreateIDMappedMount creates a IDMapped bind mount from SOURCE to TARGET using the user namespace
|
||||
// for the PID process.
|
||||
func createIDMappedMount(source, target string, pid int) error {
|
||||
func CreateIDMappedMount(source, target string, pid int) error {
|
||||
path := fmt.Sprintf("/proc/%d/ns/user", pid)
|
||||
userNsFile, err := os.Open(path)
|
||||
if err != nil {
|
||||
@ -110,9 +110,9 @@ func createIDMappedMount(source, target string, pid int) error {
|
||||
return moveMount(targetDirFd, target)
|
||||
}
|
||||
|
||||
// createUsernsProcess forks the current process and creates a user namespace using the specified
|
||||
// CreateUsernsProcess forks the current process and creates a user namespace using the specified
|
||||
// mappings. It returns the pid of the new process.
|
||||
func createUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, func(), error) {
|
||||
func CreateUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, func(), error) {
|
||||
var pid uintptr
|
||||
var err syscall.Errno
|
||||
|
22
vendor/github.com/containers/storage/pkg/idmap/idmapped_utils_unsupported.go
generated
vendored
Normal file
22
vendor/github.com/containers/storage/pkg/idmap/idmapped_utils_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
//go:build !linux
|
||||
// +build !linux
|
||||
|
||||
package idmap
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/containers/storage/pkg/idtools"
|
||||
)
|
||||
|
||||
// CreateIDMappedMount creates a IDMapped bind mount from SOURCE to TARGET using the user namespace
|
||||
// for the PID process.
|
||||
func CreateIDMappedMount(source, target string, pid int) error {
|
||||
return fmt.Errorf("IDMapped mounts are not supported")
|
||||
}
|
||||
|
||||
// CreateUsernsProcess forks the current process and creates a user namespace using the specified
|
||||
// mappings. It returns the pid of the new process.
|
||||
func CreateUsernsProcess(uidMaps []idtools.IDMap, gidMaps []idtools.IDMap) (int, func(), error) {
|
||||
return -1, nil, fmt.Errorf("IDMapped mounts are not supported")
|
||||
}
|
9
vendor/github.com/containers/storage/store.go
generated
vendored
9
vendor/github.com/containers/storage/store.go
generated
vendored
@ -3341,7 +3341,14 @@ func (s *store) GarbageCollect() error {
|
||||
return s.containerStore.GarbageCollect()
|
||||
})
|
||||
|
||||
moreErr := s.writeToLayerStore(func(rlstore rwLayerStore) error {
|
||||
moreErr := s.writeToImageStore(func() error {
|
||||
return s.imageStore.GarbageCollect()
|
||||
})
|
||||
if firstErr == nil {
|
||||
firstErr = moreErr
|
||||
}
|
||||
|
||||
moreErr = s.writeToLayerStore(func(rlstore rwLayerStore) error {
|
||||
return rlstore.GarbageCollect()
|
||||
})
|
||||
if firstErr == nil {
|
||||
|
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
@ -79,8 +79,8 @@ github.com/containerd/containerd/log
|
||||
github.com/containerd/containerd/pkg/userns
|
||||
github.com/containerd/containerd/platforms
|
||||
github.com/containerd/containerd/sys
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.13.0
|
||||
## explicit; go 1.16
|
||||
# github.com/containerd/stargz-snapshotter/estargz v0.14.1
|
||||
## explicit; go 1.19
|
||||
github.com/containerd/stargz-snapshotter/estargz
|
||||
github.com/containerd/stargz-snapshotter/estargz/errorutil
|
||||
# github.com/containernetworking/cni v1.1.2
|
||||
@ -276,7 +276,7 @@ github.com/containers/psgo/internal/dev
|
||||
github.com/containers/psgo/internal/host
|
||||
github.com/containers/psgo/internal/proc
|
||||
github.com/containers/psgo/internal/process
|
||||
# github.com/containers/storage v1.45.3
|
||||
# github.com/containers/storage v1.45.3 => github.com/containers/storage v1.45.3-0.20230131031022-998b8bf212eb
|
||||
## explicit; go 1.17
|
||||
github.com/containers/storage
|
||||
github.com/containers/storage/drivers
|
||||
@ -303,6 +303,7 @@ github.com/containers/storage/pkg/dmesg
|
||||
github.com/containers/storage/pkg/fileutils
|
||||
github.com/containers/storage/pkg/fsutils
|
||||
github.com/containers/storage/pkg/homedir
|
||||
github.com/containers/storage/pkg/idmap
|
||||
github.com/containers/storage/pkg/idtools
|
||||
github.com/containers/storage/pkg/ioutils
|
||||
github.com/containers/storage/pkg/locker
|
||||
@ -1130,3 +1131,4 @@ gopkg.in/yaml.v3
|
||||
## explicit; go 1.12
|
||||
sigs.k8s.io/yaml
|
||||
# github.com/opencontainers/runc => github.com/opencontainers/runc v1.1.1-0.20220617142545-8b9452f75cbc
|
||||
# github.com/containers/storage => github.com/containers/storage v1.45.3-0.20230131031022-998b8bf212eb
|
||||
|
Reference in New Issue
Block a user