Merge pull request #872 from giuseppe/use-user-xattr-for-unprivileged-overlay
rootless overlay: use user.* instead of trusted.*
This commit is contained in:
commit
c54ada0fc7
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"github.com/containers/storage/pkg/idtools"
|
"github.com/containers/storage/pkg/idtools"
|
||||||
"github.com/containers/storage/pkg/pools"
|
"github.com/containers/storage/pkg/pools"
|
||||||
"github.com/containers/storage/pkg/system"
|
"github.com/containers/storage/pkg/system"
|
||||||
|
"github.com/containers/storage/pkg/unshare"
|
||||||
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
@ -293,6 +294,10 @@ func doCopyXattrs(srcPath, dstPath string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if unshare.IsRootless() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// We need to copy this attribute if it appears in an overlay upper layer, as
|
// We need to copy this attribute if it appears in an overlay upper layer, as
|
||||||
// this function is used to copy those. It is set by overlay if a directory
|
// this function is used to copy those. It is set by overlay if a directory
|
||||||
// is removed and then re-created and should not inherit anything from the
|
// is removed and then re-created and should not inherit anything from the
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containers/storage/pkg/archive"
|
||||||
"github.com/containers/storage/pkg/ioutils"
|
"github.com/containers/storage/pkg/ioutils"
|
||||||
"github.com/containers/storage/pkg/mount"
|
"github.com/containers/storage/pkg/mount"
|
||||||
"github.com/containers/storage/pkg/system"
|
"github.com/containers/storage/pkg/system"
|
||||||
|
|
@ -54,7 +55,7 @@ func doesSupportNativeDiff(d, mountOpts string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark l2/d as opaque
|
// Mark l2/d as opaque
|
||||||
if err := system.Lsetxattr(filepath.Join(td, "l2", "d"), "trusted.overlay.opaque", []byte("y"), 0); err != nil {
|
if err := system.Lsetxattr(filepath.Join(td, "l2", "d"), archive.GetOverlayXattrName("opaque"), []byte("y"), 0); err != nil {
|
||||||
return errors.Wrap(err, "failed to set opaque flag on middle layer")
|
return errors.Wrap(err, "failed to set opaque flag on middle layer")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -78,7 +79,7 @@ func doesSupportNativeDiff(d, mountOpts string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check l3/d does not have opaque flag
|
// Check l3/d does not have opaque flag
|
||||||
xattrOpaque, err := system.Lgetxattr(filepath.Join(td, "l3", "d"), "trusted.overlay.opaque")
|
xattrOpaque, err := system.Lgetxattr(filepath.Join(td, "l3", "d"), archive.GetOverlayXattrName("opaque"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to read opaque flag on upper layer")
|
return errors.Wrap(err, "failed to read opaque flag on upper layer")
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +96,7 @@ func doesSupportNativeDiff(d, mountOpts string) error {
|
||||||
return errors.Wrap(err, "failed to rename dir in merged directory")
|
return errors.Wrap(err, "failed to rename dir in merged directory")
|
||||||
}
|
}
|
||||||
// get the xattr of "d2"
|
// get the xattr of "d2"
|
||||||
xattrRedirect, err := system.Lgetxattr(filepath.Join(td, "l3", "d2"), "trusted.overlay.redirect")
|
xattrRedirect, err := system.Lgetxattr(filepath.Join(td, "l3", "d2"), archive.GetOverlayXattrName("redirect"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to read redirect flag on upper layer")
|
return errors.Wrap(err, "failed to read redirect flag on upper layer")
|
||||||
}
|
}
|
||||||
|
|
@ -161,7 +162,7 @@ func doesMetacopy(d, mountOpts string) (bool, error) {
|
||||||
if err := os.Chmod(filepath.Join(td, "merged", "f"), 0600); err != nil {
|
if err := os.Chmod(filepath.Join(td, "merged", "f"), 0600); err != nil {
|
||||||
return false, errors.Wrap(err, "error changing permissions on file for metacopy check")
|
return false, errors.Wrap(err, "error changing permissions on file for metacopy check")
|
||||||
}
|
}
|
||||||
metacopy, err := system.Lgetxattr(filepath.Join(td, "l2", "f"), "trusted.overlay.metacopy")
|
metacopy, err := system.Lgetxattr(filepath.Join(td, "l2", "f"), archive.GetOverlayXattrName("metacopy"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, errors.Wrap(err, "metacopy flag was not set on file in upper layer")
|
return false, errors.Wrap(err, "metacopy flag was not set on file in upper layer")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"github.com/containers/storage/pkg/pools"
|
"github.com/containers/storage/pkg/pools"
|
||||||
"github.com/containers/storage/pkg/promise"
|
"github.com/containers/storage/pkg/promise"
|
||||||
"github.com/containers/storage/pkg/system"
|
"github.com/containers/storage/pkg/system"
|
||||||
|
"github.com/containers/storage/pkg/unshare"
|
||||||
gzip "github.com/klauspost/pgzip"
|
gzip "github.com/klauspost/pgzip"
|
||||||
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
rsystem "github.com/opencontainers/runc/libcontainer/system"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
@ -1489,3 +1490,14 @@ func TarPath(uidmap []idtools.IDMap, gidmap []idtools.IDMap) func(path string) (
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOverlayXattrName returns the xattr used by the overlay driver with the
|
||||||
|
// given name.
|
||||||
|
// It uses the trusted.overlay prefix when running as root, and user.overlay
|
||||||
|
// in rootless mode.
|
||||||
|
func GetOverlayXattrName(name string) string {
|
||||||
|
if unshare.IsRootless() {
|
||||||
|
return fmt.Sprintf("user.overlay.%s", name)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("trusted.overlay.%s", name)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ import (
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getOverlayOpaqueXattrName() string {
|
||||||
|
return GetOverlayXattrName("opaque")
|
||||||
|
}
|
||||||
|
|
||||||
func GetWhiteoutConverter(format WhiteoutFormat, data interface{}) TarWhiteoutConverter {
|
func GetWhiteoutConverter(format WhiteoutFormat, data interface{}) TarWhiteoutConverter {
|
||||||
if format == OverlayWhiteoutFormat {
|
if format == OverlayWhiteoutFormat {
|
||||||
if rolayers, ok := data.([]string); ok && len(rolayers) > 0 {
|
if rolayers, ok := data.([]string); ok && len(rolayers) > 0 {
|
||||||
|
|
@ -39,13 +43,13 @@ func (o overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi
|
||||||
|
|
||||||
if fi.Mode()&os.ModeDir != 0 {
|
if fi.Mode()&os.ModeDir != 0 {
|
||||||
// convert opaque dirs to AUFS format by writing an empty file with the whiteout prefix
|
// convert opaque dirs to AUFS format by writing an empty file with the whiteout prefix
|
||||||
opaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
|
opaque, err := system.Lgetxattr(path, getOverlayOpaqueXattrName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(opaque) == 1 && opaque[0] == 'y' {
|
if len(opaque) == 1 && opaque[0] == 'y' {
|
||||||
if hdr.Xattrs != nil {
|
if hdr.Xattrs != nil {
|
||||||
delete(hdr.Xattrs, "trusted.overlay.opaque")
|
delete(hdr.Xattrs, getOverlayOpaqueXattrName())
|
||||||
}
|
}
|
||||||
// If there are no lower layers, then it can't have been deleted in this layer.
|
// If there are no lower layers, then it can't have been deleted in this layer.
|
||||||
if len(o.rolayers) == 0 {
|
if len(o.rolayers) == 0 {
|
||||||
|
|
@ -114,7 +118,7 @@ func (overlayWhiteoutConverter) ConvertReadWithHandler(hdr *tar.Header, path str
|
||||||
|
|
||||||
// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
|
// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
|
||||||
if base == WhiteoutOpaqueDir {
|
if base == WhiteoutOpaqueDir {
|
||||||
err := handler.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'})
|
err := handler.Setxattr(dir, getOverlayOpaqueXattrName(), []byte{'y'})
|
||||||
// don't write the file itself
|
// don't write the file itself
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func setupOverlayTestDir(t *testing.T, src string) {
|
||||||
err := os.Mkdir(filepath.Join(src, "d1"), 0700)
|
err := os.Mkdir(filepath.Join(src, "d1"), 0700)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0)
|
err = system.Lsetxattr(filepath.Join(src, "d1"), getOverlayOpaqueXattrName(), []byte("y"), 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600)
|
err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600)
|
||||||
|
|
@ -36,7 +36,7 @@ func setupOverlayTestDir(t *testing.T, src string) {
|
||||||
err = os.Mkdir(filepath.Join(src, "d2"), 0750)
|
err = os.Mkdir(filepath.Join(src, "d2"), 0750)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0)
|
err = system.Lsetxattr(filepath.Join(src, "d2"), getOverlayOpaqueXattrName(), []byte("y"), 0)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660)
|
err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660)
|
||||||
|
|
@ -60,7 +60,7 @@ func setupOverlayLowerDir(t *testing.T, lower string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkOpaqueness(t *testing.T, path string, opaque string) {
|
func checkOpaqueness(t *testing.T, path string, opaque string) {
|
||||||
xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
|
xattrOpaque, err := system.Lgetxattr(path, getOverlayOpaqueXattrName())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
if string(xattrOpaque) != opaque {
|
if string(xattrOpaque) != opaque {
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ func overlayDeletedFile(layers []string, root, path string, fi os.FileInfo) (str
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
// If the directory isn't marked as opaque, then it's just a normal directory.
|
// If the directory isn't marked as opaque, then it's just a normal directory.
|
||||||
opaque, err := system.Lgetxattr(filepath.Join(root, path), "trusted.overlay.opaque")
|
opaque, err := system.Lgetxattr(filepath.Join(root, path), getOverlayOpaqueXattrName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue