// addTarFile adds to the tar archive a file from `path` as `name`
addTarFile adds to the tar archive a file from `path` as `name`
// addTarFile adds to the tar archive a file from ` path ` as ` name `
func (ta *tarAppender) addTarFile(path, name string) error {
        fi, err := os.Lstat(path)
        if err != nil {
                return err
        }
        var link string
        if fi.Mode() & os.ModeSymlink != 0 {
                var err error
                link, err = os.Readlink(path)
                if err != nil {
                        return err
                }
        }
        hdr, err := FileInfoHeader(name, fi, link)
        if err != nil {
                return err
        }
        if err := ReadSecurityXattrToTarHeader(path, hdr); err != nil {
                return err
        }
        if !fi.IsDir() && hasHardlinks(fi) {
                inode, err := getInodeFromStat(fi.Sys())
                if err != nil {
                        return err
                }
                if oldpath, ok := ta.SeenFiles[inode]; ok {
                        hdr.Typeflag = tar.TypeLink
                        hdr.Linkname = oldpath
                        hdr.Size = 0 
                } else {
                        ta.SeenFiles[inode] = name
                }
        }
        if !strings.HasPrefix(filepath.Base(hdr.Name), WhiteoutPrefix) && !ta.IDMappings.Empty() {
                fileIDPair, err := getFileUIDGID(fi.Sys())
                if err != nil {
                        return err
                }
                hdr.Uid, hdr.Gid, err = ta.IDMappings.ToContainer(fileIDPair)
                if err != nil {
                        return err
                }
        }
        if ta.WhiteoutConverter != nil {
                wo, err := ta.WhiteoutConverter.ConvertWrite(hdr, path, fi)
                if err != nil {
                        return err
                }
                if wo != nil {
                        if err := ta.TarWriter.WriteHeader(hdr); err != nil {
                                return err
                        }
                        if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
                                return fmt.Errorf("tar: cannot use whiteout for non-empty file")
                        }
                        hdr = wo
                }
        }
        if err := ta.TarWriter.WriteHeader(hdr); err != nil {
                return err
        }
        if hdr.Typeflag == tar.TypeReg && hdr.Size > 0 {
                file, err := OpenSequential(path)
                if err != nil {
                        return err
                }
                ta.Buffer.Reset(ta.TarWriter)
                defer ta.Buffer.Reset(nil)
                _, err = io.Copy(ta.Buffer, file)
                file.Close()
                if err != nil {
                        return err
                }
                err = ta.Buffer.Flush()
                if err != nil {
                        return err
                }
        }
        return nil
}
func ( ta * tarAppender ) addTarFile ( path , name string ) error { fi , err := os . Lstat ( path ) if err != nil { return err } var link string if fi . Mode ( ) & os . ModeSymlink != 0 { var err error link , err = os . Readlink ( path ) if err != nil { return err } } hdr , err := FileInfoHeader ( name , fi , link ) if err != nil { return err } if err := ReadSecurityXattrToTarHeader ( path , hdr ) ; err != nil { return err } if ! fi . IsDir ( ) && hasHardlinks ( fi ) { inode , err := getInodeFromStat ( fi . Sys ( ) ) if err != nil { return err } if oldpath , ok := ta . SeenFiles [ inode ] ; ok { hdr . Typeflag = tar . TypeLink hdr . Linkname = oldpath hdr . Size = 0 } else { ta . SeenFiles [ inode ] = name } } if ! strings . HasPrefix ( filepath . Base ( hdr . Name ) , WhiteoutPrefix ) && ! ta . IDMappings . Empty ( ) { fileIDPair , err := getFileUIDGID ( fi . Sys ( ) ) if err != nil { return err } hdr . Uid , hdr . Gid , err = ta . IDMappings . ToContainer ( fileIDPair ) if err != nil { return err } } if ta . WhiteoutConverter != nil { wo , err := ta . WhiteoutConverter . ConvertWrite ( hdr , path , fi ) if err != nil { return err } if wo != nil { if err := ta . TarWriter . WriteHeader ( hdr ) ; err != nil { return err } if hdr . Typeflag == tar . TypeReg && hdr . Size > 0 { return fmt . Errorf ( " " ) } hdr = wo } } if err := ta . TarWriter . WriteHeader ( hdr ) ; err != nil { return err } if hdr . Typeflag == tar . TypeReg && hdr . Size > 0 { file , err := OpenSequential ( path ) if err != nil { return err } ta . Buffer . Reset ( ta . TarWriter ) defer ta . Buffer . Reset ( nil ) _ , err = io . Copy ( ta . Buffer , file ) file . Close ( ) if err != nil { return err } err = ta . Buffer . Flush ( ) if err != nil { return err } } return nil }
addTarFile adds to the tar archive a file from `path` as `name`
addTarFile adds to the tar archive a file from ` path ` as ` name `
// if it's not a directory and has more than 1 link, // it's hard linked, so set the type flag accordingly // a link should have a name that it links too // and that linked name should be first in the tar archive // This Must be here for the writer math to add up! //handle re-mapping container ID mappings back to host ID mappings before //writing tar headers/files. We skip whiteout files because they were written //by the kernel and already have proper ownership relative to the host // If a new whiteout file exists, write original hdr, then // replace hdr with wo to be written after. Whiteouts should // always be written after the original. Note the original // hdr may have been updated to be a whiteout with returning // a whiteout header // We use system.OpenSequential to ensure we use sequential file // access on Windows to avoid depleting the standby list. // On Linux, this equates to a regular os.Open.