Update containerd to 2f69be5594
.
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
53c71e2b10
commit
efba8e147f
26
vendor.conf
26
vendor.conf
@ -1,13 +1,13 @@
|
|||||||
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
github.com/beorn7/perks 4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
||||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
||||||
github.com/containerd/containerd 32e788a8be3ab4418265693d9e742c30495fdd4c
|
github.com/containerd/containerd 2f69be5594cecacdbe42076ed12c7039a0638a2c
|
||||||
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||||
github.com/containerd/go-cni 22460c018b64cf8bf4151b3ff9c4d077e6a88cbf
|
github.com/containerd/go-cni 22460c018b64cf8bf4151b3ff9c4d077e6a88cbf
|
||||||
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
||||||
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
github.com/containerd/ttrpc a5bd8ce9e40bc7c065a11c6936f4d032ce6bfa2b
|
||||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||||
github.com/containernetworking/cni v0.6.0
|
github.com/containernetworking/cni v0.6.0
|
||||||
github.com/containernetworking/plugins v0.7.5
|
github.com/containernetworking/plugins v0.7.5
|
||||||
@ -17,7 +17,7 @@ github.com/docker/distribution 0d3efadf0154c2b8a4e7b6621fff9809655cc580
|
|||||||
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
github.com/docker/docker 86f080cff0914e9694068ed78d503701667c4c00
|
||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||||
github.com/docker/go-units v0.3.1
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||||
github.com/emicklei/go-restful v2.2.1
|
github.com/emicklei/go-restful v2.2.1
|
||||||
github.com/godbus/dbus v3
|
github.com/godbus/dbus v3
|
||||||
@ -28,15 +28,15 @@ github.com/google/gofuzz 44d81051d367757e1c7c6a5a86423ece9afcf63c
|
|||||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
|
github.com/grpc-ecosystem/go-grpc-prometheus v1.1
|
||||||
github.com/json-iterator/go 1.1.5
|
github.com/json-iterator/go 1.1.5
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1
|
github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||||
github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13
|
github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5205c12027fac
|
||||||
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
||||||
github.com/modern-go/concurrent 1.0.3
|
github.com/modern-go/concurrent 1.0.3
|
||||||
github.com/modern-go/reflect2 1.0.1
|
github.com/modern-go/reflect2 1.0.1
|
||||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||||
github.com/opencontainers/image-spec v1.0.1
|
github.com/opencontainers/image-spec v1.0.1
|
||||||
github.com/opencontainers/runc 029124da7af7360afa781a0234d1b083550f797c
|
github.com/opencontainers/runc v1.0.0-rc8
|
||||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
|
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4
|
||||||
github.com/opencontainers/selinux v1.2.1
|
github.com/opencontainers/selinux v1.2.2
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
||||||
@ -46,19 +46,19 @@ github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
|||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/stretchr/testify v1.1.4
|
github.com/stretchr/testify v1.1.4
|
||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
go.etcd.io/bbolt v1.3.2
|
go.etcd.io/bbolt 2eb7227adea1d5cf85f0bc2a82b7059b13c2fa68
|
||||||
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
|
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||||
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
||||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||||
golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys
|
golang.org/x/sys 4c4f7f33c9ed00de01c4c741d2177abfcfe19307 https://github.com/golang/sys
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
google.golang.org/grpc v1.12.0
|
google.golang.org/grpc 25c4f928eaa6d96443009bd842389fb4fa48664e
|
||||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||||
gopkg.in/yaml.v2 v2.2.1
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
k8s.io/api kubernetes-1.15.0-alpha.0
|
k8s.io/api kubernetes-1.15.0-alpha.0
|
||||||
|
217
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
217
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
@ -3,10 +3,13 @@
|
|||||||
package winio
|
package winio
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"runtime"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
@ -18,6 +21,48 @@ import (
|
|||||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||||
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
||||||
|
//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) = ntdll.NtCreateNamedPipeFile
|
||||||
|
//sys rtlNtStatusToDosError(status ntstatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
|
||||||
|
//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) = ntdll.RtlDosPathNameToNtPathName_U
|
||||||
|
//sys rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) = ntdll.RtlDefaultNpAcl
|
||||||
|
|
||||||
|
type ioStatusBlock struct {
|
||||||
|
Status, Information uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type objectAttributes struct {
|
||||||
|
Length uintptr
|
||||||
|
RootDirectory uintptr
|
||||||
|
ObjectName *unicodeString
|
||||||
|
Attributes uintptr
|
||||||
|
SecurityDescriptor *securityDescriptor
|
||||||
|
SecurityQoS uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type unicodeString struct {
|
||||||
|
Length uint16
|
||||||
|
MaximumLength uint16
|
||||||
|
Buffer uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type securityDescriptor struct {
|
||||||
|
Revision byte
|
||||||
|
Sbz1 byte
|
||||||
|
Control uint16
|
||||||
|
Owner uintptr
|
||||||
|
Group uintptr
|
||||||
|
Sacl uintptr
|
||||||
|
Dacl uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type ntstatus int32
|
||||||
|
|
||||||
|
func (status ntstatus) Err() error {
|
||||||
|
if status >= 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return rtlNtStatusToDosError(status)
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
cERROR_PIPE_BUSY = syscall.Errno(231)
|
cERROR_PIPE_BUSY = syscall.Errno(231)
|
||||||
@ -25,21 +70,20 @@ const (
|
|||||||
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
cERROR_PIPE_CONNECTED = syscall.Errno(535)
|
||||||
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
cERROR_SEM_TIMEOUT = syscall.Errno(121)
|
||||||
|
|
||||||
cPIPE_ACCESS_DUPLEX = 0x3
|
|
||||||
cFILE_FLAG_FIRST_PIPE_INSTANCE = 0x80000
|
|
||||||
cSECURITY_SQOS_PRESENT = 0x100000
|
cSECURITY_SQOS_PRESENT = 0x100000
|
||||||
cSECURITY_ANONYMOUS = 0
|
cSECURITY_ANONYMOUS = 0
|
||||||
|
|
||||||
cPIPE_REJECT_REMOTE_CLIENTS = 0x8
|
|
||||||
|
|
||||||
cPIPE_UNLIMITED_INSTANCES = 255
|
|
||||||
|
|
||||||
cNMPWAIT_USE_DEFAULT_WAIT = 0
|
|
||||||
cNMPWAIT_NOWAIT = 1
|
|
||||||
|
|
||||||
cPIPE_TYPE_MESSAGE = 4
|
cPIPE_TYPE_MESSAGE = 4
|
||||||
|
|
||||||
cPIPE_READMODE_MESSAGE = 2
|
cPIPE_READMODE_MESSAGE = 2
|
||||||
|
|
||||||
|
cFILE_OPEN = 1
|
||||||
|
cFILE_CREATE = 2
|
||||||
|
|
||||||
|
cFILE_PIPE_MESSAGE_TYPE = 1
|
||||||
|
cFILE_PIPE_REJECT_REMOTE_CLIENTS = 2
|
||||||
|
|
||||||
|
cSE_DACL_PRESENT = 4
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -137,9 +181,30 @@ func (s pipeAddress) String() string {
|
|||||||
return string(s)
|
return string(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
|
||||||
|
func tryDialPipe(ctx context.Context, path *string) (syscall.Handle, error) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return syscall.Handle(0), ctx.Err()
|
||||||
|
default:
|
||||||
|
h, err := createFile(*path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
||||||
|
if err == nil {
|
||||||
|
return h, nil
|
||||||
|
}
|
||||||
|
if err != cERROR_PIPE_BUSY {
|
||||||
|
return h, &os.PathError{Err: err, Op: "open", Path: *path}
|
||||||
|
}
|
||||||
|
// Wait 10 msec and try again. This is a rather simplistic
|
||||||
|
// view, as we always try each 10 milliseconds.
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// DialPipe connects to a named pipe by path, timing out if the connection
|
// DialPipe connects to a named pipe by path, timing out if the connection
|
||||||
// takes longer than the specified duration. If timeout is nil, then we use
|
// takes longer than the specified duration. If timeout is nil, then we use
|
||||||
// a default timeout of 5 seconds. (We do not use WaitNamedPipe.)
|
// a default timeout of 2 seconds. (We do not use WaitNamedPipe.)
|
||||||
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||||
var absTimeout time.Time
|
var absTimeout time.Time
|
||||||
if timeout != nil {
|
if timeout != nil {
|
||||||
@ -147,23 +212,22 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
|||||||
} else {
|
} else {
|
||||||
absTimeout = time.Now().Add(time.Second * 2)
|
absTimeout = time.Now().Add(time.Second * 2)
|
||||||
}
|
}
|
||||||
var err error
|
ctx, _ := context.WithDeadline(context.Background(), absTimeout)
|
||||||
var h syscall.Handle
|
conn, err := DialPipeContext(ctx, path)
|
||||||
for {
|
if err == context.DeadlineExceeded {
|
||||||
h, err = createFile(path, syscall.GENERIC_READ|syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OVERLAPPED|cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != cERROR_PIPE_BUSY {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if time.Now().After(absTimeout) {
|
|
||||||
return nil, ErrTimeout
|
return nil, ErrTimeout
|
||||||
}
|
}
|
||||||
|
return conn, err
|
||||||
|
}
|
||||||
|
|
||||||
// Wait 10 msec and try again. This is a rather simplistic
|
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
|
||||||
// view, as we always try each 10 milliseconds.
|
// cancellation or timeout.
|
||||||
time.Sleep(time.Millisecond * 10)
|
func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
|
||||||
}
|
var err error
|
||||||
|
var h syscall.Handle
|
||||||
|
h, err = tryDialPipe(ctx, &path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, &os.PathError{Op: "open", Path: path, Err: err}
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var flags uint32
|
var flags uint32
|
||||||
@ -196,41 +260,85 @@ type acceptResponse struct {
|
|||||||
type win32PipeListener struct {
|
type win32PipeListener struct {
|
||||||
firstHandle syscall.Handle
|
firstHandle syscall.Handle
|
||||||
path string
|
path string
|
||||||
securityDescriptor []byte
|
|
||||||
config PipeConfig
|
config PipeConfig
|
||||||
acceptCh chan (chan acceptResponse)
|
acceptCh chan (chan acceptResponse)
|
||||||
closeCh chan int
|
closeCh chan int
|
||||||
doneCh chan int
|
doneCh chan int
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeServerPipeHandle(path string, securityDescriptor []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
||||||
var flags uint32 = cPIPE_ACCESS_DUPLEX | syscall.FILE_FLAG_OVERLAPPED
|
path16, err := syscall.UTF16FromString(path)
|
||||||
if first {
|
|
||||||
flags |= cFILE_FLAG_FIRST_PIPE_INSTANCE
|
|
||||||
}
|
|
||||||
|
|
||||||
var mode uint32 = cPIPE_REJECT_REMOTE_CLIENTS
|
|
||||||
if c.MessageMode {
|
|
||||||
mode |= cPIPE_TYPE_MESSAGE
|
|
||||||
}
|
|
||||||
|
|
||||||
sa := &syscall.SecurityAttributes{}
|
|
||||||
sa.Length = uint32(unsafe.Sizeof(*sa))
|
|
||||||
if securityDescriptor != nil {
|
|
||||||
len := uint32(len(securityDescriptor))
|
|
||||||
sa.SecurityDescriptor = localAlloc(0, len)
|
|
||||||
defer localFree(sa.SecurityDescriptor)
|
|
||||||
copy((*[0xffff]byte)(unsafe.Pointer(sa.SecurityDescriptor))[:], securityDescriptor)
|
|
||||||
}
|
|
||||||
h, err := createNamedPipe(path, flags, mode, cPIPE_UNLIMITED_INSTANCES, uint32(c.OutputBufferSize), uint32(c.InputBufferSize), 0, sa)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var oa objectAttributes
|
||||||
|
oa.Length = unsafe.Sizeof(oa)
|
||||||
|
|
||||||
|
var ntPath unicodeString
|
||||||
|
if err := rtlDosPathNameToNtPathName(&path16[0], &ntPath, 0, 0).Err(); err != nil {
|
||||||
|
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||||
|
}
|
||||||
|
defer localFree(ntPath.Buffer)
|
||||||
|
oa.ObjectName = &ntPath
|
||||||
|
|
||||||
|
// The security descriptor is only needed for the first pipe.
|
||||||
|
if first {
|
||||||
|
if sd != nil {
|
||||||
|
len := uint32(len(sd))
|
||||||
|
sdb := localAlloc(0, len)
|
||||||
|
defer localFree(sdb)
|
||||||
|
copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
|
||||||
|
oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
|
||||||
|
} else {
|
||||||
|
// Construct the default named pipe security descriptor.
|
||||||
|
var dacl uintptr
|
||||||
|
if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
|
||||||
|
return 0, fmt.Errorf("getting default named pipe ACL: %s", err)
|
||||||
|
}
|
||||||
|
defer localFree(dacl)
|
||||||
|
|
||||||
|
sdb := &securityDescriptor{
|
||||||
|
Revision: 1,
|
||||||
|
Control: cSE_DACL_PRESENT,
|
||||||
|
Dacl: dacl,
|
||||||
|
}
|
||||||
|
oa.SecurityDescriptor = sdb
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typ := uint32(cFILE_PIPE_REJECT_REMOTE_CLIENTS)
|
||||||
|
if c.MessageMode {
|
||||||
|
typ |= cFILE_PIPE_MESSAGE_TYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
disposition := uint32(cFILE_OPEN)
|
||||||
|
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
|
||||||
|
if first {
|
||||||
|
disposition = cFILE_CREATE
|
||||||
|
// By not asking for read or write access, the named pipe file system
|
||||||
|
// will put this pipe into an initially disconnected state, blocking
|
||||||
|
// client connections until the next call with first == false.
|
||||||
|
access = syscall.SYNCHRONIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
timeout := int64(-50 * 10000) // 50ms
|
||||||
|
|
||||||
|
var (
|
||||||
|
h syscall.Handle
|
||||||
|
iosb ioStatusBlock
|
||||||
|
)
|
||||||
|
err = ntCreateNamedPipeFile(&h, access, &oa, &iosb, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, disposition, 0, typ, 0, 0, 0xffffffff, uint32(c.InputBufferSize), uint32(c.OutputBufferSize), &timeout).Err()
|
||||||
|
if err != nil {
|
||||||
|
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.KeepAlive(ntPath)
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
||||||
h, err := makeServerPipeHandle(l.path, l.securityDescriptor, &l.config, false)
|
h, err := makeServerPipeHandle(l.path, nil, &l.config, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -341,28 +449,9 @@ func ListenPipe(path string, c *PipeConfig) (net.Listener, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Create a client handle and connect it. This results in the pipe
|
|
||||||
// instance always existing, so that clients see ERROR_PIPE_BUSY
|
|
||||||
// rather than ERROR_FILE_NOT_FOUND. This ties the first instance
|
|
||||||
// up so that no other instances can be used. This would have been
|
|
||||||
// cleaner if the Win32 API matched CreateFile with ConnectNamedPipe
|
|
||||||
// instead of CreateNamedPipe. (Apparently created named pipes are
|
|
||||||
// considered to be in listening state regardless of whether any
|
|
||||||
// active calls to ConnectNamedPipe are outstanding.)
|
|
||||||
h2, err := createFile(path, 0, 0, nil, syscall.OPEN_EXISTING, cSECURITY_SQOS_PRESENT|cSECURITY_ANONYMOUS, 0)
|
|
||||||
if err != nil {
|
|
||||||
syscall.Close(h)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// Close the client handle. The server side of the instance will
|
|
||||||
// still be busy, leading to ERROR_PIPE_BUSY instead of
|
|
||||||
// ERROR_NOT_FOUND, as long as we don't close the server handle,
|
|
||||||
// or disconnect the client with DisconnectNamedPipe.
|
|
||||||
syscall.Close(h2)
|
|
||||||
l := &win32PipeListener{
|
l := &win32PipeListener{
|
||||||
firstHandle: h,
|
firstHandle: h,
|
||||||
path: path,
|
path: path,
|
||||||
securityDescriptor: sd,
|
|
||||||
config: *c,
|
config: *c,
|
||||||
acceptCh: make(chan (chan acceptResponse)),
|
acceptCh: make(chan (chan acceptResponse)),
|
||||||
closeCh: make(chan int),
|
closeCh: make(chan int),
|
||||||
|
21
vendor/github.com/Microsoft/go-winio/pkg/etw/eventdescriptor.go
generated
vendored
21
vendor/github.com/Microsoft/go-winio/pkg/etw/eventdescriptor.go
generated
vendored
@ -17,7 +17,7 @@ const (
|
|||||||
// will always be collected.
|
// will always be collected.
|
||||||
type Level uint8
|
type Level uint8
|
||||||
|
|
||||||
// Predefined ETW log levels.
|
// Predefined ETW log levels from winmeta.xml in the Windows SDK.
|
||||||
const (
|
const (
|
||||||
LevelAlways Level = iota
|
LevelAlways Level = iota
|
||||||
LevelCritical
|
LevelCritical
|
||||||
@ -27,13 +27,30 @@ const (
|
|||||||
LevelVerbose
|
LevelVerbose
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Opcode represents the operation that the event indicates is being performed.
|
||||||
|
type Opcode uint8
|
||||||
|
|
||||||
|
// Predefined ETW opcodes from winmeta.xml in the Windows SDK.
|
||||||
|
const (
|
||||||
|
// OpcodeInfo indicates an informational event.
|
||||||
|
OpcodeInfo Opcode = iota
|
||||||
|
// OpcodeStart indicates the start of an operation.
|
||||||
|
OpcodeStart
|
||||||
|
// OpcodeStop indicates the end of an operation.
|
||||||
|
OpcodeStop
|
||||||
|
// OpcodeDCStart indicates the start of a provider capture state operation.
|
||||||
|
OpcodeDCStart
|
||||||
|
// OpcodeDCStop indicates the end of a provider capture state operation.
|
||||||
|
OpcodeDCStop
|
||||||
|
)
|
||||||
|
|
||||||
// EventDescriptor represents various metadata for an ETW event.
|
// EventDescriptor represents various metadata for an ETW event.
|
||||||
type eventDescriptor struct {
|
type eventDescriptor struct {
|
||||||
id uint16
|
id uint16
|
||||||
version uint8
|
version uint8
|
||||||
channel Channel
|
channel Channel
|
||||||
level Level
|
level Level
|
||||||
opcode uint8
|
opcode Opcode
|
||||||
task uint16
|
task uint16
|
||||||
keyword uint64
|
keyword uint64
|
||||||
}
|
}
|
||||||
|
20
vendor/github.com/Microsoft/go-winio/pkg/etw/eventopt.go
generated
vendored
20
vendor/github.com/Microsoft/go-winio/pkg/etw/eventopt.go
generated
vendored
@ -1,13 +1,13 @@
|
|||||||
package etw
|
package etw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/sys/windows"
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type eventOptions struct {
|
type eventOptions struct {
|
||||||
descriptor *eventDescriptor
|
descriptor *eventDescriptor
|
||||||
activityID *windows.GUID
|
activityID *guid.GUID
|
||||||
relatedActivityID *windows.GUID
|
relatedActivityID *guid.GUID
|
||||||
tags uint32
|
tags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,12 +36,20 @@ func WithKeyword(keyword uint64) EventOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithChannel specifies the channel of the event to be written.
|
||||||
func WithChannel(channel Channel) EventOpt {
|
func WithChannel(channel Channel) EventOpt {
|
||||||
return func(options *eventOptions) {
|
return func(options *eventOptions) {
|
||||||
options.descriptor.channel = channel
|
options.descriptor.channel = channel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithOpcode specifies the opcode of the event to be written.
|
||||||
|
func WithOpcode(opcode Opcode) EventOpt {
|
||||||
|
return func(options *eventOptions) {
|
||||||
|
options.descriptor.opcode = opcode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithTags specifies the tags of the event to be written. Tags is a 28-bit
|
// WithTags specifies the tags of the event to be written. Tags is a 28-bit
|
||||||
// value (top 4 bits are ignored) which are interpreted by the event consumer.
|
// value (top 4 bits are ignored) which are interpreted by the event consumer.
|
||||||
func WithTags(newTags uint32) EventOpt {
|
func WithTags(newTags uint32) EventOpt {
|
||||||
@ -50,13 +58,15 @@ func WithTags(newTags uint32) EventOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithActivityID(activityID *windows.GUID) EventOpt {
|
// WithActivityID specifies the activity ID of the event to be written.
|
||||||
|
func WithActivityID(activityID *guid.GUID) EventOpt {
|
||||||
return func(options *eventOptions) {
|
return func(options *eventOptions) {
|
||||||
options.activityID = activityID
|
options.activityID = activityID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithRelatedActivityID(activityID *windows.GUID) EventOpt {
|
// WithRelatedActivityID specifies the parent activity ID of the event to be written.
|
||||||
|
func WithRelatedActivityID(activityID *guid.GUID) EventOpt {
|
||||||
return func(options *eventOptions) {
|
return func(options *eventOptions) {
|
||||||
options.relatedActivityID = activityID
|
options.relatedActivityID = activityID
|
||||||
}
|
}
|
||||||
|
123
vendor/github.com/Microsoft/go-winio/pkg/etw/fieldopt.go
generated
vendored
123
vendor/github.com/Microsoft/go-winio/pkg/etw/fieldopt.go
generated
vendored
@ -1,7 +1,9 @@
|
|||||||
package etw
|
package etw
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"reflect"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -377,3 +379,124 @@ func Struct(name string, opts ...FieldOpt) FieldOpt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Currently, we support logging basic builtin types (int, string, etc), slices
|
||||||
|
// of basic builtin types, error, types derived from the basic types (e.g. "type
|
||||||
|
// foo int"), and structs (recursively logging their fields). We do not support
|
||||||
|
// slices of derived types (e.g. "[]foo").
|
||||||
|
//
|
||||||
|
// For types that we don't support, the value is formatted via fmt.Sprint, and
|
||||||
|
// we also log a message that the type is unsupported along with the formatted
|
||||||
|
// type. The intent of this is to make it easier to see which types are not
|
||||||
|
// supported in traces, so we can evaluate adding support for more types in the
|
||||||
|
// future.
|
||||||
|
func SmartField(name string, v interface{}) FieldOpt {
|
||||||
|
switch v := v.(type) {
|
||||||
|
case bool:
|
||||||
|
return BoolField(name, v)
|
||||||
|
case []bool:
|
||||||
|
return BoolArray(name, v)
|
||||||
|
case string:
|
||||||
|
return StringField(name, v)
|
||||||
|
case []string:
|
||||||
|
return StringArray(name, v)
|
||||||
|
case int:
|
||||||
|
return IntField(name, v)
|
||||||
|
case []int:
|
||||||
|
return IntArray(name, v)
|
||||||
|
case int8:
|
||||||
|
return Int8Field(name, v)
|
||||||
|
case []int8:
|
||||||
|
return Int8Array(name, v)
|
||||||
|
case int16:
|
||||||
|
return Int16Field(name, v)
|
||||||
|
case []int16:
|
||||||
|
return Int16Array(name, v)
|
||||||
|
case int32:
|
||||||
|
return Int32Field(name, v)
|
||||||
|
case []int32:
|
||||||
|
return Int32Array(name, v)
|
||||||
|
case int64:
|
||||||
|
return Int64Field(name, v)
|
||||||
|
case []int64:
|
||||||
|
return Int64Array(name, v)
|
||||||
|
case uint:
|
||||||
|
return UintField(name, v)
|
||||||
|
case []uint:
|
||||||
|
return UintArray(name, v)
|
||||||
|
case uint8:
|
||||||
|
return Uint8Field(name, v)
|
||||||
|
case []uint8:
|
||||||
|
return Uint8Array(name, v)
|
||||||
|
case uint16:
|
||||||
|
return Uint16Field(name, v)
|
||||||
|
case []uint16:
|
||||||
|
return Uint16Array(name, v)
|
||||||
|
case uint32:
|
||||||
|
return Uint32Field(name, v)
|
||||||
|
case []uint32:
|
||||||
|
return Uint32Array(name, v)
|
||||||
|
case uint64:
|
||||||
|
return Uint64Field(name, v)
|
||||||
|
case []uint64:
|
||||||
|
return Uint64Array(name, v)
|
||||||
|
case uintptr:
|
||||||
|
return UintptrField(name, v)
|
||||||
|
case []uintptr:
|
||||||
|
return UintptrArray(name, v)
|
||||||
|
case float32:
|
||||||
|
return Float32Field(name, v)
|
||||||
|
case []float32:
|
||||||
|
return Float32Array(name, v)
|
||||||
|
case float64:
|
||||||
|
return Float64Field(name, v)
|
||||||
|
case []float64:
|
||||||
|
return Float64Array(name, v)
|
||||||
|
case error:
|
||||||
|
return StringField(name, v.Error())
|
||||||
|
default:
|
||||||
|
switch rv := reflect.ValueOf(v); rv.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return SmartField(name, rv.Bool())
|
||||||
|
case reflect.Int:
|
||||||
|
return SmartField(name, int(rv.Int()))
|
||||||
|
case reflect.Int8:
|
||||||
|
return SmartField(name, int8(rv.Int()))
|
||||||
|
case reflect.Int16:
|
||||||
|
return SmartField(name, int16(rv.Int()))
|
||||||
|
case reflect.Int32:
|
||||||
|
return SmartField(name, int32(rv.Int()))
|
||||||
|
case reflect.Int64:
|
||||||
|
return SmartField(name, int64(rv.Int()))
|
||||||
|
case reflect.Uint:
|
||||||
|
return SmartField(name, uint(rv.Uint()))
|
||||||
|
case reflect.Uint8:
|
||||||
|
return SmartField(name, uint8(rv.Uint()))
|
||||||
|
case reflect.Uint16:
|
||||||
|
return SmartField(name, uint16(rv.Uint()))
|
||||||
|
case reflect.Uint32:
|
||||||
|
return SmartField(name, uint32(rv.Uint()))
|
||||||
|
case reflect.Uint64:
|
||||||
|
return SmartField(name, uint64(rv.Uint()))
|
||||||
|
case reflect.Uintptr:
|
||||||
|
return SmartField(name, uintptr(rv.Uint()))
|
||||||
|
case reflect.Float32:
|
||||||
|
return SmartField(name, float32(rv.Float()))
|
||||||
|
case reflect.Float64:
|
||||||
|
return SmartField(name, float64(rv.Float()))
|
||||||
|
case reflect.String:
|
||||||
|
return SmartField(name, rv.String())
|
||||||
|
case reflect.Struct:
|
||||||
|
fields := make([]FieldOpt, 0, rv.NumField())
|
||||||
|
for i := 0; i < rv.NumField(); i++ {
|
||||||
|
field := rv.Field(i)
|
||||||
|
if field.CanInterface() {
|
||||||
|
fields = append(fields, SmartField(name, field.Interface()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Struct(name, fields...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return StringField(name, fmt.Sprintf("(Unsupported: %T) %v", v, v))
|
||||||
|
}
|
||||||
|
41
vendor/github.com/Microsoft/go-winio/pkg/etw/provider.go
generated
vendored
41
vendor/github.com/Microsoft/go-winio/pkg/etw/provider.go
generated
vendored
@ -4,12 +4,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
"unicode/utf16"
|
"unicode/utf16"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,7 +16,7 @@ import (
|
|||||||
// name and ID (GUID), which should always have a 1:1 mapping to each other
|
// name and ID (GUID), which should always have a 1:1 mapping to each other
|
||||||
// (e.g. don't use multiple provider names with the same ID, or vice versa).
|
// (e.g. don't use multiple provider names with the same ID, or vice versa).
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
ID *windows.GUID
|
ID *guid.GUID
|
||||||
handle providerHandle
|
handle providerHandle
|
||||||
metadata []byte
|
metadata []byte
|
||||||
callback EnableCallback
|
callback EnableCallback
|
||||||
@ -30,19 +29,7 @@ type Provider struct {
|
|||||||
|
|
||||||
// String returns the `provider`.ID as a string
|
// String returns the `provider`.ID as a string
|
||||||
func (provider *Provider) String() string {
|
func (provider *Provider) String() string {
|
||||||
data1 := make([]byte, 4)
|
return provider.ID.String()
|
||||||
binary.BigEndian.PutUint32(data1, provider.ID.Data1)
|
|
||||||
data2 := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(data2, provider.ID.Data2)
|
|
||||||
data3 := make([]byte, 2)
|
|
||||||
binary.BigEndian.PutUint16(data3, provider.ID.Data3)
|
|
||||||
return fmt.Sprintf(
|
|
||||||
"%s-%s-%s-%s-%s",
|
|
||||||
hex.EncodeToString(data1),
|
|
||||||
hex.EncodeToString(data2),
|
|
||||||
hex.EncodeToString(data3),
|
|
||||||
hex.EncodeToString(provider.ID.Data4[:2]),
|
|
||||||
hex.EncodeToString(provider.ID.Data4[2:]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type providerHandle windows.Handle
|
type providerHandle windows.Handle
|
||||||
@ -72,9 +59,9 @@ const (
|
|||||||
|
|
||||||
// EnableCallback is the form of the callback function that receives provider
|
// EnableCallback is the form of the callback function that receives provider
|
||||||
// enable/disable notifications from ETW.
|
// enable/disable notifications from ETW.
|
||||||
type EnableCallback func(*windows.GUID, ProviderState, Level, uint64, uint64, uintptr)
|
type EnableCallback func(*guid.GUID, ProviderState, Level, uint64, uint64, uintptr)
|
||||||
|
|
||||||
func providerCallback(sourceID *windows.GUID, state ProviderState, level Level, matchAnyKeyword uint64, matchAllKeyword uint64, filterData uintptr, i uintptr) {
|
func providerCallback(sourceID *guid.GUID, state ProviderState, level Level, matchAnyKeyword uint64, matchAllKeyword uint64, filterData uintptr, i uintptr) {
|
||||||
provider := providers.getProvider(uint(i))
|
provider := providers.getProvider(uint(i))
|
||||||
|
|
||||||
switch state {
|
switch state {
|
||||||
@ -96,7 +83,7 @@ func providerCallback(sourceID *windows.GUID, state ProviderState, level Level,
|
|||||||
// for provider notifications. Because Go has trouble with callback arguments of
|
// for provider notifications. Because Go has trouble with callback arguments of
|
||||||
// different size, it has only pointer-sized arguments, which are then cast to
|
// different size, it has only pointer-sized arguments, which are then cast to
|
||||||
// the appropriate types when calling providerCallback.
|
// the appropriate types when calling providerCallback.
|
||||||
func providerCallbackAdapter(sourceID *windows.GUID, state uintptr, level uintptr, matchAnyKeyword uintptr, matchAllKeyword uintptr, filterData uintptr, i uintptr) uintptr {
|
func providerCallbackAdapter(sourceID *guid.GUID, state uintptr, level uintptr, matchAnyKeyword uintptr, matchAllKeyword uintptr, filterData uintptr, i uintptr) uintptr {
|
||||||
providerCallback(sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
|
providerCallback(sourceID, ProviderState(state), Level(level), uint64(matchAnyKeyword), uint64(matchAllKeyword), filterData, i)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -108,7 +95,7 @@ func providerCallbackAdapter(sourceID *windows.GUID, state uintptr, level uintpt
|
|||||||
// The algorithm is roughly:
|
// The algorithm is roughly:
|
||||||
// Hash = Sha1(namespace + arg.ToUpper().ToUtf16be())
|
// Hash = Sha1(namespace + arg.ToUpper().ToUtf16be())
|
||||||
// Guid = Hash[0..15], with Hash[7] tweaked according to RFC 4122
|
// Guid = Hash[0..15], with Hash[7] tweaked according to RFC 4122
|
||||||
func providerIDFromName(name string) *windows.GUID {
|
func providerIDFromName(name string) *guid.GUID {
|
||||||
buffer := sha1.New()
|
buffer := sha1.New()
|
||||||
|
|
||||||
namespace := []byte{0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8, 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB}
|
namespace := []byte{0x48, 0x2C, 0x2D, 0xB2, 0xC3, 0x90, 0x47, 0xC8, 0x87, 0xF8, 0x1A, 0x15, 0xBF, 0xC1, 0x30, 0xFB}
|
||||||
@ -119,7 +106,7 @@ func providerIDFromName(name string) *windows.GUID {
|
|||||||
sum := buffer.Sum(nil)
|
sum := buffer.Sum(nil)
|
||||||
sum[7] = (sum[7] & 0xf) | 0x50
|
sum[7] = (sum[7] & 0xf) | 0x50
|
||||||
|
|
||||||
return &windows.GUID{
|
return &guid.GUID{
|
||||||
Data1: binary.LittleEndian.Uint32(sum[0:4]),
|
Data1: binary.LittleEndian.Uint32(sum[0:4]),
|
||||||
Data2: binary.LittleEndian.Uint16(sum[4:6]),
|
Data2: binary.LittleEndian.Uint16(sum[4:6]),
|
||||||
Data3: binary.LittleEndian.Uint16(sum[6:8]),
|
Data3: binary.LittleEndian.Uint16(sum[6:8]),
|
||||||
@ -137,7 +124,7 @@ func NewProvider(name string, callback EnableCallback) (provider *Provider, err
|
|||||||
// provider ID to be manually specified. This is most useful when there is an
|
// provider ID to be manually specified. This is most useful when there is an
|
||||||
// existing provider ID that must be used to conform to existing diagnostic
|
// existing provider ID that must be used to conform to existing diagnostic
|
||||||
// infrastructure.
|
// infrastructure.
|
||||||
func NewProviderWithID(name string, id *windows.GUID, callback EnableCallback) (provider *Provider, err error) {
|
func NewProviderWithID(name string, id *guid.GUID, callback EnableCallback) (provider *Provider, err error) {
|
||||||
providerCallbackOnce.Do(func() {
|
providerCallbackOnce.Do(func() {
|
||||||
globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
|
globalProviderCallback = windows.NewCallback(providerCallbackAdapter)
|
||||||
})
|
})
|
||||||
@ -151,7 +138,7 @@ func NewProviderWithID(name string, id *windows.GUID, callback EnableCallback) (
|
|||||||
provider.ID = id
|
provider.ID = id
|
||||||
provider.callback = callback
|
provider.callback = callback
|
||||||
|
|
||||||
if err := eventRegister(provider.ID, globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
|
if err := eventRegister((*windows.GUID)(provider.ID), globalProviderCallback, uintptr(provider.index), &provider.handle); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,7 +234,7 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt
|
|||||||
dataBlobs = [][]byte{ed.bytes()}
|
dataBlobs = [][]byte{ed.bytes()}
|
||||||
}
|
}
|
||||||
|
|
||||||
return provider.writeEventRaw(options.descriptor, nil, nil, [][]byte{em.bytes()}, dataBlobs)
|
return provider.writeEventRaw(options.descriptor, options.activityID, options.relatedActivityID, [][]byte{em.bytes()}, dataBlobs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeEventRaw writes a single ETW event from the provider. This function is
|
// writeEventRaw writes a single ETW event from the provider. This function is
|
||||||
@ -259,8 +246,8 @@ func (provider *Provider) WriteEvent(name string, eventOpts []EventOpt, fieldOpt
|
|||||||
// the ETW infrastructure.
|
// the ETW infrastructure.
|
||||||
func (provider *Provider) writeEventRaw(
|
func (provider *Provider) writeEventRaw(
|
||||||
descriptor *eventDescriptor,
|
descriptor *eventDescriptor,
|
||||||
activityID *windows.GUID,
|
activityID *guid.GUID,
|
||||||
relatedActivityID *windows.GUID,
|
relatedActivityID *guid.GUID,
|
||||||
metadataBlobs [][]byte,
|
metadataBlobs [][]byte,
|
||||||
dataBlobs [][]byte) error {
|
dataBlobs [][]byte) error {
|
||||||
|
|
||||||
@ -275,5 +262,5 @@ func (provider *Provider) writeEventRaw(
|
|||||||
dataDescriptors = append(dataDescriptors, newEventDataDescriptor(eventDataDescriptorTypeUserData, blob))
|
dataDescriptors = append(dataDescriptors, newEventDataDescriptor(eventDataDescriptorTypeUserData, blob))
|
||||||
}
|
}
|
||||||
|
|
||||||
return eventWriteTransfer(provider.handle, descriptor, activityID, relatedActivityID, dataDescriptorCount, &dataDescriptors[0])
|
return eventWriteTransfer(provider.handle, descriptor, (*windows.GUID)(activityID), (*windows.GUID)(relatedActivityID), dataDescriptorCount, &dataDescriptors[0])
|
||||||
}
|
}
|
||||||
|
126
vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go
generated
vendored
126
vendor/github.com/Microsoft/go-winio/pkg/etwlogrus/hook.go
generated
vendored
@ -1,9 +1,6 @@
|
|||||||
package etwlogrus
|
package etwlogrus
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/Microsoft/go-winio/pkg/etw"
|
"github.com/Microsoft/go-winio/pkg/etw"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -71,7 +68,7 @@ func (h *Hook) Fire(e *logrus.Entry) error {
|
|||||||
fields = append(fields, etw.StringField("Message", e.Message))
|
fields = append(fields, etw.StringField("Message", e.Message))
|
||||||
|
|
||||||
for k, v := range e.Data {
|
for k, v := range e.Data {
|
||||||
fields = append(fields, getFieldOpt(k, v))
|
fields = append(fields, etw.SmartField(k, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.provider.WriteEvent(
|
return h.provider.WriteEvent(
|
||||||
@ -80,127 +77,6 @@ func (h *Hook) Fire(e *logrus.Entry) error {
|
|||||||
fields)
|
fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Currently, we support logging basic builtin types (int, string, etc), slices
|
|
||||||
// of basic builtin types, error, types derived from the basic types (e.g. "type
|
|
||||||
// foo int"), and structs (recursively logging their fields). We do not support
|
|
||||||
// slices of derived types (e.g. "[]foo").
|
|
||||||
//
|
|
||||||
// For types that we don't support, the value is formatted via fmt.Sprint, and
|
|
||||||
// we also log a message that the type is unsupported along with the formatted
|
|
||||||
// type. The intent of this is to make it easier to see which types are not
|
|
||||||
// supported in traces, so we can evaluate adding support for more types in the
|
|
||||||
// future.
|
|
||||||
func getFieldOpt(k string, v interface{}) etw.FieldOpt {
|
|
||||||
switch v := v.(type) {
|
|
||||||
case bool:
|
|
||||||
return etw.BoolField(k, v)
|
|
||||||
case []bool:
|
|
||||||
return etw.BoolArray(k, v)
|
|
||||||
case string:
|
|
||||||
return etw.StringField(k, v)
|
|
||||||
case []string:
|
|
||||||
return etw.StringArray(k, v)
|
|
||||||
case int:
|
|
||||||
return etw.IntField(k, v)
|
|
||||||
case []int:
|
|
||||||
return etw.IntArray(k, v)
|
|
||||||
case int8:
|
|
||||||
return etw.Int8Field(k, v)
|
|
||||||
case []int8:
|
|
||||||
return etw.Int8Array(k, v)
|
|
||||||
case int16:
|
|
||||||
return etw.Int16Field(k, v)
|
|
||||||
case []int16:
|
|
||||||
return etw.Int16Array(k, v)
|
|
||||||
case int32:
|
|
||||||
return etw.Int32Field(k, v)
|
|
||||||
case []int32:
|
|
||||||
return etw.Int32Array(k, v)
|
|
||||||
case int64:
|
|
||||||
return etw.Int64Field(k, v)
|
|
||||||
case []int64:
|
|
||||||
return etw.Int64Array(k, v)
|
|
||||||
case uint:
|
|
||||||
return etw.UintField(k, v)
|
|
||||||
case []uint:
|
|
||||||
return etw.UintArray(k, v)
|
|
||||||
case uint8:
|
|
||||||
return etw.Uint8Field(k, v)
|
|
||||||
case []uint8:
|
|
||||||
return etw.Uint8Array(k, v)
|
|
||||||
case uint16:
|
|
||||||
return etw.Uint16Field(k, v)
|
|
||||||
case []uint16:
|
|
||||||
return etw.Uint16Array(k, v)
|
|
||||||
case uint32:
|
|
||||||
return etw.Uint32Field(k, v)
|
|
||||||
case []uint32:
|
|
||||||
return etw.Uint32Array(k, v)
|
|
||||||
case uint64:
|
|
||||||
return etw.Uint64Field(k, v)
|
|
||||||
case []uint64:
|
|
||||||
return etw.Uint64Array(k, v)
|
|
||||||
case uintptr:
|
|
||||||
return etw.UintptrField(k, v)
|
|
||||||
case []uintptr:
|
|
||||||
return etw.UintptrArray(k, v)
|
|
||||||
case float32:
|
|
||||||
return etw.Float32Field(k, v)
|
|
||||||
case []float32:
|
|
||||||
return etw.Float32Array(k, v)
|
|
||||||
case float64:
|
|
||||||
return etw.Float64Field(k, v)
|
|
||||||
case []float64:
|
|
||||||
return etw.Float64Array(k, v)
|
|
||||||
case error:
|
|
||||||
return etw.StringField(k, v.Error())
|
|
||||||
default:
|
|
||||||
switch rv := reflect.ValueOf(v); rv.Kind() {
|
|
||||||
case reflect.Bool:
|
|
||||||
return getFieldOpt(k, rv.Bool())
|
|
||||||
case reflect.Int:
|
|
||||||
return getFieldOpt(k, int(rv.Int()))
|
|
||||||
case reflect.Int8:
|
|
||||||
return getFieldOpt(k, int8(rv.Int()))
|
|
||||||
case reflect.Int16:
|
|
||||||
return getFieldOpt(k, int16(rv.Int()))
|
|
||||||
case reflect.Int32:
|
|
||||||
return getFieldOpt(k, int32(rv.Int()))
|
|
||||||
case reflect.Int64:
|
|
||||||
return getFieldOpt(k, int64(rv.Int()))
|
|
||||||
case reflect.Uint:
|
|
||||||
return getFieldOpt(k, uint(rv.Uint()))
|
|
||||||
case reflect.Uint8:
|
|
||||||
return getFieldOpt(k, uint8(rv.Uint()))
|
|
||||||
case reflect.Uint16:
|
|
||||||
return getFieldOpt(k, uint16(rv.Uint()))
|
|
||||||
case reflect.Uint32:
|
|
||||||
return getFieldOpt(k, uint32(rv.Uint()))
|
|
||||||
case reflect.Uint64:
|
|
||||||
return getFieldOpt(k, uint64(rv.Uint()))
|
|
||||||
case reflect.Uintptr:
|
|
||||||
return getFieldOpt(k, uintptr(rv.Uint()))
|
|
||||||
case reflect.Float32:
|
|
||||||
return getFieldOpt(k, float32(rv.Float()))
|
|
||||||
case reflect.Float64:
|
|
||||||
return getFieldOpt(k, float64(rv.Float()))
|
|
||||||
case reflect.String:
|
|
||||||
return getFieldOpt(k, rv.String())
|
|
||||||
case reflect.Struct:
|
|
||||||
fields := make([]etw.FieldOpt, 0, rv.NumField())
|
|
||||||
for i := 0; i < rv.NumField(); i++ {
|
|
||||||
field := rv.Field(i)
|
|
||||||
if field.CanInterface() {
|
|
||||||
fields = append(fields, getFieldOpt(k, field.Interface()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return etw.Struct(k, fields...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return etw.StringField(k, fmt.Sprintf("(Unsupported: %T) %v", v, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close cleans up the hook and closes the ETW provider. If the provder was
|
// Close cleans up the hook and closes the ETW provider. If the provder was
|
||||||
// registered by etwlogrus, it will be closed as part of `Close`. If the
|
// registered by etwlogrus, it will be closed as part of `Close`. If the
|
||||||
// provider was passed in, it will not be closed.
|
// provider was passed in, it will not be closed.
|
||||||
|
110
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
Normal file
110
vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go
generated
vendored
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
package guid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = (json.Marshaler)(&GUID{})
|
||||||
|
var _ = (json.Unmarshaler)(&GUID{})
|
||||||
|
|
||||||
|
// GUID represents a GUID/UUID. It has the same structure as
|
||||||
|
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||||
|
// that type. It is defined as its own type so that stringification and
|
||||||
|
// marshaling can be supported. The representation matches that used by native
|
||||||
|
// Windows code.
|
||||||
|
type GUID windows.GUID
|
||||||
|
|
||||||
|
// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122.
|
||||||
|
func NewV4() (*GUID, error) {
|
||||||
|
var b [16]byte
|
||||||
|
if _, err := rand.Read(b[:]); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var g GUID
|
||||||
|
g.Data1 = binary.LittleEndian.Uint32(b[0:4])
|
||||||
|
g.Data2 = binary.LittleEndian.Uint16(b[4:6])
|
||||||
|
g.Data3 = binary.LittleEndian.Uint16(b[6:8])
|
||||||
|
copy(g.Data4[:], b[8:16])
|
||||||
|
|
||||||
|
g.Data3 = (g.Data3 & 0x0fff) | 0x4000 // Version 4 (randomly generated)
|
||||||
|
g.Data4[0] = (g.Data4[0] & 0x3f) | 0x80 // RFC4122 variant
|
||||||
|
return &g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *GUID) String() string {
|
||||||
|
return fmt.Sprintf(
|
||||||
|
"%08x-%04x-%04x-%04x-%012x",
|
||||||
|
g.Data1,
|
||||||
|
g.Data2,
|
||||||
|
g.Data3,
|
||||||
|
g.Data4[:2],
|
||||||
|
g.Data4[2:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromString parses a string containing a GUID and returns the GUID. The only
|
||||||
|
// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx`
|
||||||
|
// format.
|
||||||
|
func FromString(s string) (*GUID, error) {
|
||||||
|
if len(s) != 36 {
|
||||||
|
return nil, errors.New("invalid GUID format (length)")
|
||||||
|
}
|
||||||
|
if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
|
||||||
|
return nil, errors.New("invalid GUID format (dashes)")
|
||||||
|
}
|
||||||
|
|
||||||
|
var g GUID
|
||||||
|
|
||||||
|
data1, err := strconv.ParseUint(s[0:8], 16, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "invalid GUID format (Data1)")
|
||||||
|
}
|
||||||
|
g.Data1 = uint32(data1)
|
||||||
|
|
||||||
|
data2, err := strconv.ParseUint(s[9:13], 16, 16)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "invalid GUID format (Data2)")
|
||||||
|
}
|
||||||
|
g.Data2 = uint16(data2)
|
||||||
|
|
||||||
|
data3, err := strconv.ParseUint(s[14:18], 16, 16)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "invalid GUID format (Data3)")
|
||||||
|
}
|
||||||
|
g.Data3 = uint16(data3)
|
||||||
|
|
||||||
|
for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} {
|
||||||
|
v, err := strconv.ParseUint(s[x:x+2], 16, 8)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "invalid GUID format (Data4)")
|
||||||
|
}
|
||||||
|
g.Data4[i] = uint8(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &g, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals the GUID to JSON representation and returns it as a
|
||||||
|
// slice of bytes.
|
||||||
|
func (g *GUID) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(g.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals a GUID from JSON representation and sets itself to
|
||||||
|
// the unmarshaled GUID.
|
||||||
|
func (g *GUID) UnmarshalJSON(data []byte) error {
|
||||||
|
g2, err := FromString(strings.Trim(string(data), "\""))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
*g = *g2
|
||||||
|
return nil
|
||||||
|
}
|
55
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
55
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
@ -1,4 +1,4 @@
|
|||||||
// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
|
// Code generated by 'go generate'; DO NOT EDIT.
|
||||||
|
|
||||||
package winio
|
package winio
|
||||||
|
|
||||||
@ -38,6 +38,7 @@ func errnoErr(e syscall.Errno) error {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||||
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
|
||||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||||
@ -47,10 +48,13 @@ var (
|
|||||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||||
procWaitNamedPipeW = modkernel32.NewProc("WaitNamedPipeW")
|
|
||||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||||
|
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||||
|
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||||
|
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||||
|
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||||
@ -176,27 +180,6 @@ func _createFile(name *uint16, access uint32, mode uint32, sa *syscall.SecurityA
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitNamedPipe(name string, timeout uint32) (err error) {
|
|
||||||
var _p0 *uint16
|
|
||||||
_p0, err = syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return _waitNamedPipe(_p0, timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
func _waitNamedPipe(name *uint16, timeout uint32) (err error) {
|
|
||||||
r1, _, e1 := syscall.Syscall(procWaitNamedPipeW.Addr(), 2, uintptr(unsafe.Pointer(name)), uintptr(timeout), 0)
|
|
||||||
if r1 == 0 {
|
|
||||||
if e1 != 0 {
|
|
||||||
err = errnoErr(e1)
|
|
||||||
} else {
|
|
||||||
err = syscall.EINVAL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||||
if r1 == 0 {
|
if r1 == 0 {
|
||||||
@ -227,6 +210,32 @@ func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlNtStatusToDosError(status ntstatus) (winerr error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
winerr = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func rtlDefaultNpAcl(dacl *uintptr) (status ntstatus) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||||
|
status = ntstatus(r0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||||
var _p0 *uint16
|
var _p0 *uint16
|
||||||
_p0, err = syscall.UTF16PtrFromString(accountName)
|
_p0, err = syscall.UTF16PtrFromString(accountName)
|
||||||
|
18
vendor/github.com/containerd/console/LICENSE
generated
vendored
18
vendor/github.com/containerd/console/LICENSE
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
Apache License
|
Apache License
|
||||||
Version 2.0, January 2004
|
Version 2.0, January 2004
|
||||||
http://www.apache.org/licenses/
|
https://www.apache.org/licenses/
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
@ -175,24 +176,13 @@
|
|||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
Copyright The containerd Authors
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
You may obtain a copy of the License at
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
Unless required by applicable law or agreed to in writing, software
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
10
vendor/github.com/containerd/console/README.md
generated
vendored
10
vendor/github.com/containerd/console/README.md
generated
vendored
@ -15,3 +15,13 @@ if err := current.SetRaw(); err != nil {
|
|||||||
ws, err := current.Size()
|
ws, err := current.Size()
|
||||||
current.Resize(ws)
|
current.Resize(ws)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Project details
|
||||||
|
|
||||||
|
console is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE).
|
||||||
|
As a containerd sub-project, you will find the:
|
||||||
|
* [Project governance](https://github.com/containerd/project/blob/master/GOVERNANCE.md),
|
||||||
|
* [Maintainers](https://github.com/containerd/project/blob/master/MAINTAINERS),
|
||||||
|
* and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
|
||||||
|
|
||||||
|
information in our [`containerd/project`](https://github.com/containerd/project) repository.
|
||||||
|
2
vendor/github.com/containerd/containerd/README.md
generated
vendored
2
vendor/github.com/containerd/containerd/README.md
generated
vendored
@ -1,4 +1,4 @@
|
|||||||

|

|
||||||
|
|
||||||
[](https://godoc.org/github.com/containerd/containerd)
|
[](https://godoc.org/github.com/containerd/containerd)
|
||||||
[](https://travis-ci.org/containerd/containerd)
|
[](https://travis-ci.org/containerd/containerd)
|
||||||
|
1228
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.pb.go
generated
vendored
1228
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
38
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.proto
generated
vendored
38
vendor/github.com/containerd/containerd/api/services/leases/v1/leases.proto
generated
vendored
@ -22,6 +22,15 @@ service Leases {
|
|||||||
// List lists all active leases, returning the full list of
|
// List lists all active leases, returning the full list of
|
||||||
// leases and optionally including the referenced resources.
|
// leases and optionally including the referenced resources.
|
||||||
rpc List(ListRequest) returns (ListResponse);
|
rpc List(ListRequest) returns (ListResponse);
|
||||||
|
|
||||||
|
// AddResource references the resource by the provided lease.
|
||||||
|
rpc AddResource(AddResourceRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// DeleteResource dereferences the resource by the provided lease.
|
||||||
|
rpc DeleteResource(DeleteResourceRequest) returns (google.protobuf.Empty);
|
||||||
|
|
||||||
|
// ListResources lists all the resources referenced by the lease.
|
||||||
|
rpc ListResources(ListResourcesRequest) returns (ListResourcesResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lease is an object which retains resources while it exists.
|
// Lease is an object which retains resources while it exists.
|
||||||
@ -62,3 +71,32 @@ message ListRequest {
|
|||||||
message ListResponse {
|
message ListResponse {
|
||||||
repeated Lease leases = 1;
|
repeated Lease leases = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message Resource {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
// For snapshotter resource, there are many snapshotter types here, like
|
||||||
|
// overlayfs, devmapper etc. The type will be formatted with type,
|
||||||
|
// like "snapshotter/overlayfs".
|
||||||
|
string type = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AddResourceRequest {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
Resource resource = 2 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteResourceRequest {
|
||||||
|
string id = 1;
|
||||||
|
|
||||||
|
Resource resource = 2 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListResourcesRequest {
|
||||||
|
string id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListResourcesResponse {
|
||||||
|
repeated Resource resources = 1 [(gogoproto.nullable) = false];
|
||||||
|
}
|
||||||
|
11
vendor/github.com/containerd/containerd/client.go
generated
vendored
11
vendor/github.com/containerd/containerd/client.go
generated
vendored
@ -102,7 +102,7 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
|
|||||||
grpc.WithInsecure(),
|
grpc.WithInsecure(),
|
||||||
grpc.FailOnNonTempDialError(true),
|
grpc.FailOnNonTempDialError(true),
|
||||||
grpc.WithBackoffMaxDelay(3 * time.Second),
|
grpc.WithBackoffMaxDelay(3 * time.Second),
|
||||||
grpc.WithDialer(dialer.Dialer),
|
grpc.WithContextDialer(dialer.ContextDialer),
|
||||||
|
|
||||||
// TODO(stevvooe): We may need to allow configuration of this on the client.
|
// TODO(stevvooe): We may need to allow configuration of this on the client.
|
||||||
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
|
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
|
||||||
@ -225,7 +225,7 @@ func (c *Client) IsServing(ctx context.Context) (bool, error) {
|
|||||||
return false, errors.New("no grpc connection available")
|
return false, errors.New("no grpc connection available")
|
||||||
}
|
}
|
||||||
c.connMu.Unlock()
|
c.connMu.Unlock()
|
||||||
r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{}, grpc.FailFast(false))
|
r, err := c.HealthService().Check(ctx, &grpc_health_v1.HealthCheckRequest{}, grpc.WaitForReady(true))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
@ -622,6 +622,13 @@ func (c *Client) VersionService() versionservice.VersionClient {
|
|||||||
return versionservice.NewVersionClient(c.conn)
|
return versionservice.NewVersionClient(c.conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Conn returns the underlying GRPC connection object
|
||||||
|
func (c *Client) Conn() *grpc.ClientConn {
|
||||||
|
c.connMu.Lock()
|
||||||
|
defer c.connMu.Unlock()
|
||||||
|
return c.conn
|
||||||
|
}
|
||||||
|
|
||||||
// Version of containerd
|
// Version of containerd
|
||||||
type Version struct {
|
type Version struct {
|
||||||
// Version number
|
// Version number
|
||||||
|
2
vendor/github.com/containerd/containerd/cmd/containerd/command/config.go
generated
vendored
2
vendor/github.com/containerd/containerd/cmd/containerd/command/config.go
generated
vendored
@ -60,7 +60,7 @@ var configCommand = cli.Command{
|
|||||||
if p.Config == nil {
|
if p.Config == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
config.Plugins[p.ID] = p.Config
|
config.Plugins[p.URI()] = p.Config
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err = config.WriteTo(os.Stdout)
|
_, err = config.WriteTo(os.Stdout)
|
||||||
|
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_linux.go
generated
vendored
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_linux.go
generated
vendored
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
func defaultConfig() *srvconfig.Config {
|
func defaultConfig() *srvconfig.Config {
|
||||||
return &srvconfig.Config{
|
return &srvconfig.Config{
|
||||||
|
Version: 2,
|
||||||
Root: defaults.DefaultRootDir,
|
Root: defaults.DefaultRootDir,
|
||||||
State: defaults.DefaultStateDir,
|
State: defaults.DefaultStateDir,
|
||||||
GRPC: srvconfig.GRPCConfig{
|
GRPC: srvconfig.GRPCConfig{
|
||||||
|
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_unsupported.go
generated
vendored
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_unsupported.go
generated
vendored
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
func defaultConfig() *srvconfig.Config {
|
func defaultConfig() *srvconfig.Config {
|
||||||
return &srvconfig.Config{
|
return &srvconfig.Config{
|
||||||
|
Version: 2,
|
||||||
Root: defaults.DefaultRootDir,
|
Root: defaults.DefaultRootDir,
|
||||||
State: defaults.DefaultStateDir,
|
State: defaults.DefaultStateDir,
|
||||||
GRPC: srvconfig.GRPCConfig{
|
GRPC: srvconfig.GRPCConfig{
|
||||||
|
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_windows.go
generated
vendored
1
vendor/github.com/containerd/containerd/cmd/containerd/command/config_windows.go
generated
vendored
@ -23,6 +23,7 @@ import (
|
|||||||
|
|
||||||
func defaultConfig() *srvconfig.Config {
|
func defaultConfig() *srvconfig.Config {
|
||||||
return &srvconfig.Config{
|
return &srvconfig.Config{
|
||||||
|
Version: 2,
|
||||||
Root: defaults.DefaultRootDir,
|
Root: defaults.DefaultRootDir,
|
||||||
State: defaults.DefaultStateDir,
|
State: defaults.DefaultStateDir,
|
||||||
GRPC: srvconfig.GRPCConfig{
|
GRPC: srvconfig.GRPCConfig{
|
||||||
|
14
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
14
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
@ -278,7 +278,7 @@ func setLevel(context *cli.Context, config *srvconfig.Config) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpStacks() {
|
func dumpStacks(writeToFile bool) {
|
||||||
var (
|
var (
|
||||||
buf []byte
|
buf []byte
|
||||||
stackSize int
|
stackSize int
|
||||||
@ -291,4 +291,16 @@ func dumpStacks() {
|
|||||||
}
|
}
|
||||||
buf = buf[:stackSize]
|
buf = buf[:stackSize]
|
||||||
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||||
|
|
||||||
|
if writeToFile {
|
||||||
|
// Also write to file to aid gathering diagnostics
|
||||||
|
name := filepath.Join(os.TempDir(), fmt.Sprintf("containerd.%d.stacks.log", os.Getpid()))
|
||||||
|
f, err := os.Create(name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
f.WriteString(string(buf))
|
||||||
|
logrus.Infof("goroutine stack dump written to %s", name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
2
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
@ -48,7 +48,7 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
|
|||||||
log.G(ctx).WithField("signal", s).Debug("received signal")
|
log.G(ctx).WithField("signal", s).Debug("received signal")
|
||||||
switch s {
|
switch s {
|
||||||
case unix.SIGUSR1:
|
case unix.SIGUSR1:
|
||||||
dumpStacks()
|
dumpStacks(true)
|
||||||
case unix.SIGPIPE:
|
case unix.SIGPIPE:
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
|
30
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
30
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
@ -24,7 +24,9 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
winio "github.com/Microsoft/go-winio"
|
winio "github.com/Microsoft/go-winio"
|
||||||
|
"github.com/Microsoft/go-winio/pkg/etw"
|
||||||
"github.com/Microsoft/go-winio/pkg/etwlogrus"
|
"github.com/Microsoft/go-winio/pkg/etwlogrus"
|
||||||
|
"github.com/Microsoft/go-winio/pkg/guid"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/services/server"
|
"github.com/containerd/containerd/services/server"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
@ -86,16 +88,30 @@ func setupDumpStacks() {
|
|||||||
logrus.Debugf("Stackdump - waiting signal at %s", event)
|
logrus.Debugf("Stackdump - waiting signal at %s", event)
|
||||||
for {
|
for {
|
||||||
windows.WaitForSingleObject(h, windows.INFINITE)
|
windows.WaitForSingleObject(h, windows.INFINITE)
|
||||||
dumpStacks()
|
dumpStacks(true)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func etwCallback(sourceID *guid.GUID, state etw.ProviderState, level etw.Level, matchAnyKeyword uint64, matchAllKeyword uint64, filterData uintptr) {
|
||||||
// Provider ID: {2acb92c0-eb9b-571a-69cf-8f3410f383ad}
|
if state == etw.ProviderStateCaptureState {
|
||||||
// Hook isn't closed explicitly, as it will exist until process exit.
|
dumpStacks(false)
|
||||||
// GUID is generated based on name - see Microsoft/go-winio/tools/etw-provider-gen.
|
}
|
||||||
if hook, err := etwlogrus.NewHook("ContainerD"); err == nil {
|
}
|
||||||
logrus.AddHook(hook)
|
|
||||||
|
func init() {
|
||||||
|
// Provider ID: 2acb92c0-eb9b-571a-69cf-8f3410f383ad
|
||||||
|
// Provider and hook aren't closed explicitly, as they will exist until
|
||||||
|
// process exit. GUID is generated based on name - see
|
||||||
|
// Microsoft/go-winio/tools/etw-provider-gen.
|
||||||
|
provider, err := etw.NewProvider("ContainerD", etwCallback)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Error(err)
|
||||||
|
} else {
|
||||||
|
if hook, err := etwlogrus.NewHookFromProvider(provider); err == nil {
|
||||||
|
logrus.AddHook(hook)
|
||||||
|
} else {
|
||||||
|
logrus.Error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/containerd/containerd/cmd/containerd/command/publish.go
generated
vendored
6
vendor/github.com/containerd/containerd/cmd/containerd/command/publish.go
generated
vendored
@ -84,18 +84,18 @@ func getEventPayload(r io.Reader) (*types.Any, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func connectEvents(address string) (eventsapi.EventsClient, error) {
|
func connectEvents(address string) (eventsapi.EventsClient, error) {
|
||||||
conn, err := connect(address, dialer.Dialer)
|
conn, err := connect(address, dialer.ContextDialer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to dial %q", address)
|
return nil, errors.Wrapf(err, "failed to dial %q", address)
|
||||||
}
|
}
|
||||||
return eventsapi.NewEventsClient(conn), nil
|
return eventsapi.NewEventsClient(conn), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(address string, d func(string, time.Duration) (net.Conn, error)) (*grpc.ClientConn, error) {
|
func connect(address string, d func(gocontext.Context, string) (net.Conn, error)) (*grpc.ClientConn, error) {
|
||||||
gopts := []grpc.DialOption{
|
gopts := []grpc.DialOption{
|
||||||
grpc.WithBlock(),
|
grpc.WithBlock(),
|
||||||
grpc.WithInsecure(),
|
grpc.WithInsecure(),
|
||||||
grpc.WithDialer(d),
|
grpc.WithContextDialer(d),
|
||||||
grpc.FailOnNonTempDialError(true),
|
grpc.FailOnNonTempDialError(true),
|
||||||
grpc.WithBackoffMaxDelay(3 * time.Second),
|
grpc.WithBackoffMaxDelay(3 * time.Second),
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
@ -270,8 +270,8 @@ func registerService() error {
|
|||||||
Delay uint32
|
Delay uint32
|
||||||
}
|
}
|
||||||
t := []scAction{
|
t := []scAction{
|
||||||
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
{Type: scActionRestart, Delay: uint32(15 * time.Second / time.Millisecond)},
|
||||||
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
{Type: scActionRestart, Delay: uint32(15 * time.Second / time.Millisecond)},
|
||||||
{Type: scActionNone},
|
{Type: scActionNone},
|
||||||
}
|
}
|
||||||
lpInfo := serviceFailureActions{ResetPeriod: uint32(24 * time.Hour / time.Second), ActionsCount: uint32(3), Actions: uintptr(unsafe.Pointer(&t[0]))}
|
lpInfo := serviceFailureActions{ResetPeriod: uint32(24 * time.Hour / time.Second), ActionsCount: uint32(3), Actions: uintptr(unsafe.Pointer(&t[0]))}
|
||||||
|
102
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/checkpoint.go
generated
vendored
Normal file
102
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/checkpoint.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var checkpointCommand = cli.Command{
|
||||||
|
Name: "checkpoint",
|
||||||
|
Usage: "checkpoint a container",
|
||||||
|
ArgsUsage: "CONTAINER REF",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "rw",
|
||||||
|
Usage: "include the rw layer in the checkpoint",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "image",
|
||||||
|
Usage: "include the image in the checkpoint",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "task",
|
||||||
|
Usage: "checkpoint container task",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
id := context.Args().First()
|
||||||
|
if id == "" {
|
||||||
|
return errors.New("container id must be provided")
|
||||||
|
}
|
||||||
|
ref := context.Args().Get(1)
|
||||||
|
if ref == "" {
|
||||||
|
return errors.New("ref must be provided")
|
||||||
|
}
|
||||||
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cancel()
|
||||||
|
opts := []containerd.CheckpointOpts{
|
||||||
|
containerd.WithCheckpointRuntime,
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.Bool("image") {
|
||||||
|
opts = append(opts, containerd.WithCheckpointImage)
|
||||||
|
}
|
||||||
|
if context.Bool("rw") {
|
||||||
|
opts = append(opts, containerd.WithCheckpointRW)
|
||||||
|
}
|
||||||
|
if context.Bool("task") {
|
||||||
|
opts = append(opts, containerd.WithCheckpointTask)
|
||||||
|
}
|
||||||
|
container, err := client.LoadContainer(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
task, err := container.Task(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
if !errdefs.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pause if running
|
||||||
|
if task != nil {
|
||||||
|
if err := task.Pause(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err := task.Resume(ctx); err != nil {
|
||||||
|
fmt.Println(errors.Wrap(err, "error resuming task"))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := container.Checkpoint(ctx, ref, opts...); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
154
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go
generated
vendored
154
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go
generated
vendored
@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands/run"
|
"github.com/containerd/containerd/cmd/ctr/commands/run"
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/errdefs"
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -125,7 +124,7 @@ var listCommand = cli.Command{
|
|||||||
w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 4, 8, 4, ' ', 0)
|
||||||
fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\t")
|
fmt.Fprintln(w, "CONTAINER\tIMAGE\tRUNTIME\t")
|
||||||
for _, c := range containers {
|
for _, c := range containers {
|
||||||
info, err := c.Info(ctx)
|
info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -262,7 +261,7 @@ var infoCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
info, err := container.Info(ctx)
|
info, err := container.Info(ctx, containerd.WithoutRefreshedMetadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -285,152 +284,3 @@ var infoCommand = cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var checkpointCommand = cli.Command{
|
|
||||||
Name: "checkpoint",
|
|
||||||
Usage: "checkpoint a container",
|
|
||||||
ArgsUsage: "CONTAINER REF",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "rw",
|
|
||||||
Usage: "include the rw layer in the checkpoint",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "image",
|
|
||||||
Usage: "include the image in the checkpoint",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "task",
|
|
||||||
Usage: "checkpoint container task",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(context *cli.Context) error {
|
|
||||||
id := context.Args().First()
|
|
||||||
if id == "" {
|
|
||||||
return errors.New("container id must be provided")
|
|
||||||
}
|
|
||||||
ref := context.Args().Get(1)
|
|
||||||
if ref == "" {
|
|
||||||
return errors.New("ref must be provided")
|
|
||||||
}
|
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer cancel()
|
|
||||||
opts := []containerd.CheckpointOpts{
|
|
||||||
containerd.WithCheckpointRuntime,
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.Bool("image") {
|
|
||||||
opts = append(opts, containerd.WithCheckpointImage)
|
|
||||||
}
|
|
||||||
if context.Bool("rw") {
|
|
||||||
opts = append(opts, containerd.WithCheckpointRW)
|
|
||||||
}
|
|
||||||
if context.Bool("task") {
|
|
||||||
opts = append(opts, containerd.WithCheckpointTask)
|
|
||||||
}
|
|
||||||
container, err := client.LoadContainer(ctx, id)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
task, err := container.Task(ctx, nil)
|
|
||||||
if err != nil {
|
|
||||||
if !errdefs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// pause if running
|
|
||||||
if task != nil {
|
|
||||||
if err := task.Pause(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer func() {
|
|
||||||
if err := task.Resume(ctx); err != nil {
|
|
||||||
fmt.Println(errors.Wrap(err, "error resuming task"))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := container.Checkpoint(ctx, ref, opts...); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
var restoreCommand = cli.Command{
|
|
||||||
Name: "restore",
|
|
||||||
Usage: "restore a container from checkpoint",
|
|
||||||
ArgsUsage: "CONTAINER REF",
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "rw",
|
|
||||||
Usage: "restore the rw layer from the checkpoint",
|
|
||||||
},
|
|
||||||
cli.BoolFlag{
|
|
||||||
Name: "live",
|
|
||||||
Usage: "restore the runtime and memory data from the checkpoint",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Action: func(context *cli.Context) error {
|
|
||||||
id := context.Args().First()
|
|
||||||
if id == "" {
|
|
||||||
return errors.New("container id must be provided")
|
|
||||||
}
|
|
||||||
ref := context.Args().Get(1)
|
|
||||||
if ref == "" {
|
|
||||||
return errors.New("ref must be provided")
|
|
||||||
}
|
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
checkpoint, err := client.GetImage(ctx, ref)
|
|
||||||
if err != nil {
|
|
||||||
if !errdefs.IsNotFound(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// TODO (ehazlett): consider other options (always/never fetch)
|
|
||||||
ck, err := client.Fetch(ctx, ref)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
checkpoint = containerd.NewImage(client, ck)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := []containerd.RestoreOpts{
|
|
||||||
containerd.WithRestoreImage,
|
|
||||||
containerd.WithRestoreSpec,
|
|
||||||
containerd.WithRestoreRuntime,
|
|
||||||
}
|
|
||||||
if context.Bool("rw") {
|
|
||||||
opts = append(opts, containerd.WithRestoreRW)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctr, err := client.Restore(ctx, id, checkpoint, opts...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
topts := []containerd.NewTaskOpts{}
|
|
||||||
if context.Bool("live") {
|
|
||||||
topts = append(topts, containerd.WithTaskCheckpoint(checkpoint))
|
|
||||||
}
|
|
||||||
|
|
||||||
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := task.Start(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
96
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/restore.go
generated
vendored
Normal file
96
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/restore.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package containers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containerd/containerd"
|
||||||
|
"github.com/containerd/containerd/cio"
|
||||||
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
var restoreCommand = cli.Command{
|
||||||
|
Name: "restore",
|
||||||
|
Usage: "restore a container from checkpoint",
|
||||||
|
ArgsUsage: "CONTAINER REF",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "rw",
|
||||||
|
Usage: "restore the rw layer from the checkpoint",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "live",
|
||||||
|
Usage: "restore the runtime and memory data from the checkpoint",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(context *cli.Context) error {
|
||||||
|
id := context.Args().First()
|
||||||
|
if id == "" {
|
||||||
|
return errors.New("container id must be provided")
|
||||||
|
}
|
||||||
|
ref := context.Args().Get(1)
|
||||||
|
if ref == "" {
|
||||||
|
return errors.New("ref must be provided")
|
||||||
|
}
|
||||||
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
checkpoint, err := client.GetImage(ctx, ref)
|
||||||
|
if err != nil {
|
||||||
|
if !errdefs.IsNotFound(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// TODO (ehazlett): consider other options (always/never fetch)
|
||||||
|
ck, err := client.Fetch(ctx, ref)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
checkpoint = containerd.NewImage(client, ck)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := []containerd.RestoreOpts{
|
||||||
|
containerd.WithRestoreImage,
|
||||||
|
containerd.WithRestoreSpec,
|
||||||
|
containerd.WithRestoreRuntime,
|
||||||
|
}
|
||||||
|
if context.Bool("rw") {
|
||||||
|
opts = append(opts, containerd.WithRestoreRW)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr, err := client.Restore(ctx, id, checkpoint, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
topts := []containerd.NewTaskOpts{}
|
||||||
|
if context.Bool("live") {
|
||||||
|
topts = append(topts, containerd.WithTaskCheckpoint(checkpoint))
|
||||||
|
}
|
||||||
|
|
||||||
|
task, err := ctr.NewTask(ctx, cio.NewCreator(cio.WithStdio), topts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return task.Start(ctx)
|
||||||
|
},
|
||||||
|
}
|
121
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/export.go
generated
vendored
121
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/export.go
generated
vendored
@ -21,9 +21,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/images/oci"
|
"github.com/containerd/containerd/images/archive"
|
||||||
"github.com/containerd/containerd/reference"
|
"github.com/containerd/containerd/platforms"
|
||||||
digest "github.com/opencontainers/go-digest"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -31,26 +30,24 @@ import (
|
|||||||
|
|
||||||
var exportCommand = cli.Command{
|
var exportCommand = cli.Command{
|
||||||
Name: "export",
|
Name: "export",
|
||||||
Usage: "export an image",
|
Usage: "export images",
|
||||||
ArgsUsage: "[flags] <out> <image>",
|
ArgsUsage: "[flags] <out> <image> ...",
|
||||||
Description: `Export an image to a tar stream.
|
Description: `Export images to an OCI tar archive.
|
||||||
Currently, only OCI format is supported.
|
|
||||||
|
Tar output is formatted as an OCI archive, a Docker manifest is provided for the platform.
|
||||||
|
Use '--skip-manifest-json' to avoid including the Docker manifest.json file.
|
||||||
|
Use '--platform' to define the output platform.
|
||||||
|
When '--all-platforms' is given all images in a manifest list must be available.
|
||||||
`,
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
// TODO(AkihiroSuda): make this map[string]string as in moby/moby#33355?
|
cli.BoolFlag{
|
||||||
cli.StringFlag{
|
Name: "skip-manifest-json",
|
||||||
Name: "oci-ref-name",
|
Usage: "do not add Docker compatible manifest.json to archive",
|
||||||
Value: "",
|
|
||||||
Usage: "override org.opencontainers.image.ref.name annotation",
|
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
cli.StringSliceFlag{
|
||||||
Name: "manifest",
|
Name: "platform",
|
||||||
Usage: "digest of manifest",
|
Usage: "Pull content from a specific platform",
|
||||||
},
|
Value: &cli.StringSlice{},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "manifest-type",
|
|
||||||
Usage: "media type of manifest digest",
|
|
||||||
Value: ocispec.MediaTypeImageManifest,
|
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
@ -60,42 +57,46 @@ Currently, only OCI format is supported.
|
|||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
out = context.Args().First()
|
out = context.Args().First()
|
||||||
local = context.Args().Get(1)
|
images = context.Args().Tail()
|
||||||
desc ocispec.Descriptor
|
exportOpts = []archive.ExportOpt{}
|
||||||
)
|
)
|
||||||
if out == "" || local == "" {
|
if out == "" || len(images) == 0 {
|
||||||
return errors.New("please provide both an output filename and an image reference to export")
|
return errors.New("please provide both an output filename and an image reference to export")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pss := context.StringSlice("platform"); len(pss) > 0 {
|
||||||
|
var all []ocispec.Platform
|
||||||
|
for _, ps := range pss {
|
||||||
|
p, err := platforms.Parse(ps)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "invalid platform %q", ps)
|
||||||
|
}
|
||||||
|
all = append(all, p)
|
||||||
|
}
|
||||||
|
exportOpts = append(exportOpts, archive.WithPlatform(platforms.Ordered(all...)))
|
||||||
|
} else {
|
||||||
|
exportOpts = append(exportOpts, archive.WithPlatform(platforms.Default()))
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.Bool("all-platforms") {
|
||||||
|
exportOpts = append(exportOpts, archive.WithAllPlatforms())
|
||||||
|
}
|
||||||
|
|
||||||
|
if context.Bool("skip-manifest-json") {
|
||||||
|
exportOpts = append(exportOpts, archive.WithSkipDockerManifest())
|
||||||
|
}
|
||||||
|
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer cancel()
|
defer cancel()
|
||||||
if manifest := context.String("manifest"); manifest != "" {
|
|
||||||
desc.Digest, err = digest.Parse(manifest)
|
is := client.ImageService()
|
||||||
if err != nil {
|
for _, img := range images {
|
||||||
return errors.Wrap(err, "invalid manifest digest")
|
exportOpts = append(exportOpts, archive.WithImage(is, img))
|
||||||
}
|
|
||||||
desc.MediaType = context.String("manifest-type")
|
|
||||||
} else {
|
|
||||||
img, err := client.ImageService().Get(ctx, local)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "unable to resolve image to manifest")
|
|
||||||
}
|
|
||||||
desc = img.Target
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if desc.Annotations == nil {
|
|
||||||
desc.Annotations = make(map[string]string)
|
|
||||||
}
|
|
||||||
if s, ok := desc.Annotations[ocispec.AnnotationRefName]; !ok || s == "" {
|
|
||||||
if ociRefName := determineOCIRefName(local); ociRefName != "" {
|
|
||||||
desc.Annotations[ocispec.AnnotationRefName] = ociRefName
|
|
||||||
}
|
|
||||||
if ociRefName := context.String("oci-ref-name"); ociRefName != "" {
|
|
||||||
desc.Annotations[ocispec.AnnotationRefName] = ociRefName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var w io.WriteCloser
|
var w io.WriteCloser
|
||||||
if out == "-" {
|
if out == "-" {
|
||||||
w = os.Stdout
|
w = os.Stdout
|
||||||
@ -105,32 +106,8 @@ Currently, only OCI format is supported.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
defer w.Close()
|
||||||
|
|
||||||
var (
|
return client.Export(ctx, w, exportOpts...)
|
||||||
exportOpts []oci.V1ExporterOpt
|
|
||||||
)
|
|
||||||
|
|
||||||
exportOpts = append(exportOpts, oci.WithAllPlatforms(context.Bool("all-platforms")))
|
|
||||||
|
|
||||||
r, err := client.Export(ctx, desc, exportOpts...)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := io.Copy(w, r); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := w.Close(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return r.Close()
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func determineOCIRefName(local string) string {
|
|
||||||
refspec, err := reference.Parse(local)
|
|
||||||
if err != nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
tag, _ := reference.SplitObject(refspec.Object)
|
|
||||||
return tag
|
|
||||||
}
|
|
||||||
|
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/import.go
generated
vendored
6
vendor/github.com/containerd/containerd/cmd/ctr/commands/images/import.go
generated
vendored
@ -68,6 +68,10 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
|
|||||||
Name: "all-platforms",
|
Name: "all-platforms",
|
||||||
Usage: "imports content for all platforms, false by default",
|
Usage: "imports content for all platforms, false by default",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "no-unpack",
|
||||||
|
Usage: "skip unpacking the images, false by default",
|
||||||
|
},
|
||||||
}, commands.SnapshotterFlags...),
|
}, commands.SnapshotterFlags...),
|
||||||
|
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
@ -119,6 +123,7 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
|
|||||||
return closeErr
|
return closeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !context.Bool("no-unpack") {
|
||||||
log.G(ctx).Debugf("unpacking %d images", len(imgs))
|
log.G(ctx).Debugf("unpacking %d images", len(imgs))
|
||||||
|
|
||||||
for _, img := range imgs {
|
for _, img := range imgs {
|
||||||
@ -133,6 +138,7 @@ If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadb
|
|||||||
}
|
}
|
||||||
fmt.Println("done")
|
fmt.Println("done")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
@ -115,6 +115,10 @@ var Command = cli.Command{
|
|||||||
Name: "cgroup",
|
Name: "cgroup",
|
||||||
Usage: "cgroup path (To disable use of cgroup, set to \"\" explicitly)",
|
Usage: "cgroup path (To disable use of cgroup, set to \"\" explicitly)",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "platform",
|
||||||
|
Usage: "run image for specific platform",
|
||||||
|
},
|
||||||
}, append(platformRunFlags, append(commands.SnapshotterFlags, commands.ContainerFlags...)...)...),
|
}, append(platformRunFlags, append(commands.SnapshotterFlags, commands.ContainerFlags...)...)...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
|
14
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_unix.go
generated
vendored
14
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_unix.go
generated
vendored
@ -27,6 +27,7 @@ import (
|
|||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/contrib/nvidia"
|
"github.com/containerd/containerd/contrib/nvidia"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
@ -73,10 +74,21 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
opts = append(opts, oci.WithRootFSPath(rootfs))
|
opts = append(opts, oci.WithRootFSPath(rootfs))
|
||||||
} else {
|
} else {
|
||||||
snapshotter := context.String("snapshotter")
|
snapshotter := context.String("snapshotter")
|
||||||
image, err := client.GetImage(ctx, ref)
|
var image containerd.Image
|
||||||
|
i, err := client.ImageService().Get(ctx, ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if ps := context.String("platform"); ps != "" {
|
||||||
|
platform, err := platforms.Parse(ps)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
image = containerd.NewImageWithPlatform(client, i, platforms.Only(platform))
|
||||||
|
} else {
|
||||||
|
image = containerd.NewImage(client, i)
|
||||||
|
}
|
||||||
|
|
||||||
unpacked, err := image.IsUnpacked(ctx, snapshotter)
|
unpacked, err := image.IsUnpacked(ctx, snapshotter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
33
vendor/github.com/containerd/containerd/cmd/ctr/commands/shim/shim.go
generated
vendored
33
vendor/github.com/containerd/containerd/cmd/ctr/commands/shim/shim.go
generated
vendored
@ -23,9 +23,12 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
|
"github.com/containerd/containerd/namespaces"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/shim"
|
||||||
"github.com/containerd/containerd/runtime/v2/task"
|
"github.com/containerd/containerd/runtime/v2/task"
|
||||||
"github.com/containerd/ttrpc"
|
"github.com/containerd/ttrpc"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
@ -61,8 +64,8 @@ var Command = cli.Command{
|
|||||||
Usage: "interact with a shim directly",
|
Usage: "interact with a shim directly",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "socket",
|
Name: "id",
|
||||||
Usage: "socket on which to connect to the shim",
|
Usage: "container id",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
@ -116,7 +119,7 @@ var stateCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
r, err := service.State(gocontext.Background(), &task.StateRequest{
|
r, err := service.State(gocontext.Background(), &task.StateRequest{
|
||||||
ID: context.Args().First(),
|
ID: context.GlobalString("id"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -226,20 +229,30 @@ var execCommand = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getTaskService(context *cli.Context) (task.TaskService, error) {
|
func getTaskService(context *cli.Context) (task.TaskService, error) {
|
||||||
bindSocket := context.GlobalString("socket")
|
id := context.GlobalString("id")
|
||||||
if bindSocket == "" {
|
if id == "" {
|
||||||
return nil, errors.New("socket path must be specified")
|
return nil, fmt.Errorf("container id must be specified")
|
||||||
}
|
}
|
||||||
|
ns := context.GlobalString("namespace")
|
||||||
|
|
||||||
conn, err := net.Dial("unix", "\x00"+bindSocket)
|
// /containerd-shim/ns/id/shim.sock is the old way to generate shim socket,
|
||||||
if err != nil {
|
// compatible it
|
||||||
return nil, err
|
s1 := filepath.Join(string(filepath.Separator), "containerd-shim", ns, id, "shim.sock")
|
||||||
}
|
// this should not error, ctr always get a default ns
|
||||||
|
ctx := namespaces.WithNamespace(gocontext.Background(), ns)
|
||||||
|
s2, _ := shim.SocketAddress(ctx, id)
|
||||||
|
|
||||||
|
for _, socket := range []string{s1, s2} {
|
||||||
|
conn, err := net.Dial("unix", "\x00"+socket)
|
||||||
|
if err == nil {
|
||||||
client := ttrpc.NewClient(conn)
|
client := ttrpc.NewClient(conn)
|
||||||
|
|
||||||
// TODO(stevvooe): This actually leaks the connection. We were leaking it
|
// TODO(stevvooe): This actually leaks the connection. We were leaking it
|
||||||
// before, so may not be a huge deal.
|
// before, so may not be a huge deal.
|
||||||
|
|
||||||
return task.NewTaskClient(client), nil
|
return task.NewTaskClient(client), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, fmt.Errorf("fail to connect to container %s's shim", id)
|
||||||
}
|
}
|
||||||
|
22
vendor/github.com/containerd/containerd/container.go
generated
vendored
22
vendor/github.com/containerd/containerd/container.go
generated
vendored
@ -49,7 +49,7 @@ type Container interface {
|
|||||||
// ID identifies the container
|
// ID identifies the container
|
||||||
ID() string
|
ID() string
|
||||||
// Info returns the underlying container record type
|
// Info returns the underlying container record type
|
||||||
Info(context.Context) (containers.Container, error)
|
Info(context.Context, ...InfoOpts) (containers.Container, error)
|
||||||
// Delete removes the container
|
// Delete removes the container
|
||||||
Delete(context.Context, ...DeleteOpts) error
|
Delete(context.Context, ...DeleteOpts) error
|
||||||
// NewTask creates a new task based on the container metadata
|
// NewTask creates a new task based on the container metadata
|
||||||
@ -82,6 +82,7 @@ func containerFromRecord(client *Client, c containers.Container) *container {
|
|||||||
return &container{
|
return &container{
|
||||||
client: client,
|
client: client,
|
||||||
id: c.ID,
|
id: c.ID,
|
||||||
|
metadata: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +91,7 @@ var _ = (Container)(&container{})
|
|||||||
type container struct {
|
type container struct {
|
||||||
client *Client
|
client *Client
|
||||||
id string
|
id string
|
||||||
|
metadata containers.Container
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the container's unique id
|
// ID returns the container's unique id
|
||||||
@ -97,8 +99,22 @@ func (c *container) ID() string {
|
|||||||
return c.id
|
return c.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Info(ctx context.Context) (containers.Container, error) {
|
func (c *container) Info(ctx context.Context, opts ...InfoOpts) (containers.Container, error) {
|
||||||
return c.get(ctx)
|
i := &InfoConfig{
|
||||||
|
// default to refreshing the container's local metadata
|
||||||
|
Refresh: true,
|
||||||
|
}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(i)
|
||||||
|
}
|
||||||
|
if i.Refresh {
|
||||||
|
metadata, err := c.get(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return c.metadata, err
|
||||||
|
}
|
||||||
|
c.metadata = metadata
|
||||||
|
}
|
||||||
|
return c.metadata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *container) Extensions(ctx context.Context) (map[string]prototypes.Any, error) {
|
func (c *container) Extensions(ctx context.Context) (map[string]prototypes.Any, error) {
|
||||||
|
16
vendor/github.com/containerd/containerd/container_opts.go
generated
vendored
16
vendor/github.com/containerd/containerd/container_opts.go
generated
vendored
@ -41,6 +41,15 @@ type NewContainerOpts func(ctx context.Context, client *Client, c *containers.Co
|
|||||||
// UpdateContainerOpts allows the caller to set additional options when updating a container
|
// UpdateContainerOpts allows the caller to set additional options when updating a container
|
||||||
type UpdateContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error
|
type UpdateContainerOpts func(ctx context.Context, client *Client, c *containers.Container) error
|
||||||
|
|
||||||
|
// InfoOpts controls how container metadata is fetched and returned
|
||||||
|
type InfoOpts func(*InfoConfig)
|
||||||
|
|
||||||
|
// InfoConfig specifies how container metadata is fetched
|
||||||
|
type InfoConfig struct {
|
||||||
|
// Refresh will to a fetch of the latest container metadata
|
||||||
|
Refresh bool
|
||||||
|
}
|
||||||
|
|
||||||
// WithRuntime allows a user to specify the runtime name and additional options that should
|
// WithRuntime allows a user to specify the runtime name and additional options that should
|
||||||
// be used to create tasks for the container
|
// be used to create tasks for the container
|
||||||
func WithRuntime(name string, options interface{}) NewContainerOpts {
|
func WithRuntime(name string, options interface{}) NewContainerOpts {
|
||||||
@ -123,7 +132,7 @@ func WithSnapshot(id string) NewContainerOpts {
|
|||||||
// root filesystem in read-write mode
|
// root filesystem in read-write mode
|
||||||
func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts {
|
||||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
diffIDs, err := i.RootFS(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -235,3 +244,8 @@ func WithSpec(s *oci.Spec, opts ...oci.SpecOpts) NewContainerOpts {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithoutRefreshedMetadata will use the current metadata attached to the container object
|
||||||
|
func WithoutRefreshedMetadata(i *InfoConfig) {
|
||||||
|
i.Refresh = false
|
||||||
|
}
|
||||||
|
9
vendor/github.com/containerd/containerd/content/helpers.go
generated
vendored
9
vendor/github.com/containerd/containerd/content/helpers.go
generated
vendored
@ -55,7 +55,14 @@ func ReadBlob(ctx context.Context, provider Provider, desc ocispec.Descriptor) (
|
|||||||
|
|
||||||
p := make([]byte, ra.Size())
|
p := make([]byte, ra.Size())
|
||||||
|
|
||||||
_, err = ra.ReadAt(p, 0)
|
n, err := ra.ReadAt(p, 0)
|
||||||
|
if err == io.EOF {
|
||||||
|
if int64(n) != ra.Size() {
|
||||||
|
err = io.ErrUnexpectedEOF
|
||||||
|
} else {
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
return p, err
|
return p, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
vendor/github.com/containerd/containerd/content/local/store.go
generated
vendored
18
vendor/github.com/containerd/containerd/content/local/store.go
generated
vendored
@ -35,7 +35,6 @@ import (
|
|||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/containerd/continuity"
|
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -661,6 +660,19 @@ func writeTimestampFile(p string, t time.Time) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return atomicWrite(p, b, 0666)
|
||||||
return continuity.AtomicWriteFile(p, b, 0666)
|
}
|
||||||
|
|
||||||
|
func atomicWrite(path string, data []byte, mode os.FileMode) error {
|
||||||
|
tmp := fmt.Sprintf("%s.tmp", path)
|
||||||
|
f, err := os.OpenFile(tmp, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, mode)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "create tmp file")
|
||||||
|
}
|
||||||
|
_, err = f.Write(data)
|
||||||
|
f.Close()
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "write atomic data")
|
||||||
|
}
|
||||||
|
return os.Rename(tmp, path)
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/containerd/containerd/content/local/writer.go
generated
vendored
5
vendor/github.com/containerd/containerd/content/local/writer.go
generated
vendored
@ -74,6 +74,9 @@ func (w *writer) Write(p []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||||
|
// Ensure even on error the writer is fully closed
|
||||||
|
defer unlock(w.ref)
|
||||||
|
|
||||||
var base content.Info
|
var base content.Info
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(&base); err != nil {
|
if err := opt(&base); err != nil {
|
||||||
@ -81,8 +84,6 @@ func (w *writer) Commit(ctx context.Context, size int64, expected digest.Digest,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure even on error the writer is fully closed
|
|
||||||
defer unlock(w.ref)
|
|
||||||
fp := w.fp
|
fp := w.fp
|
||||||
w.fp = nil
|
w.fp = nil
|
||||||
|
|
||||||
|
7
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go
generated
vendored
7
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp_default.go
generated
vendored
@ -20,7 +20,8 @@ package seccomp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"syscall"
|
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
|
||||||
"github.com/opencontainers/runtime-spec/specs-go"
|
"github.com/opencontainers/runtime-spec/specs-go"
|
||||||
)
|
)
|
||||||
@ -555,7 +556,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
|||||||
Args: []specs.LinuxSeccompArg{
|
Args: []specs.LinuxSeccompArg{
|
||||||
{
|
{
|
||||||
Index: 1,
|
Index: 1,
|
||||||
Value: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET,
|
Value: unix.CLONE_NEWNS | unix.CLONE_NEWUTS | unix.CLONE_NEWIPC | unix.CLONE_NEWUSER | unix.CLONE_NEWPID | unix.CLONE_NEWNET | unix.CLONE_NEWCGROUP,
|
||||||
ValueTwo: 0,
|
ValueTwo: 0,
|
||||||
Op: specs.OpMaskedEqual,
|
Op: specs.OpMaskedEqual,
|
||||||
},
|
},
|
||||||
@ -570,7 +571,7 @@ func DefaultProfile(sp *specs.Spec) *specs.LinuxSeccomp {
|
|||||||
Args: []specs.LinuxSeccompArg{
|
Args: []specs.LinuxSeccompArg{
|
||||||
{
|
{
|
||||||
Index: 0,
|
Index: 0,
|
||||||
Value: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET,
|
Value: unix.CLONE_NEWNS | unix.CLONE_NEWUTS | unix.CLONE_NEWIPC | unix.CLONE_NEWUSER | unix.CLONE_NEWPID | unix.CLONE_NEWNET | unix.CLONE_NEWCGROUP,
|
||||||
ValueTwo: 0,
|
ValueTwo: 0,
|
||||||
Op: specs.OpMaskedEqual,
|
Op: specs.OpMaskedEqual,
|
||||||
},
|
},
|
||||||
|
4
vendor/github.com/containerd/containerd/defaults/defaults.go
generated
vendored
4
vendor/github.com/containerd/containerd/defaults/defaults.go
generated
vendored
@ -23,10 +23,10 @@ const (
|
|||||||
// DefaultMaxSendMsgSize defines the default maximum message size for
|
// DefaultMaxSendMsgSize defines the default maximum message size for
|
||||||
// sending protobufs passed over the GRPC API.
|
// sending protobufs passed over the GRPC API.
|
||||||
DefaultMaxSendMsgSize = 16 << 20
|
DefaultMaxSendMsgSize = 16 << 20
|
||||||
// DefaultRuntimeNSLabel defines the namespace label to check for
|
// DefaultRuntimeNSLabel defines the namespace label to check for the
|
||||||
// default runtime
|
// default runtime
|
||||||
DefaultRuntimeNSLabel = "containerd.io/defaults/runtime"
|
DefaultRuntimeNSLabel = "containerd.io/defaults/runtime"
|
||||||
// DefaultSnapshotterNSLabel defines the namespances label to check for
|
// DefaultSnapshotterNSLabel defines the namespace label to check for the
|
||||||
// default snapshotter
|
// default snapshotter
|
||||||
DefaultSnapshotterNSLabel = "containerd.io/defaults/snapshotter"
|
DefaultSnapshotterNSLabel = "containerd.io/defaults/snapshotter"
|
||||||
)
|
)
|
||||||
|
10
vendor/github.com/containerd/containerd/diff.go
generated
vendored
10
vendor/github.com/containerd/containerd/diff.go
generated
vendored
@ -45,9 +45,15 @@ type diffRemote struct {
|
|||||||
client diffapi.DiffClient
|
client diffapi.DiffClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *diffRemote) Apply(ctx context.Context, diff ocispec.Descriptor, mounts []mount.Mount) (ocispec.Descriptor, error) {
|
func (r *diffRemote) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt) (ocispec.Descriptor, error) {
|
||||||
|
var config diff.ApplyConfig
|
||||||
|
for _, opt := range opts {
|
||||||
|
if err := opt(&config); err != nil {
|
||||||
|
return ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
req := &diffapi.ApplyRequest{
|
req := &diffapi.ApplyRequest{
|
||||||
Diff: fromDescriptor(diff),
|
Diff: fromDescriptor(desc),
|
||||||
Mounts: fromMounts(mounts),
|
Mounts: fromMounts(mounts),
|
||||||
}
|
}
|
||||||
resp, err := r.client.Apply(ctx, req)
|
resp, err := r.client.Apply(ctx, req)
|
||||||
|
2
vendor/github.com/containerd/containerd/diff/apply/apply.go
generated
vendored
2
vendor/github.com/containerd/containerd/diff/apply/apply.go
generated
vendored
@ -53,7 +53,7 @@ var emptyDesc = ocispec.Descriptor{}
|
|||||||
// Apply applies the content associated with the provided digests onto the
|
// Apply applies the content associated with the provided digests onto the
|
||||||
// provided mounts. Archive content will be extracted and decompressed if
|
// provided mounts. Archive content will be extracted and decompressed if
|
||||||
// necessary.
|
// necessary.
|
||||||
func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount) (d ocispec.Descriptor, err error) {
|
func (s *fsApplier) Apply(ctx context.Context, desc ocispec.Descriptor, mounts []mount.Mount, opts ...diff.ApplyOpt) (d ocispec.Descriptor, err error) {
|
||||||
t1 := time.Now()
|
t1 := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
9
vendor/github.com/containerd/containerd/diff/diff.go
generated
vendored
9
vendor/github.com/containerd/containerd/diff/diff.go
generated
vendored
@ -51,6 +51,13 @@ type Comparer interface {
|
|||||||
Compare(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error)
|
Compare(ctx context.Context, lower, upper []mount.Mount, opts ...Opt) (ocispec.Descriptor, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ApplyConfig is used to hold parameters needed for a apply operation
|
||||||
|
type ApplyConfig struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ApplyOpt is used to configure an Apply operation
|
||||||
|
type ApplyOpt func(*ApplyConfig) error
|
||||||
|
|
||||||
// Applier allows applying diffs between mounts
|
// Applier allows applying diffs between mounts
|
||||||
type Applier interface {
|
type Applier interface {
|
||||||
// Apply applies the content referred to by the given descriptor to
|
// Apply applies the content referred to by the given descriptor to
|
||||||
@ -58,7 +65,7 @@ type Applier interface {
|
|||||||
// implementation and content descriptor. For example, in the common
|
// implementation and content descriptor. For example, in the common
|
||||||
// case the descriptor is a file system difference in tar format,
|
// case the descriptor is a file system difference in tar format,
|
||||||
// that tar would be applied on top of the mounts.
|
// that tar would be applied on top of the mounts.
|
||||||
Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount) (ocispec.Descriptor, error)
|
Apply(ctx context.Context, desc ocispec.Descriptor, mount []mount.Mount, opts ...ApplyOpt) (ocispec.Descriptor, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithMediaType sets the media type to use for creating the diff, without
|
// WithMediaType sets the media type to use for creating the diff, without
|
||||||
|
5
vendor/github.com/containerd/containerd/diff/walking/differ.go
generated
vendored
5
vendor/github.com/containerd/containerd/diff/walking/differ.go
generated
vendored
@ -106,14 +106,15 @@ func (s *walkingDiff) Compare(ctx context.Context, lower, upper []mount.Mount, o
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if !newReference {
|
if !newReference {
|
||||||
if err := cw.Truncate(0); err != nil {
|
if err = cw.Truncate(0); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if isCompressed {
|
if isCompressed {
|
||||||
dgstr := digest.SHA256.Digester()
|
dgstr := digest.SHA256.Digester()
|
||||||
compressed, err := compression.CompressStream(cw, compression.Gzip)
|
var compressed io.WriteCloser
|
||||||
|
compressed, err = compression.CompressStream(cw, compression.Gzip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get compressed stream")
|
return errors.Wrap(err, "failed to get compressed stream")
|
||||||
}
|
}
|
||||||
|
17
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
17
vendor/github.com/containerd/containerd/errdefs/errors.go
generated
vendored
@ -26,7 +26,11 @@
|
|||||||
// client-side errors to the correct types.
|
// client-side errors to the correct types.
|
||||||
package errdefs
|
package errdefs
|
||||||
|
|
||||||
import "github.com/pkg/errors"
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
// Definitions of common error types used throughout containerd. All containerd
|
// Definitions of common error types used throughout containerd. All containerd
|
||||||
// errors returned by most packages will map into one of these errors classes.
|
// errors returned by most packages will map into one of these errors classes.
|
||||||
@ -76,3 +80,14 @@ func IsUnavailable(err error) bool {
|
|||||||
func IsNotImplemented(err error) bool {
|
func IsNotImplemented(err error) bool {
|
||||||
return errors.Cause(err) == ErrNotImplemented
|
return errors.Cause(err) == ErrNotImplemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsCanceled returns true if the error is due to `context.Canceled`.
|
||||||
|
func IsCanceled(err error) bool {
|
||||||
|
return errors.Cause(err) == context.Canceled
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsDeadlineExceeded returns true if the error is due to
|
||||||
|
// `context.DeadlineExceeded`.
|
||||||
|
func IsDeadlineExceeded(err error) bool {
|
||||||
|
return errors.Cause(err) == context.DeadlineExceeded
|
||||||
|
}
|
||||||
|
9
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
9
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
@ -17,6 +17,7 @@
|
|||||||
package errdefs
|
package errdefs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -55,6 +56,10 @@ func ToGRPC(err error) error {
|
|||||||
return status.Errorf(codes.Unavailable, err.Error())
|
return status.Errorf(codes.Unavailable, err.Error())
|
||||||
case IsNotImplemented(err):
|
case IsNotImplemented(err):
|
||||||
return status.Errorf(codes.Unimplemented, err.Error())
|
return status.Errorf(codes.Unimplemented, err.Error())
|
||||||
|
case IsCanceled(err):
|
||||||
|
return status.Errorf(codes.Canceled, err.Error())
|
||||||
|
case IsDeadlineExceeded(err):
|
||||||
|
return status.Errorf(codes.DeadlineExceeded, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@ -89,6 +94,10 @@ func FromGRPC(err error) error {
|
|||||||
cls = ErrFailedPrecondition
|
cls = ErrFailedPrecondition
|
||||||
case codes.Unimplemented:
|
case codes.Unimplemented:
|
||||||
cls = ErrNotImplemented
|
cls = ErrNotImplemented
|
||||||
|
case codes.Canceled:
|
||||||
|
cls = context.Canceled
|
||||||
|
case codes.DeadlineExceeded:
|
||||||
|
cls = context.DeadlineExceeded
|
||||||
default:
|
default:
|
||||||
cls = ErrUnknown
|
cls = ErrUnknown
|
||||||
}
|
}
|
||||||
|
26
vendor/github.com/containerd/containerd/export.go
generated
vendored
26
vendor/github.com/containerd/containerd/export.go
generated
vendored
@ -20,26 +20,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/containerd/containerd/images/oci"
|
"github.com/containerd/containerd/images/archive"
|
||||||
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Export exports an image to a Tar stream.
|
// Export exports images to a Tar stream.
|
||||||
// OCI format is used by default.
|
// The tar archive is in OCI format with a Docker compatible manifest
|
||||||
// It is up to caller to put "org.opencontainers.image.ref.name" annotation to desc.
|
// when a single target platform is given.
|
||||||
// TODO(AkihiroSuda): support exporting multiple descriptors at once to a single archive stream.
|
func (c *Client) Export(ctx context.Context, w io.Writer, opts ...archive.ExportOpt) error {
|
||||||
func (c *Client) Export(ctx context.Context, desc ocispec.Descriptor, opts ...oci.V1ExporterOpt) (io.ReadCloser, error) {
|
return archive.Export(ctx, c.ContentStore(), w, opts...)
|
||||||
|
|
||||||
exporter, err := oci.ResolveV1ExportOpt(opts...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
go func() {
|
|
||||||
pw.CloseWithError(errors.Wrap(exporter.Export(ctx, c.ContentStore(), desc, pw), "export failed"))
|
|
||||||
}()
|
|
||||||
return pr, nil
|
|
||||||
}
|
}
|
||||||
|
23
vendor/github.com/containerd/containerd/images/annotations.go
generated
vendored
Normal file
23
vendor/github.com/containerd/containerd/images/annotations.go
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package images
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AnnotationImageName is an annotation on a Descriptor in an index.json
|
||||||
|
// containing the `Name` value as used by an `Image` struct
|
||||||
|
AnnotationImageName = "io.containerd.image.name"
|
||||||
|
)
|
470
vendor/github.com/containerd/containerd/images/archive/exporter.go
generated
vendored
Normal file
470
vendor/github.com/containerd/containerd/images/archive/exporter.go
generated
vendored
Normal file
@ -0,0 +1,470 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package archive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"archive/tar"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/content"
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
|
digest "github.com/opencontainers/go-digest"
|
||||||
|
ocispecs "github.com/opencontainers/image-spec/specs-go"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type exportOptions struct {
|
||||||
|
manifests []ocispec.Descriptor
|
||||||
|
platform platforms.MatchComparer
|
||||||
|
allPlatforms bool
|
||||||
|
skipDockerManifest bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportOpt defines options for configuring exported descriptors
|
||||||
|
type ExportOpt func(context.Context, *exportOptions) error
|
||||||
|
|
||||||
|
// WithPlatform defines the platform to require manifest lists have
|
||||||
|
// not exporting all platforms.
|
||||||
|
// Additionally, platform is used to resolve image configs for
|
||||||
|
// Docker v1.1, v1.2 format compatibility.
|
||||||
|
func WithPlatform(p platforms.MatchComparer) ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
o.platform = p
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAllPlatforms exports all manifests from a manifest list.
|
||||||
|
// Missing content will fail the export.
|
||||||
|
func WithAllPlatforms() ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
o.allPlatforms = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithSkipDockerManifest skips creation of the Docker compatible
|
||||||
|
// manifest.json file.
|
||||||
|
func WithSkipDockerManifest() ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
o.skipDockerManifest = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithImage adds the provided images to the exported archive.
|
||||||
|
func WithImage(is images.Store, name string) ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
img, err := is.Get(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
img.Target.Annotations = addNameAnnotation(name, img.Target.Annotations)
|
||||||
|
o.manifests = append(o.manifests, img.Target)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithManifest adds a manifest to the exported archive.
|
||||||
|
// It is up to caller to put name annotation to on the manifest
|
||||||
|
// descriptor if needed.
|
||||||
|
func WithManifest(manifest ocispec.Descriptor) ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
o.manifests = append(o.manifests, manifest)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithNamedManifest adds a manifest to the exported archive
|
||||||
|
// with the provided names.
|
||||||
|
func WithNamedManifest(manifest ocispec.Descriptor, names ...string) ExportOpt {
|
||||||
|
return func(ctx context.Context, o *exportOptions) error {
|
||||||
|
for _, name := range names {
|
||||||
|
manifest.Annotations = addNameAnnotation(name, manifest.Annotations)
|
||||||
|
o.manifests = append(o.manifests, manifest)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func addNameAnnotation(name string, annotations map[string]string) map[string]string {
|
||||||
|
if annotations == nil {
|
||||||
|
annotations = map[string]string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
annotations[images.AnnotationImageName] = name
|
||||||
|
annotations[ocispec.AnnotationRefName] = ociReferenceName(name)
|
||||||
|
|
||||||
|
return annotations
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export implements Exporter.
|
||||||
|
func Export(ctx context.Context, store content.Provider, writer io.Writer, opts ...ExportOpt) error {
|
||||||
|
var eo exportOptions
|
||||||
|
for _, opt := range opts {
|
||||||
|
if err := opt(ctx, &eo); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
records := []tarRecord{
|
||||||
|
ociLayoutFile(""),
|
||||||
|
ociIndexRecord(eo.manifests),
|
||||||
|
}
|
||||||
|
|
||||||
|
algorithms := map[string]struct{}{}
|
||||||
|
dManifests := map[digest.Digest]*exportManifest{}
|
||||||
|
resolvedIndex := map[digest.Digest]digest.Digest{}
|
||||||
|
for _, desc := range eo.manifests {
|
||||||
|
switch desc.MediaType {
|
||||||
|
case images.MediaTypeDockerSchema2Manifest, ocispec.MediaTypeImageManifest:
|
||||||
|
mt, ok := dManifests[desc.Digest]
|
||||||
|
if !ok {
|
||||||
|
// TODO(containerd): Skip if already added
|
||||||
|
r, err := getRecords(ctx, store, desc, algorithms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
records = append(records, r...)
|
||||||
|
|
||||||
|
mt = &exportManifest{
|
||||||
|
manifest: desc,
|
||||||
|
}
|
||||||
|
dManifests[desc.Digest] = mt
|
||||||
|
}
|
||||||
|
|
||||||
|
name := desc.Annotations[images.AnnotationImageName]
|
||||||
|
if name != "" && !eo.skipDockerManifest {
|
||||||
|
mt.names = append(mt.names, name)
|
||||||
|
}
|
||||||
|
case images.MediaTypeDockerSchema2ManifestList, ocispec.MediaTypeImageIndex:
|
||||||
|
d, ok := resolvedIndex[desc.Digest]
|
||||||
|
if !ok {
|
||||||
|
records = append(records, blobRecord(store, desc))
|
||||||
|
|
||||||
|
p, err := content.ReadBlob(ctx, store, desc)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var index ocispec.Index
|
||||||
|
if err := json.Unmarshal(p, &index); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var manifests []ocispec.Descriptor
|
||||||
|
for _, m := range index.Manifests {
|
||||||
|
if eo.platform != nil {
|
||||||
|
if m.Platform == nil || eo.platform.Match(*m.Platform) {
|
||||||
|
manifests = append(manifests, m)
|
||||||
|
} else if !eo.allPlatforms {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
r, err := getRecords(ctx, store, m, algorithms)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
records = append(records, r...)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !eo.skipDockerManifest {
|
||||||
|
if len(manifests) >= 1 {
|
||||||
|
if len(manifests) > 1 {
|
||||||
|
sort.SliceStable(manifests, func(i, j int) bool {
|
||||||
|
if manifests[i].Platform == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if manifests[j].Platform == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return eo.platform.Less(*manifests[i].Platform, *manifests[j].Platform)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
d = manifests[0].Digest
|
||||||
|
dManifests[d] = &exportManifest{
|
||||||
|
manifest: manifests[0],
|
||||||
|
}
|
||||||
|
} else if eo.platform != nil {
|
||||||
|
return errors.Wrap(errdefs.ErrNotFound, "no manifest found for platform")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolvedIndex[desc.Digest] = d
|
||||||
|
}
|
||||||
|
if d != "" {
|
||||||
|
if name := desc.Annotations[images.AnnotationImageName]; name != "" {
|
||||||
|
mt := dManifests[d]
|
||||||
|
mt.names = append(mt.names, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return errors.Wrap(errdefs.ErrInvalidArgument, "only manifests may be exported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(dManifests) > 0 {
|
||||||
|
tr, err := manifestsRecord(ctx, store, dManifests)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unable to create manifests file")
|
||||||
|
}
|
||||||
|
|
||||||
|
records = append(records, tr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(algorithms) > 0 {
|
||||||
|
records = append(records, directoryRecord("blobs/", 0755))
|
||||||
|
for alg := range algorithms {
|
||||||
|
records = append(records, directoryRecord("blobs/"+alg+"/", 0755))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tw := tar.NewWriter(writer)
|
||||||
|
defer tw.Close()
|
||||||
|
return writeTar(ctx, tw, records)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRecords(ctx context.Context, store content.Provider, desc ocispec.Descriptor, algorithms map[string]struct{}) ([]tarRecord, error) {
|
||||||
|
var records []tarRecord
|
||||||
|
exportHandler := func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
||||||
|
records = append(records, blobRecord(store, desc))
|
||||||
|
algorithms[desc.Digest.Algorithm().String()] = struct{}{}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
childrenHandler := images.ChildrenHandler(store)
|
||||||
|
|
||||||
|
handlers := images.Handlers(
|
||||||
|
childrenHandler,
|
||||||
|
images.HandlerFunc(exportHandler),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Walk sequentially since the number of fetchs is likely one and doing in
|
||||||
|
// parallel requires locking the export handler
|
||||||
|
if err := images.Walk(ctx, handlers, desc); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return records, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type tarRecord struct {
|
||||||
|
Header *tar.Header
|
||||||
|
CopyTo func(context.Context, io.Writer) (int64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func blobRecord(cs content.Provider, desc ocispec.Descriptor) tarRecord {
|
||||||
|
path := path.Join("blobs", desc.Digest.Algorithm().String(), desc.Digest.Encoded())
|
||||||
|
return tarRecord{
|
||||||
|
Header: &tar.Header{
|
||||||
|
Name: path,
|
||||||
|
Mode: 0444,
|
||||||
|
Size: desc.Size,
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
},
|
||||||
|
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
||||||
|
r, err := cs.ReaderAt(ctx, desc)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "failed to get reader")
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
|
||||||
|
// Verify digest
|
||||||
|
dgstr := desc.Digest.Algorithm().Digester()
|
||||||
|
|
||||||
|
n, err := io.Copy(io.MultiWriter(w, dgstr.Hash()), content.NewReader(r))
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.Wrap(err, "failed to copy to tar")
|
||||||
|
}
|
||||||
|
if dgstr.Digest() != desc.Digest {
|
||||||
|
return 0, errors.Errorf("unexpected digest %s copied", dgstr.Digest())
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func directoryRecord(name string, mode int64) tarRecord {
|
||||||
|
return tarRecord{
|
||||||
|
Header: &tar.Header{
|
||||||
|
Name: name,
|
||||||
|
Mode: mode,
|
||||||
|
Typeflag: tar.TypeDir,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ociLayoutFile(version string) tarRecord {
|
||||||
|
if version == "" {
|
||||||
|
version = ocispec.ImageLayoutVersion
|
||||||
|
}
|
||||||
|
layout := ocispec.ImageLayout{
|
||||||
|
Version: version,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(layout)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tarRecord{
|
||||||
|
Header: &tar.Header{
|
||||||
|
Name: ocispec.ImageLayoutFile,
|
||||||
|
Mode: 0444,
|
||||||
|
Size: int64(len(b)),
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
},
|
||||||
|
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
||||||
|
n, err := w.Write(b)
|
||||||
|
return int64(n), err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func ociIndexRecord(manifests []ocispec.Descriptor) tarRecord {
|
||||||
|
index := ocispec.Index{
|
||||||
|
Versioned: ocispecs.Versioned{
|
||||||
|
SchemaVersion: 2,
|
||||||
|
},
|
||||||
|
Manifests: manifests,
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(index)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tarRecord{
|
||||||
|
Header: &tar.Header{
|
||||||
|
Name: "index.json",
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(b)),
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
},
|
||||||
|
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
||||||
|
n, err := w.Write(b)
|
||||||
|
return int64(n), err
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type exportManifest struct {
|
||||||
|
manifest ocispec.Descriptor
|
||||||
|
names []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func manifestsRecord(ctx context.Context, store content.Provider, manifests map[digest.Digest]*exportManifest) (tarRecord, error) {
|
||||||
|
mfsts := make([]struct {
|
||||||
|
Config string
|
||||||
|
RepoTags []string
|
||||||
|
Layers []string
|
||||||
|
}, len(manifests))
|
||||||
|
|
||||||
|
var i int
|
||||||
|
for _, m := range manifests {
|
||||||
|
p, err := content.ReadBlob(ctx, store, m.manifest)
|
||||||
|
if err != nil {
|
||||||
|
return tarRecord{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var manifest ocispec.Manifest
|
||||||
|
if err := json.Unmarshal(p, &manifest); err != nil {
|
||||||
|
return tarRecord{}, err
|
||||||
|
}
|
||||||
|
if err := manifest.Config.Digest.Validate(); err != nil {
|
||||||
|
return tarRecord{}, errors.Wrapf(err, "invalid manifest %q", m.manifest.Digest)
|
||||||
|
}
|
||||||
|
|
||||||
|
dgst := manifest.Config.Digest
|
||||||
|
mfsts[i].Config = path.Join("blobs", dgst.Algorithm().String(), dgst.Encoded())
|
||||||
|
for _, l := range manifest.Layers {
|
||||||
|
path := path.Join("blobs", l.Digest.Algorithm().String(), l.Digest.Encoded())
|
||||||
|
mfsts[i].Layers = append(mfsts[i].Layers, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, name := range m.names {
|
||||||
|
nname, err := familiarizeReference(name)
|
||||||
|
if err != nil {
|
||||||
|
return tarRecord{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mfsts[i].RepoTags = append(mfsts[i].RepoTags, nname)
|
||||||
|
}
|
||||||
|
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(mfsts)
|
||||||
|
if err != nil {
|
||||||
|
return tarRecord{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tarRecord{
|
||||||
|
Header: &tar.Header{
|
||||||
|
Name: "manifest.json",
|
||||||
|
Mode: 0644,
|
||||||
|
Size: int64(len(b)),
|
||||||
|
Typeflag: tar.TypeReg,
|
||||||
|
},
|
||||||
|
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
||||||
|
n, err := w.Write(b)
|
||||||
|
return int64(n), err
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTar(ctx context.Context, tw *tar.Writer, records []tarRecord) error {
|
||||||
|
sort.Slice(records, func(i, j int) bool {
|
||||||
|
return records[i].Header.Name < records[j].Header.Name
|
||||||
|
})
|
||||||
|
|
||||||
|
var last string
|
||||||
|
for _, record := range records {
|
||||||
|
if record.Header.Name == last {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
last = record.Header.Name
|
||||||
|
if err := tw.WriteHeader(record.Header); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if record.CopyTo != nil {
|
||||||
|
n, err := record.CopyTo(ctx, tw)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if n != record.Header.Size {
|
||||||
|
return errors.Errorf("unexpected copy size for %s", record.Header.Name)
|
||||||
|
}
|
||||||
|
} else if record.Header.Size > 0 {
|
||||||
|
return errors.Errorf("no content to write to record with non-zero size for %s", record.Header.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
8
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
8
vendor/github.com/containerd/containerd/images/archive/importer.go
generated
vendored
@ -181,7 +181,8 @@ func ImportIndex(ctx context.Context, store content.Store, reader io.Reader) (oc
|
|||||||
}
|
}
|
||||||
|
|
||||||
mfstdesc.Annotations = map[string]string{
|
mfstdesc.Annotations = map[string]string{
|
||||||
ocispec.AnnotationRefName: normalized,
|
images.AnnotationImageName: normalized,
|
||||||
|
ocispec.AnnotationRefName: ociReferenceName(normalized),
|
||||||
}
|
}
|
||||||
|
|
||||||
idx.Manifests = append(idx.Manifests, mfstdesc)
|
idx.Manifests = append(idx.Manifests, mfstdesc)
|
||||||
@ -197,10 +198,7 @@ func onUntarJSON(r io.Reader, j interface{}) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(b, j); err != nil {
|
return json.Unmarshal(b, j)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) {
|
func onUntarBlob(ctx context.Context, r io.Reader, store content.Ingester, size int64, ref string) (digest.Digest, error) {
|
||||||
|
30
vendor/github.com/containerd/containerd/images/archive/reference.go
generated
vendored
30
vendor/github.com/containerd/containerd/images/archive/reference.go
generated
vendored
@ -19,7 +19,8 @@ package archive
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/distribution/reference"
|
"github.com/containerd/containerd/reference"
|
||||||
|
distref "github.com/docker/distribution/reference"
|
||||||
"github.com/opencontainers/go-digest"
|
"github.com/opencontainers/go-digest"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -69,7 +70,7 @@ func isImagePrefix(s, prefix string) bool {
|
|||||||
|
|
||||||
func normalizeReference(ref string) (string, error) {
|
func normalizeReference(ref string) (string, error) {
|
||||||
// TODO: Replace this function to not depend on reference package
|
// TODO: Replace this function to not depend on reference package
|
||||||
normalized, err := reference.ParseDockerRef(ref)
|
normalized, err := distref.ParseDockerRef(ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "normalize image ref %q", ref)
|
return "", errors.Wrapf(err, "normalize image ref %q", ref)
|
||||||
}
|
}
|
||||||
@ -77,6 +78,31 @@ func normalizeReference(ref string) (string, error) {
|
|||||||
return normalized.String(), nil
|
return normalized.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func familiarizeReference(ref string) (string, error) {
|
||||||
|
named, err := distref.ParseNormalizedNamed(ref)
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrapf(err, "failed to parse %q", ref)
|
||||||
|
}
|
||||||
|
named = distref.TagNameOnly(named)
|
||||||
|
|
||||||
|
return distref.FamiliarString(named), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ociReferenceName(name string) string {
|
||||||
|
// OCI defines the reference name as only a tag excluding the
|
||||||
|
// repository. The containerd annotation contains the full image name
|
||||||
|
// since the tag is insufficent for correctly naming and referring to an
|
||||||
|
// image
|
||||||
|
var ociRef string
|
||||||
|
if spec, err := reference.Parse(name); err == nil {
|
||||||
|
ociRef = spec.Object
|
||||||
|
} else {
|
||||||
|
ociRef = name
|
||||||
|
}
|
||||||
|
|
||||||
|
return ociRef
|
||||||
|
}
|
||||||
|
|
||||||
// DigestTranslator creates a digest reference by adding the
|
// DigestTranslator creates a digest reference by adding the
|
||||||
// digest to an image name
|
// digest to an image name
|
||||||
func DigestTranslator(prefix string) func(digest.Digest) string {
|
func DigestTranslator(prefix string) func(digest.Digest) string {
|
||||||
|
241
vendor/github.com/containerd/containerd/images/oci/exporter.go
generated
vendored
241
vendor/github.com/containerd/containerd/images/oci/exporter.go
generated
vendored
@ -1,241 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright The containerd Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package oci
|
|
||||||
|
|
||||||
import (
|
|
||||||
"archive/tar"
|
|
||||||
"context"
|
|
||||||
"encoding/json"
|
|
||||||
"io"
|
|
||||||
"sort"
|
|
||||||
|
|
||||||
"github.com/containerd/containerd/content"
|
|
||||||
"github.com/containerd/containerd/images"
|
|
||||||
"github.com/containerd/containerd/platforms"
|
|
||||||
ocispecs "github.com/opencontainers/image-spec/specs-go"
|
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
// V1Exporter implements OCI Image Spec v1.
|
|
||||||
// It is up to caller to put "org.opencontainers.image.ref.name" annotation to desc.
|
|
||||||
//
|
|
||||||
// TODO(AkihiroSuda): add V1Exporter{TranslateMediaTypes: true} that transforms media types,
|
|
||||||
// e.g. application/vnd.docker.image.rootfs.diff.tar.gzip
|
|
||||||
// -> application/vnd.oci.image.layer.v1.tar+gzip
|
|
||||||
type V1Exporter struct {
|
|
||||||
AllPlatforms bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// V1ExporterOpt allows the caller to set additional options to a new V1Exporter
|
|
||||||
type V1ExporterOpt func(c *V1Exporter) error
|
|
||||||
|
|
||||||
// DefaultV1Exporter return a default V1Exporter pointer
|
|
||||||
func DefaultV1Exporter() *V1Exporter {
|
|
||||||
return &V1Exporter{
|
|
||||||
AllPlatforms: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ResolveV1ExportOpt return a new V1Exporter with V1ExporterOpt
|
|
||||||
func ResolveV1ExportOpt(opts ...V1ExporterOpt) (*V1Exporter, error) {
|
|
||||||
exporter := DefaultV1Exporter()
|
|
||||||
for _, o := range opts {
|
|
||||||
if err := o(exporter); err != nil {
|
|
||||||
return exporter, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return exporter, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithAllPlatforms set V1Exporter`s AllPlatforms option
|
|
||||||
func WithAllPlatforms(allPlatforms bool) V1ExporterOpt {
|
|
||||||
return func(c *V1Exporter) error {
|
|
||||||
c.AllPlatforms = allPlatforms
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export implements Exporter.
|
|
||||||
func (oe *V1Exporter) Export(ctx context.Context, store content.Provider, desc ocispec.Descriptor, writer io.Writer) error {
|
|
||||||
tw := tar.NewWriter(writer)
|
|
||||||
defer tw.Close()
|
|
||||||
|
|
||||||
records := []tarRecord{
|
|
||||||
ociLayoutFile(""),
|
|
||||||
ociIndexRecord(desc),
|
|
||||||
}
|
|
||||||
|
|
||||||
algorithms := map[string]struct{}{}
|
|
||||||
exportHandler := func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
|
|
||||||
records = append(records, blobRecord(store, desc))
|
|
||||||
algorithms[desc.Digest.Algorithm().String()] = struct{}{}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
childrenHandler := images.ChildrenHandler(store)
|
|
||||||
|
|
||||||
if !oe.AllPlatforms {
|
|
||||||
// get local default platform to fetch image manifest
|
|
||||||
childrenHandler = images.FilterPlatforms(childrenHandler, platforms.Any(platforms.DefaultSpec()))
|
|
||||||
}
|
|
||||||
|
|
||||||
handlers := images.Handlers(
|
|
||||||
childrenHandler,
|
|
||||||
images.HandlerFunc(exportHandler),
|
|
||||||
)
|
|
||||||
|
|
||||||
// Walk sequentially since the number of fetchs is likely one and doing in
|
|
||||||
// parallel requires locking the export handler
|
|
||||||
if err := images.Walk(ctx, handlers, desc); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(algorithms) > 0 {
|
|
||||||
records = append(records, directoryRecord("blobs/", 0755))
|
|
||||||
for alg := range algorithms {
|
|
||||||
records = append(records, directoryRecord("blobs/"+alg+"/", 0755))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return writeTar(ctx, tw, records)
|
|
||||||
}
|
|
||||||
|
|
||||||
type tarRecord struct {
|
|
||||||
Header *tar.Header
|
|
||||||
CopyTo func(context.Context, io.Writer) (int64, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
func blobRecord(cs content.Provider, desc ocispec.Descriptor) tarRecord {
|
|
||||||
path := "blobs/" + desc.Digest.Algorithm().String() + "/" + desc.Digest.Hex()
|
|
||||||
return tarRecord{
|
|
||||||
Header: &tar.Header{
|
|
||||||
Name: path,
|
|
||||||
Mode: 0444,
|
|
||||||
Size: desc.Size,
|
|
||||||
Typeflag: tar.TypeReg,
|
|
||||||
},
|
|
||||||
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
||||||
r, err := cs.ReaderAt(ctx, desc)
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "failed to get reader")
|
|
||||||
}
|
|
||||||
defer r.Close()
|
|
||||||
|
|
||||||
// Verify digest
|
|
||||||
dgstr := desc.Digest.Algorithm().Digester()
|
|
||||||
|
|
||||||
n, err := io.Copy(io.MultiWriter(w, dgstr.Hash()), content.NewReader(r))
|
|
||||||
if err != nil {
|
|
||||||
return 0, errors.Wrap(err, "failed to copy to tar")
|
|
||||||
}
|
|
||||||
if dgstr.Digest() != desc.Digest {
|
|
||||||
return 0, errors.Errorf("unexpected digest %s copied", dgstr.Digest())
|
|
||||||
}
|
|
||||||
return n, nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func directoryRecord(name string, mode int64) tarRecord {
|
|
||||||
return tarRecord{
|
|
||||||
Header: &tar.Header{
|
|
||||||
Name: name,
|
|
||||||
Mode: mode,
|
|
||||||
Typeflag: tar.TypeDir,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ociLayoutFile(version string) tarRecord {
|
|
||||||
if version == "" {
|
|
||||||
version = ocispec.ImageLayoutVersion
|
|
||||||
}
|
|
||||||
layout := ocispec.ImageLayout{
|
|
||||||
Version: version,
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(layout)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tarRecord{
|
|
||||||
Header: &tar.Header{
|
|
||||||
Name: ocispec.ImageLayoutFile,
|
|
||||||
Mode: 0444,
|
|
||||||
Size: int64(len(b)),
|
|
||||||
Typeflag: tar.TypeReg,
|
|
||||||
},
|
|
||||||
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
||||||
n, err := w.Write(b)
|
|
||||||
return int64(n), err
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func ociIndexRecord(manifests ...ocispec.Descriptor) tarRecord {
|
|
||||||
index := ocispec.Index{
|
|
||||||
Versioned: ocispecs.Versioned{
|
|
||||||
SchemaVersion: 2,
|
|
||||||
},
|
|
||||||
Manifests: manifests,
|
|
||||||
}
|
|
||||||
|
|
||||||
b, err := json.Marshal(index)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tarRecord{
|
|
||||||
Header: &tar.Header{
|
|
||||||
Name: "index.json",
|
|
||||||
Mode: 0644,
|
|
||||||
Size: int64(len(b)),
|
|
||||||
Typeflag: tar.TypeReg,
|
|
||||||
},
|
|
||||||
CopyTo: func(ctx context.Context, w io.Writer) (int64, error) {
|
|
||||||
n, err := w.Write(b)
|
|
||||||
return int64(n), err
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeTar(ctx context.Context, tw *tar.Writer, records []tarRecord) error {
|
|
||||||
sort.Slice(records, func(i, j int) bool {
|
|
||||||
return records[i].Header.Name < records[j].Header.Name
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, record := range records {
|
|
||||||
if err := tw.WriteHeader(record.Header); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if record.CopyTo != nil {
|
|
||||||
n, err := record.CopyTo(ctx, tw)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if n != record.Header.Size {
|
|
||||||
return errors.Errorf("unexpected copy size for %s", record.Header.Name)
|
|
||||||
}
|
|
||||||
} else if record.Header.Size > 0 {
|
|
||||||
return errors.Errorf("no content to write to record with non-zero size for %s", record.Header.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
24
vendor/github.com/containerd/containerd/import.go
generated
vendored
24
vendor/github.com/containerd/containerd/import.go
generated
vendored
@ -130,17 +130,13 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, m := range idx.Manifests {
|
for _, m := range idx.Manifests {
|
||||||
if ref := m.Annotations[ocispec.AnnotationRefName]; ref != "" {
|
name := imageName(m.Annotations, iopts.imageRefT)
|
||||||
if iopts.imageRefT != nil {
|
if name != "" {
|
||||||
ref = iopts.imageRefT(ref)
|
|
||||||
}
|
|
||||||
if ref != "" {
|
|
||||||
imgs = append(imgs, images.Image{
|
imgs = append(imgs, images.Image{
|
||||||
Name: ref,
|
Name: name,
|
||||||
Target: m,
|
Target: m,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if iopts.dgstRefT != nil {
|
if iopts.dgstRefT != nil {
|
||||||
ref := iopts.dgstRefT(m.Digest)
|
ref := iopts.dgstRefT(m.Digest)
|
||||||
if ref != "" {
|
if ref != "" {
|
||||||
@ -178,3 +174,17 @@ func (c *Client) Import(ctx context.Context, reader io.Reader, opts ...ImportOpt
|
|||||||
|
|
||||||
return imgs, nil
|
return imgs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func imageName(annotations map[string]string, ociCleanup func(string) string) string {
|
||||||
|
name := annotations[images.AnnotationImageName]
|
||||||
|
if name != "" {
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
name = annotations[ocispec.AnnotationRefName]
|
||||||
|
if name != "" {
|
||||||
|
if ociCleanup != nil {
|
||||||
|
name = ociCleanup(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
10
vendor/github.com/containerd/containerd/leases/lease.go
generated
vendored
10
vendor/github.com/containerd/containerd/leases/lease.go
generated
vendored
@ -32,6 +32,9 @@ type Manager interface {
|
|||||||
Create(context.Context, ...Opt) (Lease, error)
|
Create(context.Context, ...Opt) (Lease, error)
|
||||||
Delete(context.Context, Lease, ...DeleteOpt) error
|
Delete(context.Context, Lease, ...DeleteOpt) error
|
||||||
List(context.Context, ...string) ([]Lease, error)
|
List(context.Context, ...string) ([]Lease, error)
|
||||||
|
AddResource(context.Context, Lease, Resource) error
|
||||||
|
DeleteResource(context.Context, Lease, Resource) error
|
||||||
|
ListResources(context.Context, Lease) ([]Resource, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lease retains resources to prevent cleanup before
|
// Lease retains resources to prevent cleanup before
|
||||||
@ -42,6 +45,13 @@ type Lease struct {
|
|||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resource represents low level resource of image, like content, ingest and
|
||||||
|
// snapshotter.
|
||||||
|
type Resource struct {
|
||||||
|
ID string
|
||||||
|
Type string
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteOptions provide options on image delete
|
// DeleteOptions provide options on image delete
|
||||||
type DeleteOptions struct {
|
type DeleteOptions struct {
|
||||||
Synchronous bool
|
Synchronous bool
|
||||||
|
40
vendor/github.com/containerd/containerd/leases/proxy/manager.go
generated
vendored
40
vendor/github.com/containerd/containerd/leases/proxy/manager.go
generated
vendored
@ -91,3 +91,43 @@ func (pm *proxyManager) List(ctx context.Context, filters ...string) ([]leases.L
|
|||||||
|
|
||||||
return l, nil
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pm *proxyManager) AddResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
_, err := pm.client.AddResource(ctx, &leasesapi.AddResourceRequest{
|
||||||
|
ID: lease.ID,
|
||||||
|
Resource: leasesapi.Resource{
|
||||||
|
ID: r.ID,
|
||||||
|
Type: r.Type,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return errdefs.FromGRPC(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pm *proxyManager) DeleteResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
_, err := pm.client.DeleteResource(ctx, &leasesapi.DeleteResourceRequest{
|
||||||
|
ID: lease.ID,
|
||||||
|
Resource: leasesapi.Resource{
|
||||||
|
ID: r.ID,
|
||||||
|
Type: r.Type,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return errdefs.FromGRPC(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pm *proxyManager) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
|
||||||
|
resp, err := pm.client.ListResources(ctx, &leasesapi.ListResourcesRequest{
|
||||||
|
ID: lease.ID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errdefs.FromGRPC(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := make([]leases.Resource, 0, len(resp.Resources))
|
||||||
|
for _, i := range resp.Resources {
|
||||||
|
rs = append(rs, leases.Resource{
|
||||||
|
ID: i.ID,
|
||||||
|
Type: i.Type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return rs, nil
|
||||||
|
}
|
||||||
|
8
vendor/github.com/containerd/containerd/metadata/content.go
generated
vendored
8
vendor/github.com/containerd/containerd/metadata/content.go
generated
vendored
@ -567,6 +567,8 @@ func (nw *namespacedWriter) createAndCopy(ctx context.Context, desc ocispec.Desc
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
func (nw *namespacedWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||||
|
ctx = namespaces.WithNamespace(ctx, nw.namespace)
|
||||||
|
|
||||||
nw.l.RLock()
|
nw.l.RLock()
|
||||||
defer nw.l.RUnlock()
|
defer nw.l.RUnlock()
|
||||||
|
|
||||||
@ -767,11 +769,7 @@ func writeExpireAt(expire time.Time, bkt *bolt.Bucket) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := bkt.Put(bucketKeyExpireAt, expireAt); err != nil {
|
return bkt.Put(bucketKeyExpireAt, expireAt)
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *contentStore) garbageCollect(ctx context.Context) (d time.Duration, err error) {
|
func (cs *contentStore) garbageCollect(ctx context.Context) (d time.Duration, err error) {
|
||||||
|
157
vendor/github.com/containerd/containerd/metadata/leases.go
generated
vendored
157
vendor/github.com/containerd/containerd/metadata/leases.go
generated
vendored
@ -18,6 +18,8 @@ package metadata
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
@ -167,6 +169,128 @@ func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease,
|
|||||||
return ll, nil
|
return ll, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddResource references the resource by the provided lease.
|
||||||
|
func (lm *LeaseManager) AddResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
namespace, err := namespaces.NamespaceRequired(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
topbkt := getBucket(lm.tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID))
|
||||||
|
if topbkt == nil {
|
||||||
|
return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
keys, ref, err := parseLeaseResource(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bkt := topbkt
|
||||||
|
for _, key := range keys {
|
||||||
|
bkt, err = bkt.CreateBucketIfNotExists([]byte(key))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bkt.Put([]byte(ref), nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteResource dereferences the resource by the provided lease.
|
||||||
|
func (lm *LeaseManager) DeleteResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
namespace, err := namespaces.NamespaceRequired(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
topbkt := getBucket(lm.tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID))
|
||||||
|
if topbkt == nil {
|
||||||
|
return errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
keys, ref, err := parseLeaseResource(r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
bkt := topbkt
|
||||||
|
for _, key := range keys {
|
||||||
|
if bkt == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
bkt = bkt.Bucket([]byte(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
if bkt == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return bkt.Delete([]byte(ref))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListResources lists all the resources referenced by the lease.
|
||||||
|
func (lm *LeaseManager) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
|
||||||
|
namespace, err := namespaces.NamespaceRequired(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
topbkt := getBucket(lm.tx, bucketKeyVersion, []byte(namespace), bucketKeyObjectLeases, []byte(lease.ID))
|
||||||
|
if topbkt == nil {
|
||||||
|
return nil, errors.Wrapf(errdefs.ErrNotFound, "lease %q", lease.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := make([]leases.Resource, 0)
|
||||||
|
|
||||||
|
// content resources
|
||||||
|
if cbkt := topbkt.Bucket(bucketKeyObjectContent); cbkt != nil {
|
||||||
|
if err := cbkt.ForEach(func(k, _ []byte) error {
|
||||||
|
rs = append(rs, leases.Resource{
|
||||||
|
ID: string(k),
|
||||||
|
Type: string(bucketKeyObjectContent),
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ingest resources
|
||||||
|
if lbkt := topbkt.Bucket(bucketKeyObjectIngests); lbkt != nil {
|
||||||
|
if err := lbkt.ForEach(func(k, _ []byte) error {
|
||||||
|
rs = append(rs, leases.Resource{
|
||||||
|
ID: string(k),
|
||||||
|
Type: string(bucketKeyObjectIngests),
|
||||||
|
})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// snapshot resources
|
||||||
|
if sbkt := topbkt.Bucket(bucketKeyObjectSnapshots); sbkt != nil {
|
||||||
|
if err := sbkt.ForEach(func(sk, sv []byte) error {
|
||||||
|
if sv != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
snbkt := sbkt.Bucket(sk)
|
||||||
|
return snbkt.ForEach(func(k, _ []byte) error {
|
||||||
|
rs = append(rs, leases.Resource{
|
||||||
|
ID: string(k),
|
||||||
|
Type: fmt.Sprintf("%s/%s", bucketKeyObjectSnapshots, sk),
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rs, nil
|
||||||
|
}
|
||||||
|
|
||||||
func addSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) error {
|
func addSnapshotLease(ctx context.Context, tx *bolt.Tx, snapshotter, key string) error {
|
||||||
lid, ok := leases.FromContext(ctx)
|
lid, ok := leases.FromContext(ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -307,3 +431,36 @@ func removeIngestLease(ctx context.Context, tx *bolt.Tx, ref string) error {
|
|||||||
|
|
||||||
return bkt.Delete([]byte(ref))
|
return bkt.Delete([]byte(ref))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseLeaseResource(r leases.Resource) ([]string, string, error) {
|
||||||
|
var (
|
||||||
|
ref = r.ID
|
||||||
|
typ = r.Type
|
||||||
|
keys = strings.Split(typ, "/")
|
||||||
|
)
|
||||||
|
|
||||||
|
switch k := keys[0]; k {
|
||||||
|
case string(bucketKeyObjectContent),
|
||||||
|
string(bucketKeyObjectIngests):
|
||||||
|
|
||||||
|
if len(keys) != 1 {
|
||||||
|
return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid resource type %s", typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
if k == string(bucketKeyObjectContent) {
|
||||||
|
dgst, err := digest.Parse(ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid content resource id %s: %v", ref, err)
|
||||||
|
}
|
||||||
|
ref = dgst.String()
|
||||||
|
}
|
||||||
|
case string(bucketKeyObjectSnapshots):
|
||||||
|
if len(keys) != 2 {
|
||||||
|
return nil, "", errors.Wrapf(errdefs.ErrInvalidArgument, "invalid snapshot resource type %s", typ)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, "", errors.Wrapf(errdefs.ErrNotImplemented, "resource type %s not supported yet", typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys, ref, nil
|
||||||
|
}
|
||||||
|
11
vendor/github.com/containerd/containerd/mount/mount_linux.go
generated
vendored
11
vendor/github.com/containerd/containerd/mount/mount_linux.go
generated
vendored
@ -111,7 +111,18 @@ func unmount(target string, flags int) error {
|
|||||||
// UnmountAll repeatedly unmounts the given mount point until there
|
// UnmountAll repeatedly unmounts the given mount point until there
|
||||||
// are no mounts remaining (EINVAL is returned by mount), which is
|
// are no mounts remaining (EINVAL is returned by mount), which is
|
||||||
// useful for undoing a stack of mounts on the same mount point.
|
// useful for undoing a stack of mounts on the same mount point.
|
||||||
|
// UnmountAll all is noop when the first argument is an empty string.
|
||||||
|
// This is done when the containerd client did not specify any rootfs
|
||||||
|
// mounts (e.g. because the rootfs is managed outside containerd)
|
||||||
|
// UnmountAll is noop when the mount path does not exist.
|
||||||
func UnmountAll(mount string, flags int) error {
|
func UnmountAll(mount string, flags int) error {
|
||||||
|
if mount == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(mount); os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if err := unmount(mount, flags); err != nil {
|
if err := unmount(mount, flags); err != nil {
|
||||||
// EINVAL is returned if the target is not a
|
// EINVAL is returned if the target is not a
|
||||||
|
12
vendor/github.com/containerd/containerd/namespaces/context.go
generated
vendored
12
vendor/github.com/containerd/containerd/namespaces/context.go
generated
vendored
@ -36,10 +36,9 @@ type namespaceKey struct{}
|
|||||||
// WithNamespace sets a given namespace on the context
|
// WithNamespace sets a given namespace on the context
|
||||||
func WithNamespace(ctx context.Context, namespace string) context.Context {
|
func WithNamespace(ctx context.Context, namespace string) context.Context {
|
||||||
ctx = context.WithValue(ctx, namespaceKey{}, namespace) // set our key for namespace
|
ctx = context.WithValue(ctx, namespaceKey{}, namespace) // set our key for namespace
|
||||||
|
// also store on the grpc and ttrpc headers so it gets picked up by any clients that
|
||||||
// also store on the grpc headers so it gets picked up by any clients that
|
|
||||||
// are using this.
|
// are using this.
|
||||||
return withGRPCNamespaceHeader(ctx, namespace)
|
return withTTRPCNamespaceHeader(withGRPCNamespaceHeader(ctx, namespace), namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NamespaceFromEnv uses the namespace defined in CONTAINERD_NAMESPACE or
|
// NamespaceFromEnv uses the namespace defined in CONTAINERD_NAMESPACE or
|
||||||
@ -58,9 +57,10 @@ func NamespaceFromEnv(ctx context.Context) context.Context {
|
|||||||
func Namespace(ctx context.Context) (string, bool) {
|
func Namespace(ctx context.Context) (string, bool) {
|
||||||
namespace, ok := ctx.Value(namespaceKey{}).(string)
|
namespace, ok := ctx.Value(namespaceKey{}).(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return fromGRPCHeader(ctx)
|
if namespace, ok = fromGRPCHeader(ctx); !ok {
|
||||||
|
return fromTTRPCHeader(ctx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespace, ok
|
return namespace, ok
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,10 +70,8 @@ func NamespaceRequired(ctx context.Context) (string, error) {
|
|||||||
if !ok || namespace == "" {
|
if !ok || namespace == "" {
|
||||||
return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "namespace is required")
|
return "", errors.Wrapf(errdefs.ErrFailedPrecondition, "namespace is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := Validate(namespace); err != nil {
|
if err := Validate(namespace); err != nil {
|
||||||
return "", errors.Wrap(err, "namespace validation")
|
return "", errors.Wrap(err, "namespace validation")
|
||||||
}
|
}
|
||||||
|
|
||||||
return namespace, nil
|
return namespace, nil
|
||||||
}
|
}
|
||||||
|
41
vendor/github.com/containerd/containerd/namespaces/ttrpc.go
generated
vendored
Normal file
41
vendor/github.com/containerd/containerd/namespaces/ttrpc.go
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package namespaces
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/containerd/ttrpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// TTRPCHeader defines the header name for specifying a containerd namespace
|
||||||
|
TTRPCHeader = "containerd-namespace-ttrpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func withTTRPCNamespaceHeader(ctx context.Context, namespace string) context.Context {
|
||||||
|
md, ok := ttrpc.GetMetadata(ctx)
|
||||||
|
if !ok {
|
||||||
|
md = ttrpc.Metadata{}
|
||||||
|
}
|
||||||
|
md.Set(TTRPCHeader, namespace)
|
||||||
|
return ttrpc.WithMetadata(ctx, md)
|
||||||
|
}
|
||||||
|
|
||||||
|
func fromTTRPCHeader(ctx context.Context) (string, bool) {
|
||||||
|
return ttrpc.GetMetadataValue(ctx, TTRPCHeader)
|
||||||
|
}
|
14
vendor/github.com/containerd/containerd/pkg/dialer/dialer.go
generated
vendored
14
vendor/github.com/containerd/containerd/pkg/dialer/dialer.go
generated
vendored
@ -17,6 +17,7 @@
|
|||||||
package dialer
|
package dialer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -28,8 +29,19 @@ type dialResult struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ContextDialer returns a GRPC net.Conn connected to the provided address
|
||||||
|
func ContextDialer(ctx context.Context, address string) (net.Conn, error) {
|
||||||
|
if deadline, ok := ctx.Deadline(); ok {
|
||||||
|
return timeoutDialer(address, time.Until(deadline))
|
||||||
|
}
|
||||||
|
return timeoutDialer(address, 0)
|
||||||
|
}
|
||||||
|
|
||||||
// Dialer returns a GRPC net.Conn connected to the provided address
|
// Dialer returns a GRPC net.Conn connected to the provided address
|
||||||
func Dialer(address string, timeout time.Duration) (net.Conn, error) {
|
// Deprecated: use ContextDialer and grpc.WithContextDialer.
|
||||||
|
var Dialer = timeoutDialer
|
||||||
|
|
||||||
|
func timeoutDialer(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
var (
|
var (
|
||||||
stopC = make(chan struct{})
|
stopC = make(chan struct{})
|
||||||
synC = make(chan *dialResult)
|
synC = make(chan *dialResult)
|
||||||
|
105
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
Normal file
105
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client.go
generated
vendored
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ttrpcutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
||||||
|
"github.com/containerd/ttrpc"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ttrpcDialTimeout = 5 * time.Second
|
||||||
|
|
||||||
|
type ttrpcConnector func() (*ttrpc.Client, error)
|
||||||
|
|
||||||
|
// Client is the client to interact with TTRPC part of containerd server (plugins, events)
|
||||||
|
type Client struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
connector ttrpcConnector
|
||||||
|
client *ttrpc.Client
|
||||||
|
closed bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient returns a new containerd TTRPC client that is connected to the containerd instance provided by address
|
||||||
|
func NewClient(address string, opts ...ttrpc.ClientOpts) (*Client, error) {
|
||||||
|
connector := func() (*ttrpc.Client, error) {
|
||||||
|
conn, err := ttrpcDial(address, ttrpcDialTimeout)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to connect")
|
||||||
|
}
|
||||||
|
|
||||||
|
client := ttrpc.NewClient(conn, opts...)
|
||||||
|
return client, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := connector()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
connector: connector,
|
||||||
|
client: client,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconnect re-establishes the TTRPC connection to the containerd daemon
|
||||||
|
func (c *Client) Reconnect() error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
if c.connector == nil {
|
||||||
|
return errors.New("unable to reconnect to containerd, no connector available")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.closed {
|
||||||
|
return errors.New("client is closed")
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := c.connector()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
c.client = client
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventsService creates an EventsService client
|
||||||
|
func (c *Client) EventsService() v1.EventsService {
|
||||||
|
return v1.NewEventsClient(c.Client())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Client returns the underlying TTRPC client object
|
||||||
|
func (c *Client) Client() *ttrpc.Client {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
return c.client
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes the clients TTRPC connection to containerd
|
||||||
|
func (c *Client) Close() error {
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
|
|
||||||
|
c.closed = true
|
||||||
|
return c.client.Close()
|
||||||
|
}
|
30
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client_unix.go
generated
vendored
Normal file
30
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client_unix.go
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// +build !windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ttrpcutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ttrpcDial(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
address = strings.TrimPrefix(address, "unix://")
|
||||||
|
return net.DialTimeout("unix", address, timeout)
|
||||||
|
}
|
60
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client_windows.go
generated
vendored
Normal file
60
vendor/github.com/containerd/containerd/pkg/ttrpcutil/client_windows.go
generated
vendored
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ttrpcutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
winio "github.com/Microsoft/go-winio"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ttrpcDial(address string, timeout time.Duration) (net.Conn, error) {
|
||||||
|
var c net.Conn
|
||||||
|
var lastError error
|
||||||
|
timedOutError := errors.Errorf("timed out waiting for npipe %s", address)
|
||||||
|
start := time.Now()
|
||||||
|
for {
|
||||||
|
remaining := timeout - time.Since(start)
|
||||||
|
if remaining <= 0 {
|
||||||
|
lastError = timedOutError
|
||||||
|
break
|
||||||
|
}
|
||||||
|
c, lastError = winio.DialPipe(address, &remaining)
|
||||||
|
if lastError == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if !os.IsNotExist(lastError) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// There is nobody serving the pipe. We limit the timeout for this case
|
||||||
|
// to 5 seconds because any shim that would serve this endpoint should
|
||||||
|
// serve it within 5 seconds. We use the passed in timeout for the
|
||||||
|
// `DialPipe` timeout if the pipe exists however to give the pipe time
|
||||||
|
// to `Accept` the connection.
|
||||||
|
if time.Since(start) >= 5*time.Second {
|
||||||
|
lastError = timedOutError
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
}
|
||||||
|
return c, lastError
|
||||||
|
}
|
37
vendor/github.com/containerd/containerd/platforms/compare.go
generated
vendored
37
vendor/github.com/containerd/containerd/platforms/compare.go
generated
vendored
@ -29,11 +29,48 @@ type MatchComparer interface {
|
|||||||
// Only returns a match comparer for a single platform
|
// Only returns a match comparer for a single platform
|
||||||
// using default resolution logic for the platform.
|
// using default resolution logic for the platform.
|
||||||
//
|
//
|
||||||
|
// For ARMv8, will also match ARMv7, ARMv6 and ARMv5 (for 32bit runtimes)
|
||||||
// For ARMv7, will also match ARMv6 and ARMv5
|
// For ARMv7, will also match ARMv6 and ARMv5
|
||||||
// For ARMv6, will also match ARMv5
|
// For ARMv6, will also match ARMv5
|
||||||
func Only(platform specs.Platform) MatchComparer {
|
func Only(platform specs.Platform) MatchComparer {
|
||||||
platform = Normalize(platform)
|
platform = Normalize(platform)
|
||||||
if platform.Architecture == "arm" {
|
if platform.Architecture == "arm" {
|
||||||
|
if platform.Variant == "v8" {
|
||||||
|
return orderedPlatformComparer{
|
||||||
|
matchers: []Matcher{
|
||||||
|
&matcher{
|
||||||
|
Platform: platform,
|
||||||
|
},
|
||||||
|
&matcher{
|
||||||
|
Platform: specs.Platform{
|
||||||
|
Architecture: platform.Architecture,
|
||||||
|
OS: platform.OS,
|
||||||
|
OSVersion: platform.OSVersion,
|
||||||
|
OSFeatures: platform.OSFeatures,
|
||||||
|
Variant: "v7",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&matcher{
|
||||||
|
Platform: specs.Platform{
|
||||||
|
Architecture: platform.Architecture,
|
||||||
|
OS: platform.OS,
|
||||||
|
OSVersion: platform.OSVersion,
|
||||||
|
OSFeatures: platform.OSFeatures,
|
||||||
|
Variant: "v6",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&matcher{
|
||||||
|
Platform: specs.Platform{
|
||||||
|
Architecture: platform.Architecture,
|
||||||
|
OS: platform.OS,
|
||||||
|
OSVersion: platform.OSVersion,
|
||||||
|
OSFeatures: platform.OSFeatures,
|
||||||
|
Variant: "v5",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
if platform.Variant == "v7" {
|
if platform.Variant == "v7" {
|
||||||
return orderedPlatformComparer{
|
return orderedPlatformComparer{
|
||||||
matchers: []Matcher{
|
matchers: []Matcher{
|
||||||
|
2
vendor/github.com/containerd/containerd/platforms/cpuinfo.go
generated
vendored
2
vendor/github.com/containerd/containerd/platforms/cpuinfo.go
generated
vendored
@ -97,7 +97,7 @@ func getCPUVariant() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch variant {
|
switch variant {
|
||||||
case "8":
|
case "8", "AArch64":
|
||||||
variant = "v8"
|
variant = "v8"
|
||||||
case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
|
case "7", "7M", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
|
||||||
variant = "v7"
|
variant = "v7"
|
||||||
|
49
vendor/github.com/containerd/containerd/plugin/plugin.go
generated
vendored
49
vendor/github.com/containerd/containerd/plugin/plugin.go
generated
vendored
@ -30,7 +30,8 @@ var (
|
|||||||
ErrNoType = errors.New("plugin: no type")
|
ErrNoType = errors.New("plugin: no type")
|
||||||
// ErrNoPluginID is returned when no id is specified
|
// ErrNoPluginID is returned when no id is specified
|
||||||
ErrNoPluginID = errors.New("plugin: no id")
|
ErrNoPluginID = errors.New("plugin: no id")
|
||||||
|
// ErrIDRegistered is returned when a duplicate id is already registered
|
||||||
|
ErrIDRegistered = errors.New("plugin: id already registered")
|
||||||
// ErrSkipPlugin is used when a plugin is not initialized and should not be loaded,
|
// ErrSkipPlugin is used when a plugin is not initialized and should not be loaded,
|
||||||
// this allows the plugin loader differentiate between a plugin which is configured
|
// this allows the plugin loader differentiate between a plugin which is configured
|
||||||
// not to load and one that fails to load.
|
// not to load and one that fails to load.
|
||||||
@ -100,6 +101,8 @@ type Registration struct {
|
|||||||
// context are passed in. The init function may modify the registration to
|
// context are passed in. The init function may modify the registration to
|
||||||
// add exports, capabilities and platform support declarations.
|
// add exports, capabilities and platform support declarations.
|
||||||
InitFn func(*InitContext) (interface{}, error)
|
InitFn func(*InitContext) (interface{}, error)
|
||||||
|
// Disable the plugin from loading
|
||||||
|
Disable bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init the registered plugin
|
// Init the registered plugin
|
||||||
@ -157,12 +160,16 @@ func Load(path string) (err error) {
|
|||||||
func Register(r *Registration) {
|
func Register(r *Registration) {
|
||||||
register.Lock()
|
register.Lock()
|
||||||
defer register.Unlock()
|
defer register.Unlock()
|
||||||
|
|
||||||
if r.Type == "" {
|
if r.Type == "" {
|
||||||
panic(ErrNoType)
|
panic(ErrNoType)
|
||||||
}
|
}
|
||||||
if r.ID == "" {
|
if r.ID == "" {
|
||||||
panic(ErrNoPluginID)
|
panic(ErrNoPluginID)
|
||||||
}
|
}
|
||||||
|
if err := checkUnique(r); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
var last bool
|
var last bool
|
||||||
for _, requires := range r.Requires {
|
for _, requires := range r.Requires {
|
||||||
@ -177,24 +184,36 @@ func Register(r *Registration) {
|
|||||||
register.r = append(register.r, r)
|
register.r = append(register.r, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkUnique(r *Registration) error {
|
||||||
|
for _, registered := range register.r {
|
||||||
|
if r.URI() == registered.URI() {
|
||||||
|
return errors.Wrap(ErrIDRegistered, r.URI())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableFilter filters out disabled plugins
|
||||||
|
type DisableFilter func(r *Registration) bool
|
||||||
|
|
||||||
// Graph returns an ordered list of registered plugins for initialization.
|
// Graph returns an ordered list of registered plugins for initialization.
|
||||||
// Plugins in disableList specified by id will be disabled.
|
// Plugins in disableList specified by id will be disabled.
|
||||||
func Graph(disableList []string) (ordered []*Registration) {
|
func Graph(filter DisableFilter) (ordered []*Registration) {
|
||||||
register.RLock()
|
register.RLock()
|
||||||
defer register.RUnlock()
|
defer register.RUnlock()
|
||||||
for _, d := range disableList {
|
|
||||||
for i, r := range register.r {
|
for _, r := range register.r {
|
||||||
if r.ID == d {
|
if filter(r) {
|
||||||
register.r = append(register.r[:i], register.r[i+1:]...)
|
r.Disable = true
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
added := map[*Registration]bool{}
|
added := map[*Registration]bool{}
|
||||||
for _, r := range register.r {
|
for _, r := range register.r {
|
||||||
|
if r.Disable {
|
||||||
children(r.ID, r.Requires, added, &ordered)
|
continue
|
||||||
|
}
|
||||||
|
children(r, added, &ordered)
|
||||||
if !added[r] {
|
if !added[r] {
|
||||||
ordered = append(ordered, r)
|
ordered = append(ordered, r)
|
||||||
added[r] = true
|
added[r] = true
|
||||||
@ -203,11 +222,13 @@ func Graph(disableList []string) (ordered []*Registration) {
|
|||||||
return ordered
|
return ordered
|
||||||
}
|
}
|
||||||
|
|
||||||
func children(id string, types []Type, added map[*Registration]bool, ordered *[]*Registration) {
|
func children(reg *Registration, added map[*Registration]bool, ordered *[]*Registration) {
|
||||||
for _, t := range types {
|
for _, t := range reg.Requires {
|
||||||
for _, r := range register.r {
|
for _, r := range register.r {
|
||||||
if r.ID != id && (t == "*" || r.Type == t) {
|
if !r.Disable &&
|
||||||
children(r.ID, r.Requires, added, ordered)
|
r.URI() != reg.URI() &&
|
||||||
|
(t == "*" || r.Type == t) {
|
||||||
|
children(r, added, ordered)
|
||||||
if !added[r] {
|
if !added[r] {
|
||||||
*ordered = append(*ordered, r)
|
*ordered = append(*ordered, r)
|
||||||
added[r] = true
|
added[r] = true
|
||||||
|
2
vendor/github.com/containerd/containerd/remotes/docker/handler.go
generated
vendored
2
vendor/github.com/containerd/containerd/remotes/docker/handler.go
generated
vendored
@ -88,7 +88,7 @@ func appendDistributionSourceLabel(originLabel, repo string) string {
|
|||||||
}
|
}
|
||||||
repos = append(repos, repo)
|
repos = append(repos, repo)
|
||||||
|
|
||||||
// use emtpy string to present duplicate items
|
// use empty string to present duplicate items
|
||||||
for i := 1; i < len(repos); i++ {
|
for i := 1; i < len(repos); i++ {
|
||||||
tmp, j := repos[i], i-1
|
tmp, j := repos[i], i-1
|
||||||
for ; j >= 0 && repos[j] >= tmp; j-- {
|
for ; j >= 0 && repos[j] >= tmp; j-- {
|
||||||
|
79
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
79
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
@ -18,10 +18,10 @@ package docker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
@ -29,6 +29,7 @@ import (
|
|||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
"github.com/containerd/containerd/reference"
|
"github.com/containerd/containerd/reference"
|
||||||
"github.com/containerd/containerd/remotes"
|
"github.com/containerd/containerd/remotes"
|
||||||
|
"github.com/containerd/containerd/remotes/docker/schema1"
|
||||||
"github.com/containerd/containerd/version"
|
"github.com/containerd/containerd/version"
|
||||||
digest "github.com/opencontainers/go-digest"
|
digest "github.com/opencontainers/go-digest"
|
||||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
@ -150,6 +151,32 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getManifestMediaType(resp *http.Response) string {
|
||||||
|
// Strip encoding data (manifests should always be ascii JSON)
|
||||||
|
contentType := resp.Header.Get("Content-Type")
|
||||||
|
if sp := strings.IndexByte(contentType, ';'); sp != -1 {
|
||||||
|
contentType = contentType[0:sp]
|
||||||
|
}
|
||||||
|
|
||||||
|
// As of Apr 30 2019 the registry.access.redhat.com registry does not specify
|
||||||
|
// the content type of any data but uses schema1 manifests.
|
||||||
|
if contentType == "text/plain" {
|
||||||
|
contentType = images.MediaTypeDockerSchema1Manifest
|
||||||
|
}
|
||||||
|
return contentType
|
||||||
|
}
|
||||||
|
|
||||||
|
type countingReader struct {
|
||||||
|
reader io.Reader
|
||||||
|
bytesRead int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *countingReader) Read(p []byte) (int, error) {
|
||||||
|
n, err := r.reader.Read(p)
|
||||||
|
r.bytesRead += int64(n)
|
||||||
|
return n, err
|
||||||
|
}
|
||||||
|
|
||||||
var _ remotes.Resolver = &dockerResolver{}
|
var _ remotes.Resolver = &dockerResolver{}
|
||||||
|
|
||||||
func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocispec.Descriptor, error) {
|
func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocispec.Descriptor, error) {
|
||||||
@ -220,40 +247,56 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
|||||||
}
|
}
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
|
return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status)
|
||||||
}
|
}
|
||||||
|
size := resp.ContentLength
|
||||||
|
|
||||||
// this is the only point at which we trust the registry. we use the
|
// this is the only point at which we trust the registry. we use the
|
||||||
// content headers to assemble a descriptor for the name. when this becomes
|
// content headers to assemble a descriptor for the name. when this becomes
|
||||||
// more robust, we mostly get this information from a secure trust store.
|
// more robust, we mostly get this information from a secure trust store.
|
||||||
dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest"))
|
dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest"))
|
||||||
|
contentType := getManifestMediaType(resp)
|
||||||
|
|
||||||
if dgstHeader != "" {
|
if dgstHeader != "" && size != -1 {
|
||||||
if err := dgstHeader.Validate(); err != nil {
|
if err := dgstHeader.Validate(); err != nil {
|
||||||
return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader)
|
return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader)
|
||||||
}
|
}
|
||||||
dgst = dgstHeader
|
dgst = dgstHeader
|
||||||
}
|
} else {
|
||||||
|
log.G(ctx).Debug("no Docker-Content-Digest header, fetching manifest instead")
|
||||||
|
|
||||||
if dgst == "" {
|
req, err := http.NewRequest(http.MethodGet, u, nil)
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("could not resolve digest for %v", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
size int64
|
|
||||||
sizeHeader = resp.Header.Get("Content-Length")
|
|
||||||
)
|
|
||||||
|
|
||||||
size, err = strconv.ParseInt(sizeHeader, 10, 64)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
return "", ocispec.Descriptor{}, errors.Wrapf(err, "invalid size header: %q", sizeHeader)
|
|
||||||
}
|
}
|
||||||
if size < 0 {
|
req.Header = r.headers
|
||||||
return "", ocispec.Descriptor{}, errors.Errorf("%q in header not a valid size", sizeHeader)
|
|
||||||
|
resp, err := fetcher.doRequestWithRetries(ctx, req, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
bodyReader := countingReader{reader: resp.Body}
|
||||||
|
|
||||||
|
contentType = getManifestMediaType(resp)
|
||||||
|
if contentType == images.MediaTypeDockerSchema1Manifest {
|
||||||
|
b, err := schema1.ReadStripSignature(&bodyReader)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
dgst = digest.FromBytes(b)
|
||||||
|
} else {
|
||||||
|
dgst, err = digest.FromReader(&bodyReader)
|
||||||
|
if err != nil {
|
||||||
|
return "", ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = bodyReader.bytesRead
|
||||||
}
|
}
|
||||||
|
|
||||||
desc := ocispec.Descriptor{
|
desc := ocispec.Descriptor{
|
||||||
Digest: dgst,
|
Digest: dgst,
|
||||||
MediaType: resp.Header.Get("Content-Type"), // need to strip disposition?
|
MediaType: contentType,
|
||||||
Size: size,
|
Size: size,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go
generated
vendored
18
vendor/github.com/containerd/containerd/remotes/docker/schema1/converter.go
generated
vendored
@ -227,6 +227,17 @@ func (c *Converter) Convert(ctx context.Context, opts ...ConvertOpt) (ocispec.De
|
|||||||
return desc, nil
|
return desc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadStripSignature reads in a schema1 manifest and returns a byte array
|
||||||
|
// with the "signatures" field stripped
|
||||||
|
func ReadStripSignature(schema1Blob io.Reader) ([]byte, error) {
|
||||||
|
b, err := ioutil.ReadAll(io.LimitReader(schema1Blob, manifestSizeLimit)) // limit to 8MB
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return stripSignature(b)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) error {
|
func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor) error {
|
||||||
log.G(ctx).Debug("fetch schema 1")
|
log.G(ctx).Debug("fetch schema 1")
|
||||||
|
|
||||||
@ -235,17 +246,12 @@ func (c *Converter) fetchManifest(ctx context.Context, desc ocispec.Descriptor)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err := ioutil.ReadAll(io.LimitReader(rc, manifestSizeLimit)) // limit to 8MB
|
b, err := ReadStripSignature(rc)
|
||||||
rc.Close()
|
rc.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
b, err = stripSignature(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var m manifest
|
var m manifest
|
||||||
if err := json.Unmarshal(b, &m); err != nil {
|
if err := json.Unmarshal(b, &m); err != nil {
|
||||||
return err
|
return err
|
||||||
|
6
vendor/github.com/containerd/containerd/remotes/resolver.go
generated
vendored
6
vendor/github.com/containerd/containerd/remotes/resolver.go
generated
vendored
@ -72,9 +72,9 @@ func (fn FetcherFunc) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.Re
|
|||||||
|
|
||||||
// PusherFunc allows package users to implement a Pusher with just a
|
// PusherFunc allows package users to implement a Pusher with just a
|
||||||
// function.
|
// function.
|
||||||
type PusherFunc func(ctx context.Context, desc ocispec.Descriptor, r io.Reader) error
|
type PusherFunc func(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error)
|
||||||
|
|
||||||
// Push content
|
// Push content
|
||||||
func (fn PusherFunc) Push(ctx context.Context, desc ocispec.Descriptor, r io.Reader) error {
|
func (fn PusherFunc) Push(ctx context.Context, desc ocispec.Descriptor) (content.Writer, error) {
|
||||||
return fn(ctx, desc, r)
|
return fn(ctx, desc)
|
||||||
}
|
}
|
||||||
|
6
vendor/github.com/containerd/containerd/runtime/v1/linux/bundle.go
generated
vendored
6
vendor/github.com/containerd/containerd/runtime/v1/linux/bundle.go
generated
vendored
@ -65,7 +65,8 @@ func newBundle(id, path, workDir string, spec []byte) (b *bundle, err error) {
|
|||||||
os.RemoveAll(workDir)
|
os.RemoveAll(workDir)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if err := os.Mkdir(filepath.Join(path, "rootfs"), 0711); err != nil {
|
rootfs := filepath.Join(path, "rootfs")
|
||||||
|
if err := os.MkdirAll(rootfs, 0711); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(filepath.Join(path, configFilename), spec, 0666)
|
err = ioutil.WriteFile(filepath.Join(path, configFilename), spec, 0666)
|
||||||
@ -182,6 +183,9 @@ func atomicDelete(path string) error {
|
|||||||
// create a hidden dir for an atomic removal
|
// create a hidden dir for an atomic removal
|
||||||
atomicPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
atomicPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
||||||
if err := os.Rename(path, atomicPath); err != nil {
|
if err := os.Rename(path, atomicPath); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.RemoveAll(atomicPath)
|
return os.RemoveAll(atomicPath)
|
||||||
|
5
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
generated
vendored
5
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
generated
vendored
@ -22,6 +22,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/containerd/console"
|
"github.com/containerd/console"
|
||||||
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/runtime/proc"
|
"github.com/containerd/containerd/runtime/proc"
|
||||||
google_protobuf "github.com/gogo/protobuf/types"
|
google_protobuf "github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -55,11 +56,11 @@ func (s *deletedState) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *deletedState) Delete(ctx context.Context) error {
|
func (s *deletedState) Delete(ctx context.Context) error {
|
||||||
return errors.Errorf("cannot delete a deleted process")
|
return errors.Wrap(errdefs.ErrNotFound, "cannot delete a deleted process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *deletedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *deletedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
return errors.Errorf("cannot kill a deleted process")
|
return errors.Wrap(errdefs.ErrNotFound, "cannot kill a deleted process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *deletedState) SetExited(status int) {
|
func (s *deletedState) SetExited(status int) {
|
||||||
|
7
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
7
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
@ -324,13 +324,6 @@ func (p *Init) Resize(ws console.WinSize) error {
|
|||||||
return p.console.Resize(ws)
|
return p.console.Resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) resize(ws console.WinSize) error {
|
|
||||||
if p.console == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return p.console.Resize(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pause the init process and all its child processes
|
// Pause the init process and all its child processes
|
||||||
func (p *Init) Pause(ctx context.Context) error {
|
func (p *Init) Pause(ctx context.Context) error {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
|
22
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
22
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
@ -21,7 +21,6 @@ package proc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/containerd/console"
|
|
||||||
"github.com/containerd/containerd/runtime/proc"
|
"github.com/containerd/containerd/runtime/proc"
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
google_protobuf "github.com/gogo/protobuf/types"
|
google_protobuf "github.com/gogo/protobuf/types"
|
||||||
@ -30,7 +29,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type initState interface {
|
type initState interface {
|
||||||
Resize(console.WinSize) error
|
|
||||||
Start(context.Context) error
|
Start(context.Context) error
|
||||||
Delete(context.Context) error
|
Delete(context.Context) error
|
||||||
Pause(context.Context) error
|
Pause(context.Context) error
|
||||||
@ -76,10 +74,6 @@ func (s *createdState) Checkpoint(ctx context.Context, r *CheckpointConfig) erro
|
|||||||
return errors.Errorf("cannot checkpoint a task in created state")
|
return errors.Errorf("cannot checkpoint a task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Resize(ws console.WinSize) error {
|
|
||||||
return s.p.resize(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *createdState) Start(ctx context.Context) error {
|
func (s *createdState) Start(ctx context.Context) error {
|
||||||
if err := s.p.start(ctx); err != nil {
|
if err := s.p.start(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -145,10 +139,6 @@ func (s *createdCheckpointState) Checkpoint(ctx context.Context, r *CheckpointCo
|
|||||||
return errors.Errorf("cannot checkpoint a task in created state")
|
return errors.Errorf("cannot checkpoint a task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Resize(ws console.WinSize) error {
|
|
||||||
return s.p.resize(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *createdCheckpointState) Start(ctx context.Context) error {
|
func (s *createdCheckpointState) Start(ctx context.Context) error {
|
||||||
p := s.p
|
p := s.p
|
||||||
sio := p.stdio
|
sio := p.stdio
|
||||||
@ -255,10 +245,6 @@ func (s *runningState) Checkpoint(ctx context.Context, r *CheckpointConfig) erro
|
|||||||
return s.p.checkpoint(ctx, r)
|
return s.p.checkpoint(ctx, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Resize(ws console.WinSize) error {
|
|
||||||
return s.p.resize(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *runningState) Start(ctx context.Context) error {
|
func (s *runningState) Start(ctx context.Context) error {
|
||||||
return errors.Errorf("cannot start a running process")
|
return errors.Errorf("cannot start a running process")
|
||||||
}
|
}
|
||||||
@ -319,10 +305,6 @@ func (s *pausedState) Checkpoint(ctx context.Context, r *CheckpointConfig) error
|
|||||||
return s.p.checkpoint(ctx, r)
|
return s.p.checkpoint(ctx, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Resize(ws console.WinSize) error {
|
|
||||||
return s.p.resize(ws)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *pausedState) Start(ctx context.Context) error {
|
func (s *pausedState) Start(ctx context.Context) error {
|
||||||
return errors.Errorf("cannot start a paused process")
|
return errors.Errorf("cannot start a paused process")
|
||||||
}
|
}
|
||||||
@ -381,10 +363,6 @@ func (s *stoppedState) Checkpoint(ctx context.Context, r *CheckpointConfig) erro
|
|||||||
return errors.Errorf("cannot checkpoint a stopped container")
|
return errors.Errorf("cannot checkpoint a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Resize(ws console.WinSize) error {
|
|
||||||
return errors.Errorf("cannot resize a stopped container")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *stoppedState) Start(ctx context.Context) error {
|
func (s *stoppedState) Start(ctx context.Context) error {
|
||||||
return errors.Errorf("cannot start a stopped process")
|
return errors.Errorf("cannot start a stopped process")
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
generated
vendored
10
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/io.go
generated
vendored
@ -271,27 +271,35 @@ func newBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
|
|||||||
)
|
)
|
||||||
out, err := newPipe()
|
out, err := newPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
serr, err := newPipe()
|
serr, err := newPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
r, w, err := os.Pipe()
|
r, w, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
|
cmd.ExtraFiles = append(cmd.ExtraFiles, out.r, serr.r, w)
|
||||||
// don't need to register this with the reaper or wait when
|
// don't need to register this with the reaper or wait when
|
||||||
// running inside a shim
|
// running inside a shim
|
||||||
if err := cmd.Start(); err != nil {
|
if err := cmd.Start(); err != nil {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// close our side of the pipe after start
|
// close our side of the pipe after start
|
||||||
w.Close()
|
if err := w.Close(); err != nil {
|
||||||
|
cancel()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
// wait for the logging binary to be ready
|
// wait for the logging binary to be ready
|
||||||
b := make([]byte, 1)
|
b := make([]byte, 1)
|
||||||
if _, err := r.Read(b); err != nil && err != io.EOF {
|
if _, err := r.Read(b); err != nil && err != io.EOF {
|
||||||
|
cancel()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &binaryIO{
|
return &binaryIO{
|
||||||
|
1
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
generated
vendored
1
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/utils.go
generated
vendored
@ -56,6 +56,7 @@ func getLastRuntimeError(r *runc.Runc) (string, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errMsg string
|
errMsg string
|
||||||
|
63
vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
generated
vendored
63
vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
generated
vendored
@ -191,18 +191,13 @@ func (r *Runtime) Create(ctx context.Context, id string, opts runtime.CreateOpts
|
|||||||
}
|
}
|
||||||
exitHandler := func() {
|
exitHandler := func() {
|
||||||
log.G(ctx).WithField("id", id).Info("shim reaped")
|
log.G(ctx).WithField("id", id).Info("shim reaped")
|
||||||
t, err := r.tasks.Get(ctx, id)
|
|
||||||
if err != nil {
|
if _, err := r.tasks.Get(ctx, id); err != nil {
|
||||||
// Task was never started or was already successfully deleted
|
// Task was never started or was already successfully deleted
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lc := t.(*Task)
|
|
||||||
|
|
||||||
log.G(ctx).WithFields(logrus.Fields{
|
if err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id); err != nil {
|
||||||
"id": id,
|
|
||||||
"namespace": namespace,
|
|
||||||
}).Warn("cleaning up after killed shim")
|
|
||||||
if err = r.cleanupAfterDeadShim(context.Background(), bundle, namespace, id, lc.pid); err != nil {
|
|
||||||
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
||||||
"id": id,
|
"id": id,
|
||||||
"namespace": namespace,
|
"namespace": namespace,
|
||||||
@ -330,6 +325,10 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
id := path.Name()
|
id := path.Name()
|
||||||
|
// skip hidden directories
|
||||||
|
if len(id) > 0 && id[0] == '.' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
bundle := loadBundle(
|
bundle := loadBundle(
|
||||||
id,
|
id,
|
||||||
filepath.Join(r.state, ns, id),
|
filepath.Join(r.state, ns, id),
|
||||||
@ -337,9 +336,15 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
)
|
)
|
||||||
ctx = namespaces.WithNamespace(ctx, ns)
|
ctx = namespaces.WithNamespace(ctx, ns)
|
||||||
pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, proc.InitPidFile))
|
pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, proc.InitPidFile))
|
||||||
|
shimExit := make(chan struct{})
|
||||||
s, err := bundle.NewShimClient(ctx, ns, ShimConnect(r.config, func() {
|
s, err := bundle.NewShimClient(ctx, ns, ShimConnect(r.config, func() {
|
||||||
err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid)
|
defer close(shimExit)
|
||||||
if err != nil {
|
if _, err := r.tasks.Get(ctx, id); err != nil {
|
||||||
|
// Task was never started or was already successfully deleted
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.cleanupAfterDeadShim(ctx, bundle, ns, id); err != nil {
|
||||||
log.G(ctx).WithError(err).WithField("bundle", bundle.path).
|
log.G(ctx).WithError(err).WithField("bundle", bundle.path).
|
||||||
Error("cleaning up after dead shim")
|
Error("cleaning up after dead shim")
|
||||||
}
|
}
|
||||||
@ -349,7 +354,7 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
"id": id,
|
"id": id,
|
||||||
"namespace": ns,
|
"namespace": ns,
|
||||||
}).Error("connecting to shim")
|
}).Error("connecting to shim")
|
||||||
err := r.cleanupAfterDeadShim(ctx, bundle, ns, id, pid)
|
err := r.cleanupAfterDeadShim(ctx, bundle, ns, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithError(err).WithField("bundle", bundle.path).
|
log.G(ctx).WithError(err).WithField("bundle", bundle.path).
|
||||||
Error("cleaning up after dead shim")
|
Error("cleaning up after dead shim")
|
||||||
@ -359,6 +364,18 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
|
|
||||||
logDirPath := filepath.Join(r.root, ns, id)
|
logDirPath := filepath.Join(r.root, ns, id)
|
||||||
|
|
||||||
|
copyAndClose := func(dst io.Writer, src io.ReadWriteCloser) {
|
||||||
|
copyDone := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
io.Copy(dst, src)
|
||||||
|
close(copyDone)
|
||||||
|
}()
|
||||||
|
select {
|
||||||
|
case <-shimExit:
|
||||||
|
case <-copyDone:
|
||||||
|
}
|
||||||
|
src.Close()
|
||||||
|
}
|
||||||
shimStdoutLog, err := v1.OpenShimStdoutLog(ctx, logDirPath)
|
shimStdoutLog, err := v1.OpenShimStdoutLog(ctx, logDirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
||||||
@ -368,7 +385,11 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
}).Error("opening shim stdout log pipe")
|
}).Error("opening shim stdout log pipe")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go io.Copy(os.Stdout, shimStdoutLog)
|
if r.config.ShimDebug {
|
||||||
|
go copyAndClose(os.Stdout, shimStdoutLog)
|
||||||
|
} else {
|
||||||
|
go copyAndClose(ioutil.Discard, shimStdoutLog)
|
||||||
|
}
|
||||||
|
|
||||||
shimStderrLog, err := v1.OpenShimStderrLog(ctx, logDirPath)
|
shimStderrLog, err := v1.OpenShimStderrLog(ctx, logDirPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -379,7 +400,11 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
}).Error("opening shim stderr log pipe")
|
}).Error("opening shim stderr log pipe")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
go io.Copy(os.Stderr, shimStderrLog)
|
if r.config.ShimDebug {
|
||||||
|
go copyAndClose(os.Stderr, shimStderrLog)
|
||||||
|
} else {
|
||||||
|
go copyAndClose(ioutil.Discard, shimStderrLog)
|
||||||
|
}
|
||||||
|
|
||||||
t, err := newTask(id, ns, pid, s, r.events, r.tasks, bundle)
|
t, err := newTask(id, ns, pid, s, r.events, r.tasks, bundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -391,7 +416,13 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, id string, pid int) error {
|
func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns, id string) error {
|
||||||
|
log.G(ctx).WithFields(logrus.Fields{
|
||||||
|
"id": id,
|
||||||
|
"namespace": ns,
|
||||||
|
}).Warn("cleaning up after shim dead")
|
||||||
|
|
||||||
|
pid, _ := runc.ReadPidFile(filepath.Join(bundle.path, proc.InitPidFile))
|
||||||
ctx = namespaces.WithNamespace(ctx, ns)
|
ctx = namespaces.WithNamespace(ctx, ns)
|
||||||
if err := r.terminate(ctx, bundle, ns, id); err != nil {
|
if err := r.terminate(ctx, bundle, ns, id); err != nil {
|
||||||
if r.config.ShimDebug {
|
if r.config.ShimDebug {
|
||||||
@ -414,6 +445,10 @@ func (r *Runtime) cleanupAfterDeadShim(ctx context.Context, bundle *bundle, ns,
|
|||||||
if err := bundle.Delete(); err != nil {
|
if err := bundle.Delete(); err != nil {
|
||||||
log.G(ctx).WithError(err).Error("delete bundle")
|
log.G(ctx).WithError(err).Error("delete bundle")
|
||||||
}
|
}
|
||||||
|
// kill shim
|
||||||
|
if shimPid, err := runc.ReadPidFile(filepath.Join(bundle.path, "shim.pid")); err == nil && shimPid > 0 {
|
||||||
|
unix.Kill(shimPid, unix.SIGKILL)
|
||||||
|
}
|
||||||
|
|
||||||
r.events.Publish(ctx, runtime.TaskDeleteEventTopic, &eventstypes.TaskDelete{
|
r.events.Publish(ctx, runtime.TaskDeleteEventTopic, &eventstypes.TaskDelete{
|
||||||
ContainerID: id,
|
ContainerID: id,
|
||||||
|
2
vendor/github.com/containerd/containerd/runtime/v1/linux/task.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/v1/linux/task.go
generated
vendored
@ -87,7 +87,7 @@ func (t *Task) Namespace() string {
|
|||||||
// Delete the task and return the exit status
|
// Delete the task and return the exit status
|
||||||
func (t *Task) Delete(ctx context.Context) (*runtime.Exit, error) {
|
func (t *Task) Delete(ctx context.Context) (*runtime.Exit, error) {
|
||||||
rsp, err := t.shim.Delete(ctx, empty)
|
rsp, err := t.shim.Delete(ctx, empty)
|
||||||
if err != nil {
|
if err != nil && !errdefs.IsNotFound(err) {
|
||||||
return nil, errdefs.FromGRPC(err)
|
return nil, errdefs.FromGRPC(err)
|
||||||
}
|
}
|
||||||
t.tasks.Delete(ctx, t.id)
|
t.tasks.Delete(ctx, t.id)
|
||||||
|
17
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
17
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
@ -26,6 +26,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -98,9 +99,9 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
exitHandler()
|
exitHandler()
|
||||||
if stdoutLog != nil {
|
if stdoutLog != nil {
|
||||||
stderrLog.Close()
|
stdoutLog.Close()
|
||||||
}
|
}
|
||||||
if stdoutLog != nil {
|
if stderrLog != nil {
|
||||||
stderrLog.Close()
|
stderrLog.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -110,7 +111,10 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
"debug": debug,
|
"debug": debug,
|
||||||
}).Infof("shim %s started", binary)
|
}).Infof("shim %s started", binary)
|
||||||
|
|
||||||
if err := writeAddress(filepath.Join(config.Path, "address"), address); err != nil {
|
if err := writeFile(filepath.Join(config.Path, "address"), address); err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
if err := writeFile(filepath.Join(config.Path, "shim.pid"), strconv.Itoa(cmd.Process.Pid)); err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
// set shim in cgroup if it is provided
|
// set shim in cgroup if it is provided
|
||||||
@ -172,8 +176,8 @@ func newCommand(binary, daemonAddress string, debug bool, config shim.Config, so
|
|||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// writeAddress writes a address file atomically
|
// writeFile writes a address file atomically
|
||||||
func writeAddress(path, address string) error {
|
func writeFile(path, address string) error {
|
||||||
path, err := filepath.Abs(path)
|
path, err := filepath.Abs(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -219,8 +223,7 @@ func WithConnect(address string, onClose func()) Opt {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
client := ttrpc.NewClient(conn)
|
client := ttrpc.NewClient(conn, ttrpc.WithOnClose(onClose))
|
||||||
client.OnClose(onClose)
|
|
||||||
return shimapi.NewShimClient(client), conn, nil
|
return shimapi.NewShimClient(client), conn, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
15
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
@ -124,6 +124,14 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rootfs := ""
|
||||||
|
if len(mounts) > 0 {
|
||||||
|
rootfs = filepath.Join(r.Bundle, "rootfs")
|
||||||
|
if err := os.Mkdir(rootfs, 0711); err != nil && !os.IsExist(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config := &proc.CreateConfig{
|
config := &proc.CreateConfig{
|
||||||
ID: r.ID,
|
ID: r.ID,
|
||||||
Bundle: r.Bundle,
|
Bundle: r.Bundle,
|
||||||
@ -137,7 +145,6 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
|
|||||||
ParentCheckpoint: r.ParentCheckpoint,
|
ParentCheckpoint: r.ParentCheckpoint,
|
||||||
Options: r.Options,
|
Options: r.Options,
|
||||||
}
|
}
|
||||||
rootfs := filepath.Join(r.Bundle, "rootfs")
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
if err2 := mount.UnmountAll(rootfs, 0); err2 != nil {
|
||||||
@ -169,6 +176,7 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
|
|||||||
s.config.SystemdCgroup,
|
s.config.SystemdCgroup,
|
||||||
s.platform,
|
s.platform,
|
||||||
config,
|
config,
|
||||||
|
rootfs,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
@ -546,7 +554,7 @@ func shouldKillAllOnExit(bundlePath string) (bool, error) {
|
|||||||
|
|
||||||
if bundleSpec.Linux != nil {
|
if bundleSpec.Linux != nil {
|
||||||
for _, ns := range bundleSpec.Linux.Namespaces {
|
for _, ns := range bundleSpec.Linux.Namespaces {
|
||||||
if ns.Type == specs.PIDNamespace {
|
if ns.Type == specs.PIDNamespace && ns.Path == "" {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -632,7 +640,7 @@ func getTopic(ctx context.Context, e interface{}) string {
|
|||||||
return runtime.TaskUnknownTopic
|
return runtime.TaskUnknownTopic
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace, criu string, systemdCgroup bool, platform rproc.Platform, r *proc.CreateConfig) (*proc.Init, error) {
|
func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace, criu string, systemdCgroup bool, platform rproc.Platform, r *proc.CreateConfig, rootfs string) (*proc.Init, error) {
|
||||||
var options runctypes.CreateOptions
|
var options runctypes.CreateOptions
|
||||||
if r.Options != nil {
|
if r.Options != nil {
|
||||||
v, err := typeurl.UnmarshalAny(r.Options)
|
v, err := typeurl.UnmarshalAny(r.Options)
|
||||||
@ -642,7 +650,6 @@ func newInit(ctx context.Context, path, workDir, runtimeRoot, namespace, criu st
|
|||||||
options = *v.(*runctypes.CreateOptions)
|
options = *v.(*runctypes.CreateOptions)
|
||||||
}
|
}
|
||||||
|
|
||||||
rootfs := filepath.Join(path, "rootfs")
|
|
||||||
runtime := proc.NewRunc(runtimeRoot, path, namespace, r.Runtime, criu, systemdCgroup)
|
runtime := proc.NewRunc(runtimeRoot, path, namespace, r.Runtime, criu, systemdCgroup)
|
||||||
p := proc.New(r.ID, runtime, rproc.Stdio{
|
p := proc.New(r.ID, runtime, rproc.Stdio{
|
||||||
Stdin: r.Stdin,
|
Stdin: r.Stdin,
|
||||||
|
16
vendor/github.com/containerd/containerd/runtime/v2/binary.go
generated
vendored
16
vendor/github.com/containerd/containerd/runtime/v2/binary.go
generated
vendored
@ -30,6 +30,7 @@ import (
|
|||||||
client "github.com/containerd/containerd/runtime/v2/shim"
|
client "github.com/containerd/containerd/runtime/v2/shim"
|
||||||
"github.com/containerd/containerd/runtime/v2/task"
|
"github.com/containerd/containerd/runtime/v2/task"
|
||||||
"github.com/containerd/ttrpc"
|
"github.com/containerd/ttrpc"
|
||||||
|
"github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -52,7 +53,7 @@ type binary struct {
|
|||||||
rtTasks *runtime.TaskList
|
rtTasks *runtime.TaskList
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *binary) Start(ctx context.Context) (_ *shim, err error) {
|
func (b *binary) Start(ctx context.Context, opts *types.Any, onClose func()) (_ *shim, err error) {
|
||||||
args := []string{"-id", b.bundle.ID}
|
args := []string{"-id", b.bundle.ID}
|
||||||
if logrus.GetLevel() == logrus.DebugLevel {
|
if logrus.GetLevel() == logrus.DebugLevel {
|
||||||
args = append(args, "-debug")
|
args = append(args, "-debug")
|
||||||
@ -64,6 +65,7 @@ func (b *binary) Start(ctx context.Context) (_ *shim, err error) {
|
|||||||
b.runtime,
|
b.runtime,
|
||||||
b.containerdAddress,
|
b.containerdAddress,
|
||||||
b.bundle.Path,
|
b.bundle.Path,
|
||||||
|
opts,
|
||||||
args...,
|
args...,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -84,8 +86,13 @@ func (b *binary) Start(ctx context.Context) (_ *shim, err error) {
|
|||||||
go func() {
|
go func() {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if _, err := io.Copy(os.Stderr, f); err != nil {
|
if _, err := io.Copy(os.Stderr, f); err != nil {
|
||||||
|
// When using a multi-container shim the 2nd to Nth container in the
|
||||||
|
// shim will not have a seperate log pipe. Ignore the failure log
|
||||||
|
// message here when the shim connect times out.
|
||||||
|
if !os.IsNotExist(errors.Cause(err)) {
|
||||||
log.G(ctx).WithError(err).Error("copy shim log")
|
log.G(ctx).WithError(err).Error("copy shim log")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
out, err := cmd.CombinedOutput()
|
out, err := cmd.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -96,8 +103,7 @@ func (b *binary) Start(ctx context.Context) (_ *shim, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
client := ttrpc.NewClient(conn)
|
client := ttrpc.NewClient(conn, ttrpc.WithOnClose(onClose))
|
||||||
client.OnClose(func() { conn.Close() })
|
|
||||||
return &shim{
|
return &shim{
|
||||||
bundle: b.bundle,
|
bundle: b.bundle,
|
||||||
client: client,
|
client: client,
|
||||||
@ -122,6 +128,7 @@ func (b *binary) Delete(ctx context.Context) (*runtime.Exit, error) {
|
|||||||
b.runtime,
|
b.runtime,
|
||||||
b.containerdAddress,
|
b.containerdAddress,
|
||||||
bundlePath,
|
bundlePath,
|
||||||
|
nil,
|
||||||
"-id", b.bundle.ID,
|
"-id", b.bundle.ID,
|
||||||
"-bundle", b.bundle.Path,
|
"-bundle", b.bundle.Path,
|
||||||
"delete")
|
"delete")
|
||||||
@ -148,9 +155,6 @@ func (b *binary) Delete(ctx context.Context) (*runtime.Exit, error) {
|
|||||||
if err := b.bundle.Delete(); err != nil {
|
if err := b.bundle.Delete(); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// remove self from the runtime task list
|
|
||||||
// this seems dirty but it cleans up the API across runtimes, tasks, and the service
|
|
||||||
b.rtTasks.Delete(ctx, b.bundle.ID)
|
|
||||||
return &runtime.Exit{
|
return &runtime.Exit{
|
||||||
Status: response.ExitStatus,
|
Status: response.ExitStatus,
|
||||||
Timestamp: response.ExitedAt,
|
Timestamp: response.ExitedAt,
|
||||||
|
20
vendor/github.com/containerd/containerd/runtime/v2/bundle.go
generated
vendored
20
vendor/github.com/containerd/containerd/runtime/v2/bundle.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/containerd/containerd/identifiers"
|
"github.com/containerd/containerd/identifiers"
|
||||||
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -79,6 +80,11 @@ func NewBundle(ctx context.Context, root, state, id string, spec []byte) (b *Bun
|
|||||||
if err := os.MkdirAll(filepath.Dir(work), 0711); err != nil {
|
if err := os.MkdirAll(filepath.Dir(work), 0711); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
rootfs := filepath.Join(b.Path, "rootfs")
|
||||||
|
if err := os.MkdirAll(rootfs, 0711); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
paths = append(paths, rootfs)
|
||||||
if err := os.Mkdir(work, 0711); err != nil {
|
if err := os.Mkdir(work, 0711); err != nil {
|
||||||
if !os.IsExist(err) {
|
if !os.IsExist(err) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -89,10 +95,6 @@ func NewBundle(ctx context.Context, root, state, id string, spec []byte) (b *Bun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
paths = append(paths, work)
|
paths = append(paths, work)
|
||||||
// create rootfs dir
|
|
||||||
if err := os.Mkdir(filepath.Join(b.Path, "rootfs"), 0711); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// symlink workdir
|
// symlink workdir
|
||||||
if err := os.Symlink(work, filepath.Join(b.Path, "work")); err != nil {
|
if err := os.Symlink(work, filepath.Join(b.Path, "work")); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -115,6 +117,13 @@ type Bundle struct {
|
|||||||
// Delete a bundle atomically
|
// Delete a bundle atomically
|
||||||
func (b *Bundle) Delete() error {
|
func (b *Bundle) Delete() error {
|
||||||
work, werr := os.Readlink(filepath.Join(b.Path, "work"))
|
work, werr := os.Readlink(filepath.Join(b.Path, "work"))
|
||||||
|
rootfs := filepath.Join(b.Path, "rootfs")
|
||||||
|
if err := mount.UnmountAll(rootfs, 0); err != nil {
|
||||||
|
return errors.Wrapf(err, "unmount rootfs %s", rootfs)
|
||||||
|
}
|
||||||
|
if err := os.Remove(rootfs); err != nil && os.IsNotExist(err) {
|
||||||
|
return errors.Wrap(err, "failed to remove bundle rootfs")
|
||||||
|
}
|
||||||
err := atomicDelete(b.Path)
|
err := atomicDelete(b.Path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if werr == nil {
|
if werr == nil {
|
||||||
@ -138,6 +147,9 @@ func atomicDelete(path string) error {
|
|||||||
// create a hidden dir for an atomic removal
|
// create a hidden dir for an atomic removal
|
||||||
atomicPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
atomicPath := filepath.Join(filepath.Dir(path), fmt.Sprintf(".%s", filepath.Base(path)))
|
||||||
if err := os.Rename(path, atomicPath); err != nil {
|
if err := os.Rename(path, atomicPath); err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return os.RemoveAll(atomicPath)
|
return os.RemoveAll(atomicPath)
|
||||||
|
41
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
41
vendor/github.com/containerd/containerd/runtime/v2/manager.go
generated
vendored
@ -113,6 +113,10 @@ func (m *TaskManager) ID() string {
|
|||||||
|
|
||||||
// Create a new task
|
// Create a new task
|
||||||
func (m *TaskManager) Create(ctx context.Context, id string, opts runtime.CreateOpts) (_ runtime.Task, err error) {
|
func (m *TaskManager) Create(ctx context.Context, id string, opts runtime.CreateOpts) (_ runtime.Task, err error) {
|
||||||
|
ns, err := namespaces.NamespaceRequired(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
bundle, err := NewBundle(ctx, m.root, m.state, id, opts.Spec.Value)
|
bundle, err := NewBundle(ctx, m.root, m.state, id, opts.Spec.Value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -122,8 +126,21 @@ func (m *TaskManager) Create(ctx context.Context, id string, opts runtime.Create
|
|||||||
bundle.Delete()
|
bundle.Delete()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
topts := opts.TaskOptions
|
||||||
|
if topts == nil {
|
||||||
|
topts = opts.RuntimeOptions
|
||||||
|
}
|
||||||
|
|
||||||
b := shimBinary(ctx, bundle, opts.Runtime, m.containerdAddress, m.events, m.tasks)
|
b := shimBinary(ctx, bundle, opts.Runtime, m.containerdAddress, m.events, m.tasks)
|
||||||
shim, err := b.Start(ctx)
|
shim, err := b.Start(ctx, topts, func() {
|
||||||
|
log.G(ctx).WithField("id", id).Info("shim disconnected")
|
||||||
|
_, err := m.tasks.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
// Task was never started or was already successfully deleted
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cleanupAfterDeadShim(context.Background(), id, ns, m.events, b)
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -202,6 +219,10 @@ func (m *TaskManager) loadTasks(ctx context.Context) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
id := sd.Name()
|
id := sd.Name()
|
||||||
|
// skip hidden directories
|
||||||
|
if len(id) > 0 && id[0] == '.' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
bundle, err := LoadBundle(ctx, m.state, id)
|
bundle, err := LoadBundle(ctx, m.state, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// fine to return error here, it is a programmer error if the context
|
// fine to return error here, it is a programmer error if the context
|
||||||
@ -219,12 +240,9 @@ func (m *TaskManager) loadTasks(ctx context.Context) error {
|
|||||||
bundle.Delete()
|
bundle.Delete()
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
shim, err := loadShim(ctx, bundle, m.events, m.tasks)
|
|
||||||
if err != nil {
|
|
||||||
log.G(ctx).WithError(err).Errorf("cleanup dead shim %s", id)
|
|
||||||
container, err := m.container(ctx, id)
|
container, err := m.container(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ctx).WithError(err).Errorf("loading dead container %s", id)
|
log.G(ctx).WithError(err).Errorf("loading container %s", id)
|
||||||
if err := mount.UnmountAll(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
|
if err := mount.UnmountAll(filepath.Join(bundle.Path, "rootfs"), 0); err != nil {
|
||||||
log.G(ctx).WithError(err).Errorf("forceful unmount of rootfs %s", id)
|
log.G(ctx).WithError(err).Errorf("forceful unmount of rootfs %s", id)
|
||||||
}
|
}
|
||||||
@ -232,10 +250,17 @@ func (m *TaskManager) loadTasks(ctx context.Context) error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
binaryCall := shimBinary(ctx, bundle, container.Runtime.Name, m.containerdAddress, m.events, m.tasks)
|
binaryCall := shimBinary(ctx, bundle, container.Runtime.Name, m.containerdAddress, m.events, m.tasks)
|
||||||
if _, err := binaryCall.Delete(ctx); err != nil {
|
shim, err := loadShim(ctx, bundle, m.events, m.tasks, func() {
|
||||||
log.G(ctx).WithError(err).Errorf("binary call to delete for %s", id)
|
log.G(ctx).WithField("id", id).Info("shim disconnected")
|
||||||
continue
|
_, err := m.tasks.Get(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
// Task was never started or was already successfully deleted
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
cleanupAfterDeadShim(context.Background(), id, ns, m.events, binaryCall)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
cleanupAfterDeadShim(ctx, id, ns, m.events, binaryCall)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
m.tasks.Add(ctx, shim)
|
m.tasks.Add(ctx, shim)
|
||||||
|
99
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
99
vendor/github.com/containerd/containerd/runtime/v2/shim.go
generated
vendored
@ -24,18 +24,21 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
eventstypes "github.com/containerd/containerd/api/events"
|
||||||
"github.com/containerd/containerd/api/types"
|
"github.com/containerd/containerd/api/types"
|
||||||
tasktypes "github.com/containerd/containerd/api/types/task"
|
tasktypes "github.com/containerd/containerd/api/types/task"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/events/exchange"
|
"github.com/containerd/containerd/events/exchange"
|
||||||
"github.com/containerd/containerd/identifiers"
|
"github.com/containerd/containerd/identifiers"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/runtime"
|
"github.com/containerd/containerd/runtime"
|
||||||
client "github.com/containerd/containerd/runtime/v2/shim"
|
client "github.com/containerd/containerd/runtime/v2/shim"
|
||||||
"github.com/containerd/containerd/runtime/v2/task"
|
"github.com/containerd/containerd/runtime/v2/task"
|
||||||
"github.com/containerd/ttrpc"
|
"github.com/containerd/ttrpc"
|
||||||
ptypes "github.com/gogo/protobuf/types"
|
ptypes "github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func loadAddress(path string) (string, error) {
|
func loadAddress(path string) (string, error) {
|
||||||
@ -46,7 +49,7 @@ func loadAddress(path string) (string, error) {
|
|||||||
return string(data), nil
|
return string(data), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt *runtime.TaskList) (_ *shim, err error) {
|
func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt *runtime.TaskList, onClose func()) (_ *shim, err error) {
|
||||||
address, err := loadAddress(filepath.Join(bundle.Path, "address"))
|
address, err := loadAddress(filepath.Join(bundle.Path, "address"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -55,6 +58,11 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
f, err := openShimLog(ctx, bundle)
|
f, err := openShimLog(ctx, bundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "open shim log pipe")
|
return nil, errors.Wrap(err, "open shim log pipe")
|
||||||
@ -70,12 +78,21 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt
|
|||||||
go func() {
|
go func() {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if _, err := io.Copy(os.Stderr, f); err != nil {
|
if _, err := io.Copy(os.Stderr, f); err != nil {
|
||||||
|
// When using a multi-container shim the 2nd to Nth container in the
|
||||||
|
// shim will not have a seperate log pipe. Ignore the failure log
|
||||||
|
// message here when the shim connect times out.
|
||||||
|
if !os.IsNotExist(errors.Cause(err)) {
|
||||||
log.G(ctx).WithError(err).Error("copy shim log")
|
log.G(ctx).WithError(err).Error("copy shim log")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
client := ttrpc.NewClient(conn)
|
client := ttrpc.NewClient(conn, ttrpc.WithOnClose(onClose))
|
||||||
client.OnClose(func() { conn.Close() })
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
client.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
s := &shim{
|
s := &shim{
|
||||||
client: client,
|
client: client,
|
||||||
task: task.NewTaskClient(client),
|
task: task.NewTaskClient(client),
|
||||||
@ -89,6 +106,52 @@ func loadShim(ctx context.Context, bundle *Bundle, events *exchange.Exchange, rt
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func cleanupAfterDeadShim(ctx context.Context, id, ns string, events *exchange.Exchange, binaryCall *binary) {
|
||||||
|
ctx = namespaces.WithNamespace(ctx, ns)
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
log.G(ctx).WithFields(logrus.Fields{
|
||||||
|
"id": id,
|
||||||
|
"namespace": ns,
|
||||||
|
}).Warn("cleaning up after shim disconnected")
|
||||||
|
response, err := binaryCall.Delete(ctx)
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
||||||
|
"id": id,
|
||||||
|
"namespace": ns,
|
||||||
|
}).Warn("failed to clean up after shim disconnected")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pid uint32
|
||||||
|
exitStatus uint32
|
||||||
|
exitedAt time.Time
|
||||||
|
)
|
||||||
|
if response != nil {
|
||||||
|
pid = response.Pid
|
||||||
|
exitStatus = response.Status
|
||||||
|
exitedAt = response.Timestamp
|
||||||
|
} else {
|
||||||
|
exitStatus = 255
|
||||||
|
exitedAt = time.Now()
|
||||||
|
}
|
||||||
|
events.Publish(ctx, runtime.TaskExitEventTopic, &eventstypes.TaskExit{
|
||||||
|
ContainerID: id,
|
||||||
|
ID: id,
|
||||||
|
Pid: pid,
|
||||||
|
ExitStatus: exitStatus,
|
||||||
|
ExitedAt: exitedAt,
|
||||||
|
})
|
||||||
|
|
||||||
|
events.Publish(ctx, runtime.TaskDeleteEventTopic, &eventstypes.TaskDelete{
|
||||||
|
ContainerID: id,
|
||||||
|
Pid: pid,
|
||||||
|
ExitStatus: exitStatus,
|
||||||
|
ExitedAt: exitedAt,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type shim struct {
|
type shim struct {
|
||||||
bundle *Bundle
|
bundle *Bundle
|
||||||
client *ttrpc.Client
|
client *ttrpc.Client
|
||||||
@ -120,19 +183,9 @@ func (s *shim) Shutdown(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *shim) waitShutdown(ctx context.Context) error {
|
func (s *shim) waitShutdown(ctx context.Context) error {
|
||||||
dead := make(chan struct{})
|
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)
|
||||||
go func() {
|
defer cancel()
|
||||||
if err := s.Shutdown(ctx); err != nil {
|
return s.Shutdown(ctx)
|
||||||
log.G(ctx).WithError(err).Error("shim shutdown error")
|
|
||||||
}
|
|
||||||
close(dead)
|
|
||||||
}()
|
|
||||||
select {
|
|
||||||
case <-time.After(3 * time.Second):
|
|
||||||
return errors.New("failed to shutdown shim in time")
|
|
||||||
case <-dead:
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID of the shim/task
|
// ID of the shim/task
|
||||||
@ -152,18 +205,18 @@ func (s *shim) Delete(ctx context.Context) (*runtime.Exit, error) {
|
|||||||
response, err := s.task.Delete(ctx, &task.DeleteRequest{
|
response, err := s.task.Delete(ctx, &task.DeleteRequest{
|
||||||
ID: s.ID(),
|
ID: s.ID(),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil && !errdefs.IsNotFound(err) {
|
||||||
return nil, errdefs.FromGRPC(err)
|
return nil, errdefs.FromGRPC(err)
|
||||||
}
|
}
|
||||||
if err := s.waitShutdown(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := s.bundle.Delete(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
// remove self from the runtime task list
|
// remove self from the runtime task list
|
||||||
// this seems dirty but it cleans up the API across runtimes, tasks, and the service
|
// this seems dirty but it cleans up the API across runtimes, tasks, and the service
|
||||||
s.rtTasks.Delete(ctx, s.ID())
|
s.rtTasks.Delete(ctx, s.ID())
|
||||||
|
if err := s.waitShutdown(ctx); err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("failed to shutdown shim")
|
||||||
|
}
|
||||||
|
if err := s.bundle.Delete(); err != nil {
|
||||||
|
log.G(ctx).WithError(err).Error("failed to delete bundle")
|
||||||
|
}
|
||||||
return &runtime.Exit{
|
return &runtime.Exit{
|
||||||
Status: response.ExitStatus,
|
Status: response.ExitStatus,
|
||||||
Timestamp: response.ExitedAt,
|
Timestamp: response.ExitedAt,
|
||||||
|
87
vendor/github.com/containerd/containerd/runtime/v2/shim/dialer.go
generated
vendored
87
vendor/github.com/containerd/containerd/runtime/v2/shim/dialer.go
generated
vendored
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright The containerd Authors.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package shim
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"sync"
|
|
||||||
|
|
||||||
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
|
||||||
"github.com/containerd/ttrpc"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type dialConnect func() (net.Conn, error)
|
|
||||||
|
|
||||||
var errDialerClosed = errors.New("events dialer is closed")
|
|
||||||
|
|
||||||
func newDialier(newFn dialConnect) *dialer {
|
|
||||||
return &dialer{
|
|
||||||
newFn: newFn,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type dialer struct {
|
|
||||||
mu sync.Mutex
|
|
||||||
|
|
||||||
newFn dialConnect
|
|
||||||
service v1.EventsService
|
|
||||||
conn net.Conn
|
|
||||||
closed bool
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *dialer) Get() (v1.EventsService, error) {
|
|
||||||
d.mu.Lock()
|
|
||||||
defer d.mu.Unlock()
|
|
||||||
|
|
||||||
if d.closed {
|
|
||||||
return nil, errDialerClosed
|
|
||||||
}
|
|
||||||
if d.service == nil {
|
|
||||||
conn, err := d.newFn()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
d.conn = conn
|
|
||||||
d.service = v1.NewEventsClient(ttrpc.NewClient(conn))
|
|
||||||
}
|
|
||||||
return d.service, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *dialer) Put(err error) {
|
|
||||||
if err != nil {
|
|
||||||
d.mu.Lock()
|
|
||||||
d.conn.Close()
|
|
||||||
d.service = nil
|
|
||||||
d.mu.Unlock()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *dialer) Close() (err error) {
|
|
||||||
d.mu.Lock()
|
|
||||||
if d.closed {
|
|
||||||
return errDialerClosed
|
|
||||||
}
|
|
||||||
if d.conn != nil {
|
|
||||||
err = d.conn.Close()
|
|
||||||
}
|
|
||||||
d.service = nil
|
|
||||||
d.closed = true
|
|
||||||
d.mu.Unlock()
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
69
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
69
vendor/github.com/containerd/containerd/runtime/v2/shim/publisher.go
generated
vendored
@ -18,13 +18,14 @@ package shim
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
v1 "github.com/containerd/containerd/api/services/ttrpc/events/v1"
|
||||||
"github.com/containerd/containerd/events"
|
"github.com/containerd/containerd/events"
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
|
"github.com/containerd/containerd/pkg/ttrpcutil"
|
||||||
|
"github.com/containerd/ttrpc"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -40,20 +41,24 @@ type item struct {
|
|||||||
count int
|
count int
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPublisher(address string) *remoteEventsPublisher {
|
func newPublisher(address string) (*remoteEventsPublisher, error) {
|
||||||
|
client, err := ttrpcutil.NewClient(address)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
l := &remoteEventsPublisher{
|
l := &remoteEventsPublisher{
|
||||||
dialer: newDialier(func() (net.Conn, error) {
|
client: client,
|
||||||
return connect(address, dial)
|
|
||||||
}),
|
|
||||||
closed: make(chan struct{}),
|
closed: make(chan struct{}),
|
||||||
requeue: make(chan *item, queueSize),
|
requeue: make(chan *item, queueSize),
|
||||||
}
|
}
|
||||||
|
|
||||||
go l.processQueue()
|
go l.processQueue()
|
||||||
return l
|
return l, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type remoteEventsPublisher struct {
|
type remoteEventsPublisher struct {
|
||||||
dialer *dialer
|
client *ttrpcutil.Client
|
||||||
closed chan struct{}
|
closed chan struct{}
|
||||||
closer sync.Once
|
closer sync.Once
|
||||||
requeue chan *item
|
requeue chan *item
|
||||||
@ -64,7 +69,7 @@ func (l *remoteEventsPublisher) Done() <-chan struct{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *remoteEventsPublisher) Close() (err error) {
|
func (l *remoteEventsPublisher) Close() (err error) {
|
||||||
err = l.dialer.Close()
|
err = l.client.Close()
|
||||||
l.closer.Do(func() {
|
l.closer.Do(func() {
|
||||||
close(l.closed)
|
close(l.closed)
|
||||||
})
|
})
|
||||||
@ -79,18 +84,7 @@ func (l *remoteEventsPublisher) processQueue() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
client, err := l.dialer.Get()
|
if err := l.forwardRequest(i.ctx, &v1.ForwardRequest{Envelope: i.ev}); err != nil {
|
||||||
if err != nil {
|
|
||||||
l.dialer.Put(err)
|
|
||||||
|
|
||||||
l.queue(i)
|
|
||||||
logrus.WithError(err).Error("get events client")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if _, err := client.Forward(i.ctx, &v1.ForwardRequest{
|
|
||||||
Envelope: i.ev,
|
|
||||||
}); err != nil {
|
|
||||||
l.dialer.Put(err)
|
|
||||||
logrus.WithError(err).Error("forward event")
|
logrus.WithError(err).Error("forward event")
|
||||||
l.queue(i)
|
l.queue(i)
|
||||||
}
|
}
|
||||||
@ -124,22 +118,33 @@ func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event
|
|||||||
},
|
},
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
}
|
}
|
||||||
client, err := l.dialer.Get()
|
|
||||||
if err != nil {
|
if err := l.forwardRequest(i.ctx, &v1.ForwardRequest{Envelope: i.ev}); err != nil {
|
||||||
l.dialer.Put(err)
|
|
||||||
l.queue(i)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := client.Forward(i.ctx, &v1.ForwardRequest{
|
|
||||||
Envelope: i.ev,
|
|
||||||
}); err != nil {
|
|
||||||
l.dialer.Put(err)
|
|
||||||
l.queue(i)
|
l.queue(i)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func connect(address string, d func(string, time.Duration) (net.Conn, error)) (net.Conn, error) {
|
func (l *remoteEventsPublisher) forwardRequest(ctx context.Context, req *v1.ForwardRequest) error {
|
||||||
return d(address, 5*time.Second)
|
_, err := l.client.EventsService().Forward(ctx, req)
|
||||||
|
if err == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != ttrpc.ErrClosed {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconnect and retry request
|
||||||
|
if err := l.client.Reconnect(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := l.client.EventsService().Forward(ctx, req); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
12
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
12
vendor/github.com/containerd/containerd/runtime/v2/shim/shim.go
generated
vendored
@ -78,6 +78,8 @@ type Config struct {
|
|||||||
NoSubreaper bool
|
NoSubreaper bool
|
||||||
// NoReaper disables the shim binary from reaping any child process implicitly
|
// NoReaper disables the shim binary from reaping any child process implicitly
|
||||||
NoReaper bool
|
NoReaper bool
|
||||||
|
// NoSetupLogger disables automatic configuration of logrus to use the shim FIFO
|
||||||
|
NoSetupLogger bool
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -160,9 +162,13 @@ func run(id string, initFunc Init, config Config) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
address := fmt.Sprintf("%s.ttrpc", addressFlag)
|
|
||||||
|
|
||||||
publisher := newPublisher(address)
|
address := fmt.Sprintf("%s.ttrpc", addressFlag)
|
||||||
|
publisher, err := newPublisher(address)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
defer publisher.Close()
|
defer publisher.Close()
|
||||||
|
|
||||||
if namespaceFlag == "" {
|
if namespaceFlag == "" {
|
||||||
@ -206,9 +212,11 @@ func run(id string, initFunc Init, config Config) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
default:
|
default:
|
||||||
|
if !config.NoSetupLogger {
|
||||||
if err := setLogger(ctx, idFlag); err != nil {
|
if err := setLogger(ctx, idFlag); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
client := NewShimClient(ctx, service, signals)
|
client := NewShimClient(ctx, service, signals)
|
||||||
if err := client.Serve(); err != nil {
|
if err := client.Serve(); err != nil {
|
||||||
if err != context.Canceled {
|
if err != context.Canceled {
|
||||||
|
7
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
7
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
@ -24,9 +24,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/containerd/fifo"
|
"github.com/containerd/fifo"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -93,8 +91,3 @@ func handleSignals(ctx context.Context, logger *logrus.Entry, signals chan os.Si
|
|||||||
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
||||||
return fifo.OpenFifo(ctx, "log", unix.O_WRONLY, 0700)
|
return fifo.OpenFifo(ctx, "log", unix.O_WRONLY, 0700)
|
||||||
}
|
}
|
||||||
|
|
||||||
func dial(address string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
address = strings.TrimPrefix(address, "unix://")
|
|
||||||
return net.DialTimeout("unix", address, timeout)
|
|
||||||
}
|
|
||||||
|
33
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
33
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
@ -26,7 +26,6 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
winio "github.com/Microsoft/go-winio"
|
winio "github.com/Microsoft/go-winio"
|
||||||
@ -286,35 +285,3 @@ func openLog(ctx context.Context, id string) (io.Writer, error) {
|
|||||||
go dswl.beginAccept()
|
go dswl.beginAccept()
|
||||||
return dswl, nil
|
return dswl, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func dial(address string, timeout time.Duration) (net.Conn, error) {
|
|
||||||
var c net.Conn
|
|
||||||
var lastError error
|
|
||||||
timedOutError := errors.Errorf("timed out waiting for npipe %s", address)
|
|
||||||
start := time.Now()
|
|
||||||
for {
|
|
||||||
remaining := timeout - time.Since(start)
|
|
||||||
if remaining <= 0 {
|
|
||||||
lastError = timedOutError
|
|
||||||
break
|
|
||||||
}
|
|
||||||
c, lastError = winio.DialPipe(address, &remaining)
|
|
||||||
if lastError == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if !os.IsNotExist(lastError) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
// There is nobody serving the pipe. We limit the timeout for this case
|
|
||||||
// to 5 seconds because any shim that would serve this endpoint should
|
|
||||||
// serve it within 5 seconds. We use the passed in timeout for the
|
|
||||||
// `DialPipe` timeout if the pipe exists however to give the pipe time
|
|
||||||
// to `Accept` the connection.
|
|
||||||
if time.Since(start) >= 5*time.Second {
|
|
||||||
lastError = timedOutError
|
|
||||||
break
|
|
||||||
}
|
|
||||||
time.Sleep(10 * time.Millisecond)
|
|
||||||
}
|
|
||||||
return c, lastError
|
|
||||||
}
|
|
||||||
|
12
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
12
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
@ -17,6 +17,7 @@
|
|||||||
package shim
|
package shim
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -29,13 +30,15 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
"github.com/gogo/protobuf/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var runtimePaths sync.Map
|
var runtimePaths sync.Map
|
||||||
|
|
||||||
// Command returns the shim command with the provided args and configuration
|
// Command returns the shim command with the provided args and configuration
|
||||||
func Command(ctx context.Context, runtime, containerdAddress, path string, cmdArgs ...string) (*exec.Cmd, error) {
|
func Command(ctx context.Context, runtime, containerdAddress, path string, opts *types.Any, cmdArgs ...string) (*exec.Cmd, error) {
|
||||||
ns, err := namespaces.NamespaceRequired(ctx)
|
ns, err := namespaces.NamespaceRequired(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -94,6 +97,13 @@ func Command(ctx context.Context, runtime, containerdAddress, path string, cmdAr
|
|||||||
cmd.Dir = path
|
cmd.Dir = path
|
||||||
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
||||||
cmd.SysProcAttr = getSysProcAttr()
|
cmd.SysProcAttr = getSysProcAttr()
|
||||||
|
if opts != nil {
|
||||||
|
d, err := proto.Marshal(opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
cmd.Stdin = bytes.NewReader(d)
|
||||||
|
}
|
||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
vendor/github.com/containerd/containerd/runtime/v2/shim_unix.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/v2/shim_unix.go
generated
vendored
@ -28,5 +28,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) {
|
func openShimLog(ctx context.Context, bundle *Bundle) (io.ReadCloser, error) {
|
||||||
return fifo.OpenFifo(ctx, filepath.Join(bundle.Path, "log"), unix.O_RDWR|unix.O_CREAT, 0700)
|
return fifo.OpenFifo(ctx, filepath.Join(bundle.Path, "log"), unix.O_RDONLY|unix.O_CREAT|unix.O_NONBLOCK, 0700)
|
||||||
}
|
}
|
||||||
|
4
vendor/github.com/containerd/containerd/services/diff/local.go
generated
vendored
4
vendor/github.com/containerd/containerd/services/diff/local.go
generated
vendored
@ -99,8 +99,10 @@ func (l *local) Apply(ctx context.Context, er *diffapi.ApplyRequest, _ ...grpc.C
|
|||||||
mounts = toMounts(er.Mounts)
|
mounts = toMounts(er.Mounts)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var opts []diff.ApplyOpt
|
||||||
|
|
||||||
for _, differ := range l.differs {
|
for _, differ := range l.differs {
|
||||||
ocidesc, err = differ.Apply(ctx, desc, mounts)
|
ocidesc, err = differ.Apply(ctx, desc, mounts, opts...)
|
||||||
if !errdefs.IsNotImplemented(err) {
|
if !errdefs.IsNotImplemented(err) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
24
vendor/github.com/containerd/containerd/services/leases/local.go
generated
vendored
24
vendor/github.com/containerd/containerd/services/leases/local.go
generated
vendored
@ -107,3 +107,27 @@ func (l *local) List(ctx context.Context, filters ...string) ([]leases.Lease, er
|
|||||||
}
|
}
|
||||||
return ll, nil
|
return ll, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *local) AddResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
return l.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
return metadata.NewLeaseManager(tx).AddResource(ctx, lease, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *local) DeleteResource(ctx context.Context, lease leases.Lease, r leases.Resource) error {
|
||||||
|
return l.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
return metadata.NewLeaseManager(tx).DeleteResource(ctx, lease, r)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *local) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
|
||||||
|
var rs []leases.Resource
|
||||||
|
if err := l.db.View(func(tx *bolt.Tx) error {
|
||||||
|
var err error
|
||||||
|
rs, err = metadata.NewLeaseManager(tx).ListResources(ctx, lease)
|
||||||
|
return err
|
||||||
|
}); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return rs, nil
|
||||||
|
}
|
||||||
|
50
vendor/github.com/containerd/containerd/services/leases/service.go
generated
vendored
50
vendor/github.com/containerd/containerd/services/leases/service.go
generated
vendored
@ -113,6 +113,56 @@ func (s *service) List(ctx context.Context, r *api.ListRequest) (*api.ListRespon
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *service) AddResource(ctx context.Context, r *api.AddResourceRequest) (*ptypes.Empty, error) {
|
||||||
|
lease := leases.Lease{
|
||||||
|
ID: r.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.lm.AddResource(ctx, lease, leases.Resource{
|
||||||
|
ID: r.Resource.ID,
|
||||||
|
Type: r.Resource.Type,
|
||||||
|
}); err != nil {
|
||||||
|
return nil, errdefs.ToGRPC(err)
|
||||||
|
}
|
||||||
|
return &ptypes.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) DeleteResource(ctx context.Context, r *api.DeleteResourceRequest) (*ptypes.Empty, error) {
|
||||||
|
lease := leases.Lease{
|
||||||
|
ID: r.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := s.lm.DeleteResource(ctx, lease, leases.Resource{
|
||||||
|
ID: r.Resource.ID,
|
||||||
|
Type: r.Resource.Type,
|
||||||
|
}); err != nil {
|
||||||
|
return nil, errdefs.ToGRPC(err)
|
||||||
|
}
|
||||||
|
return &ptypes.Empty{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *service) ListResources(ctx context.Context, r *api.ListResourcesRequest) (*api.ListResourcesResponse, error) {
|
||||||
|
lease := leases.Lease{
|
||||||
|
ID: r.ID,
|
||||||
|
}
|
||||||
|
|
||||||
|
rs, err := s.lm.ListResources(ctx, lease)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errdefs.ToGRPC(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiResources := make([]api.Resource, 0, len(rs))
|
||||||
|
for _, i := range rs {
|
||||||
|
apiResources = append(apiResources, api.Resource{
|
||||||
|
ID: i.ID,
|
||||||
|
Type: i.Type,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return &api.ListResourcesResponse{
|
||||||
|
Resources: apiResources,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func leaseToGRPC(l leases.Lease) *api.Lease {
|
func leaseToGRPC(l leases.Lease) *api.Lease {
|
||||||
return &api.Lease{
|
return &api.Lease{
|
||||||
ID: l.ID,
|
ID: l.ID,
|
||||||
|
79
vendor/github.com/containerd/containerd/services/server/config/config.go
generated
vendored
79
vendor/github.com/containerd/containerd/services/server/config/config.go
generated
vendored
@ -17,13 +17,18 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config provides containerd configuration data for the server
|
// Config provides containerd configuration data for the server
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
// Version of the config file
|
||||||
|
Version int `toml:"version"`
|
||||||
// Root is the path to a directory where containerd will store persistent data
|
// Root is the path to a directory where containerd will store persistent data
|
||||||
Root string `toml:"root"`
|
Root string `toml:"root"`
|
||||||
// State is the path to a directory where containerd will store transient data
|
// State is the path to a directory where containerd will store transient data
|
||||||
@ -54,6 +59,42 @@ type Config struct {
|
|||||||
md toml.MetaData
|
md toml.MetaData
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetVersion returns the config file's version
|
||||||
|
func (c *Config) GetVersion() int {
|
||||||
|
if c.Version == 0 {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
return c.Version
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateV2 validates the config for a v2 file
|
||||||
|
func (c *Config) ValidateV2() error {
|
||||||
|
if c.GetVersion() != 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, p := range c.DisabledPlugins {
|
||||||
|
if len(strings.Split(p, ".")) < 4 {
|
||||||
|
return errors.Errorf("invalid disabled plugin URI %q expect io.containerd.x.vx", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, p := range c.RequiredPlugins {
|
||||||
|
if len(strings.Split(p, ".")) < 4 {
|
||||||
|
return errors.Errorf("invalid required plugin URI %q expect io.containerd.x.vx", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for p := range c.Plugins {
|
||||||
|
if len(strings.Split(p, ".")) < 4 {
|
||||||
|
return errors.Errorf("invalid plugin key URI %q expect io.containerd.x.vx", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for p := range c.ProxyPlugins {
|
||||||
|
if len(strings.Split(p, ".")) < 4 {
|
||||||
|
return errors.Errorf("invalid proxy plugin key URI %q expect io.containerd.x.vx", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// GRPCConfig provides GRPC configuration for the socket
|
// GRPCConfig provides GRPC configuration for the socket
|
||||||
type GRPCConfig struct {
|
type GRPCConfig struct {
|
||||||
Address string `toml:"address"`
|
Address string `toml:"address"`
|
||||||
@ -130,15 +171,19 @@ func (bc *BoltConfig) Validate() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Decode unmarshals a plugin specific configuration by plugin id
|
// Decode unmarshals a plugin specific configuration by plugin id
|
||||||
func (c *Config) Decode(id string, v interface{}) (interface{}, error) {
|
func (c *Config) Decode(p *plugin.Registration) (interface{}, error) {
|
||||||
|
id := p.URI()
|
||||||
|
if c.GetVersion() == 1 {
|
||||||
|
id = p.ID
|
||||||
|
}
|
||||||
data, ok := c.Plugins[id]
|
data, ok := c.Plugins[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return v, nil
|
return p.Config, nil
|
||||||
}
|
}
|
||||||
if err := c.md.PrimitiveDecode(data, v); err != nil {
|
if err := c.md.PrimitiveDecode(data, p.Config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return v, nil
|
return p.Config, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadConfig loads the containerd server config from the provided path
|
// LoadConfig loads the containerd server config from the provided path
|
||||||
@ -151,5 +196,29 @@ func LoadConfig(path string, v *Config) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.md = md
|
v.md = md
|
||||||
return nil
|
return v.ValidateV2()
|
||||||
|
}
|
||||||
|
|
||||||
|
// V1DisabledFilter matches based on ID
|
||||||
|
func V1DisabledFilter(list []string) plugin.DisableFilter {
|
||||||
|
set := make(map[string]struct{}, len(list))
|
||||||
|
for _, l := range list {
|
||||||
|
set[l] = struct{}{}
|
||||||
|
}
|
||||||
|
return func(r *plugin.Registration) bool {
|
||||||
|
_, ok := set[r.ID]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// V2DisabledFilter matches based on URI
|
||||||
|
func V2DisabledFilter(list []string) plugin.DisableFilter {
|
||||||
|
set := make(map[string]struct{}, len(list))
|
||||||
|
for _, l := range list {
|
||||||
|
set[l] = struct{}{}
|
||||||
|
}
|
||||||
|
return func(r *plugin.Registration) bool {
|
||||||
|
_, ok := set[r.URI()]
|
||||||
|
return ok
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
31
vendor/github.com/containerd/containerd/services/server/server.go
generated
vendored
31
vendor/github.com/containerd/containerd/services/server/server.go
generated
vendored
@ -67,10 +67,8 @@ func CreateTopLevelDirectories(config *srvconfig.Config) error {
|
|||||||
if err := sys.MkdirAllWithACL(config.Root, 0711); err != nil {
|
if err := sys.MkdirAllWithACL(config.Root, 0711); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := sys.MkdirAllWithACL(config.State, 0711); err != nil {
|
|
||||||
return err
|
return sys.MkdirAllWithACL(config.State, 0711)
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates and initializes a new containerd server
|
// New creates and initializes a new containerd server
|
||||||
@ -128,6 +126,10 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
}
|
}
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
id := p.URI()
|
id := p.URI()
|
||||||
|
reqID := id
|
||||||
|
if config.GetVersion() == 1 {
|
||||||
|
reqID = p.ID
|
||||||
|
}
|
||||||
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
log.G(ctx).WithField("type", p.Type).Infof("loading plugin %q...", id)
|
||||||
|
|
||||||
initContext := plugin.NewContext(
|
initContext := plugin.NewContext(
|
||||||
@ -142,11 +144,11 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
|
|
||||||
// load the plugin specific configuration if it is provided
|
// load the plugin specific configuration if it is provided
|
||||||
if p.Config != nil {
|
if p.Config != nil {
|
||||||
pluginConfig, err := config.Decode(p.ID, p.Config)
|
pc, err := config.Decode(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
initContext.Config = pluginConfig
|
initContext.Config = pc
|
||||||
}
|
}
|
||||||
result := p.Init(initContext)
|
result := p.Init(initContext)
|
||||||
if err := initialized.Add(result); err != nil {
|
if err := initialized.Add(result); err != nil {
|
||||||
@ -160,12 +162,13 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
} else {
|
} else {
|
||||||
log.G(ctx).WithError(err).Warnf("failed to load plugin %s", id)
|
log.G(ctx).WithError(err).Warnf("failed to load plugin %s", id)
|
||||||
}
|
}
|
||||||
if _, ok := required[p.ID]; ok {
|
if _, ok := required[reqID]; ok {
|
||||||
return nil, errors.Wrapf(err, "load required plugin %s", id)
|
return nil, errors.Wrapf(err, "load required plugin %s", id)
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
delete(required, p.ID)
|
|
||||||
|
delete(required, reqID)
|
||||||
// check for grpc services that should be registered with the server
|
// check for grpc services that should be registered with the server
|
||||||
if src, ok := instance.(plugin.Service); ok {
|
if src, ok := instance.(plugin.Service); ok {
|
||||||
grpcServices = append(grpcServices, src)
|
grpcServices = append(grpcServices, src)
|
||||||
@ -268,7 +271,7 @@ func (s *Server) Stop() {
|
|||||||
p := s.plugins[i]
|
p := s.plugins[i]
|
||||||
instance, err := p.Instance()
|
instance, err := p.Instance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.L.WithError(err).WithField("id", p.Registration.ID).
|
log.L.WithError(err).WithField("id", p.Registration.URI()).
|
||||||
Errorf("could not get plugin instance")
|
Errorf("could not get plugin instance")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -277,7 +280,7 @@ func (s *Server) Stop() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := closer.Close(); err != nil {
|
if err := closer.Close(); err != nil {
|
||||||
log.L.WithError(err).WithField("id", p.Registration.ID).
|
log.L.WithError(err).WithField("id", p.Registration.URI()).
|
||||||
Errorf("failed to close plugin")
|
Errorf("failed to close plugin")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -417,8 +420,12 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filter := srvconfig.V2DisabledFilter
|
||||||
|
if config.GetVersion() == 1 {
|
||||||
|
filter = srvconfig.V1DisabledFilter
|
||||||
|
}
|
||||||
// return the ordered graph for plugins
|
// return the ordered graph for plugins
|
||||||
return plugin.Graph(config.DisabledPlugins), nil
|
return plugin.Graph(filter(config.DisabledPlugins)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyClients struct {
|
type proxyClients struct {
|
||||||
@ -438,7 +445,7 @@ func (pc *proxyClients) getClient(address string) (*grpc.ClientConn, error) {
|
|||||||
gopts := []grpc.DialOption{
|
gopts := []grpc.DialOption{
|
||||||
grpc.WithInsecure(),
|
grpc.WithInsecure(),
|
||||||
grpc.WithBackoffMaxDelay(3 * time.Second),
|
grpc.WithBackoffMaxDelay(3 * time.Second),
|
||||||
grpc.WithDialer(dialer.Dialer),
|
grpc.WithContextDialer(dialer.ContextDialer),
|
||||||
|
|
||||||
// TODO(stevvooe): We may need to allow configuration of this on the client.
|
// TODO(stevvooe): We may need to allow configuration of this on the client.
|
||||||
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
|
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(defaults.DefaultMaxRecvMsgSize)),
|
||||||
|
2
vendor/github.com/containerd/containerd/services/server/server_solaris.go
generated
vendored
2
vendor/github.com/containerd/containerd/services/server/server_solaris.go
generated
vendored
@ -19,7 +19,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
srvconfig "github.com/containerd/containerd/server/config"
|
srvconfig "github.com/containerd/containerd/services/server/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
func apply(_ context.Context, _ *srvconfig.Config) error {
|
func apply(_ context.Context, _ *srvconfig.Config) error {
|
||||||
|
26
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
26
vendor/github.com/containerd/containerd/task_opts_unix.go
generated
vendored
@ -77,3 +77,29 @@ func WithNoPivotRoot(_ context.Context, _ *Client, ti *TaskInfo) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithShimCgroup sets the existing cgroup for the shim
|
||||||
|
func WithShimCgroup(path string) NewTaskOpts {
|
||||||
|
return func(ctx context.Context, c *Client, ti *TaskInfo) error {
|
||||||
|
if CheckRuntime(ti.Runtime(), "io.containerd.runc") {
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &options.Options{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*options.Options)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("invalid v2 shim create options format")
|
||||||
|
}
|
||||||
|
opts.ShimCgroup = path
|
||||||
|
} else {
|
||||||
|
if ti.Options == nil {
|
||||||
|
ti.Options = &runctypes.CreateOptions{}
|
||||||
|
}
|
||||||
|
opts, ok := ti.Options.(*runctypes.CreateOptions)
|
||||||
|
if !ok {
|
||||||
|
return errors.New("could not cast TaskInfo Options to CreateOptions")
|
||||||
|
}
|
||||||
|
opts.ShimCgroup = path
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
31
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
31
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
@ -1,5 +1,5 @@
|
|||||||
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
github.com/containerd/go-runc 5a6d9f37cfa36b15efba46dc7ea349fa9b7143c3
|
||||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
github.com/containerd/console 0650fd9eeb50bab4fc99dceb9f2e14cf58f36e7f
|
||||||
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
github.com/containerd/cgroups 4994991857f9b0ae8dc439551e8bebdbb4bf66c1
|
||||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||||
@ -8,7 +8,7 @@ github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
|||||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||||
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
|
||||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||||
github.com/docker/go-units v0.3.1
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||||
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
|
||||||
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
||||||
@ -20,32 +20,32 @@ github.com/gogo/protobuf v1.2.1
|
|||||||
github.com/gogo/googleapis v1.2.0
|
github.com/gogo/googleapis v1.2.0
|
||||||
github.com/golang/protobuf v1.2.0
|
github.com/golang/protobuf v1.2.0
|
||||||
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
github.com/opencontainers/runtime-spec 29686dbc5559d93fb1ef402eeda3e35c38d75af4 # v1.0.1-59-g29686db
|
||||||
github.com/opencontainers/runc 029124da7af7360afa781a0234d1b083550f797c
|
github.com/opencontainers/runc v1.0.0-rc8
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1
|
||||||
github.com/sirupsen/logrus v1.4.1
|
github.com/sirupsen/logrus v1.4.1
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net f3200d17e092c607f615320ecaad13d87ad9a2b3
|
||||||
google.golang.org/grpc v1.12.0
|
google.golang.org/grpc 25c4f928eaa6d96443009bd842389fb4fa48664e # v1.20.1
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1
|
||||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||||
golang.org/x/sys d455e41777fca6e8a5a79e34a14b8368bc11d9ba https://github.com/golang/sys
|
golang.org/x/sys 4c4f7f33c9ed00de01c4c741d2177abfcfe19307 https://github.com/golang/sys
|
||||||
github.com/opencontainers/image-spec v1.0.1
|
github.com/opencontainers/image-spec v1.0.1
|
||||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||||
github.com/Microsoft/go-winio c599b533b43b1363d7d7c6cfda5ede70ed73ff13
|
github.com/Microsoft/go-winio 84b4ab48a50763fe7b3abcef38e5205c12027fac
|
||||||
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
github.com/Microsoft/hcsshim 8abdbb8205e4192c68b5f84c31197156f31be517
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
github.com/containerd/ttrpc f02858b1457c5ca3aaec3a0803eb0d59f96e41d6
|
github.com/containerd/ttrpc a5bd8ce9e40bc7c065a11c6936f4d032ce6bfa2b
|
||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||||
gotest.tools v2.3.0
|
gotest.tools v2.3.0
|
||||||
github.com/google/go-cmp v0.2.0
|
github.com/google/go-cmp v0.2.0
|
||||||
go.etcd.io/bbolt v1.3.2
|
go.etcd.io/bbolt 2eb7227adea1d5cf85f0bc2a82b7059b13c2fa68
|
||||||
|
|
||||||
# cri dependencies
|
# cri dependencies
|
||||||
github.com/containerd/cri 6d353571e64417d80c9478ffaea793714dd539d0 # master
|
github.com/containerd/cri 2fc62db8146ce66f27b37306ad5fda34207835f3 # master
|
||||||
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
github.com/containerd/go-cni 891c2a41e18144b2d7921f971d6c9789a68046b2
|
||||||
github.com/containernetworking/cni v0.6.0
|
github.com/containernetworking/cni v0.6.0
|
||||||
github.com/containernetworking/plugins v0.7.0
|
github.com/containernetworking/plugins v0.7.0
|
||||||
github.com/davecgh/go-spew v1.1.0
|
github.com/davecgh/go-spew v1.1.0
|
||||||
@ -59,10 +59,10 @@ github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
|||||||
github.com/json-iterator/go 1.1.5
|
github.com/json-iterator/go 1.1.5
|
||||||
github.com/modern-go/reflect2 1.0.1
|
github.com/modern-go/reflect2 1.0.1
|
||||||
github.com/modern-go/concurrent 1.0.3
|
github.com/modern-go/concurrent 1.0.3
|
||||||
github.com/opencontainers/selinux v1.2.1
|
github.com/opencontainers/selinux v1.2.2
|
||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
golang.org/x/crypto 49796115aa4b964c318aad4f3084fdb41e9aa067
|
golang.org/x/crypto 88737f569e3a9c7ab309cdc09a07fe7fc87233c3
|
||||||
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
golang.org/x/oauth2 a6bd8cefa1811bd24b86f8902872e4e8225f74c4
|
||||||
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
golang.org/x/time f51c12702a4d776e4c1fa9b0fabab841babae631
|
||||||
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
gopkg.in/inf.v0 3887ee99ecf07df5b447e9b00d9c0b2adaa9f3e4
|
||||||
@ -78,8 +78,7 @@ sigs.k8s.io/yaml v1.1.0
|
|||||||
|
|
||||||
# zfs dependencies
|
# zfs dependencies
|
||||||
github.com/containerd/zfs 31af176f2ae84fe142ef2655bf7bb2aa618b3b1f
|
github.com/containerd/zfs 31af176f2ae84fe142ef2655bf7bb2aa618b3b1f
|
||||||
github.com/mistifyio/go-zfs d5b163290a48f624cbf244ebe4e89ce38653064c
|
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
||||||
github.com/pborman/uuid v1.2.0
|
|
||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
|
|
||||||
# aufs dependencies
|
# aufs dependencies
|
||||||
|
25
vendor/github.com/containerd/ttrpc/client.go
generated
vendored
25
vendor/github.com/containerd/ttrpc/client.go
generated
vendored
@ -49,7 +49,15 @@ type Client struct {
|
|||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClient(conn net.Conn) *Client {
|
type ClientOpts func(c *Client)
|
||||||
|
|
||||||
|
func WithOnClose(onClose func()) ClientOpts {
|
||||||
|
return func(c *Client) {
|
||||||
|
c.closeFunc = onClose
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(conn net.Conn, opts ...ClientOpts) *Client {
|
||||||
c := &Client{
|
c := &Client{
|
||||||
codec: codec{},
|
codec: codec{},
|
||||||
conn: conn,
|
conn: conn,
|
||||||
@ -60,6 +68,10 @@ func NewClient(conn net.Conn) *Client {
|
|||||||
closeFunc: func() {},
|
closeFunc: func() {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, o := range opts {
|
||||||
|
o(c)
|
||||||
|
}
|
||||||
|
|
||||||
go c.run()
|
go c.run()
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
@ -87,6 +99,10 @@ func (c *Client) Call(ctx context.Context, service, method string, req, resp int
|
|||||||
cresp = &Response{}
|
cresp = &Response{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if metadata, ok := GetMetadata(ctx); ok {
|
||||||
|
creq.Metadata = metadata
|
||||||
|
}
|
||||||
|
|
||||||
if dl, ok := ctx.Deadline(); ok {
|
if dl, ok := ctx.Deadline(); ok {
|
||||||
creq.TimeoutNano = dl.Sub(time.Now()).Nanoseconds()
|
creq.TimeoutNano = dl.Sub(time.Now()).Nanoseconds()
|
||||||
}
|
}
|
||||||
@ -141,11 +157,6 @@ func (c *Client) Close() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnClose allows a close func to be called when the server is closed
|
|
||||||
func (c *Client) OnClose(closer func()) {
|
|
||||||
c.closeFunc = closer
|
|
||||||
}
|
|
||||||
|
|
||||||
type message struct {
|
type message struct {
|
||||||
messageHeader
|
messageHeader
|
||||||
p []byte
|
p []byte
|
||||||
@ -255,7 +266,7 @@ func (c *Client) recv(resp *Response, msg *message) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if msg.Type != messageTypeResponse {
|
if msg.Type != messageTypeResponse {
|
||||||
return errors.New("unkown message type received")
|
return errors.New("unknown message type received")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer c.channel.putmbuf(msg.p)
|
defer c.channel.putmbuf(msg.p)
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user