aufs compatibility
Signed-off-by: Viktor Stanchev <me@viktorstanchev.com>
This commit is contained in:
parent
9b79cbe713
commit
60dbea6c25
1 changed files with 80 additions and 5 deletions
|
@ -47,6 +47,9 @@ type (
|
||||||
GIDMaps []idtools.IDMap
|
GIDMaps []idtools.IDMap
|
||||||
ChownOpts *TarChownOptions
|
ChownOpts *TarChownOptions
|
||||||
IncludeSourceDir bool
|
IncludeSourceDir bool
|
||||||
|
// When unpacking convert whiteouts and opaque dirs from aufs format to overlayfs format
|
||||||
|
// When packing convert whiteouts and opaque dirs from overlayfs format to aufs format
|
||||||
|
OverlayFormat bool
|
||||||
// When unpacking, specifies whether overwriting a directory with a
|
// When unpacking, specifies whether overwriting a directory with a
|
||||||
// non-directory is allowed and vice versa.
|
// non-directory is allowed and vice versa.
|
||||||
NoOverwriteDirNonDir bool
|
NoOverwriteDirNonDir bool
|
||||||
|
@ -236,6 +239,11 @@ type tarAppender struct {
|
||||||
SeenFiles map[uint64]string
|
SeenFiles map[uint64]string
|
||||||
UIDMaps []idtools.IDMap
|
UIDMaps []idtools.IDMap
|
||||||
GIDMaps []idtools.IDMap
|
GIDMaps []idtools.IDMap
|
||||||
|
|
||||||
|
// `overlayFormat` controls whether to interpret character devices with numbers 0,0
|
||||||
|
// and directories with the attribute `trusted.overlay.opaque` using their overlayfs
|
||||||
|
// meanings and remap them to AUFS format
|
||||||
|
OverlayFormat bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// canonicalTarName provides a platform-independent and consistent posix-style
|
// canonicalTarName provides a platform-independent and consistent posix-style
|
||||||
|
@ -253,6 +261,7 @@ func canonicalTarName(name string, isDir bool) (string, error) {
|
||||||
return name, nil
|
return name, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addTarFile adds to the tar archive a file from `path` as `name`
|
||||||
func (ta *tarAppender) addTarFile(path, name string) error {
|
func (ta *tarAppender) addTarFile(path, name string) error {
|
||||||
fi, err := os.Lstat(path)
|
fi, err := os.Lstat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -323,6 +332,16 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
||||||
hdr.Gid = xGID
|
hdr.Gid = xGID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ta.OverlayFormat {
|
||||||
|
// convert whiteouts to AUFS format
|
||||||
|
if fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 {
|
||||||
|
// we just rename the file and make it normal
|
||||||
|
hdr.Name = WhiteoutPrefix + hdr.Name
|
||||||
|
hdr.Mode = 0600
|
||||||
|
hdr.Typeflag = tar.TypeReg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := ta.TarWriter.WriteHeader(hdr); err != nil {
|
if err := ta.TarWriter.WriteHeader(hdr); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -346,6 +365,30 @@ func (ta *tarAppender) addTarFile(path, name string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ta.OverlayFormat {
|
||||||
|
// convert opaque dirs to AUFS format by writing an empty file with the prefix
|
||||||
|
opaque, _ := system.Lgetxattr(path, "trusted.overlay.opaque")
|
||||||
|
if opaque != nil && len(opaque) == 1 && opaque[0] == 'y' {
|
||||||
|
// create a header for the whiteout file
|
||||||
|
// it should inherit some properties from the parent, but be a regular file
|
||||||
|
whHdr := &tar.Header{
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
Mode: hdr.Mode & int64(os.ModePerm),
|
||||||
|
Name: filepath.Join(name, WhiteoutOpaqueDir),
|
||||||
|
Size: 0,
|
||||||
|
Uid: hdr.Uid,
|
||||||
|
Uname: hdr.Uname,
|
||||||
|
Gid: hdr.Gid,
|
||||||
|
Gname: hdr.Gname,
|
||||||
|
AccessTime: hdr.AccessTime,
|
||||||
|
ChangeTime: hdr.ChangeTime,
|
||||||
|
}
|
||||||
|
if err := ta.TarWriter.WriteHeader(whHdr); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,11 +544,12 @@ func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
ta := &tarAppender{
|
ta := &tarAppender{
|
||||||
TarWriter: tar.NewWriter(compressWriter),
|
TarWriter: tar.NewWriter(compressWriter),
|
||||||
Buffer: pools.BufioWriter32KPool.Get(nil),
|
Buffer: pools.BufioWriter32KPool.Get(nil),
|
||||||
SeenFiles: make(map[uint64]string),
|
SeenFiles: make(map[uint64]string),
|
||||||
UIDMaps: options.UIDMaps,
|
UIDMaps: options.UIDMaps,
|
||||||
GIDMaps: options.GIDMaps,
|
GIDMaps: options.GIDMaps,
|
||||||
|
OverlayFormat: options.OverlayFormat,
|
||||||
}
|
}
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -766,6 +810,37 @@ loop:
|
||||||
hdr.Gid = xGID
|
hdr.Gid = xGID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base := filepath.Base(path)
|
||||||
|
dir := filepath.Dir(path)
|
||||||
|
|
||||||
|
if options.OverlayFormat {
|
||||||
|
// if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay
|
||||||
|
if base == WhiteoutOpaqueDir {
|
||||||
|
if err := syscall.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't write the file itself
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a file was deleted and we are using overlay, we need to create a character device
|
||||||
|
if strings.HasPrefix(base, WhiteoutPrefix) {
|
||||||
|
originalBase := base[len(WhiteoutPrefix):]
|
||||||
|
originalPath := filepath.Join(dir, originalBase)
|
||||||
|
|
||||||
|
if err := syscall.Mknod(originalPath, syscall.S_IFCHR, 0); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// don't write the file itself
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown, options.ChownOpts); err != nil {
|
if err := createTarFile(path, dest, hdr, trBuf, !options.NoLchown, options.ChownOpts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue