mirror of
https://github.com/moby/moby.git
synced 2026-08-07 08:31:39 +00:00
Merge pull request #42451 from thaJeztah/remove_lcow_step1
Remove LCOW code (step 1)
This commit is contained in:
1325
vendor/github.com/Microsoft/hcsshim/ext4/internal/compactext4/compact.go
generated
vendored
1325
vendor/github.com/Microsoft/hcsshim/ext4/internal/compactext4/compact.go
generated
vendored
File diff suppressed because it is too large
Load Diff
411
vendor/github.com/Microsoft/hcsshim/ext4/internal/format/format.go
generated
vendored
411
vendor/github.com/Microsoft/hcsshim/ext4/internal/format/format.go
generated
vendored
@@ -1,411 +0,0 @@
|
||||
package format
|
||||
|
||||
type SuperBlock struct {
|
||||
InodesCount uint32
|
||||
BlocksCountLow uint32
|
||||
RootBlocksCountLow uint32
|
||||
FreeBlocksCountLow uint32
|
||||
FreeInodesCount uint32
|
||||
FirstDataBlock uint32
|
||||
LogBlockSize uint32
|
||||
LogClusterSize uint32
|
||||
BlocksPerGroup uint32
|
||||
ClustersPerGroup uint32
|
||||
InodesPerGroup uint32
|
||||
Mtime uint32
|
||||
Wtime uint32
|
||||
MountCount uint16
|
||||
MaxMountCount uint16
|
||||
Magic uint16
|
||||
State uint16
|
||||
Errors uint16
|
||||
MinorRevisionLevel uint16
|
||||
LastCheck uint32
|
||||
CheckInterval uint32
|
||||
CreatorOS uint32
|
||||
RevisionLevel uint32
|
||||
DefaultReservedUid uint16
|
||||
DefaultReservedGid uint16
|
||||
FirstInode uint32
|
||||
InodeSize uint16
|
||||
BlockGroupNr uint16
|
||||
FeatureCompat CompatFeature
|
||||
FeatureIncompat IncompatFeature
|
||||
FeatureRoCompat RoCompatFeature
|
||||
UUID [16]uint8
|
||||
VolumeName [16]byte
|
||||
LastMounted [64]byte
|
||||
AlgorithmUsageBitmap uint32
|
||||
PreallocBlocks uint8
|
||||
PreallocDirBlocks uint8
|
||||
ReservedGdtBlocks uint16
|
||||
JournalUUID [16]uint8
|
||||
JournalInum uint32
|
||||
JournalDev uint32
|
||||
LastOrphan uint32
|
||||
HashSeed [4]uint32
|
||||
DefHashVersion uint8
|
||||
JournalBackupType uint8
|
||||
DescSize uint16
|
||||
DefaultMountOpts uint32
|
||||
FirstMetaBg uint32
|
||||
MkfsTime uint32
|
||||
JournalBlocks [17]uint32
|
||||
BlocksCountHigh uint32
|
||||
RBlocksCountHigh uint32
|
||||
FreeBlocksCountHigh uint32
|
||||
MinExtraIsize uint16
|
||||
WantExtraIsize uint16
|
||||
Flags uint32
|
||||
RaidStride uint16
|
||||
MmpInterval uint16
|
||||
MmpBlock uint64
|
||||
RaidStripeWidth uint32
|
||||
LogGroupsPerFlex uint8
|
||||
ChecksumType uint8
|
||||
ReservedPad uint16
|
||||
KbytesWritten uint64
|
||||
SnapshotInum uint32
|
||||
SnapshotID uint32
|
||||
SnapshotRBlocksCount uint64
|
||||
SnapshotList uint32
|
||||
ErrorCount uint32
|
||||
FirstErrorTime uint32
|
||||
FirstErrorInode uint32
|
||||
FirstErrorBlock uint64
|
||||
FirstErrorFunc [32]uint8
|
||||
FirstErrorLine uint32
|
||||
LastErrorTime uint32
|
||||
LastErrorInode uint32
|
||||
LastErrorLine uint32
|
||||
LastErrorBlock uint64
|
||||
LastErrorFunc [32]uint8
|
||||
MountOpts [64]uint8
|
||||
UserQuotaInum uint32
|
||||
GroupQuotaInum uint32
|
||||
OverheadBlocks uint32
|
||||
BackupBgs [2]uint32
|
||||
EncryptAlgos [4]uint8
|
||||
EncryptPwSalt [16]uint8
|
||||
LpfInode uint32
|
||||
ProjectQuotaInum uint32
|
||||
ChecksumSeed uint32
|
||||
WtimeHigh uint8
|
||||
MtimeHigh uint8
|
||||
MkfsTimeHigh uint8
|
||||
LastcheckHigh uint8
|
||||
FirstErrorTimeHigh uint8
|
||||
LastErrorTimeHigh uint8
|
||||
Pad [2]uint8
|
||||
Reserved [96]uint32
|
||||
Checksum uint32
|
||||
}
|
||||
|
||||
const SuperBlockMagic uint16 = 0xef53
|
||||
|
||||
type CompatFeature uint32
|
||||
type IncompatFeature uint32
|
||||
type RoCompatFeature uint32
|
||||
|
||||
const (
|
||||
CompatDirPrealloc CompatFeature = 0x1
|
||||
CompatImagicInodes CompatFeature = 0x2
|
||||
CompatHasJournal CompatFeature = 0x4
|
||||
CompatExtAttr CompatFeature = 0x8
|
||||
CompatResizeInode CompatFeature = 0x10
|
||||
CompatDirIndex CompatFeature = 0x20
|
||||
CompatLazyBg CompatFeature = 0x40
|
||||
CompatExcludeInode CompatFeature = 0x80
|
||||
CompatExcludeBitmap CompatFeature = 0x100
|
||||
CompatSparseSuper2 CompatFeature = 0x200
|
||||
|
||||
IncompatCompression IncompatFeature = 0x1
|
||||
IncompatFiletype IncompatFeature = 0x2
|
||||
IncompatRecover IncompatFeature = 0x4
|
||||
IncompatJournalDev IncompatFeature = 0x8
|
||||
IncompatMetaBg IncompatFeature = 0x10
|
||||
IncompatExtents IncompatFeature = 0x40
|
||||
Incompat_64Bit IncompatFeature = 0x80
|
||||
IncompatMmp IncompatFeature = 0x100
|
||||
IncompatFlexBg IncompatFeature = 0x200
|
||||
IncompatEaInode IncompatFeature = 0x400
|
||||
IncompatDirdata IncompatFeature = 0x1000
|
||||
IncompatCsumSeed IncompatFeature = 0x2000
|
||||
IncompatLargedir IncompatFeature = 0x4000
|
||||
IncompatInlineData IncompatFeature = 0x8000
|
||||
IncompatEncrypt IncompatFeature = 0x10000
|
||||
|
||||
RoCompatSparseSuper RoCompatFeature = 0x1
|
||||
RoCompatLargeFile RoCompatFeature = 0x2
|
||||
RoCompatBtreeDir RoCompatFeature = 0x4
|
||||
RoCompatHugeFile RoCompatFeature = 0x8
|
||||
RoCompatGdtCsum RoCompatFeature = 0x10
|
||||
RoCompatDirNlink RoCompatFeature = 0x20
|
||||
RoCompatExtraIsize RoCompatFeature = 0x40
|
||||
RoCompatHasSnapshot RoCompatFeature = 0x80
|
||||
RoCompatQuota RoCompatFeature = 0x100
|
||||
RoCompatBigalloc RoCompatFeature = 0x200
|
||||
RoCompatMetadataCsum RoCompatFeature = 0x400
|
||||
RoCompatReplica RoCompatFeature = 0x800
|
||||
RoCompatReadonly RoCompatFeature = 0x1000
|
||||
RoCompatProject RoCompatFeature = 0x2000
|
||||
)
|
||||
|
||||
type BlockGroupFlag uint16
|
||||
|
||||
const (
|
||||
BlockGroupInodeUninit BlockGroupFlag = 0x1
|
||||
BlockGroupBlockUninit BlockGroupFlag = 0x2
|
||||
BlockGroupInodeZeroed BlockGroupFlag = 0x4
|
||||
)
|
||||
|
||||
type GroupDescriptor struct {
|
||||
BlockBitmapLow uint32
|
||||
InodeBitmapLow uint32
|
||||
InodeTableLow uint32
|
||||
FreeBlocksCountLow uint16
|
||||
FreeInodesCountLow uint16
|
||||
UsedDirsCountLow uint16
|
||||
Flags BlockGroupFlag
|
||||
ExcludeBitmapLow uint32
|
||||
BlockBitmapCsumLow uint16
|
||||
InodeBitmapCsumLow uint16
|
||||
ItableUnusedLow uint16
|
||||
Checksum uint16
|
||||
}
|
||||
|
||||
type GroupDescriptor64 struct {
|
||||
GroupDescriptor
|
||||
BlockBitmapHigh uint32
|
||||
InodeBitmapHigh uint32
|
||||
InodeTableHigh uint32
|
||||
FreeBlocksCountHigh uint16
|
||||
FreeInodesCountHigh uint16
|
||||
UsedDirsCountHigh uint16
|
||||
ItableUnusedHigh uint16
|
||||
ExcludeBitmapHigh uint32
|
||||
BlockBitmapCsumHigh uint16
|
||||
InodeBitmapCsumHigh uint16
|
||||
Reserved uint32
|
||||
}
|
||||
|
||||
const (
|
||||
S_IXOTH = 0x1
|
||||
S_IWOTH = 0x2
|
||||
S_IROTH = 0x4
|
||||
S_IXGRP = 0x8
|
||||
S_IWGRP = 0x10
|
||||
S_IRGRP = 0x20
|
||||
S_IXUSR = 0x40
|
||||
S_IWUSR = 0x80
|
||||
S_IRUSR = 0x100
|
||||
S_ISVTX = 0x200
|
||||
S_ISGID = 0x400
|
||||
S_ISUID = 0x800
|
||||
S_IFIFO = 0x1000
|
||||
S_IFCHR = 0x2000
|
||||
S_IFDIR = 0x4000
|
||||
S_IFBLK = 0x6000
|
||||
S_IFREG = 0x8000
|
||||
S_IFLNK = 0xA000
|
||||
S_IFSOCK = 0xC000
|
||||
|
||||
TypeMask uint16 = 0xF000
|
||||
)
|
||||
|
||||
type InodeNumber uint32
|
||||
|
||||
const (
|
||||
InodeRoot = 2
|
||||
)
|
||||
|
||||
type Inode struct {
|
||||
Mode uint16
|
||||
Uid uint16
|
||||
SizeLow uint32
|
||||
Atime uint32
|
||||
Ctime uint32
|
||||
Mtime uint32
|
||||
Dtime uint32
|
||||
Gid uint16
|
||||
LinksCount uint16
|
||||
BlocksLow uint32
|
||||
Flags InodeFlag
|
||||
Version uint32
|
||||
Block [60]byte
|
||||
Generation uint32
|
||||
XattrBlockLow uint32
|
||||
SizeHigh uint32
|
||||
ObsoleteFragmentAddr uint32
|
||||
BlocksHigh uint16
|
||||
XattrBlockHigh uint16
|
||||
UidHigh uint16
|
||||
GidHigh uint16
|
||||
ChecksumLow uint16
|
||||
Reserved uint16
|
||||
ExtraIsize uint16
|
||||
ChecksumHigh uint16
|
||||
CtimeExtra uint32
|
||||
MtimeExtra uint32
|
||||
AtimeExtra uint32
|
||||
Crtime uint32
|
||||
CrtimeExtra uint32
|
||||
VersionHigh uint32
|
||||
Projid uint32
|
||||
}
|
||||
|
||||
type InodeFlag uint32
|
||||
|
||||
const (
|
||||
InodeFlagSecRm InodeFlag = 0x1
|
||||
InodeFlagUnRm InodeFlag = 0x2
|
||||
InodeFlagCompressed InodeFlag = 0x4
|
||||
InodeFlagSync InodeFlag = 0x8
|
||||
InodeFlagImmutable InodeFlag = 0x10
|
||||
InodeFlagAppend InodeFlag = 0x20
|
||||
InodeFlagNoDump InodeFlag = 0x40
|
||||
InodeFlagNoAtime InodeFlag = 0x80
|
||||
InodeFlagDirtyCompressed InodeFlag = 0x100
|
||||
InodeFlagCompressedClusters InodeFlag = 0x200
|
||||
InodeFlagNoCompress InodeFlag = 0x400
|
||||
InodeFlagEncrypted InodeFlag = 0x800
|
||||
InodeFlagHashedIndex InodeFlag = 0x1000
|
||||
InodeFlagMagic InodeFlag = 0x2000
|
||||
InodeFlagJournalData InodeFlag = 0x4000
|
||||
InodeFlagNoTail InodeFlag = 0x8000
|
||||
InodeFlagDirSync InodeFlag = 0x10000
|
||||
InodeFlagTopDir InodeFlag = 0x20000
|
||||
InodeFlagHugeFile InodeFlag = 0x40000
|
||||
InodeFlagExtents InodeFlag = 0x80000
|
||||
InodeFlagEaInode InodeFlag = 0x200000
|
||||
InodeFlagEOFBlocks InodeFlag = 0x400000
|
||||
InodeFlagSnapfile InodeFlag = 0x01000000
|
||||
InodeFlagSnapfileDeleted InodeFlag = 0x04000000
|
||||
InodeFlagSnapfileShrunk InodeFlag = 0x08000000
|
||||
InodeFlagInlineData InodeFlag = 0x10000000
|
||||
InodeFlagProjectIDInherit InodeFlag = 0x20000000
|
||||
InodeFlagReserved InodeFlag = 0x80000000
|
||||
)
|
||||
|
||||
const (
|
||||
MaxLinks = 65000
|
||||
)
|
||||
|
||||
type ExtentHeader struct {
|
||||
Magic uint16
|
||||
Entries uint16
|
||||
Max uint16
|
||||
Depth uint16
|
||||
Generation uint32
|
||||
}
|
||||
|
||||
const ExtentHeaderMagic uint16 = 0xf30a
|
||||
|
||||
type ExtentIndexNode struct {
|
||||
Block uint32
|
||||
LeafLow uint32
|
||||
LeafHigh uint16
|
||||
Unused uint16
|
||||
}
|
||||
|
||||
type ExtentLeafNode struct {
|
||||
Block uint32
|
||||
Length uint16
|
||||
StartHigh uint16
|
||||
StartLow uint32
|
||||
}
|
||||
|
||||
type ExtentTail struct {
|
||||
Checksum uint32
|
||||
}
|
||||
|
||||
type DirectoryEntry struct {
|
||||
Inode InodeNumber
|
||||
RecordLength uint16
|
||||
NameLength uint8
|
||||
FileType FileType
|
||||
//Name []byte
|
||||
}
|
||||
|
||||
type FileType uint8
|
||||
|
||||
const (
|
||||
FileTypeUnknown FileType = 0x0
|
||||
FileTypeRegular FileType = 0x1
|
||||
FileTypeDirectory FileType = 0x2
|
||||
FileTypeCharacter FileType = 0x3
|
||||
FileTypeBlock FileType = 0x4
|
||||
FileTypeFIFO FileType = 0x5
|
||||
FileTypeSocket FileType = 0x6
|
||||
FileTypeSymbolicLink FileType = 0x7
|
||||
)
|
||||
|
||||
type DirectoryEntryTail struct {
|
||||
ReservedZero1 uint32
|
||||
RecordLength uint16
|
||||
ReservedZero2 uint8
|
||||
FileType uint8
|
||||
Checksum uint32
|
||||
}
|
||||
|
||||
type DirectoryTreeRoot struct {
|
||||
Dot DirectoryEntry
|
||||
DotName [4]byte
|
||||
DotDot DirectoryEntry
|
||||
DotDotName [4]byte
|
||||
ReservedZero uint32
|
||||
HashVersion uint8
|
||||
InfoLength uint8
|
||||
IndirectLevels uint8
|
||||
UnusedFlags uint8
|
||||
Limit uint16
|
||||
Count uint16
|
||||
Block uint32
|
||||
//Entries []DirectoryTreeEntry
|
||||
}
|
||||
|
||||
type DirectoryTreeNode struct {
|
||||
FakeInode uint32
|
||||
FakeRecordLength uint16
|
||||
NameLength uint8
|
||||
FileType uint8
|
||||
Limit uint16
|
||||
Count uint16
|
||||
Block uint32
|
||||
//Entries []DirectoryTreeEntry
|
||||
}
|
||||
|
||||
type DirectoryTreeEntry struct {
|
||||
Hash uint32
|
||||
Block uint32
|
||||
}
|
||||
|
||||
type DirectoryTreeTail struct {
|
||||
Reserved uint32
|
||||
Checksum uint32
|
||||
}
|
||||
|
||||
type XAttrInodeBodyHeader struct {
|
||||
Magic uint32
|
||||
}
|
||||
|
||||
type XAttrHeader struct {
|
||||
Magic uint32
|
||||
ReferenceCount uint32
|
||||
Blocks uint32
|
||||
Hash uint32
|
||||
Checksum uint32
|
||||
Reserved [3]uint32
|
||||
}
|
||||
|
||||
const XAttrHeaderMagic uint32 = 0xea020000
|
||||
|
||||
type XAttrEntry struct {
|
||||
NameLength uint8
|
||||
NameIndex uint8
|
||||
ValueOffset uint16
|
||||
ValueInum uint32
|
||||
ValueSize uint32
|
||||
Hash uint32
|
||||
//Name []byte
|
||||
}
|
||||
209
vendor/github.com/Microsoft/hcsshim/ext4/tar2ext4/tar2ext4.go
generated
vendored
209
vendor/github.com/Microsoft/hcsshim/ext4/tar2ext4/tar2ext4.go
generated
vendored
@@ -1,209 +0,0 @@
|
||||
package tar2ext4
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/Microsoft/hcsshim/ext4/internal/compactext4"
|
||||
"github.com/Microsoft/hcsshim/ext4/internal/format"
|
||||
)
|
||||
|
||||
type params struct {
|
||||
convertWhiteout bool
|
||||
appendVhdFooter bool
|
||||
ext4opts []compactext4.Option
|
||||
}
|
||||
|
||||
// Option is the type for optional parameters to Convert.
|
||||
type Option func(*params)
|
||||
|
||||
// ConvertWhiteout instructs the converter to convert OCI-style whiteouts
|
||||
// (beginning with .wh.) to overlay-style whiteouts.
|
||||
func ConvertWhiteout(p *params) {
|
||||
p.convertWhiteout = true
|
||||
}
|
||||
|
||||
// AppendVhdFooter instructs the converter to add a fixed VHD footer to the
|
||||
// file.
|
||||
func AppendVhdFooter(p *params) {
|
||||
p.appendVhdFooter = true
|
||||
}
|
||||
|
||||
// InlineData instructs the converter to write small files into the inode
|
||||
// structures directly. This creates smaller images but currently is not
|
||||
// compatible with DAX.
|
||||
func InlineData(p *params) {
|
||||
p.ext4opts = append(p.ext4opts, compactext4.InlineData)
|
||||
}
|
||||
|
||||
// MaximumDiskSize instructs the writer to limit the disk size to the specified
|
||||
// value. This also reserves enough metadata space for the specified disk size.
|
||||
// If not provided, then 16GB is the default.
|
||||
func MaximumDiskSize(size int64) Option {
|
||||
return func(p *params) {
|
||||
p.ext4opts = append(p.ext4opts, compactext4.MaximumDiskSize(size))
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
whiteoutPrefix = ".wh."
|
||||
opaqueWhiteout = ".wh..wh..opq"
|
||||
)
|
||||
|
||||
// Convert writes a compact ext4 file system image that contains the files in the
|
||||
// input tar stream.
|
||||
func Convert(r io.Reader, w io.ReadWriteSeeker, options ...Option) error {
|
||||
var p params
|
||||
for _, opt := range options {
|
||||
opt(&p)
|
||||
}
|
||||
t := tar.NewReader(bufio.NewReader(r))
|
||||
fs := compactext4.NewWriter(w, p.ext4opts...)
|
||||
for {
|
||||
hdr, err := t.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if p.convertWhiteout {
|
||||
dir, name := path.Split(hdr.Name)
|
||||
if strings.HasPrefix(name, whiteoutPrefix) {
|
||||
if name == opaqueWhiteout {
|
||||
// Update the directory with the appropriate xattr.
|
||||
f, err := fs.Stat(dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Xattrs["trusted.overlay.opaque"] = []byte("y")
|
||||
err = fs.Create(dir, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Create an overlay-style whiteout.
|
||||
f := &compactext4.File{
|
||||
Mode: compactext4.S_IFCHR,
|
||||
Devmajor: 0,
|
||||
Devminor: 0,
|
||||
}
|
||||
err = fs.Create(path.Join(dir, name[len(whiteoutPrefix):]), f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if hdr.Typeflag == tar.TypeLink {
|
||||
err = fs.Link(hdr.Linkname, hdr.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
f := &compactext4.File{
|
||||
Mode: uint16(hdr.Mode),
|
||||
Atime: hdr.AccessTime,
|
||||
Mtime: hdr.ModTime,
|
||||
Ctime: hdr.ChangeTime,
|
||||
Crtime: hdr.ModTime,
|
||||
Size: hdr.Size,
|
||||
Uid: uint32(hdr.Uid),
|
||||
Gid: uint32(hdr.Gid),
|
||||
Linkname: hdr.Linkname,
|
||||
Devmajor: uint32(hdr.Devmajor),
|
||||
Devminor: uint32(hdr.Devminor),
|
||||
Xattrs: make(map[string][]byte),
|
||||
}
|
||||
for key, value := range hdr.PAXRecords {
|
||||
const xattrPrefix = "SCHILY.xattr."
|
||||
if strings.HasPrefix(key, xattrPrefix) {
|
||||
f.Xattrs[key[len(xattrPrefix):]] = []byte(value)
|
||||
}
|
||||
}
|
||||
|
||||
var typ uint16
|
||||
switch hdr.Typeflag {
|
||||
case tar.TypeReg, tar.TypeRegA:
|
||||
typ = compactext4.S_IFREG
|
||||
case tar.TypeSymlink:
|
||||
typ = compactext4.S_IFLNK
|
||||
case tar.TypeChar:
|
||||
typ = compactext4.S_IFCHR
|
||||
case tar.TypeBlock:
|
||||
typ = compactext4.S_IFBLK
|
||||
case tar.TypeDir:
|
||||
typ = compactext4.S_IFDIR
|
||||
case tar.TypeFifo:
|
||||
typ = compactext4.S_IFIFO
|
||||
}
|
||||
f.Mode &= ^compactext4.TypeMask
|
||||
f.Mode |= typ
|
||||
err = fs.CreateWithParents(hdr.Name, f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = io.Copy(fs, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
err := fs.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p.appendVhdFooter {
|
||||
size, err := w.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = binary.Write(w, binary.BigEndian, makeFixedVHDFooter(size))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadExt4SuperBlock reads and returns ext4 super block from VHD
|
||||
//
|
||||
// The layout on disk is as follows:
|
||||
// | Group 0 padding | - 1024 bytes
|
||||
// | ext4 SuperBlock | - 1 block
|
||||
// | Group Descriptors | - many blocks
|
||||
// | Reserved GDT Blocks | - many blocks
|
||||
// | Data Block Bitmap | - 1 block
|
||||
// | inode Bitmap | - 1 block
|
||||
// | inode Table | - many blocks
|
||||
// | Data Blocks | - many blocks
|
||||
//
|
||||
// More details can be found here https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout
|
||||
//
|
||||
// Our goal is to skip the Group 0 padding, read and return the ext4 SuperBlock
|
||||
func ReadExt4SuperBlock(vhdPath string) (*format.SuperBlock, error) {
|
||||
vhd, err := os.OpenFile(vhdPath, os.O_RDONLY, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer vhd.Close()
|
||||
|
||||
// Skip padding at the start
|
||||
if _, err := vhd.Seek(1024, io.SeekStart); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var sb format.SuperBlock
|
||||
if err := binary.Read(vhd, binary.LittleEndian, &sb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &sb, nil
|
||||
}
|
||||
76
vendor/github.com/Microsoft/hcsshim/ext4/tar2ext4/vhdfooter.go
generated
vendored
76
vendor/github.com/Microsoft/hcsshim/ext4/tar2ext4/vhdfooter.go
generated
vendored
@@ -1,76 +0,0 @@
|
||||
package tar2ext4
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
// Constants for the VHD footer
|
||||
const (
|
||||
cookieMagic = "conectix"
|
||||
featureMask = 0x2
|
||||
fileFormatVersionMagic = 0x00010000
|
||||
fixedDataOffset = -1
|
||||
creatorVersionMagic = 0x000a0000
|
||||
diskTypeFixed = 2
|
||||
)
|
||||
|
||||
type vhdFooter struct {
|
||||
Cookie [8]byte
|
||||
Features uint32
|
||||
FileFormatVersion uint32
|
||||
DataOffset int64
|
||||
TimeStamp uint32
|
||||
CreatorApplication [4]byte
|
||||
CreatorVersion uint32
|
||||
CreatorHostOS [4]byte
|
||||
OriginalSize int64
|
||||
CurrentSize int64
|
||||
DiskGeometry uint32
|
||||
DiskType uint32
|
||||
Checksum uint32
|
||||
UniqueID [16]uint8
|
||||
SavedState uint8
|
||||
Reserved [427]uint8
|
||||
}
|
||||
|
||||
func makeFixedVHDFooter(size int64) *vhdFooter {
|
||||
footer := &vhdFooter{
|
||||
Features: featureMask,
|
||||
FileFormatVersion: fileFormatVersionMagic,
|
||||
DataOffset: fixedDataOffset,
|
||||
CreatorVersion: creatorVersionMagic,
|
||||
OriginalSize: size,
|
||||
CurrentSize: size,
|
||||
DiskType: diskTypeFixed,
|
||||
UniqueID: generateUUID(),
|
||||
}
|
||||
copy(footer.Cookie[:], cookieMagic)
|
||||
footer.Checksum = calculateCheckSum(footer)
|
||||
return footer
|
||||
}
|
||||
|
||||
func calculateCheckSum(footer *vhdFooter) uint32 {
|
||||
oldchk := footer.Checksum
|
||||
footer.Checksum = 0
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
_ = binary.Write(buf, binary.BigEndian, footer)
|
||||
|
||||
var chk uint32
|
||||
bufBytes := buf.Bytes()
|
||||
for i := 0; i < len(bufBytes); i++ {
|
||||
chk += uint32(bufBytes[i])
|
||||
}
|
||||
footer.Checksum = oldchk
|
||||
return uint32(^chk)
|
||||
}
|
||||
|
||||
func generateUUID() [16]byte {
|
||||
res := [16]byte{}
|
||||
if _, err := rand.Read(res[:]); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
109
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/defs.go
generated
vendored
109
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/defs.go
generated
vendored
@@ -1,109 +0,0 @@
|
||||
package remotefs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RemotefsCmd is the name of the remotefs meta command
|
||||
const RemotefsCmd = "remotefs"
|
||||
|
||||
// Name of the commands when called from the cli context (remotefs <CMD> ...)
|
||||
const (
|
||||
StatCmd = "stat"
|
||||
LstatCmd = "lstat"
|
||||
ReadlinkCmd = "readlink"
|
||||
MkdirCmd = "mkdir"
|
||||
MkdirAllCmd = "mkdirall"
|
||||
RemoveCmd = "remove"
|
||||
RemoveAllCmd = "removeall"
|
||||
LinkCmd = "link"
|
||||
SymlinkCmd = "symlink"
|
||||
LchmodCmd = "lchmod"
|
||||
LchownCmd = "lchown"
|
||||
MknodCmd = "mknod"
|
||||
MkfifoCmd = "mkfifo"
|
||||
OpenFileCmd = "openfile"
|
||||
ReadFileCmd = "readfile"
|
||||
WriteFileCmd = "writefile"
|
||||
ReadDirCmd = "readdir"
|
||||
ResolvePathCmd = "resolvepath"
|
||||
ExtractArchiveCmd = "extractarchive"
|
||||
ArchivePathCmd = "archivepath"
|
||||
)
|
||||
|
||||
// ErrInvalid is returned if the parameters are invalid
|
||||
var ErrInvalid = errors.New("invalid arguments")
|
||||
|
||||
// ErrUnknown is returned for an unknown remotefs command
|
||||
var ErrUnknown = errors.New("unkown command")
|
||||
|
||||
// ExportedError is the serialized version of the a Go error.
|
||||
// It also provides a trivial implementation of the error interface.
|
||||
type ExportedError struct {
|
||||
ErrString string
|
||||
ErrNum int `json:",omitempty"`
|
||||
}
|
||||
|
||||
// Error returns an error string
|
||||
func (ee *ExportedError) Error() string {
|
||||
return ee.ErrString
|
||||
}
|
||||
|
||||
// FileInfo is the stat struct returned by the remotefs system. It
|
||||
// fulfills the os.FileInfo interface.
|
||||
type FileInfo struct {
|
||||
NameVar string
|
||||
SizeVar int64
|
||||
ModeVar os.FileMode
|
||||
ModTimeVar int64 // Serialization of time.Time breaks in travis, so use an int
|
||||
IsDirVar bool
|
||||
}
|
||||
|
||||
var _ os.FileInfo = &FileInfo{}
|
||||
|
||||
// Name returns the filename from a FileInfo structure
|
||||
func (f *FileInfo) Name() string { return f.NameVar }
|
||||
|
||||
// Size returns the size from a FileInfo structure
|
||||
func (f *FileInfo) Size() int64 { return f.SizeVar }
|
||||
|
||||
// Mode returns the mode from a FileInfo structure
|
||||
func (f *FileInfo) Mode() os.FileMode { return f.ModeVar }
|
||||
|
||||
// ModTime returns the modification time from a FileInfo structure
|
||||
func (f *FileInfo) ModTime() time.Time { return time.Unix(0, f.ModTimeVar) }
|
||||
|
||||
// IsDir returns the is-directory indicator from a FileInfo structure
|
||||
func (f *FileInfo) IsDir() bool { return f.IsDirVar }
|
||||
|
||||
// Sys provides an interface to a FileInfo structure
|
||||
func (f *FileInfo) Sys() interface{} { return nil }
|
||||
|
||||
// FileHeader is a header for remote *os.File operations for remotefs.OpenFile
|
||||
type FileHeader struct {
|
||||
Cmd uint32
|
||||
Size uint64
|
||||
}
|
||||
|
||||
const (
|
||||
// Read request command.
|
||||
Read uint32 = iota
|
||||
// Write request command.
|
||||
Write
|
||||
// Seek request command.
|
||||
Seek
|
||||
// Close request command.
|
||||
Close
|
||||
// CmdOK is a response meaning request succeeded.
|
||||
CmdOK
|
||||
// CmdFailed is a response meaning request failed.
|
||||
CmdFailed
|
||||
)
|
||||
|
||||
// SeekHeader is header for the Seek operation for remotefs.OpenFile
|
||||
type SeekHeader struct {
|
||||
Offset int64
|
||||
Whence int32
|
||||
}
|
||||
578
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/remotefs.go
generated
vendored
578
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/remotefs.go
generated
vendored
@@ -1,578 +0,0 @@
|
||||
// +build !windows
|
||||
|
||||
package remotefs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/docker/docker/pkg/symlink"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
// Func is the function definition for a generic remote fs function
|
||||
// The input to the function is any serialized structs / data from in and the string slice
|
||||
// from args. The output of the function will be serialized and written to out.
|
||||
type Func func(stdin io.Reader, stdout io.Writer, args []string) error
|
||||
|
||||
// Commands provide a string -> remotefs function mapping.
|
||||
// This is useful for commandline programs that will receive a string
|
||||
// as the function to execute.
|
||||
var Commands = map[string]Func{
|
||||
StatCmd: Stat,
|
||||
LstatCmd: Lstat,
|
||||
ReadlinkCmd: Readlink,
|
||||
MkdirCmd: Mkdir,
|
||||
MkdirAllCmd: MkdirAll,
|
||||
RemoveCmd: Remove,
|
||||
RemoveAllCmd: RemoveAll,
|
||||
LinkCmd: Link,
|
||||
SymlinkCmd: Symlink,
|
||||
LchmodCmd: Lchmod,
|
||||
LchownCmd: Lchown,
|
||||
MknodCmd: Mknod,
|
||||
MkfifoCmd: Mkfifo,
|
||||
OpenFileCmd: OpenFile,
|
||||
ReadFileCmd: ReadFile,
|
||||
WriteFileCmd: WriteFile,
|
||||
ReadDirCmd: ReadDir,
|
||||
ResolvePathCmd: ResolvePath,
|
||||
ExtractArchiveCmd: ExtractArchive,
|
||||
ArchivePathCmd: ArchivePath,
|
||||
}
|
||||
|
||||
// Stat functions like os.Stat.
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
// Out:
|
||||
// - out = FileInfo object
|
||||
func Stat(in io.Reader, out io.Writer, args []string) error {
|
||||
return stat(in, out, args, os.Stat)
|
||||
}
|
||||
|
||||
// Lstat functions like os.Lstat.
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
// Out:
|
||||
// - out = FileInfo object
|
||||
func Lstat(in io.Reader, out io.Writer, args []string) error {
|
||||
return stat(in, out, args, os.Lstat)
|
||||
}
|
||||
|
||||
func stat(in io.Reader, out io.Writer, args []string, statfunc func(string) (os.FileInfo, error)) error {
|
||||
if len(args) < 1 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
fi, err := statfunc(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
info := FileInfo{
|
||||
NameVar: fi.Name(),
|
||||
SizeVar: fi.Size(),
|
||||
ModeVar: fi.Mode(),
|
||||
ModTimeVar: fi.ModTime().UnixNano(),
|
||||
IsDirVar: fi.IsDir(),
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := out.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Readlink works like os.Readlink
|
||||
// In:
|
||||
// - args[0] is path
|
||||
// Out:
|
||||
// - Write link result to out
|
||||
func Readlink(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
l, err := os.Readlink(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := out.Write([]byte(l)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mkdir works like os.Mkdir
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
// - args[1] is the permissions in octal (like 0755)
|
||||
func Mkdir(in io.Reader, out io.Writer, args []string) error {
|
||||
return mkdir(in, out, args, os.Mkdir)
|
||||
}
|
||||
|
||||
// MkdirAll works like os.MkdirAll.
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
// - args[1] is the permissions in octal (like 0755)
|
||||
func MkdirAll(in io.Reader, out io.Writer, args []string) error {
|
||||
return mkdir(in, out, args, os.MkdirAll)
|
||||
}
|
||||
|
||||
func mkdir(in io.Reader, out io.Writer, args []string, mkdirFunc func(string, os.FileMode) error) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[1], 8, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return mkdirFunc(args[0], os.FileMode(perm))
|
||||
}
|
||||
|
||||
// Remove works like os.Remove
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
func Remove(in io.Reader, out io.Writer, args []string) error {
|
||||
return remove(in, out, args, os.Remove)
|
||||
}
|
||||
|
||||
// RemoveAll works like os.RemoveAll
|
||||
// Args:
|
||||
// - args[0] is the path
|
||||
func RemoveAll(in io.Reader, out io.Writer, args []string) error {
|
||||
return remove(in, out, args, os.RemoveAll)
|
||||
}
|
||||
|
||||
func remove(in io.Reader, out io.Writer, args []string, removefunc func(string) error) error {
|
||||
if len(args) < 1 {
|
||||
return ErrInvalid
|
||||
}
|
||||
return removefunc(args[0])
|
||||
}
|
||||
|
||||
// Link works like os.Link
|
||||
// Args:
|
||||
// - args[0] = old path name (link source)
|
||||
// - args[1] = new path name (link dest)
|
||||
func Link(in io.Reader, out io.Writer, args []string) error {
|
||||
return link(in, out, args, os.Link)
|
||||
}
|
||||
|
||||
// Symlink works like os.Symlink
|
||||
// Args:
|
||||
// - args[0] = old path name (link source)
|
||||
// - args[1] = new path name (link dest)
|
||||
func Symlink(in io.Reader, out io.Writer, args []string) error {
|
||||
return link(in, out, args, os.Symlink)
|
||||
}
|
||||
|
||||
func link(in io.Reader, out io.Writer, args []string, linkfunc func(string, string) error) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
return linkfunc(args[0], args[1])
|
||||
}
|
||||
|
||||
// Lchmod changes permission of the given file without following symlinks
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = permission mode in octal (like 0755)
|
||||
func Lchmod(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[1], 8, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
path := args[0]
|
||||
if !filepath.IsAbs(path) {
|
||||
path, err = filepath.Abs(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return unix.Fchmodat(0, path, uint32(perm), unix.AT_SYMLINK_NOFOLLOW)
|
||||
}
|
||||
|
||||
// Lchown works like os.Lchown
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = uid in base 10
|
||||
// - args[2] = gid in base 10
|
||||
func Lchown(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 3 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
uid, err := strconv.ParseInt(args[1], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gid, err := strconv.ParseInt(args[2], 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Lchown(args[0], int(uid), int(gid))
|
||||
}
|
||||
|
||||
// Mknod works like syscall.Mknod
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = permission mode in octal (like 0755)
|
||||
// - args[2] = major device number in base 10
|
||||
// - args[3] = minor device number in base 10
|
||||
func Mknod(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 4 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[1], 8, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
major, err := strconv.ParseInt(args[2], 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
minor, err := strconv.ParseInt(args[3], 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dev := unix.Mkdev(uint32(major), uint32(minor))
|
||||
return unix.Mknod(args[0], uint32(perm), int(dev))
|
||||
}
|
||||
|
||||
// Mkfifo creates a FIFO special file with the given path name and permissions
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = permission mode in octal (like 0755)
|
||||
func Mkfifo(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[1], 8, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return unix.Mkfifo(args[0], uint32(perm))
|
||||
}
|
||||
|
||||
// OpenFile works like os.OpenFile. To manage the file pointer state,
|
||||
// this function acts as a single file "file server" with Read/Write/Close
|
||||
// being serialized control codes from in.
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = flag in base 10
|
||||
// - args[2] = permission mode in octal (like 0755)
|
||||
func OpenFile(in io.Reader, out io.Writer, args []string) (err error) {
|
||||
logrus.Debugf("OpenFile: %v", args)
|
||||
|
||||
defer func() {
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: return is non-nil, so writing cmdFailed back: %v", err)
|
||||
// error code will be serialized by the caller, so don't write it here
|
||||
WriteFileHeader(out, &FileHeader{Cmd: CmdFailed}, nil)
|
||||
}
|
||||
}()
|
||||
|
||||
if len(args) < 3 {
|
||||
logrus.Errorf("OpenFile: Not enough parameters")
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
flag, err := strconv.ParseInt(args[1], 10, 32)
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Invalid flag: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[2], 8, 32)
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Invalid permission: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(args[0], int(flag), os.FileMode(perm))
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Failed to open: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Signal the client that OpenFile succeeded
|
||||
logrus.Debugf("OpenFile: Sending OK header")
|
||||
if err := WriteFileHeader(out, &FileHeader{Cmd: CmdOK}, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
logrus.Debugf("OpenFile: reading header")
|
||||
hdr, err := ReadFileHeader(in)
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Failed to ReadFileHeader: %v", err)
|
||||
return err
|
||||
}
|
||||
logrus.Debugf("OpenFile: Header: %+v", hdr)
|
||||
|
||||
var buf []byte
|
||||
switch hdr.Cmd {
|
||||
case Read:
|
||||
logrus.Debugf("OpenFile: Read command")
|
||||
buf = make([]byte, hdr.Size, hdr.Size)
|
||||
n, err := f.Read(buf)
|
||||
logrus.Debugf("OpenFile: Issued a read for %d, got %d bytes and error %v", hdr.Size, n, err)
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Read failed: %v", err)
|
||||
return err
|
||||
}
|
||||
buf = buf[:n]
|
||||
case Write:
|
||||
logrus.Debugf("OpenFile: Write command")
|
||||
if _, err := io.CopyN(f, in, int64(hdr.Size)); err != nil {
|
||||
logrus.Errorf("OpenFile: Write CopyN() failed: %v", err)
|
||||
return err
|
||||
}
|
||||
case Seek:
|
||||
logrus.Debugf("OpenFile: Seek command")
|
||||
seekHdr := &SeekHeader{}
|
||||
if err := binary.Read(in, binary.BigEndian, seekHdr); err != nil {
|
||||
logrus.Errorf("OpenFile: Seek Read() failed: %v", err)
|
||||
return err
|
||||
}
|
||||
res, err := f.Seek(seekHdr.Offset, int(seekHdr.Whence))
|
||||
if err != nil {
|
||||
logrus.Errorf("OpenFile: Seek Seek() failed: %v", err)
|
||||
return err
|
||||
}
|
||||
buffer := &bytes.Buffer{}
|
||||
if err := binary.Write(buffer, binary.BigEndian, res); err != nil {
|
||||
logrus.Errorf("OpenFile: Seek Write() failed: %v", err)
|
||||
return err
|
||||
}
|
||||
buf = buffer.Bytes()
|
||||
case Close:
|
||||
logrus.Debugf("OpenFile: Close command")
|
||||
if err := f.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
logrus.Errorf("OpenFile: unknown command")
|
||||
return ErrUnknown
|
||||
}
|
||||
|
||||
logrus.Debugf("OpenFile: Writing back OK header of size %d", len(buf))
|
||||
retHdr := &FileHeader{
|
||||
Cmd: CmdOK,
|
||||
Size: uint64(len(buf)),
|
||||
}
|
||||
if err := WriteFileHeader(out, retHdr, buf); err != nil {
|
||||
logrus.Errorf("OpenFile: WriteFileHeader() failed: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if hdr.Cmd == Close {
|
||||
break
|
||||
}
|
||||
}
|
||||
logrus.Debugf("OpenFile: Done, no error")
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFile works like ioutil.ReadFile but instead writes the file to a writer
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// Out:
|
||||
// - Write file contents to out
|
||||
func ReadFile(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
f, err := os.Open(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := io.Copy(out, f); err != nil {
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteFile works like ioutil.WriteFile but instead reads the file from a reader
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = permission mode in octal (like 0755)
|
||||
// - input data stream from in
|
||||
func WriteFile(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
perm, err := strconv.ParseUint(args[1], 8, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(args[0], os.O_WRONLY|os.O_CREATE|os.O_TRUNC, os.FileMode(perm))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if _, err := io.Copy(f, in); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadDir works like *os.File.Readdir but instead writes the result to a writer
|
||||
// Args:
|
||||
// - args[0] = path
|
||||
// - args[1] = number of directory entries to return. If <= 0, return all entries in directory
|
||||
func ReadDir(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
n, err := strconv.ParseInt(args[1], 10, 32)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, err := os.Open(args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
infos, err := f.Readdir(int(n))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fileInfos := make([]FileInfo, len(infos))
|
||||
for i := range infos {
|
||||
fileInfos[i] = FileInfo{
|
||||
NameVar: infos[i].Name(),
|
||||
SizeVar: infos[i].Size(),
|
||||
ModeVar: infos[i].Mode(),
|
||||
ModTimeVar: infos[i].ModTime().UnixNano(),
|
||||
IsDirVar: infos[i].IsDir(),
|
||||
}
|
||||
}
|
||||
|
||||
buf, err := json.Marshal(fileInfos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := out.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolvePath works like docker's symlink.FollowSymlinkInScope.
|
||||
// It takens in a `path` and a `root` and evaluates symlinks in `path`
|
||||
// as if they were scoped in `root`. `path` must be a child path of `root`.
|
||||
// In other words, `path` must have `root` as a prefix.
|
||||
// Example:
|
||||
// path=/foo/bar -> /baz
|
||||
// root=/foo,
|
||||
// Expected result = /foo/baz
|
||||
//
|
||||
// Args:
|
||||
// - args[0] is `path`
|
||||
// - args[1] is `root`
|
||||
// Out:
|
||||
// - Write resolved path to stdout
|
||||
func ResolvePath(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 2 {
|
||||
return ErrInvalid
|
||||
}
|
||||
res, err := symlink.FollowSymlinkInScope(args[0], args[1])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err = out.Write([]byte(res)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExtractArchive extracts the archive read from in.
|
||||
// Args:
|
||||
// - in = size of json | json of archive.TarOptions | input tar stream
|
||||
// - args[0] = extract directory name
|
||||
func ExtractArchive(in io.Reader, out io.Writer, args []string) error {
|
||||
logrus.Debugln("ExtractArchive:", args)
|
||||
if len(args) < 1 {
|
||||
logrus.Errorln("ExtractArchive: invalid args")
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
opts, err := ReadTarOptions(in)
|
||||
if err != nil {
|
||||
logrus.Errorf("ExtractArchive: Failed to read tar options: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
logrus.Debugf("ExtractArchive: Tar options: %+v", opts)
|
||||
if err := archive.Untar(in, args[0], opts); err != nil {
|
||||
logrus.Errorf("ExtractArchive: Failed to Untar: %v", err)
|
||||
return err
|
||||
}
|
||||
logrus.Debugf("ExtractArchive: Success")
|
||||
return nil
|
||||
}
|
||||
|
||||
// ArchivePath archives the given directory and writes it to out.
|
||||
// Args:
|
||||
// - in = size of json | json of archive.TarOptions
|
||||
// - args[0] = source directory name
|
||||
// Out:
|
||||
// - out = tar file of the archive
|
||||
func ArchivePath(in io.Reader, out io.Writer, args []string) error {
|
||||
if len(args) < 1 {
|
||||
return ErrInvalid
|
||||
}
|
||||
|
||||
opts, err := ReadTarOptions(in)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r, err := archive.TarWithOptions(args[0], opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := io.Copy(out, r); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
170
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/utils.go
generated
vendored
170
vendor/github.com/Microsoft/opengcs/service/gcsutils/remotefs/utils.go
generated
vendored
@@ -1,170 +0,0 @@
|
||||
package remotefs
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
)
|
||||
|
||||
// ReadError is an utility function that reads a serialized error from the given reader
|
||||
// and deserializes it.
|
||||
func ReadError(in io.Reader) (*ExportedError, error) {
|
||||
b, err := ioutil.ReadAll(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// No error
|
||||
if len(b) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var exportedErr ExportedError
|
||||
if err := json.Unmarshal(b, &exportedErr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &exportedErr, nil
|
||||
}
|
||||
|
||||
// ExportedToError will convert a ExportedError to an error. It will try to match
|
||||
// the error to any existing known error like os.ErrNotExist. Otherwise, it will just
|
||||
// return an implementation of the error interface.
|
||||
func ExportedToError(ee *ExportedError) error {
|
||||
if ee.Error() == os.ErrNotExist.Error() {
|
||||
return os.ErrNotExist
|
||||
} else if ee.Error() == os.ErrExist.Error() {
|
||||
return os.ErrExist
|
||||
} else if ee.Error() == os.ErrPermission.Error() {
|
||||
return os.ErrPermission
|
||||
} else if ee.Error() == io.EOF.Error() {
|
||||
return io.EOF
|
||||
}
|
||||
return ee
|
||||
}
|
||||
|
||||
// WriteError is an utility function that serializes the error
|
||||
// and writes it to the output writer.
|
||||
func WriteError(err error, out io.Writer) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
err = fixOSError(err)
|
||||
|
||||
var errno int
|
||||
switch typedError := err.(type) {
|
||||
case *os.PathError:
|
||||
if se, ok := typedError.Err.(syscall.Errno); ok {
|
||||
errno = int(se)
|
||||
}
|
||||
case *os.LinkError:
|
||||
if se, ok := typedError.Err.(syscall.Errno); ok {
|
||||
errno = int(se)
|
||||
}
|
||||
case *os.SyscallError:
|
||||
if se, ok := typedError.Err.(syscall.Errno); ok {
|
||||
errno = int(se)
|
||||
}
|
||||
}
|
||||
|
||||
exportedError := &ExportedError{
|
||||
ErrString: err.Error(),
|
||||
ErrNum: errno,
|
||||
}
|
||||
|
||||
b, err1 := json.Marshal(exportedError)
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
|
||||
_, err1 = out.Write(b)
|
||||
if err1 != nil {
|
||||
return err1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fixOSError converts possible platform dependent error into the portable errors in the
|
||||
// Go os package if possible.
|
||||
func fixOSError(err error) error {
|
||||
// The os.IsExist, os.IsNotExist, and os.IsPermissions functions are platform
|
||||
// dependent, so sending the raw error might break those functions on a different OS.
|
||||
// Go defines portable errors for these.
|
||||
if os.IsExist(err) {
|
||||
return os.ErrExist
|
||||
} else if os.IsNotExist(err) {
|
||||
return os.ErrNotExist
|
||||
} else if os.IsPermission(err) {
|
||||
return os.ErrPermission
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ReadTarOptions reads from the specified reader and deserializes an archive.TarOptions struct.
|
||||
func ReadTarOptions(r io.Reader) (*archive.TarOptions, error) {
|
||||
var size uint64
|
||||
if err := binary.Read(r, binary.BigEndian, &size); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rawJSON := make([]byte, size)
|
||||
if _, err := io.ReadFull(r, rawJSON); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var opts archive.TarOptions
|
||||
if err := json.Unmarshal(rawJSON, &opts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &opts, nil
|
||||
}
|
||||
|
||||
// WriteTarOptions serializes a archive.TarOptions struct and writes it to the writer.
|
||||
func WriteTarOptions(w io.Writer, opts *archive.TarOptions) error {
|
||||
optsBuf, err := json.Marshal(opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
optsSize := uint64(len(optsBuf))
|
||||
optsSizeBuf := &bytes.Buffer{}
|
||||
if err := binary.Write(optsSizeBuf, binary.BigEndian, optsSize); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := optsSizeBuf.WriteTo(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := w.Write(optsBuf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadFileHeader reads from r and returns a deserialized FileHeader
|
||||
func ReadFileHeader(r io.Reader) (*FileHeader, error) {
|
||||
hdr := &FileHeader{}
|
||||
if err := binary.Read(r, binary.BigEndian, hdr); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return hdr, nil
|
||||
}
|
||||
|
||||
// WriteFileHeader serializes a FileHeader and writes it to w, along with any extra data
|
||||
func WriteFileHeader(w io.Writer, hdr *FileHeader, extraData []byte) error {
|
||||
if err := binary.Write(w, binary.BigEndian, hdr); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := w.Write(extraData); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user