Update vendor to include /docker/docker/pkg/system
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
c3cb1cfde8
commit
2bf31ee08c
35
vendor/github.com/docker/docker/pkg/system/chtimes.go
generated
vendored
Normal file
35
vendor/github.com/docker/docker/pkg/system/chtimes.go
generated
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Chtimes changes the access time and modified time of a file at the given path
|
||||||
|
func Chtimes(name string, atime time.Time, mtime time.Time) error {
|
||||||
|
unixMinTime := time.Unix(0, 0)
|
||||||
|
unixMaxTime := maxTime
|
||||||
|
|
||||||
|
// If the modified time is prior to the Unix Epoch, or after the
|
||||||
|
// end of Unix Time, os.Chtimes has undefined behavior
|
||||||
|
// default to Unix Epoch in this case, just in case
|
||||||
|
|
||||||
|
if atime.Before(unixMinTime) || atime.After(unixMaxTime) {
|
||||||
|
atime = unixMinTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if mtime.Before(unixMinTime) || mtime.After(unixMaxTime) {
|
||||||
|
mtime = unixMinTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.Chtimes(name, atime, mtime); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take platform specific action for setting create time.
|
||||||
|
if err := setCTime(name, mtime); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
14
vendor/github.com/docker/docker/pkg/system/chtimes_unix.go
generated
vendored
Normal file
14
vendor/github.com/docker/docker/pkg/system/chtimes_unix.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
//setCTime will set the create time on a file. On Unix, the create
|
||||||
|
//time is updated as a side effect of setting the modified time, so
|
||||||
|
//no action is required.
|
||||||
|
func setCTime(path string, ctime time.Time) error {
|
||||||
|
return nil
|
||||||
|
}
|
28
vendor/github.com/docker/docker/pkg/system/chtimes_windows.go
generated
vendored
Normal file
28
vendor/github.com/docker/docker/pkg/system/chtimes_windows.go
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
//setCTime will set the create time on a file. On Windows, this requires
|
||||||
|
//calling SetFileTime and explicitly including the create time.
|
||||||
|
func setCTime(path string, ctime time.Time) error {
|
||||||
|
ctimespec := windows.NsecToTimespec(ctime.UnixNano())
|
||||||
|
pathp, e := windows.UTF16PtrFromString(path)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
h, e := windows.CreateFile(pathp,
|
||||||
|
windows.FILE_WRITE_ATTRIBUTES, windows.FILE_SHARE_WRITE, nil,
|
||||||
|
windows.OPEN_EXISTING, windows.FILE_FLAG_BACKUP_SEMANTICS, 0)
|
||||||
|
if e != nil {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
defer windows.Close(h)
|
||||||
|
c := windows.NsecToFiletime(windows.TimespecToNsec(ctimespec))
|
||||||
|
return windows.SetFileTime(h, &c, nil, nil)
|
||||||
|
}
|
10
vendor/github.com/docker/docker/pkg/system/errors.go
generated
vendored
Normal file
10
vendor/github.com/docker/docker/pkg/system/errors.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrNotSupportedPlatform means the platform is not supported.
|
||||||
|
ErrNotSupportedPlatform = errors.New("platform and architecture is not supported")
|
||||||
|
)
|
85
vendor/github.com/docker/docker/pkg/system/events_windows.go
generated
vendored
Normal file
85
vendor/github.com/docker/docker/pkg/system/events_windows.go
generated
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
// This file implements syscalls for Win32 events which are not implemented
|
||||||
|
// in golang.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
procCreateEvent = modkernel32.NewProc("CreateEventW")
|
||||||
|
procOpenEvent = modkernel32.NewProc("OpenEventW")
|
||||||
|
procSetEvent = modkernel32.NewProc("SetEvent")
|
||||||
|
procResetEvent = modkernel32.NewProc("ResetEvent")
|
||||||
|
procPulseEvent = modkernel32.NewProc("PulseEvent")
|
||||||
|
)
|
||||||
|
|
||||||
|
// CreateEvent implements win32 CreateEventW func in golang. It will create an event object.
|
||||||
|
func CreateEvent(eventAttributes *windows.SecurityAttributes, manualReset bool, initialState bool, name string) (handle windows.Handle, err error) {
|
||||||
|
namep, _ := windows.UTF16PtrFromString(name)
|
||||||
|
var _p1 uint32
|
||||||
|
if manualReset {
|
||||||
|
_p1 = 1
|
||||||
|
}
|
||||||
|
var _p2 uint32
|
||||||
|
if initialState {
|
||||||
|
_p2 = 1
|
||||||
|
}
|
||||||
|
r0, _, e1 := procCreateEvent.Call(uintptr(unsafe.Pointer(eventAttributes)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(namep)))
|
||||||
|
use(unsafe.Pointer(namep))
|
||||||
|
handle = windows.Handle(r0)
|
||||||
|
if handle == windows.InvalidHandle {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenEvent implements win32 OpenEventW func in golang. It opens an event object.
|
||||||
|
func OpenEvent(desiredAccess uint32, inheritHandle bool, name string) (handle windows.Handle, err error) {
|
||||||
|
namep, _ := windows.UTF16PtrFromString(name)
|
||||||
|
var _p1 uint32
|
||||||
|
if inheritHandle {
|
||||||
|
_p1 = 1
|
||||||
|
}
|
||||||
|
r0, _, e1 := procOpenEvent.Call(uintptr(desiredAccess), uintptr(_p1), uintptr(unsafe.Pointer(namep)))
|
||||||
|
use(unsafe.Pointer(namep))
|
||||||
|
handle = windows.Handle(r0)
|
||||||
|
if handle == windows.InvalidHandle {
|
||||||
|
err = e1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEvent implements win32 SetEvent func in golang.
|
||||||
|
func SetEvent(handle windows.Handle) (err error) {
|
||||||
|
return setResetPulse(handle, procSetEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetEvent implements win32 ResetEvent func in golang.
|
||||||
|
func ResetEvent(handle windows.Handle) (err error) {
|
||||||
|
return setResetPulse(handle, procResetEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PulseEvent implements win32 PulseEvent func in golang.
|
||||||
|
func PulseEvent(handle windows.Handle) (err error) {
|
||||||
|
return setResetPulse(handle, procPulseEvent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setResetPulse(handle windows.Handle, proc *windows.LazyProc) (err error) {
|
||||||
|
r0, _, _ := proc.Call(uintptr(handle))
|
||||||
|
if r0 != 0 {
|
||||||
|
err = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var temp unsafe.Pointer
|
||||||
|
|
||||||
|
// use ensures a variable is kept alive without the GC freeing while still needed
|
||||||
|
func use(p unsafe.Pointer) {
|
||||||
|
temp = p
|
||||||
|
}
|
33
vendor/github.com/docker/docker/pkg/system/exitcode.go
generated
vendored
Normal file
33
vendor/github.com/docker/docker/pkg/system/exitcode.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetExitCode returns the ExitStatus of the specified error if its type is
|
||||||
|
// exec.ExitError, returns 0 and an error otherwise.
|
||||||
|
func GetExitCode(err error) (int, error) {
|
||||||
|
exitCode := 0
|
||||||
|
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||||
|
if procExit, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||||
|
return procExit.ExitStatus(), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exitCode, fmt.Errorf("failed to get exit code")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProcessExitCode process the specified error and returns the exit status code
|
||||||
|
// if the error was of type exec.ExitError, returns nothing otherwise.
|
||||||
|
func ProcessExitCode(err error) (exitCode int) {
|
||||||
|
if err != nil {
|
||||||
|
var exiterr error
|
||||||
|
if exitCode, exiterr = GetExitCode(err); exiterr != nil {
|
||||||
|
// TODO: Fix this so we check the error's text.
|
||||||
|
// we've failed to retrieve exit code, so we set it to 127
|
||||||
|
exitCode = 127
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
67
vendor/github.com/docker/docker/pkg/system/filesys.go
generated
vendored
Normal file
67
vendor/github.com/docker/docker/pkg/system/filesys.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MkdirAllWithACL is a wrapper for MkdirAll on unix systems.
|
||||||
|
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||||
|
return MkdirAll(path, perm, sddl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MkdirAll creates a directory named path along with any necessary parents,
|
||||||
|
// with permission specified by attribute perm for all dir created.
|
||||||
|
func MkdirAll(path string, perm os.FileMode, sddl string) error {
|
||||||
|
return os.MkdirAll(path, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAbs is a platform-specific wrapper for filepath.IsAbs.
|
||||||
|
func IsAbs(path string) bool {
|
||||||
|
return filepath.IsAbs(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The functions below here are wrappers for the equivalents in the os and ioutils packages.
|
||||||
|
// They are passthrough on Unix platforms, and only relevant on Windows.
|
||||||
|
|
||||||
|
// CreateSequential creates the named file with mode 0666 (before umask), truncating
|
||||||
|
// it if it already exists. If successful, methods on the returned
|
||||||
|
// File can be used for I/O; the associated file descriptor has mode
|
||||||
|
// O_RDWR.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func CreateSequential(name string) (*os.File, error) {
|
||||||
|
return os.Create(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenSequential opens the named file for reading. If successful, methods on
|
||||||
|
// the returned file can be used for reading; the associated file
|
||||||
|
// descriptor has mode O_RDONLY.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func OpenSequential(name string) (*os.File, error) {
|
||||||
|
return os.Open(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenFileSequential is the generalized open call; most users will use Open
|
||||||
|
// or Create instead. It opens the named file with specified flag
|
||||||
|
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
|
||||||
|
// methods on the returned File can be used for I/O.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func OpenFileSequential(name string, flag int, perm os.FileMode) (*os.File, error) {
|
||||||
|
return os.OpenFile(name, flag, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempFileSequential creates a new temporary file in the directory dir
|
||||||
|
// with a name beginning with prefix, opens the file for reading
|
||||||
|
// and writing, and returns the resulting *os.File.
|
||||||
|
// If dir is the empty string, TempFile uses the default directory
|
||||||
|
// for temporary files (see os.TempDir).
|
||||||
|
// Multiple programs calling TempFile simultaneously
|
||||||
|
// will not choose the same file. The caller can use f.Name()
|
||||||
|
// to find the pathname of the file. It is the caller's responsibility
|
||||||
|
// to remove the file when no longer needed.
|
||||||
|
func TempFileSequential(dir, prefix string) (f *os.File, err error) {
|
||||||
|
return ioutil.TempFile(dir, prefix)
|
||||||
|
}
|
298
vendor/github.com/docker/docker/pkg/system/filesys_windows.go
generated
vendored
Normal file
298
vendor/github.com/docker/docker/pkg/system/filesys_windows.go
generated
vendored
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
winio "github.com/Microsoft/go-winio"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// SddlAdministratorsLocalSystem is local administrators plus NT AUTHORITY\System
|
||||||
|
SddlAdministratorsLocalSystem = "D:P(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
|
||||||
|
// SddlNtvmAdministratorsLocalSystem is NT VIRTUAL MACHINE\Virtual Machines plus local administrators plus NT AUTHORITY\System
|
||||||
|
SddlNtvmAdministratorsLocalSystem = "D:P(A;OICI;GA;;;S-1-5-83-0)(A;OICI;GA;;;BA)(A;OICI;GA;;;SY)"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MkdirAllWithACL is a wrapper for MkdirAll that creates a directory
|
||||||
|
// with an appropriate SDDL defined ACL.
|
||||||
|
func MkdirAllWithACL(path string, perm os.FileMode, sddl string) error {
|
||||||
|
return mkdirall(path, true, sddl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MkdirAll implementation that is volume path aware for Windows.
|
||||||
|
func MkdirAll(path string, _ os.FileMode, sddl string) error {
|
||||||
|
return mkdirall(path, false, sddl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// mkdirall is a custom version of os.MkdirAll modified for use on Windows
|
||||||
|
// so that it is both volume path aware, and can create a directory with
|
||||||
|
// a DACL.
|
||||||
|
func mkdirall(path string, applyACL bool, sddl string) error {
|
||||||
|
if re := regexp.MustCompile(`^\\\\\?\\Volume{[a-z0-9-]+}$`); re.MatchString(path) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// The rest of this method is largely copied from os.MkdirAll and should be kept
|
||||||
|
// as-is to ensure compatibility.
|
||||||
|
|
||||||
|
// Fast path: if we can tell whether path is a directory or file, stop with success or error.
|
||||||
|
dir, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
if dir.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &os.PathError{
|
||||||
|
Op: "mkdir",
|
||||||
|
Path: path,
|
||||||
|
Err: syscall.ENOTDIR,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Slow path: make sure parent exists and then call Mkdir for path.
|
||||||
|
i := len(path)
|
||||||
|
for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
|
||||||
|
j := i
|
||||||
|
for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.
|
||||||
|
j--
|
||||||
|
}
|
||||||
|
|
||||||
|
if j > 1 {
|
||||||
|
// Create parent
|
||||||
|
err = mkdirall(path[0:j-1], false, sddl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parent now exists; invoke os.Mkdir or mkdirWithACL and use its result.
|
||||||
|
if applyACL {
|
||||||
|
err = mkdirWithACL(path, sddl)
|
||||||
|
} else {
|
||||||
|
err = os.Mkdir(path, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// Handle arguments like "foo/." by
|
||||||
|
// double-checking that directory doesn't exist.
|
||||||
|
dir, err1 := os.Lstat(path)
|
||||||
|
if err1 == nil && dir.IsDir() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mkdirWithACL creates a new directory. If there is an error, it will be of
|
||||||
|
// type *PathError. .
|
||||||
|
//
|
||||||
|
// This is a modified and combined version of os.Mkdir and windows.Mkdir
|
||||||
|
// in golang to cater for creating a directory am ACL permitting full
|
||||||
|
// access, with inheritance, to any subfolder/file for Built-in Administrators
|
||||||
|
// and Local System.
|
||||||
|
func mkdirWithACL(name string, sddl string) error {
|
||||||
|
sa := windows.SecurityAttributes{Length: 0}
|
||||||
|
sd, err := winio.SddlToSecurityDescriptor(sddl)
|
||||||
|
if err != nil {
|
||||||
|
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||||
|
}
|
||||||
|
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||||
|
sa.InheritHandle = 1
|
||||||
|
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
|
||||||
|
|
||||||
|
namep, err := windows.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return &os.PathError{Op: "mkdir", Path: name, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
e := windows.CreateDirectory(namep, &sa)
|
||||||
|
if e != nil {
|
||||||
|
return &os.PathError{Op: "mkdir", Path: name, Err: e}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsAbs is a platform-specific wrapper for filepath.IsAbs. On Windows,
|
||||||
|
// golang filepath.IsAbs does not consider a path \windows\system32 as absolute
|
||||||
|
// as it doesn't start with a drive-letter/colon combination. However, in
|
||||||
|
// docker we need to verify things such as WORKDIR /windows/system32 in
|
||||||
|
// a Dockerfile (which gets translated to \windows\system32 when being processed
|
||||||
|
// by the daemon. This SHOULD be treated as absolute from a docker processing
|
||||||
|
// perspective.
|
||||||
|
func IsAbs(path string) bool {
|
||||||
|
if !filepath.IsAbs(path) {
|
||||||
|
if !strings.HasPrefix(path, string(os.PathSeparator)) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// The origin of the functions below here are the golang OS and windows packages,
|
||||||
|
// slightly modified to only cope with files, not directories due to the
|
||||||
|
// specific use case.
|
||||||
|
//
|
||||||
|
// The alteration is to allow a file on Windows to be opened with
|
||||||
|
// FILE_FLAG_SEQUENTIAL_SCAN (particular for docker load), to avoid eating
|
||||||
|
// the standby list, particularly when accessing large files such as layer.tar.
|
||||||
|
|
||||||
|
// CreateSequential creates the named file with mode 0666 (before umask), truncating
|
||||||
|
// it if it already exists. If successful, methods on the returned
|
||||||
|
// File can be used for I/O; the associated file descriptor has mode
|
||||||
|
// O_RDWR.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func CreateSequential(name string) (*os.File, error) {
|
||||||
|
return OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenSequential opens the named file for reading. If successful, methods on
|
||||||
|
// the returned file can be used for reading; the associated file
|
||||||
|
// descriptor has mode O_RDONLY.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func OpenSequential(name string) (*os.File, error) {
|
||||||
|
return OpenFileSequential(name, os.O_RDONLY, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenFileSequential is the generalized open call; most users will use Open
|
||||||
|
// or Create instead.
|
||||||
|
// If there is an error, it will be of type *PathError.
|
||||||
|
func OpenFileSequential(name string, flag int, _ os.FileMode) (*os.File, error) {
|
||||||
|
if name == "" {
|
||||||
|
return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOENT}
|
||||||
|
}
|
||||||
|
r, errf := windowsOpenFileSequential(name, flag, 0)
|
||||||
|
if errf == nil {
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
return nil, &os.PathError{Op: "open", Path: name, Err: errf}
|
||||||
|
}
|
||||||
|
|
||||||
|
func windowsOpenFileSequential(name string, flag int, _ os.FileMode) (file *os.File, err error) {
|
||||||
|
r, e := windowsOpenSequential(name, flag|windows.O_CLOEXEC, 0)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
return os.NewFile(uintptr(r), name), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeInheritSa() *windows.SecurityAttributes {
|
||||||
|
var sa windows.SecurityAttributes
|
||||||
|
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||||
|
sa.InheritHandle = 1
|
||||||
|
return &sa
|
||||||
|
}
|
||||||
|
|
||||||
|
func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle, err error) {
|
||||||
|
if len(path) == 0 {
|
||||||
|
return windows.InvalidHandle, windows.ERROR_FILE_NOT_FOUND
|
||||||
|
}
|
||||||
|
pathp, err := windows.UTF16PtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return windows.InvalidHandle, err
|
||||||
|
}
|
||||||
|
var access uint32
|
||||||
|
switch mode & (windows.O_RDONLY | windows.O_WRONLY | windows.O_RDWR) {
|
||||||
|
case windows.O_RDONLY:
|
||||||
|
access = windows.GENERIC_READ
|
||||||
|
case windows.O_WRONLY:
|
||||||
|
access = windows.GENERIC_WRITE
|
||||||
|
case windows.O_RDWR:
|
||||||
|
access = windows.GENERIC_READ | windows.GENERIC_WRITE
|
||||||
|
}
|
||||||
|
if mode&windows.O_CREAT != 0 {
|
||||||
|
access |= windows.GENERIC_WRITE
|
||||||
|
}
|
||||||
|
if mode&windows.O_APPEND != 0 {
|
||||||
|
access &^= windows.GENERIC_WRITE
|
||||||
|
access |= windows.FILE_APPEND_DATA
|
||||||
|
}
|
||||||
|
sharemode := uint32(windows.FILE_SHARE_READ | windows.FILE_SHARE_WRITE)
|
||||||
|
var sa *windows.SecurityAttributes
|
||||||
|
if mode&windows.O_CLOEXEC == 0 {
|
||||||
|
sa = makeInheritSa()
|
||||||
|
}
|
||||||
|
var createmode uint32
|
||||||
|
switch {
|
||||||
|
case mode&(windows.O_CREAT|windows.O_EXCL) == (windows.O_CREAT | windows.O_EXCL):
|
||||||
|
createmode = windows.CREATE_NEW
|
||||||
|
case mode&(windows.O_CREAT|windows.O_TRUNC) == (windows.O_CREAT | windows.O_TRUNC):
|
||||||
|
createmode = windows.CREATE_ALWAYS
|
||||||
|
case mode&windows.O_CREAT == windows.O_CREAT:
|
||||||
|
createmode = windows.OPEN_ALWAYS
|
||||||
|
case mode&windows.O_TRUNC == windows.O_TRUNC:
|
||||||
|
createmode = windows.TRUNCATE_EXISTING
|
||||||
|
default:
|
||||||
|
createmode = windows.OPEN_EXISTING
|
||||||
|
}
|
||||||
|
// Use FILE_FLAG_SEQUENTIAL_SCAN rather than FILE_ATTRIBUTE_NORMAL as implemented in golang.
|
||||||
|
//https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
|
||||||
|
const fileFlagSequentialScan = 0x08000000 // FILE_FLAG_SEQUENTIAL_SCAN
|
||||||
|
h, e := windows.CreateFile(pathp, access, sharemode, sa, createmode, fileFlagSequentialScan, 0)
|
||||||
|
return h, e
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helpers for TempFileSequential
|
||||||
|
var rand uint32
|
||||||
|
var randmu sync.Mutex
|
||||||
|
|
||||||
|
func reseed() uint32 {
|
||||||
|
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
|
||||||
|
}
|
||||||
|
func nextSuffix() string {
|
||||||
|
randmu.Lock()
|
||||||
|
r := rand
|
||||||
|
if r == 0 {
|
||||||
|
r = reseed()
|
||||||
|
}
|
||||||
|
r = r*1664525 + 1013904223 // constants from Numerical Recipes
|
||||||
|
rand = r
|
||||||
|
randmu.Unlock()
|
||||||
|
return strconv.Itoa(int(1e9 + r%1e9))[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// TempFileSequential is a copy of ioutil.TempFile, modified to use sequential
|
||||||
|
// file access. Below is the original comment from golang:
|
||||||
|
// TempFile creates a new temporary file in the directory dir
|
||||||
|
// with a name beginning with prefix, opens the file for reading
|
||||||
|
// and writing, and returns the resulting *os.File.
|
||||||
|
// If dir is the empty string, TempFile uses the default directory
|
||||||
|
// for temporary files (see os.TempDir).
|
||||||
|
// Multiple programs calling TempFile simultaneously
|
||||||
|
// will not choose the same file. The caller can use f.Name()
|
||||||
|
// to find the pathname of the file. It is the caller's responsibility
|
||||||
|
// to remove the file when no longer needed.
|
||||||
|
func TempFileSequential(dir, prefix string) (f *os.File, err error) {
|
||||||
|
if dir == "" {
|
||||||
|
dir = os.TempDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
nconflict := 0
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
|
name := filepath.Join(dir, prefix+nextSuffix())
|
||||||
|
f, err = OpenFileSequential(name, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0600)
|
||||||
|
if os.IsExist(err) {
|
||||||
|
if nconflict++; nconflict > 10 {
|
||||||
|
randmu.Lock()
|
||||||
|
rand = reseed()
|
||||||
|
randmu.Unlock()
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
22
vendor/github.com/docker/docker/pkg/system/init.go
generated
vendored
Normal file
22
vendor/github.com/docker/docker/pkg/system/init.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Used by chtimes
|
||||||
|
var maxTime time.Time
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// chtimes initialization
|
||||||
|
if unsafe.Sizeof(syscall.Timespec{}.Nsec) == 8 {
|
||||||
|
// This is a 64 bit timespec
|
||||||
|
// os.Chtimes limits time to the following
|
||||||
|
maxTime = time.Unix(0, 1<<63-1)
|
||||||
|
} else {
|
||||||
|
// This is a 32 bit timespec
|
||||||
|
maxTime = time.Unix(1<<31-1, 0)
|
||||||
|
}
|
||||||
|
}
|
17
vendor/github.com/docker/docker/pkg/system/init_windows.go
generated
vendored
Normal file
17
vendor/github.com/docker/docker/pkg/system/init_windows.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// LCOWSupported determines if Linux Containers on Windows are supported.
|
||||||
|
// Note: This feature is in development (06/17) and enabled through an
|
||||||
|
// environment variable. At a future time, it will be enabled based
|
||||||
|
// on build number. @jhowardmsft
|
||||||
|
var lcowSupported = false
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// LCOW initialization
|
||||||
|
if os.Getenv("LCOW_SUPPORTED") != "" {
|
||||||
|
lcowSupported = true
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
vendor/github.com/docker/docker/pkg/system/lcow_unix.go
generated
vendored
Normal file
8
vendor/github.com/docker/docker/pkg/system/lcow_unix.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// LCOWSupported returns true if Linux containers on Windows are supported.
|
||||||
|
func LCOWSupported() bool {
|
||||||
|
return false
|
||||||
|
}
|
6
vendor/github.com/docker/docker/pkg/system/lcow_windows.go
generated
vendored
Normal file
6
vendor/github.com/docker/docker/pkg/system/lcow_windows.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
// LCOWSupported returns true if Linux containers on Windows are supported.
|
||||||
|
func LCOWSupported() bool {
|
||||||
|
return lcowSupported
|
||||||
|
}
|
19
vendor/github.com/docker/docker/pkg/system/lstat_unix.go
generated
vendored
Normal file
19
vendor/github.com/docker/docker/pkg/system/lstat_unix.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Lstat takes a path to a file and returns
|
||||||
|
// a system.StatT type pertaining to that file.
|
||||||
|
//
|
||||||
|
// Throws an error if the file does not exist
|
||||||
|
func Lstat(path string) (*StatT, error) {
|
||||||
|
s := &syscall.Stat_t{}
|
||||||
|
if err := syscall.Lstat(path, s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fromStatT(s)
|
||||||
|
}
|
14
vendor/github.com/docker/docker/pkg/system/lstat_windows.go
generated
vendored
Normal file
14
vendor/github.com/docker/docker/pkg/system/lstat_windows.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
// Lstat calls os.Lstat to get a fileinfo interface back.
|
||||||
|
// This is then copied into our own locally defined structure.
|
||||||
|
func Lstat(path string) (*StatT, error) {
|
||||||
|
fi, err := os.Lstat(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fromStatT(&fi)
|
||||||
|
}
|
17
vendor/github.com/docker/docker/pkg/system/meminfo.go
generated
vendored
Normal file
17
vendor/github.com/docker/docker/pkg/system/meminfo.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
// MemInfo contains memory statistics of the host system.
|
||||||
|
type MemInfo struct {
|
||||||
|
// Total usable RAM (i.e. physical RAM minus a few reserved bits and the
|
||||||
|
// kernel binary code).
|
||||||
|
MemTotal int64
|
||||||
|
|
||||||
|
// Amount of free memory.
|
||||||
|
MemFree int64
|
||||||
|
|
||||||
|
// Total amount of swap space available.
|
||||||
|
SwapTotal int64
|
||||||
|
|
||||||
|
// Amount of swap space that is currently unused.
|
||||||
|
SwapFree int64
|
||||||
|
}
|
65
vendor/github.com/docker/docker/pkg/system/meminfo_linux.go
generated
vendored
Normal file
65
vendor/github.com/docker/docker/pkg/system/meminfo_linux.go
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/docker/go-units"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||||
|
// MemInfo type.
|
||||||
|
func ReadMemInfo() (*MemInfo, error) {
|
||||||
|
file, err := os.Open("/proc/meminfo")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
return parseMemInfo(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseMemInfo parses the /proc/meminfo file into
|
||||||
|
// a MemInfo object given an io.Reader to the file.
|
||||||
|
// Throws error if there are problems reading from the file
|
||||||
|
func parseMemInfo(reader io.Reader) (*MemInfo, error) {
|
||||||
|
meminfo := &MemInfo{}
|
||||||
|
scanner := bufio.NewScanner(reader)
|
||||||
|
for scanner.Scan() {
|
||||||
|
// Expected format: ["MemTotal:", "1234", "kB"]
|
||||||
|
parts := strings.Fields(scanner.Text())
|
||||||
|
|
||||||
|
// Sanity checks: Skip malformed entries.
|
||||||
|
if len(parts) < 3 || parts[2] != "kB" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to bytes.
|
||||||
|
size, err := strconv.Atoi(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bytes := int64(size) * units.KiB
|
||||||
|
|
||||||
|
switch parts[0] {
|
||||||
|
case "MemTotal:":
|
||||||
|
meminfo.MemTotal = bytes
|
||||||
|
case "MemFree:":
|
||||||
|
meminfo.MemFree = bytes
|
||||||
|
case "SwapTotal:":
|
||||||
|
meminfo.SwapTotal = bytes
|
||||||
|
case "SwapFree:":
|
||||||
|
meminfo.SwapFree = bytes
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle errors that may have occurred during the reading of the file.
|
||||||
|
if err := scanner.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return meminfo, nil
|
||||||
|
}
|
129
vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go
generated
vendored
Normal file
129
vendor/github.com/docker/docker/pkg/system/meminfo_solaris.go
generated
vendored
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
// +build solaris,cgo
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// #cgo CFLAGS: -std=c99
|
||||||
|
// #cgo LDFLAGS: -lkstat
|
||||||
|
// #include <unistd.h>
|
||||||
|
// #include <stdlib.h>
|
||||||
|
// #include <stdio.h>
|
||||||
|
// #include <kstat.h>
|
||||||
|
// #include <sys/swap.h>
|
||||||
|
// #include <sys/param.h>
|
||||||
|
// struct swaptable *allocSwaptable(int num) {
|
||||||
|
// struct swaptable *st;
|
||||||
|
// struct swapent *swapent;
|
||||||
|
// st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
|
||||||
|
// swapent = st->swt_ent;
|
||||||
|
// for (int i = 0; i < num; i++,swapent++) {
|
||||||
|
// swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
|
||||||
|
// }
|
||||||
|
// st->swt_n = num;
|
||||||
|
// return st;
|
||||||
|
//}
|
||||||
|
// void freeSwaptable (struct swaptable *st) {
|
||||||
|
// struct swapent *swapent = st->swt_ent;
|
||||||
|
// for (int i = 0; i < st->swt_n; i++,swapent++) {
|
||||||
|
// free(swapent->ste_path);
|
||||||
|
// }
|
||||||
|
// free(st);
|
||||||
|
// }
|
||||||
|
// swapent_t getSwapEnt(swapent_t *ent, int i) {
|
||||||
|
// return ent[i];
|
||||||
|
// }
|
||||||
|
// int64_t getPpKernel() {
|
||||||
|
// int64_t pp_kernel = 0;
|
||||||
|
// kstat_ctl_t *ksc;
|
||||||
|
// kstat_t *ks;
|
||||||
|
// kstat_named_t *knp;
|
||||||
|
// kid_t kid;
|
||||||
|
//
|
||||||
|
// if ((ksc = kstat_open()) == NULL) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
|
||||||
|
// ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// switch (knp->data_type) {
|
||||||
|
// case KSTAT_DATA_UINT64:
|
||||||
|
// pp_kernel = knp->value.ui64;
|
||||||
|
// break;
|
||||||
|
// case KSTAT_DATA_UINT32:
|
||||||
|
// pp_kernel = knp->value.ui32;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// pp_kernel *= sysconf(_SC_PAGESIZE);
|
||||||
|
// return (pp_kernel > 0 ? pp_kernel : -1);
|
||||||
|
// }
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
// Get the system memory info using sysconf same as prtconf
|
||||||
|
func getTotalMem() int64 {
|
||||||
|
pagesize := C.sysconf(C._SC_PAGESIZE)
|
||||||
|
npages := C.sysconf(C._SC_PHYS_PAGES)
|
||||||
|
return int64(pagesize * npages)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getFreeMem() int64 {
|
||||||
|
pagesize := C.sysconf(C._SC_PAGESIZE)
|
||||||
|
npages := C.sysconf(C._SC_AVPHYS_PAGES)
|
||||||
|
return int64(pagesize * npages)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||||
|
// MemInfo type.
|
||||||
|
func ReadMemInfo() (*MemInfo, error) {
|
||||||
|
|
||||||
|
ppKernel := C.getPpKernel()
|
||||||
|
MemTotal := getTotalMem()
|
||||||
|
MemFree := getFreeMem()
|
||||||
|
SwapTotal, SwapFree, err := getSysSwap()
|
||||||
|
|
||||||
|
if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
|
||||||
|
SwapFree < 0 {
|
||||||
|
return nil, fmt.Errorf("error getting system memory info %v\n", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
meminfo := &MemInfo{}
|
||||||
|
// Total memory is total physical memory less than memory locked by kernel
|
||||||
|
meminfo.MemTotal = MemTotal - int64(ppKernel)
|
||||||
|
meminfo.MemFree = MemFree
|
||||||
|
meminfo.SwapTotal = SwapTotal
|
||||||
|
meminfo.SwapFree = SwapFree
|
||||||
|
|
||||||
|
return meminfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSysSwap() (int64, int64, error) {
|
||||||
|
var tSwap int64
|
||||||
|
var fSwap int64
|
||||||
|
var diskblksPerPage int64
|
||||||
|
num, err := C.swapctl(C.SC_GETNSWP, nil)
|
||||||
|
if err != nil {
|
||||||
|
return -1, -1, err
|
||||||
|
}
|
||||||
|
st := C.allocSwaptable(num)
|
||||||
|
_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
|
||||||
|
if err != nil {
|
||||||
|
C.freeSwaptable(st)
|
||||||
|
return -1, -1, err
|
||||||
|
}
|
||||||
|
|
||||||
|
diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
|
||||||
|
for i := 0; i < int(num); i++ {
|
||||||
|
swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
|
||||||
|
tSwap += int64(swapent.ste_pages) * diskblksPerPage
|
||||||
|
fSwap += int64(swapent.ste_free) * diskblksPerPage
|
||||||
|
}
|
||||||
|
C.freeSwaptable(st)
|
||||||
|
return tSwap, fSwap, nil
|
||||||
|
}
|
8
vendor/github.com/docker/docker/pkg/system/meminfo_unsupported.go
generated
vendored
Normal file
8
vendor/github.com/docker/docker/pkg/system/meminfo_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// +build !linux,!windows,!solaris
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// ReadMemInfo is not supported on platforms other than linux and windows.
|
||||||
|
func ReadMemInfo() (*MemInfo, error) {
|
||||||
|
return nil, ErrNotSupportedPlatform
|
||||||
|
}
|
45
vendor/github.com/docker/docker/pkg/system/meminfo_windows.go
generated
vendored
Normal file
45
vendor/github.com/docker/docker/pkg/system/meminfo_windows.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx")
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx
|
||||||
|
type memorystatusex struct {
|
||||||
|
dwLength uint32
|
||||||
|
dwMemoryLoad uint32
|
||||||
|
ullTotalPhys uint64
|
||||||
|
ullAvailPhys uint64
|
||||||
|
ullTotalPageFile uint64
|
||||||
|
ullAvailPageFile uint64
|
||||||
|
ullTotalVirtual uint64
|
||||||
|
ullAvailVirtual uint64
|
||||||
|
ullAvailExtendedVirtual uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadMemInfo retrieves memory statistics of the host system and returns a
|
||||||
|
// MemInfo type.
|
||||||
|
func ReadMemInfo() (*MemInfo, error) {
|
||||||
|
msi := &memorystatusex{
|
||||||
|
dwLength: 64,
|
||||||
|
}
|
||||||
|
r1, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(msi)))
|
||||||
|
if r1 == 0 {
|
||||||
|
return &MemInfo{}, nil
|
||||||
|
}
|
||||||
|
return &MemInfo{
|
||||||
|
MemTotal: int64(msi.ullTotalPhys),
|
||||||
|
MemFree: int64(msi.ullAvailPhys),
|
||||||
|
SwapTotal: int64(msi.ullTotalPageFile),
|
||||||
|
SwapFree: int64(msi.ullAvailPageFile),
|
||||||
|
}, nil
|
||||||
|
}
|
22
vendor/github.com/docker/docker/pkg/system/mknod.go
generated
vendored
Normal file
22
vendor/github.com/docker/docker/pkg/system/mknod.go
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mknod creates a filesystem node (file, device special file or named pipe) named path
|
||||||
|
// with attributes specified by mode and dev.
|
||||||
|
func Mknod(path string, mode uint32, dev int) error {
|
||||||
|
return unix.Mknod(path, mode, dev)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mkdev is used to build the value of linux devices (in /dev/) which specifies major
|
||||||
|
// and minor number of the newly created device special file.
|
||||||
|
// Linux device nodes are a bit weird due to backwards compat with 16 bit device nodes.
|
||||||
|
// They are, from low to high: the lower 8 bits of the minor, then 12 bits of the major,
|
||||||
|
// then the top 12 bits of the minor.
|
||||||
|
func Mkdev(major int64, minor int64) uint32 {
|
||||||
|
return uint32(((minor & 0xfff00) << 12) | ((major & 0xfff) << 8) | (minor & 0xff))
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/mknod_windows.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/mknod_windows.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// Mknod is not implemented on Windows.
|
||||||
|
func Mknod(path string, mode uint32, dev int) error {
|
||||||
|
return ErrNotSupportedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mkdev is not implemented on Windows.
|
||||||
|
func Mkdev(major int64, minor int64) uint32 {
|
||||||
|
panic("Mkdev not implemented on Windows.")
|
||||||
|
}
|
21
vendor/github.com/docker/docker/pkg/system/path.go
generated
vendored
Normal file
21
vendor/github.com/docker/docker/pkg/system/path.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "runtime"
|
||||||
|
|
||||||
|
const defaultUnixPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
|
|
||||||
|
// DefaultPathEnv is unix style list of directories to search for
|
||||||
|
// executables. Each directory is separated from the next by a colon
|
||||||
|
// ':' character .
|
||||||
|
func DefaultPathEnv(platform string) string {
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
if platform != runtime.GOOS && LCOWSupported() {
|
||||||
|
return defaultUnixPathEnv
|
||||||
|
}
|
||||||
|
// Deliberately empty on Windows containers on Windows as the default path will be set by
|
||||||
|
// the container. Docker has no context of what the default path should be.
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return defaultUnixPathEnv
|
||||||
|
|
||||||
|
}
|
9
vendor/github.com/docker/docker/pkg/system/path_unix.go
generated
vendored
Normal file
9
vendor/github.com/docker/docker/pkg/system/path_unix.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
|
||||||
|
// is the system drive. This is a no-op on Linux.
|
||||||
|
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||||
|
return path, nil
|
||||||
|
}
|
33
vendor/github.com/docker/docker/pkg/system/path_windows.go
generated
vendored
Normal file
33
vendor/github.com/docker/docker/pkg/system/path_windows.go
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
|
||||||
|
// This is used, for example, when validating a user provided path in docker cp.
|
||||||
|
// If a drive letter is supplied, it must be the system drive. The drive letter
|
||||||
|
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
|
||||||
|
// need the path in this syntax so that it can ultimately be concatenated with
|
||||||
|
// a Windows long-path which doesn't support drive-letters. Examples:
|
||||||
|
// C: --> Fail
|
||||||
|
// C:\ --> \
|
||||||
|
// a --> a
|
||||||
|
// /a --> \a
|
||||||
|
// d:\ --> Fail
|
||||||
|
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
|
||||||
|
if len(path) == 2 && string(path[1]) == ":" {
|
||||||
|
return "", fmt.Errorf("No relative path specified in %q", path)
|
||||||
|
}
|
||||||
|
if !filepath.IsAbs(path) || len(path) < 2 {
|
||||||
|
return filepath.FromSlash(path), nil
|
||||||
|
}
|
||||||
|
if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
|
||||||
|
return "", fmt.Errorf("The specified path is not on the system drive (C:)")
|
||||||
|
}
|
||||||
|
return filepath.FromSlash(path[2:]), nil
|
||||||
|
}
|
24
vendor/github.com/docker/docker/pkg/system/process_unix.go
generated
vendored
Normal file
24
vendor/github.com/docker/docker/pkg/system/process_unix.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// +build linux freebsd solaris darwin
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IsProcessAlive returns true if process with a given pid is running.
|
||||||
|
func IsProcessAlive(pid int) bool {
|
||||||
|
err := unix.Kill(pid, syscall.Signal(0))
|
||||||
|
if err == nil || err == unix.EPERM {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// KillProcess force-stops a process.
|
||||||
|
func KillProcess(pid int) {
|
||||||
|
unix.Kill(pid, unix.SIGKILL)
|
||||||
|
}
|
80
vendor/github.com/docker/docker/pkg/system/rm.go
generated
vendored
Normal file
80
vendor/github.com/docker/docker/pkg/system/rm.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/docker/docker/pkg/mount"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EnsureRemoveAll wraps `os.RemoveAll` to check for specific errors that can
|
||||||
|
// often be remedied.
|
||||||
|
// Only use `EnsureRemoveAll` if you really want to make every effort to remove
|
||||||
|
// a directory.
|
||||||
|
//
|
||||||
|
// Because of the way `os.Remove` (and by extension `os.RemoveAll`) works, there
|
||||||
|
// can be a race between reading directory entries and then actually attempting
|
||||||
|
// to remove everything in the directory.
|
||||||
|
// These types of errors do not need to be returned since it's ok for the dir to
|
||||||
|
// be gone we can just retry the remove operation.
|
||||||
|
//
|
||||||
|
// This should not return a `os.ErrNotExist` kind of error under any circumstances
|
||||||
|
func EnsureRemoveAll(dir string) error {
|
||||||
|
notExistErr := make(map[string]bool)
|
||||||
|
|
||||||
|
// track retries
|
||||||
|
exitOnErr := make(map[string]int)
|
||||||
|
maxRetry := 5
|
||||||
|
|
||||||
|
// Attempt to unmount anything beneath this dir first
|
||||||
|
mount.RecursiveUnmount(dir)
|
||||||
|
|
||||||
|
for {
|
||||||
|
err := os.RemoveAll(dir)
|
||||||
|
if err == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pe, ok := err.(*os.PathError)
|
||||||
|
if !ok {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
if notExistErr[pe.Path] {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
notExistErr[pe.Path] = true
|
||||||
|
|
||||||
|
// There is a race where some subdir can be removed but after the parent
|
||||||
|
// dir entries have been read.
|
||||||
|
// So the path could be from `os.Remove(subdir)`
|
||||||
|
// If the reported non-existent path is not the passed in `dir` we
|
||||||
|
// should just retry, but otherwise return with no error.
|
||||||
|
if pe.Path == dir {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if pe.Err != syscall.EBUSY {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if mounted, _ := mount.Mounted(pe.Path); mounted {
|
||||||
|
if e := mount.Unmount(pe.Path); e != nil {
|
||||||
|
if mounted, _ := mount.Mounted(pe.Path); mounted {
|
||||||
|
return errors.Wrapf(e, "error while removing %s", dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if exitOnErr[pe.Path] == maxRetry {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
exitOnErr[pe.Path]++
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/stat_darwin.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/stat_darwin.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return &StatT{size: s.Size,
|
||||||
|
mode: uint32(s.Mode),
|
||||||
|
uid: s.Uid,
|
||||||
|
gid: s.Gid,
|
||||||
|
rdev: uint64(s.Rdev),
|
||||||
|
mtim: s.Mtimespec}, nil
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/stat_freebsd.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/stat_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return &StatT{size: s.Size,
|
||||||
|
mode: uint32(s.Mode),
|
||||||
|
uid: s.Uid,
|
||||||
|
gid: s.Gid,
|
||||||
|
rdev: uint64(s.Rdev),
|
||||||
|
mtim: s.Mtimespec}, nil
|
||||||
|
}
|
19
vendor/github.com/docker/docker/pkg/system/stat_linux.go
generated
vendored
Normal file
19
vendor/github.com/docker/docker/pkg/system/stat_linux.go
generated
vendored
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return &StatT{size: s.Size,
|
||||||
|
mode: uint32(s.Mode),
|
||||||
|
uid: s.Uid,
|
||||||
|
gid: s.Gid,
|
||||||
|
rdev: uint64(s.Rdev),
|
||||||
|
mtim: s.Mtim}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
// This is exposed on Linux as pkg/archive/changes uses it.
|
||||||
|
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return fromStatT(s)
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/stat_openbsd.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/stat_openbsd.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return &StatT{size: s.Size,
|
||||||
|
mode: uint32(s.Mode),
|
||||||
|
uid: s.Uid,
|
||||||
|
gid: s.Gid,
|
||||||
|
rdev: uint64(s.Rdev),
|
||||||
|
mtim: s.Mtim}, nil
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/stat_solaris.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/stat_solaris.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// fromStatT converts a syscall.Stat_t type to a system.Stat_t type
|
||||||
|
func fromStatT(s *syscall.Stat_t) (*StatT, error) {
|
||||||
|
return &StatT{size: s.Size,
|
||||||
|
mode: uint32(s.Mode),
|
||||||
|
uid: s.Uid,
|
||||||
|
gid: s.Gid,
|
||||||
|
rdev: uint64(s.Rdev),
|
||||||
|
mtim: s.Mtim}, nil
|
||||||
|
}
|
60
vendor/github.com/docker/docker/pkg/system/stat_unix.go
generated
vendored
Normal file
60
vendor/github.com/docker/docker/pkg/system/stat_unix.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StatT type contains status of a file. It contains metadata
|
||||||
|
// like permission, owner, group, size, etc about a file.
|
||||||
|
type StatT struct {
|
||||||
|
mode uint32
|
||||||
|
uid uint32
|
||||||
|
gid uint32
|
||||||
|
rdev uint64
|
||||||
|
size int64
|
||||||
|
mtim syscall.Timespec
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode returns file's permission mode.
|
||||||
|
func (s StatT) Mode() uint32 {
|
||||||
|
return s.mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// UID returns file's user id of owner.
|
||||||
|
func (s StatT) UID() uint32 {
|
||||||
|
return s.uid
|
||||||
|
}
|
||||||
|
|
||||||
|
// GID returns file's group id of owner.
|
||||||
|
func (s StatT) GID() uint32 {
|
||||||
|
return s.gid
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rdev returns file's device ID (if it's special file).
|
||||||
|
func (s StatT) Rdev() uint64 {
|
||||||
|
return s.rdev
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns file's size.
|
||||||
|
func (s StatT) Size() int64 {
|
||||||
|
return s.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mtim returns file's last modification time.
|
||||||
|
func (s StatT) Mtim() syscall.Timespec {
|
||||||
|
return s.mtim
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat takes a path to a file and returns
|
||||||
|
// a system.StatT type pertaining to that file.
|
||||||
|
//
|
||||||
|
// Throws an error if the file does not exist
|
||||||
|
func Stat(path string) (*StatT, error) {
|
||||||
|
s := &syscall.Stat_t{}
|
||||||
|
if err := syscall.Stat(path, s); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fromStatT(s)
|
||||||
|
}
|
49
vendor/github.com/docker/docker/pkg/system/stat_windows.go
generated
vendored
Normal file
49
vendor/github.com/docker/docker/pkg/system/stat_windows.go
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// StatT type contains status of a file. It contains metadata
|
||||||
|
// like permission, size, etc about a file.
|
||||||
|
type StatT struct {
|
||||||
|
mode os.FileMode
|
||||||
|
size int64
|
||||||
|
mtim time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size returns file's size.
|
||||||
|
func (s StatT) Size() int64 {
|
||||||
|
return s.size
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mode returns file's permission mode.
|
||||||
|
func (s StatT) Mode() os.FileMode {
|
||||||
|
return os.FileMode(s.mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mtim returns file's last modification time.
|
||||||
|
func (s StatT) Mtim() time.Time {
|
||||||
|
return time.Time(s.mtim)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat takes a path to a file and returns
|
||||||
|
// a system.StatT type pertaining to that file.
|
||||||
|
//
|
||||||
|
// Throws an error if the file does not exist
|
||||||
|
func Stat(path string) (*StatT, error) {
|
||||||
|
fi, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return fromStatT(&fi)
|
||||||
|
}
|
||||||
|
|
||||||
|
// fromStatT converts a os.FileInfo type to a system.StatT type
|
||||||
|
func fromStatT(fi *os.FileInfo) (*StatT, error) {
|
||||||
|
return &StatT{
|
||||||
|
size: (*fi).Size(),
|
||||||
|
mode: (*fi).Mode(),
|
||||||
|
mtim: (*fi).ModTime()}, nil
|
||||||
|
}
|
17
vendor/github.com/docker/docker/pkg/system/syscall_unix.go
generated
vendored
Normal file
17
vendor/github.com/docker/docker/pkg/system/syscall_unix.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// +build linux freebsd
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
// Unmount is a platform-specific helper function to call
|
||||||
|
// the unmount syscall.
|
||||||
|
func Unmount(dest string) error {
|
||||||
|
return unix.Unmount(dest, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandLineToArgv should not be used on Unix.
|
||||||
|
// It simply returns commandLine in the only element in the returned array.
|
||||||
|
func CommandLineToArgv(commandLine string) ([]string, error) {
|
||||||
|
return []string{commandLine}, nil
|
||||||
|
}
|
122
vendor/github.com/docker/docker/pkg/system/syscall_windows.go
generated
vendored
Normal file
122
vendor/github.com/docker/docker/pkg/system/syscall_windows.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ntuserApiset = windows.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
|
||||||
|
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
|
||||||
|
procGetProductInfo = modkernel32.NewProc("GetProductInfo")
|
||||||
|
)
|
||||||
|
|
||||||
|
// OSVersion is a wrapper for Windows version information
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx
|
||||||
|
type OSVersion struct {
|
||||||
|
Version uint32
|
||||||
|
MajorVersion uint8
|
||||||
|
MinorVersion uint8
|
||||||
|
Build uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
|
||||||
|
type osVersionInfoEx struct {
|
||||||
|
OSVersionInfoSize uint32
|
||||||
|
MajorVersion uint32
|
||||||
|
MinorVersion uint32
|
||||||
|
BuildNumber uint32
|
||||||
|
PlatformID uint32
|
||||||
|
CSDVersion [128]uint16
|
||||||
|
ServicePackMajor uint16
|
||||||
|
ServicePackMinor uint16
|
||||||
|
SuiteMask uint16
|
||||||
|
ProductType byte
|
||||||
|
Reserve byte
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetOSVersion gets the operating system version on Windows. Note that
|
||||||
|
// docker.exe must be manifested to get the correct version information.
|
||||||
|
func GetOSVersion() OSVersion {
|
||||||
|
var err error
|
||||||
|
osv := OSVersion{}
|
||||||
|
osv.Version, err = windows.GetVersion()
|
||||||
|
if err != nil {
|
||||||
|
// GetVersion never fails.
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
osv.MajorVersion = uint8(osv.Version & 0xFF)
|
||||||
|
osv.MinorVersion = uint8(osv.Version >> 8 & 0xFF)
|
||||||
|
osv.Build = uint16(osv.Version >> 16)
|
||||||
|
return osv
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsWindowsClient returns true if the SKU is client
|
||||||
|
// @engine maintainers - this function should not be removed or modified as it
|
||||||
|
// is used to enforce licensing restrictions on Windows.
|
||||||
|
func IsWindowsClient() bool {
|
||||||
|
osviex := &osVersionInfoEx{OSVersionInfoSize: 284}
|
||||||
|
r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex)))
|
||||||
|
if r1 == 0 {
|
||||||
|
logrus.Warnf("GetVersionExW failed - assuming server SKU: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const verNTWorkstation = 0x00000001
|
||||||
|
return osviex.ProductType == verNTWorkstation
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsIoTCore returns true if the currently running image is based off of
|
||||||
|
// Windows 10 IoT Core.
|
||||||
|
// @engine maintainers - this function should not be removed or modified as it
|
||||||
|
// is used to enforce licensing restrictions on Windows.
|
||||||
|
func IsIoTCore() bool {
|
||||||
|
var returnedProductType uint32
|
||||||
|
r1, _, err := procGetProductInfo.Call(6, 1, 0, 0, uintptr(unsafe.Pointer(&returnedProductType)))
|
||||||
|
if r1 == 0 {
|
||||||
|
logrus.Warnf("GetProductInfo failed - assuming this is not IoT: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
const productIoTUAP = 0x0000007B
|
||||||
|
const productIoTUAPCommercial = 0x00000083
|
||||||
|
return returnedProductType == productIoTUAP || returnedProductType == productIoTUAPCommercial
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unmount is a platform-specific helper function to call
|
||||||
|
// the unmount syscall. Not supported on Windows
|
||||||
|
func Unmount(dest string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CommandLineToArgv wraps the Windows syscall to turn a commandline into an argument array.
|
||||||
|
func CommandLineToArgv(commandLine string) ([]string, error) {
|
||||||
|
var argc int32
|
||||||
|
|
||||||
|
argsPtr, err := windows.UTF16PtrFromString(commandLine)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
argv, err := windows.CommandLineToArgv(argsPtr, &argc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer windows.LocalFree(windows.Handle(uintptr(unsafe.Pointer(argv))))
|
||||||
|
|
||||||
|
newArgs := make([]string, argc)
|
||||||
|
for i, v := range (*argv)[:argc] {
|
||||||
|
newArgs[i] = string(windows.UTF16ToString((*v)[:]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArgs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasWin32KSupport determines whether containers that depend on win32k can
|
||||||
|
// run on this machine. Win32k is the driver used to implement windowing.
|
||||||
|
func HasWin32KSupport() bool {
|
||||||
|
// For now, check for ntuser API support on the host. In the future, a host
|
||||||
|
// may support win32k in containers even if the host does not support ntuser
|
||||||
|
// APIs.
|
||||||
|
return ntuserApiset.Load() == nil
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/umask.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/umask.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Umask sets current process's file mode creation mask to newmask
|
||||||
|
// and returns oldmask.
|
||||||
|
func Umask(newmask int) (oldmask int, err error) {
|
||||||
|
return unix.Umask(newmask), nil
|
||||||
|
}
|
9
vendor/github.com/docker/docker/pkg/system/umask_windows.go
generated
vendored
Normal file
9
vendor/github.com/docker/docker/pkg/system/umask_windows.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// Umask is not supported on the windows platform.
|
||||||
|
func Umask(newmask int) (oldmask int, err error) {
|
||||||
|
// should not be called on cli code path
|
||||||
|
return 0, ErrNotSupportedPlatform
|
||||||
|
}
|
24
vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go
generated
vendored
Normal file
24
vendor/github.com/docker/docker/pkg/system/utimes_freebsd.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LUtimesNano is used to change access and modification time of the specified path.
|
||||||
|
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||||
|
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||||
|
var _path *byte
|
||||||
|
_path, err := unix.BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, _, err := unix.Syscall(unix.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != unix.ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
25
vendor/github.com/docker/docker/pkg/system/utimes_linux.go
generated
vendored
Normal file
25
vendor/github.com/docker/docker/pkg/system/utimes_linux.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// LUtimesNano is used to change access and modification time of the specified path.
|
||||||
|
// It's used for symbol link file because unix.UtimesNano doesn't support a NOFOLLOW flag atm.
|
||||||
|
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||||
|
atFdCwd := unix.AT_FDCWD
|
||||||
|
|
||||||
|
var _path *byte
|
||||||
|
_path, err := unix.BytePtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, _, err := unix.Syscall6(unix.SYS_UTIMENSAT, uintptr(atFdCwd), uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), unix.AT_SYMLINK_NOFOLLOW, 0, 0); err != 0 && err != unix.ENOSYS {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
10
vendor/github.com/docker/docker/pkg/system/utimes_unsupported.go
generated
vendored
Normal file
10
vendor/github.com/docker/docker/pkg/system/utimes_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// +build !linux,!freebsd
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
// LUtimesNano is only supported on linux and freebsd.
|
||||||
|
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||||
|
return ErrNotSupportedPlatform
|
||||||
|
}
|
29
vendor/github.com/docker/docker/pkg/system/xattrs_linux.go
generated
vendored
Normal file
29
vendor/github.com/docker/docker/pkg/system/xattrs_linux.go
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package system
|
||||||
|
|
||||||
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
|
// Lgetxattr retrieves the value of the extended attribute identified by attr
|
||||||
|
// and associated with the given path in the file system.
|
||||||
|
// It will returns a nil slice and nil error if the xattr is not set.
|
||||||
|
func Lgetxattr(path string, attr string) ([]byte, error) {
|
||||||
|
dest := make([]byte, 128)
|
||||||
|
sz, errno := unix.Lgetxattr(path, attr, dest)
|
||||||
|
if errno == unix.ENODATA {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
if errno == unix.ERANGE {
|
||||||
|
dest = make([]byte, sz)
|
||||||
|
sz, errno = unix.Lgetxattr(path, attr, dest)
|
||||||
|
}
|
||||||
|
if errno != nil {
|
||||||
|
return nil, errno
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest[:sz], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lsetxattr sets the value of the extended attribute identified by attr
|
||||||
|
// and associated with the given path in the file system.
|
||||||
|
func Lsetxattr(path string, attr string, data []byte, flags int) error {
|
||||||
|
return unix.Lsetxattr(path, attr, data, flags)
|
||||||
|
}
|
13
vendor/github.com/docker/docker/pkg/system/xattrs_unsupported.go
generated
vendored
Normal file
13
vendor/github.com/docker/docker/pkg/system/xattrs_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build !linux
|
||||||
|
|
||||||
|
package system
|
||||||
|
|
||||||
|
// Lgetxattr is not supported on platforms other than linux.
|
||||||
|
func Lgetxattr(path string, attr string) ([]byte, error) {
|
||||||
|
return nil, ErrNotSupportedPlatform
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lsetxattr is not supported on platforms other than linux.
|
||||||
|
func Lsetxattr(path string, attr string, data []byte, flags int) error {
|
||||||
|
return ErrNotSupportedPlatform
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user