Update containerd to 6937c5a3ba
Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
parent
de967051d4
commit
2cc1edcfc3
@ -3,7 +3,7 @@ github.com/blang/semver v3.1.0
|
|||||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||||
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
|
github.com/containerd/cgroups 5e610833b72089b37d0e615de9a92dfc043757c2
|
||||||
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
github.com/containerd/console c12b1e7919c14469339a5d38f2f8ed9b64a9de23
|
||||||
github.com/containerd/containerd v1.2.0
|
github.com/containerd/containerd 6937c5a3ba8280edff9e9030767e3b0cb742581c
|
||||||
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 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
github.com/containerd/go-cni 40bcf8ec8acd7372be1d77031d585d5d8e561c90
|
||||||
@ -34,12 +34,12 @@ github.com/hashicorp/go-multierror ed905158d87462226a13fe39ddf685ea65f1c11f
|
|||||||
github.com/json-iterator/go 1.1.5
|
github.com/json-iterator/go 1.1.5
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
github.com/matttproud/golang_protobuf_extensions v1.0.0
|
||||||
github.com/Microsoft/go-winio v0.4.11
|
github.com/Microsoft/go-winio v0.4.11
|
||||||
github.com/Microsoft/hcsshim v0.7.12
|
github.com/Microsoft/hcsshim v0.8.2
|
||||||
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 58592df56734acf62e574865fe40b9e53e967910
|
github.com/opencontainers/runc v1.0.0-rc6
|
||||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
|
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353
|
||||||
github.com/opencontainers/runtime-tools fb101d5d42ab9c040f7d0a004e78336e5d5cb197
|
github.com/opencontainers/runtime-tools fb101d5d42ab9c040f7d0a004e78336e5d5cb197
|
||||||
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
|
||||||
@ -50,7 +50,7 @@ github.com/prometheus/client_model 99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c
|
|||||||
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
github.com/prometheus/common 89604d197083d4781071d3c65855d24ecfb0a563
|
||||||
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
github.com/prometheus/procfs cb4147076ac75738c9a7d279075a253c0cc5acbd
|
||||||
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
github.com/seccomp/libseccomp-golang 32f571b70023028bd57d9288c20efbcb237f3ce0
|
||||||
github.com/sirupsen/logrus v1.0.0
|
github.com/sirupsen/logrus v1.0.3
|
||||||
github.com/stretchr/testify v1.1.4
|
github.com/stretchr/testify v1.1.4
|
||||||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||||
github.com/tchap/go-patricia v2.2.6
|
github.com/tchap/go-patricia v2.2.6
|
||||||
|
4
vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/hnspolicylist.go
generated
vendored
@ -37,8 +37,8 @@ func GetPolicyListByID(policyListID string) (*PolicyList, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddLoadBalancer policy list for the specified endpoints
|
// AddLoadBalancer policy list for the specified endpoints
|
||||||
func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
|
func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, isDSR bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
|
||||||
return hns.AddLoadBalancer(endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
|
return hns.AddLoadBalancer(endpoints, isILB, isDSR, sourceVIP, vip, protocol, internalPort, externalPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddRoute adds route policy list for the specified endpoints
|
// AddRoute adds route policy list for the specified endpoints
|
||||||
|
5
vendor/github.com/Microsoft/hcsshim/interface.go
generated
vendored
5
vendor/github.com/Microsoft/hcsshim/interface.go
generated
vendored
@ -17,6 +17,11 @@ type MappedPipe = schema1.MappedPipe
|
|||||||
type HvRuntime = schema1.HvRuntime
|
type HvRuntime = schema1.HvRuntime
|
||||||
type MappedVirtualDisk = schema1.MappedVirtualDisk
|
type MappedVirtualDisk = schema1.MappedVirtualDisk
|
||||||
|
|
||||||
|
// AssignedDevice represents a device that has been directly assigned to a container
|
||||||
|
//
|
||||||
|
// NOTE: Support added in RS5
|
||||||
|
type AssignedDevice = schema1.AssignedDevice
|
||||||
|
|
||||||
// ContainerConfig is used as both the input of CreateContainer
|
// ContainerConfig is used as both the input of CreateContainer
|
||||||
// and to convert the parameters to JSON for passing onto the HCS
|
// and to convert the parameters to JSON for passing onto the HCS
|
||||||
type ContainerConfig = schema1.ContainerConfig
|
type ContainerConfig = schema1.ContainerConfig
|
||||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicylist.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/hns/hnspolicylist.go
generated
vendored
@ -20,6 +20,7 @@ type ELBPolicy struct {
|
|||||||
SourceVIP string `json:"SourceVIP,omitempty"`
|
SourceVIP string `json:"SourceVIP,omitempty"`
|
||||||
VIPs []string `json:"VIPs,omitempty"`
|
VIPs []string `json:"VIPs,omitempty"`
|
||||||
ILB bool `json:"ILB,omitempty"`
|
ILB bool `json:"ILB,omitempty"`
|
||||||
|
DSR bool `json:"IsDSR,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// LBPolicy is a structure defining schema for LoadBalancing based Policy
|
// LBPolicy is a structure defining schema for LoadBalancing based Policy
|
||||||
@ -139,7 +140,7 @@ func (policylist *PolicyList) RemoveEndpoint(endpoint *HNSEndpoint) (*PolicyList
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddLoadBalancer policy list for the specified endpoints
|
// AddLoadBalancer policy list for the specified endpoints
|
||||||
func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
|
func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, isDSR bool, sourceVIP, vip string, protocol uint16, internalPort uint16, externalPort uint16) (*PolicyList, error) {
|
||||||
operation := "AddLoadBalancer"
|
operation := "AddLoadBalancer"
|
||||||
title := "hcsshim::PolicyList::" + operation
|
title := "hcsshim::PolicyList::" + operation
|
||||||
logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
|
logrus.Debugf(title+" endpointId=%v, isILB=%v, sourceVIP=%s, vip=%s, protocol=%v, internalPort=%v, externalPort=%v", endpoints, isILB, sourceVIP, vip, protocol, internalPort, externalPort)
|
||||||
@ -149,6 +150,7 @@ func AddLoadBalancer(endpoints []HNSEndpoint, isILB bool, sourceVIP, vip string,
|
|||||||
elbPolicy := &ELBPolicy{
|
elbPolicy := &ELBPolicy{
|
||||||
SourceVIP: sourceVIP,
|
SourceVIP: sourceVIP,
|
||||||
ILB: isILB,
|
ILB: isILB,
|
||||||
|
DSR: isDSR,
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(vip) > 0 {
|
if len(vip) > 0 {
|
||||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/schema2/memory_2.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/schema2/memory_2.go
generated
vendored
@ -10,7 +10,6 @@
|
|||||||
package hcsschema
|
package hcsschema
|
||||||
|
|
||||||
type Memory2 struct {
|
type Memory2 struct {
|
||||||
|
|
||||||
SizeInMB int32 `json:"SizeInMB,omitempty"`
|
SizeInMB int32 `json:"SizeInMB,omitempty"`
|
||||||
|
|
||||||
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
|
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
|
||||||
@ -20,4 +19,7 @@ type Memory2 struct {
|
|||||||
EnableColdHint bool `json:"EnableColdHint,omitempty"`
|
EnableColdHint bool `json:"EnableColdHint,omitempty"`
|
||||||
|
|
||||||
EnableEpf bool `json:"EnableEpf,omitempty"`
|
EnableEpf bool `json:"EnableEpf,omitempty"`
|
||||||
|
|
||||||
|
// EnableDeferredCommit is private in the schema. If regenerated need to add back.
|
||||||
|
EnableDeferredCommit bool `json:"EnableDeferredCommit,omitempty"`
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/Microsoft/hcsshim/internal/schema2/virtual_p_mem_controller.go
generated
vendored
5
vendor/github.com/Microsoft/hcsshim/internal/schema2/virtual_p_mem_controller.go
generated
vendored
@ -10,12 +10,11 @@
|
|||||||
package hcsschema
|
package hcsschema
|
||||||
|
|
||||||
type VirtualPMemController struct {
|
type VirtualPMemController struct {
|
||||||
|
|
||||||
Devices map[string]VirtualPMemDevice `json:"Devices,omitempty"`
|
Devices map[string]VirtualPMemDevice `json:"Devices,omitempty"`
|
||||||
|
|
||||||
MaximumCount int32 `json:"MaximumCount,omitempty"`
|
MaximumCount uint32 `json:"MaximumCount,omitempty"`
|
||||||
|
|
||||||
MaximumSizeBytes int32 `json:"MaximumSizeBytes,omitempty"`
|
MaximumSizeBytes uint64 `json:"MaximumSizeBytes,omitempty"`
|
||||||
|
|
||||||
Backing string `json:"Backing,omitempty"`
|
Backing string `json:"Backing,omitempty"`
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/containerd/containerd/README.md
generated
vendored
8
vendor/github.com/containerd/containerd/README.md
generated
vendored
@ -224,7 +224,8 @@ This will be the best place to discuss design and implementation.
|
|||||||
|
|
||||||
For sync communication we have a community slack with a #containerd channel that everyone is welcome to join and chat about development.
|
For sync communication we have a community slack with a #containerd channel that everyone is welcome to join and chat about development.
|
||||||
|
|
||||||
**Slack:** https://join.slack.com/t/dockercommunity/shared_invite/enQtNDM4NjAwNDMyOTUwLWZlMDZmYWRjZjk4Zjc5ZGQ5NWZkOWI1Yjk2NGE3ZWVlYjYxM2VhYjczOWIyZDFhZTE3NTUwZWQzMjhmNGYyZTg
|
**Slack:** Catch us in the #containerd and #containerd-dev channels on dockercommunity.slack.com.
|
||||||
|
[Click here for an invite to docker community slack.](https://join.slack.com/t/dockercommunity/shared_invite/enQtNDY4MDc1Mzc0MzIwLTgxZDBlMmM4ZGEyNDc1N2FkMzlhODJkYmE1YTVkYjM1MDE3ZjAwZjBkOGFlOTJkZjRmZGYzNjYyY2M3ZTUxYzQ)
|
||||||
|
|
||||||
### Reporting security issues
|
### Reporting security issues
|
||||||
|
|
||||||
@ -249,3 +250,8 @@ Please find all these core project documents, including the:
|
|||||||
* and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
|
* and [Contributing guidelines](https://github.com/containerd/project/blob/master/CONTRIBUTING.md)
|
||||||
|
|
||||||
information in our [`containerd/project`](https://github.com/containerd/project) repository.
|
information in our [`containerd/project`](https://github.com/containerd/project) repository.
|
||||||
|
|
||||||
|
## Adoption
|
||||||
|
|
||||||
|
Interested to see who is using containerd? Are you using containerd in a project?
|
||||||
|
Please add yourself via pull request to our [ADOPTERS.md](./ADOPTERS.md) file.
|
||||||
|
2
vendor/github.com/containerd/containerd/archive/tar.go
generated
vendored
2
vendor/github.com/containerd/containerd/archive/tar.go
generated
vendored
@ -295,7 +295,7 @@ func applyNaive(ctx context.Context, root string, tr *tar.Reader, options ApplyO
|
|||||||
linkBasename := filepath.Base(hdr.Linkname)
|
linkBasename := filepath.Base(hdr.Linkname)
|
||||||
srcHdr = aufsHardlinks[linkBasename]
|
srcHdr = aufsHardlinks[linkBasename]
|
||||||
if srcHdr == nil {
|
if srcHdr == nil {
|
||||||
return 0, fmt.Errorf("Invalid aufs hardlink")
|
return 0, fmt.Errorf("invalid aufs hardlink")
|
||||||
}
|
}
|
||||||
p, err := fs.RootPath(aufsTempdir, linkBasename)
|
p, err := fs.RootPath(aufsTempdir, linkBasename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
41
vendor/github.com/containerd/containerd/client.go
generated
vendored
41
vendor/github.com/containerd/containerd/client.go
generated
vendored
@ -17,7 +17,9 @@
|
|||||||
package containerd
|
package containerd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"runtime"
|
"runtime"
|
||||||
@ -520,6 +522,45 @@ func (c *Client) ListImages(ctx context.Context, filters ...string) ([]Image, er
|
|||||||
return images, nil
|
return images, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore restores a container from a checkpoint
|
||||||
|
func (c *Client) Restore(ctx context.Context, id string, checkpoint Image, opts ...RestoreOpts) (Container, error) {
|
||||||
|
store := c.ContentStore()
|
||||||
|
index, err := decodeIndex(ctx, store, checkpoint.Target())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, done, err := c.WithLease(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer done(ctx)
|
||||||
|
|
||||||
|
copts := []NewContainerOpts{}
|
||||||
|
for _, o := range opts {
|
||||||
|
copts = append(copts, o(ctx, id, c, checkpoint, index))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctr, err := c.NewContainer(ctx, id, copts...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctr, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref string) (d ocispec.Descriptor, err error) {
|
||||||
|
labels := map[string]string{}
|
||||||
|
for i, m := range index.Manifests {
|
||||||
|
labels[fmt.Sprintf("containerd.io/gc.ref.content.%d", i)] = m.Digest.String()
|
||||||
|
}
|
||||||
|
data, err := json.Marshal(index)
|
||||||
|
if err != nil {
|
||||||
|
return ocispec.Descriptor{}, err
|
||||||
|
}
|
||||||
|
return writeContent(ctx, client.ContentStore(), ocispec.MediaTypeImageIndex, ref, bytes.NewReader(data), content.WithLabels(labels))
|
||||||
|
}
|
||||||
|
|
||||||
// Subscribe to events that match one or more of the provided filters.
|
// Subscribe to events that match one or more of the provided filters.
|
||||||
//
|
//
|
||||||
// Callers should listen on both the envelope and errs channels. If the errs
|
// Callers should listen on both the envelope and errs channels. If the errs
|
||||||
|
57
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
57
vendor/github.com/containerd/containerd/cmd/containerd/command/main.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
@ -91,6 +92,7 @@ func App() *cli.App {
|
|||||||
Usage: "containerd state directory",
|
Usage: "containerd state directory",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
app.Flags = append(app.Flags, serviceFlags()...)
|
||||||
app.Commands = []cli.Command{
|
app.Commands = []cli.Command{
|
||||||
configCommand,
|
configCommand,
|
||||||
publishCommand,
|
publishCommand,
|
||||||
@ -105,18 +107,34 @@ func App() *cli.App {
|
|||||||
config = defaultConfig()
|
config = defaultConfig()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if err := srvconfig.LoadConfig(context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply flags to the config
|
||||||
|
if err := applyFlags(context, config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure top-level directories are created early.
|
||||||
|
if err := server.CreateTopLevelDirectories(config); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop if we are registering or unregistering against Windows SCM.
|
||||||
|
stop, err := registerUnregisterService(config.Root)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
done := handleSignals(ctx, signals, serverC)
|
done := handleSignals(ctx, signals, serverC)
|
||||||
// start the signal handler as soon as we can to make sure that
|
// start the signal handler as soon as we can to make sure that
|
||||||
// we don't miss any signals during boot
|
// we don't miss any signals during boot
|
||||||
signal.Notify(signals, handledSignals...)
|
signal.Notify(signals, handledSignals...)
|
||||||
|
|
||||||
if err := srvconfig.LoadConfig(context.GlobalString("config"), config); err != nil && !os.IsNotExist(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// apply flags to the config
|
|
||||||
if err := applyFlags(context, config); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// cleanup temp mounts
|
// cleanup temp mounts
|
||||||
if err := mount.SetTempMountLocation(filepath.Join(config.Root, "tmpmounts")); err != nil {
|
if err := mount.SetTempMountLocation(filepath.Join(config.Root, "tmpmounts")); err != nil {
|
||||||
return errors.Wrap(err, "creating temp mount location")
|
return errors.Wrap(err, "creating temp mount location")
|
||||||
@ -142,7 +160,14 @@ func App() *cli.App {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Launch as a Windows Service if necessary
|
||||||
|
if err := launchService(server, done); err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
serverC <- server
|
serverC <- server
|
||||||
|
|
||||||
if config.Debug.Address != "" {
|
if config.Debug.Address != "" {
|
||||||
var l net.Listener
|
var l net.Listener
|
||||||
if filepath.IsAbs(config.Debug.Address) {
|
if filepath.IsAbs(config.Debug.Address) {
|
||||||
@ -215,6 +240,9 @@ func applyFlags(context *cli.Context, config *srvconfig.Config) error {
|
|||||||
*v.d = s
|
*v.d = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyPlatformFlags(context)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,3 +260,18 @@ func setLevel(context *cli.Context, config *srvconfig.Config) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func dumpStacks() {
|
||||||
|
var (
|
||||||
|
buf []byte
|
||||||
|
stackSize int
|
||||||
|
)
|
||||||
|
bufferLen := 16384
|
||||||
|
for stackSize == len(buf) {
|
||||||
|
buf = make([]byte, bufferLen)
|
||||||
|
stackSize = runtime.Stack(buf, true)
|
||||||
|
bufferLen *= 2
|
||||||
|
}
|
||||||
|
buf = buf[:stackSize]
|
||||||
|
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
||||||
|
}
|
||||||
|
17
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
17
vendor/github.com/containerd/containerd/cmd/containerd/command/main_unix.go
generated
vendored
@ -21,11 +21,9 @@ package command
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"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"
|
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -66,18 +64,3 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
|
|||||||
}()
|
}()
|
||||||
return done
|
return done
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpStacks() {
|
|
||||||
var (
|
|
||||||
buf []byte
|
|
||||||
stackSize int
|
|
||||||
)
|
|
||||||
bufferLen := 16384
|
|
||||||
for stackSize == len(buf) {
|
|
||||||
buf = make([]byte, bufferLen)
|
|
||||||
stackSize = runtime.Stack(buf, true)
|
|
||||||
bufferLen *= 2
|
|
||||||
}
|
|
||||||
buf = buf[:stackSize]
|
|
||||||
logrus.Infof("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
|
|
||||||
}
|
|
||||||
|
35
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
35
vendor/github.com/containerd/containerd/cmd/containerd/command/main_windows.go
generated
vendored
@ -18,12 +18,15 @@ package command
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
winio "github.com/Microsoft/go-winio"
|
||||||
"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"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -54,5 +57,35 @@ func handleSignals(ctx context.Context, signals chan os.Signal, serverC chan *se
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
setupDumpStacks()
|
||||||
return done
|
return done
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupDumpStacks() {
|
||||||
|
// Windows does not support signals like *nix systems. So instead of
|
||||||
|
// trapping on SIGUSR1 to dump stacks, we wait on a Win32 event to be
|
||||||
|
// signaled. ACL'd to builtin administrators and local system
|
||||||
|
event := "Global\\containerd-daemon-" + fmt.Sprint(os.Getpid())
|
||||||
|
ev, _ := windows.UTF16PtrFromString(event)
|
||||||
|
sd, err := winio.SddlToSecurityDescriptor("D:P(A;;GA;;;BA)(A;;GA;;;SY)")
|
||||||
|
if err != nil {
|
||||||
|
logrus.Errorf("failed to get security descriptor for debug stackdump event %s: %s", event, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var sa windows.SecurityAttributes
|
||||||
|
sa.Length = uint32(unsafe.Sizeof(sa))
|
||||||
|
sa.InheritHandle = 1
|
||||||
|
sa.SecurityDescriptor = uintptr(unsafe.Pointer(&sd[0]))
|
||||||
|
h, err := windows.CreateEvent(&sa, 0, 0, ev)
|
||||||
|
if h == 0 || err != nil {
|
||||||
|
logrus.Errorf("failed to create debug stackdump event %s: %s", event, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
logrus.Debugf("Stackdump - waiting signal at %s", event)
|
||||||
|
for {
|
||||||
|
windows.WaitForSingleObject(h, windows.INFINITE)
|
||||||
|
dumpStacks()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
44
vendor/github.com/containerd/containerd/cmd/containerd/command/service_unsupported.go
generated
vendored
Normal file
44
vendor/github.com/containerd/containerd/cmd/containerd/command/service_unsupported.go
generated
vendored
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// +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 command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/containerd/containerd/services/server"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// serviceFlags returns an array of flags for configuring containerd to run
|
||||||
|
// as a service. Only relevant on Windows.
|
||||||
|
func serviceFlags() []cli.Flag {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// applyPlatformFlags applys platform-specific flags.
|
||||||
|
func applyPlatformFlags(context *cli.Context) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// registerUnregisterService is only relevant on Windows.
|
||||||
|
func registerUnregisterService(root string) (bool, error) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// launchService is only relevant on Windows.
|
||||||
|
func launchService(s *server.Server, done chan struct{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
467
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
Normal file
467
vendor/github.com/containerd/containerd/cmd/containerd/command/service_windows.go
generated
vendored
Normal file
@ -0,0 +1,467 @@
|
|||||||
|
/*
|
||||||
|
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 command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/services/server"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"golang.org/x/sys/windows/svc"
|
||||||
|
"golang.org/x/sys/windows/svc/debug"
|
||||||
|
"golang.org/x/sys/windows/svc/eventlog"
|
||||||
|
"golang.org/x/sys/windows/svc/mgr"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
serviceNameFlag string
|
||||||
|
registerServiceFlag bool
|
||||||
|
unregisterServiceFlag bool
|
||||||
|
runServiceFlag bool
|
||||||
|
|
||||||
|
setStdHandle = windows.NewLazySystemDLL("kernel32.dll").NewProc("SetStdHandle")
|
||||||
|
oldStderr windows.Handle
|
||||||
|
panicFile *os.File
|
||||||
|
|
||||||
|
service *handler
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// These should match the values in event_messages.mc.
|
||||||
|
eventInfo = 1
|
||||||
|
eventWarn = 1
|
||||||
|
eventError = 1
|
||||||
|
eventDebug = 2
|
||||||
|
eventPanic = 3
|
||||||
|
eventFatal = 4
|
||||||
|
|
||||||
|
eventExtraOffset = 10 // Add this to any event to get a string that supports extended data
|
||||||
|
)
|
||||||
|
|
||||||
|
// serviceFlags returns an array of flags for configuring containerd to run
|
||||||
|
// as a Windows service under control of SCM.
|
||||||
|
func serviceFlags() []cli.Flag {
|
||||||
|
return []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "service-name",
|
||||||
|
Usage: "Set the Windows service name",
|
||||||
|
Value: "containerd",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "register-service",
|
||||||
|
Usage: "Register the service and exit",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "unregister-service",
|
||||||
|
Usage: "Unregister the service and exit",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "run-service",
|
||||||
|
Usage: "",
|
||||||
|
Hidden: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// applyPlatformFlags applys platform-specific flags.
|
||||||
|
func applyPlatformFlags(context *cli.Context) {
|
||||||
|
|
||||||
|
if s := context.GlobalString("service-name"); s != "" {
|
||||||
|
serviceNameFlag = s
|
||||||
|
}
|
||||||
|
for _, v := range []struct {
|
||||||
|
name string
|
||||||
|
d *bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "register-service",
|
||||||
|
d: ®isterServiceFlag,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unregister-service",
|
||||||
|
d: &unregisterServiceFlag,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "run-service",
|
||||||
|
d: &runServiceFlag,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
*v.d = context.GlobalBool(v.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type handler struct {
|
||||||
|
fromsvc chan error
|
||||||
|
s *server.Server
|
||||||
|
done chan struct{} // Indicates back to app main to quit
|
||||||
|
}
|
||||||
|
|
||||||
|
type etwHook struct {
|
||||||
|
log *eventlog.Log
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *etwHook) Levels() []logrus.Level {
|
||||||
|
return []logrus.Level{
|
||||||
|
logrus.PanicLevel,
|
||||||
|
logrus.FatalLevel,
|
||||||
|
logrus.ErrorLevel,
|
||||||
|
logrus.WarnLevel,
|
||||||
|
logrus.InfoLevel,
|
||||||
|
logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *etwHook) Fire(e *logrus.Entry) error {
|
||||||
|
var (
|
||||||
|
etype uint16
|
||||||
|
eid uint32
|
||||||
|
)
|
||||||
|
|
||||||
|
switch e.Level {
|
||||||
|
case logrus.PanicLevel:
|
||||||
|
etype = windows.EVENTLOG_ERROR_TYPE
|
||||||
|
eid = eventPanic
|
||||||
|
case logrus.FatalLevel:
|
||||||
|
etype = windows.EVENTLOG_ERROR_TYPE
|
||||||
|
eid = eventFatal
|
||||||
|
case logrus.ErrorLevel:
|
||||||
|
etype = windows.EVENTLOG_ERROR_TYPE
|
||||||
|
eid = eventError
|
||||||
|
case logrus.WarnLevel:
|
||||||
|
etype = windows.EVENTLOG_WARNING_TYPE
|
||||||
|
eid = eventWarn
|
||||||
|
case logrus.InfoLevel:
|
||||||
|
etype = windows.EVENTLOG_INFORMATION_TYPE
|
||||||
|
eid = eventInfo
|
||||||
|
case logrus.DebugLevel:
|
||||||
|
etype = windows.EVENTLOG_INFORMATION_TYPE
|
||||||
|
eid = eventDebug
|
||||||
|
default:
|
||||||
|
return errors.New("unknown level")
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is additional data, include it as a second string.
|
||||||
|
exts := ""
|
||||||
|
if len(e.Data) > 0 {
|
||||||
|
fs := bytes.Buffer{}
|
||||||
|
for k, v := range e.Data {
|
||||||
|
fs.WriteString(k)
|
||||||
|
fs.WriteByte('=')
|
||||||
|
fmt.Fprint(&fs, v)
|
||||||
|
fs.WriteByte(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
exts = fs.String()[:fs.Len()-1]
|
||||||
|
eid += eventExtraOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
if h.log == nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "%s [%s]\n", e.Message, exts)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ss [2]*uint16
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
|
||||||
|
ss[0], err = windows.UTF16PtrFromString(e.Message)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
count := uint16(1)
|
||||||
|
if exts != "" {
|
||||||
|
ss[1], err = windows.UTF16PtrFromString(exts)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
return windows.ReportEvent(h.log.Handle, etype, 0, eid, 0, count, 0, &ss[0], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServicePath() (string, error) {
|
||||||
|
p, err := exec.LookPath(os.Args[0])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Abs(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func registerService() error {
|
||||||
|
p, err := getServicePath()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
m, err := mgr.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer m.Disconnect()
|
||||||
|
|
||||||
|
c := mgr.Config{
|
||||||
|
ServiceType: windows.SERVICE_WIN32_OWN_PROCESS,
|
||||||
|
StartType: mgr.StartAutomatic,
|
||||||
|
ErrorControl: mgr.ErrorNormal,
|
||||||
|
DisplayName: "Containerd",
|
||||||
|
Description: "Container runtime",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the service to launch with the arguments that were just passed.
|
||||||
|
args := []string{"--run-service"}
|
||||||
|
for _, a := range os.Args[1:] {
|
||||||
|
if a != "--register-service" && a != "--unregister-service" {
|
||||||
|
args = append(args, a)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := m.CreateService(serviceNameFlag, p, c, args...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
// See http://stackoverflow.com/questions/35151052/how-do-i-configure-failure-actions-of-a-windows-service-written-in-go
|
||||||
|
const (
|
||||||
|
scActionNone = 0
|
||||||
|
scActionRestart = 1
|
||||||
|
|
||||||
|
serviceConfigFailureActions = 2
|
||||||
|
)
|
||||||
|
|
||||||
|
type serviceFailureActions struct {
|
||||||
|
ResetPeriod uint32
|
||||||
|
RebootMsg *uint16
|
||||||
|
Command *uint16
|
||||||
|
ActionsCount uint32
|
||||||
|
Actions uintptr
|
||||||
|
}
|
||||||
|
|
||||||
|
type scAction struct {
|
||||||
|
Type uint32
|
||||||
|
Delay uint32
|
||||||
|
}
|
||||||
|
t := []scAction{
|
||||||
|
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
||||||
|
{Type: scActionRestart, Delay: uint32(60 * time.Second / time.Millisecond)},
|
||||||
|
{Type: scActionNone},
|
||||||
|
}
|
||||||
|
lpInfo := serviceFailureActions{ResetPeriod: uint32(24 * time.Hour / time.Second), ActionsCount: uint32(3), Actions: uintptr(unsafe.Pointer(&t[0]))}
|
||||||
|
err = windows.ChangeServiceConfig2(s.Handle, serviceConfigFailureActions, (*byte)(unsafe.Pointer(&lpInfo)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventlog.Install(serviceNameFlag, p, false, eventlog.Info|eventlog.Warning|eventlog.Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func unregisterService() error {
|
||||||
|
m, err := mgr.Connect()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer m.Disconnect()
|
||||||
|
|
||||||
|
s, err := m.OpenService(serviceNameFlag)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
eventlog.Remove(serviceNameFlag)
|
||||||
|
err = s.Delete()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// registerUnregisterService is an entrypoint early in the daemon startup
|
||||||
|
// to handle (un-)registering against Windows Service Control Manager (SCM).
|
||||||
|
// It returns an indication to stop on successful SCM operation, and an error.
|
||||||
|
func registerUnregisterService(root string) (bool, error) {
|
||||||
|
|
||||||
|
if unregisterServiceFlag {
|
||||||
|
if registerServiceFlag {
|
||||||
|
return true, errors.New("--register-service and --unregister-service cannot be used together")
|
||||||
|
}
|
||||||
|
return true, unregisterService()
|
||||||
|
}
|
||||||
|
|
||||||
|
if registerServiceFlag {
|
||||||
|
return true, registerService()
|
||||||
|
}
|
||||||
|
|
||||||
|
if runServiceFlag {
|
||||||
|
if err := initPanicFile(filepath.Join(root, "panic.log")); err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
interactive, err := svc.IsAnInteractiveSession()
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var log *eventlog.Log
|
||||||
|
if !interactive {
|
||||||
|
log, err = eventlog.Open(serviceNameFlag)
|
||||||
|
if err != nil {
|
||||||
|
return true, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logrus.AddHook(&etwHook{log})
|
||||||
|
logrus.SetOutput(ioutil.Discard)
|
||||||
|
|
||||||
|
}
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// launchService is the entry point for running the daemon under SCM.
|
||||||
|
func launchService(s *server.Server, done chan struct{}) error {
|
||||||
|
|
||||||
|
if !runServiceFlag {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
h := &handler{
|
||||||
|
fromsvc: make(chan error),
|
||||||
|
s: s,
|
||||||
|
done: done,
|
||||||
|
}
|
||||||
|
|
||||||
|
interactive, err := svc.IsAnInteractiveSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
service = h
|
||||||
|
go func() {
|
||||||
|
if interactive {
|
||||||
|
err = debug.Run(serviceNameFlag, h)
|
||||||
|
} else {
|
||||||
|
err = svc.Run(serviceNameFlag, h)
|
||||||
|
}
|
||||||
|
h.fromsvc <- err
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Wait for the first signal from the service handler.
|
||||||
|
err = <-h.fromsvc
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *handler) Execute(_ []string, r <-chan svc.ChangeRequest, s chan<- svc.Status) (bool, uint32) {
|
||||||
|
s <- svc.Status{State: svc.StartPending, Accepts: 0}
|
||||||
|
// Unblock launchService()
|
||||||
|
h.fromsvc <- nil
|
||||||
|
|
||||||
|
s <- svc.Status{State: svc.Running, Accepts: svc.AcceptStop | svc.AcceptShutdown | svc.Accepted(windows.SERVICE_ACCEPT_PARAMCHANGE)}
|
||||||
|
Loop:
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case c := <-r:
|
||||||
|
switch c.Cmd {
|
||||||
|
case svc.Interrogate:
|
||||||
|
s <- c.CurrentStatus
|
||||||
|
case svc.Stop, svc.Shutdown:
|
||||||
|
s <- svc.Status{State: svc.StopPending, Accepts: 0}
|
||||||
|
h.s.Stop()
|
||||||
|
break Loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removePanicFile()
|
||||||
|
close(h.done)
|
||||||
|
return false, 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func initPanicFile(path string) error {
|
||||||
|
var err error
|
||||||
|
panicFile, err = os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
st, err := panicFile.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are contents in the file already, move the file out of the way
|
||||||
|
// and replace it.
|
||||||
|
if st.Size() > 0 {
|
||||||
|
panicFile.Close()
|
||||||
|
os.Rename(path, path+".old")
|
||||||
|
panicFile, err = os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update STD_ERROR_HANDLE to point to the panic file so that Go writes to
|
||||||
|
// it when it panics. Remember the old stderr to restore it before removing
|
||||||
|
// the panic file.
|
||||||
|
sh := windows.STD_ERROR_HANDLE
|
||||||
|
h, err := windows.GetStdHandle(uint32(sh))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oldStderr = h
|
||||||
|
|
||||||
|
r, _, err := setStdHandle.Call(uintptr(sh), panicFile.Fd())
|
||||||
|
if r == 0 && err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset os.Stderr to the panic file (so fmt.Fprintf(os.Stderr,...) actually gets redirected)
|
||||||
|
os.Stderr = os.NewFile(panicFile.Fd(), "/dev/stderr")
|
||||||
|
|
||||||
|
// Force threads that panic to write to stderr (the panicFile handle now), otherwise it will go into the ether
|
||||||
|
log.SetOutput(os.Stderr)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func removePanicFile() {
|
||||||
|
if st, err := panicFile.Stat(); err == nil {
|
||||||
|
if st.Size() == 0 {
|
||||||
|
sh := windows.STD_ERROR_HANDLE
|
||||||
|
setStdHandle.Call(uintptr(sh), uintptr(oldStderr))
|
||||||
|
panicFile.Close()
|
||||||
|
os.Remove(panicFile.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/commands.go
generated
vendored
4
vendor/github.com/containerd/containerd/cmd/ctr/commands/commands.go
generated
vendored
@ -71,10 +71,6 @@ var (
|
|||||||
Name: "config,c",
|
Name: "config,c",
|
||||||
Usage: "path to the runtime-specific spec config file",
|
Usage: "path to the runtime-specific spec config file",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "checkpoint",
|
|
||||||
Usage: "provide the checkpoint digest to restore the container",
|
|
||||||
},
|
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "cwd",
|
Name: "cwd",
|
||||||
Usage: "specify the working directory of the process",
|
Usage: "specify the working directory of the process",
|
||||||
|
156
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go
generated
vendored
156
vendor/github.com/containerd/containerd/cmd/ctr/commands/containers/containers.go
generated
vendored
@ -18,7 +18,6 @@ package containers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -29,8 +28,10 @@ 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/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -45,13 +46,15 @@ var Command = cli.Command{
|
|||||||
infoCommand,
|
infoCommand,
|
||||||
listCommand,
|
listCommand,
|
||||||
setLabelsCommand,
|
setLabelsCommand,
|
||||||
|
checkpointCommand,
|
||||||
|
restoreCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var createCommand = cli.Command{
|
var createCommand = cli.Command{
|
||||||
Name: "create",
|
Name: "create",
|
||||||
Usage: "create container",
|
Usage: "create container",
|
||||||
ArgsUsage: "[flags] Image|RootFS CONTAINER",
|
ArgsUsage: "[flags] Image|RootFS CONTAINER [COMMAND] [ARG...]",
|
||||||
Flags: append(commands.SnapshotterFlags, commands.ContainerFlags...),
|
Flags: append(commands.SnapshotterFlags, commands.ContainerFlags...),
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
@ -282,3 +285,152 @@ 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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
2
vendor/github.com/containerd/containerd/cmd/ctr/commands/resolver.go
generated
vendored
2
vendor/github.com/containerd/containerd/cmd/ctr/commands/resolver.go
generated
vendored
@ -90,7 +90,7 @@ func GetResolver(ctx gocontext.Context, clicontext *cli.Context) (remotes.Resolv
|
|||||||
IdleConnTimeout: 30 * time.Second,
|
IdleConnTimeout: 30 * time.Second,
|
||||||
TLSHandshakeTimeout: 10 * time.Second,
|
TLSHandshakeTimeout: 10 * time.Second,
|
||||||
TLSClientConfig: &tls.Config{
|
TLSClientConfig: &tls.Config{
|
||||||
InsecureSkipVerify: clicontext.Bool("insecure"),
|
InsecureSkipVerify: clicontext.Bool("skip-verify"),
|
||||||
},
|
},
|
||||||
ExpectContinueTimeout: 5 * time.Second,
|
ExpectContinueTimeout: 5 * time.Second,
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
8
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run.go
generated
vendored
@ -106,11 +106,11 @@ var Command = cli.Command{
|
|||||||
Name: "fifo-dir",
|
Name: "fifo-dir",
|
||||||
Usage: "directory used for storing IO FIFOs",
|
Usage: "directory used for storing IO FIFOs",
|
||||||
},
|
},
|
||||||
cli.BoolFlag{
|
cli.StringFlag{
|
||||||
Name: "isolated",
|
Name: "cgroup",
|
||||||
Usage: "run the container with vm isolation",
|
Usage: "cgroup path (To disable use of cgroup, set to \"\" explicitly)",
|
||||||
},
|
},
|
||||||
}, 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 (
|
||||||
err error
|
err error
|
||||||
|
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
@ -32,6 +32,8 @@ import (
|
|||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var platformRunFlags []cli.Flag
|
||||||
|
|
||||||
// NewContainer creates a new container
|
// NewContainer creates a new container
|
||||||
func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
|
func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
|
||||||
var (
|
var (
|
||||||
@ -44,14 +46,6 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
id = context.Args().Get(1)
|
id = context.Args().Get(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if raw := context.String("checkpoint"); raw != "" {
|
|
||||||
im, err := client.GetImage(ctx, raw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return client.NewContainer(ctx, id, containerd.WithCheckpoint(im, id), containerd.WithRuntime(context.String("runtime"), nil))
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
opts []oci.SpecOpts
|
opts []oci.SpecOpts
|
||||||
cOpts []containerd.NewContainerOpts
|
cOpts []containerd.NewContainerOpts
|
||||||
@ -141,6 +135,10 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
if context.IsSet("allow-new-privs") {
|
if context.IsSet("allow-new-privs") {
|
||||||
opts = append(opts, oci.WithNewPrivileges)
|
opts = append(opts, oci.WithNewPrivileges)
|
||||||
}
|
}
|
||||||
|
if context.IsSet("cgroup") {
|
||||||
|
// NOTE: can be set to "" explicitly for disabling cgroup.
|
||||||
|
opts = append(opts, oci.WithCgroup(context.String("cgroup")))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
|
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
|
||||||
|
17
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_windows.go
generated
vendored
17
vendor/github.com/containerd/containerd/cmd/ctr/commands/run/run_windows.go
generated
vendored
@ -23,11 +23,19 @@ import (
|
|||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runhcs/options"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/urfave/cli"
|
"github.com/urfave/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var platformRunFlags = []cli.Flag{
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "isolated",
|
||||||
|
Usage: "run the container with vm isolation",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
// NewContainer creates a new container
|
// NewContainer creates a new container
|
||||||
func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
|
func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli.Context) (containerd.Container, error) {
|
||||||
var (
|
var (
|
||||||
@ -100,7 +108,14 @@ func NewContainer(ctx gocontext.Context, client *containerd.Client, context *cli
|
|||||||
}
|
}
|
||||||
|
|
||||||
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
cOpts = append(cOpts, containerd.WithContainerLabels(commands.LabelArgs(context.StringSlice("label"))))
|
||||||
cOpts = append(cOpts, containerd.WithRuntime(context.String("runtime"), nil))
|
runtime := context.String("runtime")
|
||||||
|
var runtimeOpts interface{}
|
||||||
|
if runtime == "io.containerd.runhcs.v1" {
|
||||||
|
runtimeOpts = &options.Options{
|
||||||
|
Debug: context.GlobalBool("debug"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cOpts = append(cOpts, containerd.WithRuntime(runtime, runtimeOpts))
|
||||||
|
|
||||||
var s specs.Spec
|
var s specs.Spec
|
||||||
spec = containerd.WithSpec(&s, opts...)
|
spec = containerd.WithSpec(&s, opts...)
|
||||||
|
12
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/checkpoint.go
generated
vendored
12
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/checkpoint.go
generated
vendored
@ -18,7 +18,6 @@ package tasks
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/containerd/containerd"
|
"github.com/containerd/containerd"
|
||||||
"github.com/containerd/containerd/cmd/ctr/commands"
|
"github.com/containerd/containerd/cmd/ctr/commands"
|
||||||
@ -37,11 +36,6 @@ var checkpointCommand = cli.Command{
|
|||||||
Name: "exit",
|
Name: "exit",
|
||||||
Usage: "stop the container after the checkpoint",
|
Usage: "stop the container after the checkpoint",
|
||||||
},
|
},
|
||||||
cli.StringFlag{
|
|
||||||
Name: "runtime",
|
|
||||||
Usage: "runtime name",
|
|
||||||
Value: fmt.Sprintf("io.containerd.runtime.v1.%s", runtime.GOOS),
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
id := context.Args().First()
|
id := context.Args().First()
|
||||||
@ -61,9 +55,13 @@ var checkpointCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
info, err := container.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
var opts []containerd.CheckpointTaskOpts
|
var opts []containerd.CheckpointTaskOpts
|
||||||
if context.Bool("exit") {
|
if context.Bool("exit") {
|
||||||
opts = append(opts, withExit(context.String("runtime")))
|
opts = append(opts, withExit(info.Runtime.Name))
|
||||||
}
|
}
|
||||||
checkpoint, err := task.Checkpoint(ctx, opts...)
|
checkpoint, err := task.Checkpoint(ctx, opts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
36
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/delete.go
generated
vendored
36
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/delete.go
generated
vendored
@ -32,8 +32,16 @@ var deleteCommand = cli.Command{
|
|||||||
Name: "force, f",
|
Name: "force, f",
|
||||||
Usage: "force delete task process",
|
Usage: "force delete task process",
|
||||||
},
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "exec-id",
|
||||||
|
Usage: "process ID to kill",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
|
var (
|
||||||
|
execID = context.String("exec-id")
|
||||||
|
force = context.Bool("force")
|
||||||
|
)
|
||||||
client, ctx, cancel, err := commands.NewClient(context)
|
client, ctx, cancel, err := commands.NewClient(context)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -48,15 +56,29 @@ var deleteCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var opts []containerd.ProcessDeleteOpts
|
var opts []containerd.ProcessDeleteOpts
|
||||||
if context.Bool("force") {
|
if force {
|
||||||
opts = append(opts, containerd.WithProcessKill)
|
opts = append(opts, containerd.WithProcessKill)
|
||||||
}
|
}
|
||||||
status, err := task.Delete(ctx, opts...)
|
if execID != "" {
|
||||||
if err != nil {
|
p, err := task.LoadProcess(ctx, execID, nil)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if ec := status.ExitCode(); ec != 0 {
|
}
|
||||||
return cli.NewExitError("", int(ec))
|
status, err := p.Delete(ctx, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ec := status.ExitCode(); ec != 0 {
|
||||||
|
return cli.NewExitError("", int(ec))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
status, err := task.Delete(ctx, opts...)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if ec := status.ExitCode(); ec != 0 {
|
||||||
|
return cli.NewExitError("", int(ec))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
33
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/exec.go
generated
vendored
33
vendor/github.com/containerd/containerd/cmd/ctr/commands/tasks/exec.go
generated
vendored
@ -40,6 +40,10 @@ var execCommand = cli.Command{
|
|||||||
Name: "tty,t",
|
Name: "tty,t",
|
||||||
Usage: "allocate a TTY for the container",
|
Usage: "allocate a TTY for the container",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "detach,d",
|
||||||
|
Usage: "detach from the task after it has started execution",
|
||||||
|
},
|
||||||
cli.StringFlag{
|
cli.StringFlag{
|
||||||
Name: "exec-id",
|
Name: "exec-id",
|
||||||
Usage: "exec specific id for the process",
|
Usage: "exec specific id for the process",
|
||||||
@ -51,9 +55,10 @@ var execCommand = cli.Command{
|
|||||||
},
|
},
|
||||||
Action: func(context *cli.Context) error {
|
Action: func(context *cli.Context) error {
|
||||||
var (
|
var (
|
||||||
id = context.Args().First()
|
id = context.Args().First()
|
||||||
args = context.Args().Tail()
|
args = context.Args().Tail()
|
||||||
tty = context.Bool("tty")
|
tty = context.Bool("tty")
|
||||||
|
detach = context.Bool("detach")
|
||||||
)
|
)
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return errors.New("container id must be provided")
|
return errors.New("container id must be provided")
|
||||||
@ -89,7 +94,10 @@ var execCommand = cli.Command{
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer process.Delete(ctx)
|
// if detach, we should not call this defer
|
||||||
|
if !detach {
|
||||||
|
defer process.Delete(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
statusC, err := process.Wait(ctx)
|
statusC, err := process.Wait(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -104,18 +112,23 @@ var execCommand = cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if tty {
|
if !detach {
|
||||||
if err := HandleConsoleResize(ctx, process, con); err != nil {
|
if tty {
|
||||||
logrus.WithError(err).Error("console resize")
|
if err := HandleConsoleResize(ctx, process, con); err != nil {
|
||||||
|
logrus.WithError(err).Error("console resize")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sigc := commands.ForwardAllSignals(ctx, process)
|
||||||
|
defer commands.StopCatch(sigc)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
sigc := commands.ForwardAllSignals(ctx, process)
|
|
||||||
defer commands.StopCatch(sigc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := process.Start(ctx); err != nil {
|
if err := process.Start(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if detach {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
status := <-statusC
|
status := <-statusC
|
||||||
code, _, err := status.Result()
|
code, _, err := status.Result()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
76
vendor/github.com/containerd/containerd/container.go
generated
vendored
76
vendor/github.com/containerd/containerd/container.go
generated
vendored
@ -28,12 +28,22 @@ import (
|
|||||||
"github.com/containerd/containerd/cio"
|
"github.com/containerd/containerd/cio"
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
"github.com/containerd/containerd/oci"
|
"github.com/containerd/containerd/oci"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
"github.com/containerd/typeurl"
|
"github.com/containerd/typeurl"
|
||||||
prototypes "github.com/gogo/protobuf/types"
|
prototypes "github.com/gogo/protobuf/types"
|
||||||
|
ver "github.com/opencontainers/image-spec/specs-go"
|
||||||
|
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
checkpointImageNameLabel = "org.opencontainers.image.ref.name"
|
||||||
|
checkpointRuntimeNameLabel = "io.containerd.checkpoint.runtime"
|
||||||
|
checkpointSnapshotterNameLabel = "io.containerd.checkpoint.snapshotter"
|
||||||
|
)
|
||||||
|
|
||||||
// Container is a metadata object for container resources and task creation
|
// Container is a metadata object for container resources and task creation
|
||||||
type Container interface {
|
type Container interface {
|
||||||
// ID identifies the container
|
// ID identifies the container
|
||||||
@ -64,6 +74,8 @@ type Container interface {
|
|||||||
Extensions(context.Context) (map[string]prototypes.Any, error)
|
Extensions(context.Context) (map[string]prototypes.Any, error)
|
||||||
// Update a container
|
// Update a container
|
||||||
Update(context.Context, ...UpdateContainerOpts) error
|
Update(context.Context, ...UpdateContainerOpts) error
|
||||||
|
// Checkpoint creates a checkpoint image of the current container
|
||||||
|
Checkpoint(context.Context, string, ...CheckpointOpts) (Image, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func containerFromRecord(client *Client, c containers.Container) *container {
|
func containerFromRecord(client *Client, c containers.Container) *container {
|
||||||
@ -272,6 +284,70 @@ func (c *container) Update(ctx context.Context, opts ...UpdateContainerOpts) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *container) Checkpoint(ctx context.Context, ref string, opts ...CheckpointOpts) (Image, error) {
|
||||||
|
index := &ocispec.Index{
|
||||||
|
Versioned: ver.Versioned{
|
||||||
|
SchemaVersion: 2,
|
||||||
|
},
|
||||||
|
Annotations: make(map[string]string),
|
||||||
|
}
|
||||||
|
copts := &options.CheckpointOptions{
|
||||||
|
Exit: false,
|
||||||
|
OpenTcp: false,
|
||||||
|
ExternalUnixSockets: false,
|
||||||
|
Terminal: false,
|
||||||
|
FileLocks: true,
|
||||||
|
EmptyNamespaces: nil,
|
||||||
|
}
|
||||||
|
info, err := c.Info(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
img, err := c.Image(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, done, err := c.client.WithLease(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer done(ctx)
|
||||||
|
|
||||||
|
// add image name to manifest
|
||||||
|
index.Annotations[checkpointImageNameLabel] = img.Name()
|
||||||
|
// add runtime info to index
|
||||||
|
index.Annotations[checkpointRuntimeNameLabel] = info.Runtime.Name
|
||||||
|
// add snapshotter info to index
|
||||||
|
index.Annotations[checkpointSnapshotterNameLabel] = info.Snapshotter
|
||||||
|
|
||||||
|
// process remaining opts
|
||||||
|
for _, o := range opts {
|
||||||
|
if err := o(ctx, c.client, &info, index, copts); err != nil {
|
||||||
|
err = errdefs.FromGRPC(err)
|
||||||
|
if !errdefs.IsAlreadyExists(err) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
desc, err := writeIndex(ctx, index, c.client, c.ID()+"index")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
i := images.Image{
|
||||||
|
Name: ref,
|
||||||
|
Target: desc,
|
||||||
|
}
|
||||||
|
checkpoint, err := c.client.ImageService().Create(ctx, i)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewImage(c.client, checkpoint), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, error) {
|
func (c *container) loadTask(ctx context.Context, ioAttach cio.Attach) (Task, error) {
|
||||||
response, err := c.client.TaskService().Get(ctx, &tasks.GetRequest{
|
response, err := c.client.TaskService().Get(ctx, &tasks.GetRequest{
|
||||||
ContainerID: c.id,
|
ContainerID: c.id,
|
||||||
|
155
vendor/github.com/containerd/containerd/container_checkpoint_opts.go
generated
vendored
Normal file
155
vendor/github.com/containerd/containerd/container_checkpoint_opts.go
generated
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
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 containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
tasks "github.com/containerd/containerd/api/services/tasks/v1"
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/containerd/containerd/diff"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
|
"github.com/containerd/containerd/rootfs"
|
||||||
|
"github.com/containerd/containerd/runtime/v2/runc/options"
|
||||||
|
"github.com/containerd/typeurl"
|
||||||
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrCheckpointRWUnsupported is returned if the container runtime does not support checkpoint
|
||||||
|
ErrCheckpointRWUnsupported = errors.New("rw checkpoint is only supported on v2 runtimes")
|
||||||
|
// ErrMediaTypeNotFound returns an error when a media type in the manifest is unknown
|
||||||
|
ErrMediaTypeNotFound = errors.New("media type not found")
|
||||||
|
)
|
||||||
|
|
||||||
|
// CheckpointOpts are options to manage the checkpoint operation
|
||||||
|
type CheckpointOpts func(context.Context, *Client, *containers.Container, *imagespec.Index, *options.CheckpointOptions) error
|
||||||
|
|
||||||
|
// WithCheckpointImage includes the container image in the checkpoint
|
||||||
|
func WithCheckpointImage(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
||||||
|
ir, err := client.ImageService().Get(ctx, c.Image)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
index.Manifests = append(index.Manifests, ir.Target)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCheckpointTask includes the running task
|
||||||
|
func WithCheckpointTask(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
||||||
|
any, err := typeurl.MarshalAny(copts)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
task, err := client.TaskService().Checkpoint(ctx, &tasks.CheckpointTaskRequest{
|
||||||
|
ContainerID: c.ID,
|
||||||
|
Options: any,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, d := range task.Descriptors {
|
||||||
|
platformSpec := platforms.DefaultSpec()
|
||||||
|
index.Manifests = append(index.Manifests, imagespec.Descriptor{
|
||||||
|
MediaType: d.MediaType,
|
||||||
|
Size: d.Size_,
|
||||||
|
Digest: d.Digest,
|
||||||
|
Platform: &platformSpec,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// save copts
|
||||||
|
data, err := any.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r := bytes.NewReader(data)
|
||||||
|
desc, err := writeContent(ctx, client.ContentStore(), images.MediaTypeContainerd1CheckpointOptions, c.ID+"-checkpoint-options", r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
desc.Platform = &imagespec.Platform{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
Architecture: runtime.GOARCH,
|
||||||
|
}
|
||||||
|
index.Manifests = append(index.Manifests, desc)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCheckpointRuntime includes the container runtime info
|
||||||
|
func WithCheckpointRuntime(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
||||||
|
if c.Runtime.Options != nil {
|
||||||
|
data, err := c.Runtime.Options.Marshal()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r := bytes.NewReader(data)
|
||||||
|
desc, err := writeContent(ctx, client.ContentStore(), images.MediaTypeContainerd1CheckpointRuntimeOptions, c.ID+"-runtime-options", r)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
desc.Platform = &imagespec.Platform{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
Architecture: runtime.GOARCH,
|
||||||
|
}
|
||||||
|
index.Manifests = append(index.Manifests, desc)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCheckpointRW includes the rw in the checkpoint
|
||||||
|
func WithCheckpointRW(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
||||||
|
diffOpts := []diff.Opt{
|
||||||
|
diff.WithReference(fmt.Sprintf("checkpoint-rw-%s", c.SnapshotKey)),
|
||||||
|
}
|
||||||
|
rw, err := rootfs.CreateDiff(ctx,
|
||||||
|
c.SnapshotKey,
|
||||||
|
client.SnapshotService(c.Snapshotter),
|
||||||
|
client.DiffService(),
|
||||||
|
diffOpts...,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
|
||||||
|
}
|
||||||
|
rw.Platform = &imagespec.Platform{
|
||||||
|
OS: runtime.GOOS,
|
||||||
|
Architecture: runtime.GOARCH,
|
||||||
|
}
|
||||||
|
index.Manifests = append(index.Manifests, rw)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithCheckpointTaskExit causes the task to exit after checkpoint
|
||||||
|
func WithCheckpointTaskExit(ctx context.Context, client *Client, c *containers.Container, index *imagespec.Index, copts *options.CheckpointOptions) error {
|
||||||
|
copts.Exit = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIndexByMediaType returns the index in a manifest for the specified media type
|
||||||
|
func GetIndexByMediaType(index *imagespec.Index, mt string) (*imagespec.Descriptor, error) {
|
||||||
|
for _, d := range index.Manifests {
|
||||||
|
if d.MediaType == mt {
|
||||||
|
return &d, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, ErrMediaTypeNotFound
|
||||||
|
}
|
69
vendor/github.com/containerd/containerd/container_opts_unix.go
generated
vendored
69
vendor/github.com/containerd/containerd/container_opts_unix.go
generated
vendored
@ -26,81 +26,12 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/containerd/containerd/containers"
|
"github.com/containerd/containerd/containers"
|
||||||
"github.com/containerd/containerd/content"
|
|
||||||
"github.com/containerd/containerd/errdefs"
|
"github.com/containerd/containerd/errdefs"
|
||||||
"github.com/containerd/containerd/images"
|
|
||||||
"github.com/containerd/containerd/mount"
|
"github.com/containerd/containerd/mount"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/gogo/protobuf/proto"
|
|
||||||
protobuf "github.com/gogo/protobuf/types"
|
|
||||||
"github.com/opencontainers/image-spec/identity"
|
"github.com/opencontainers/image-spec/identity"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// WithCheckpoint allows a container to be created from the checkpointed information
|
|
||||||
// provided by the descriptor. The image, snapshot, and runtime specifications are
|
|
||||||
// restored on the container
|
|
||||||
func WithCheckpoint(im Image, snapshotKey string) NewContainerOpts {
|
|
||||||
// set image and rw, and spec
|
|
||||||
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
|
||||||
var (
|
|
||||||
desc = im.Target()
|
|
||||||
store = client.ContentStore()
|
|
||||||
)
|
|
||||||
index, err := decodeIndex(ctx, store, desc)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var rw *v1.Descriptor
|
|
||||||
for _, m := range index.Manifests {
|
|
||||||
switch m.MediaType {
|
|
||||||
case v1.MediaTypeImageLayer:
|
|
||||||
fk := m
|
|
||||||
rw = &fk
|
|
||||||
case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList:
|
|
||||||
config, err := images.Config(ctx, store, m, platforms.Default())
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "unable to resolve image config")
|
|
||||||
}
|
|
||||||
diffIDs, err := images.RootFS(ctx, store, config)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "unable to get rootfs")
|
|
||||||
}
|
|
||||||
setSnapshotterIfEmpty(c)
|
|
||||||
if _, err := client.SnapshotService(c.Snapshotter).Prepare(ctx, snapshotKey, identity.ChainID(diffIDs).String()); err != nil {
|
|
||||||
if !errdefs.IsAlreadyExists(err) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.Image = index.Annotations["image.name"]
|
|
||||||
case images.MediaTypeContainerd1CheckpointConfig:
|
|
||||||
data, err := content.ReadBlob(ctx, store, m)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "unable to read checkpoint config")
|
|
||||||
}
|
|
||||||
var any protobuf.Any
|
|
||||||
if err := proto.Unmarshal(data, &any); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.Spec = &any
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if rw != nil {
|
|
||||||
// apply the rw snapshot to the new rw layer
|
|
||||||
mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, snapshotKey)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrapf(err, "unable to get mounts for %s", snapshotKey)
|
|
||||||
}
|
|
||||||
if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
|
|
||||||
return errors.Wrap(err, "unable to apply rw diff")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c.SnapshotKey = snapshotKey
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WithRemappedSnapshot creates a new snapshot and remaps the uid/gid for the
|
// WithRemappedSnapshot creates a new snapshot and remaps the uid/gid for the
|
||||||
// filesystem to be used by a container with user namespaces
|
// filesystem to be used by a container with user namespaces
|
||||||
func WithRemappedSnapshot(id string, i Image, uid, gid uint32) NewContainerOpts {
|
func WithRemappedSnapshot(id string, i Image, uid, gid uint32) NewContainerOpts {
|
||||||
|
150
vendor/github.com/containerd/containerd/container_restore_opts.go
generated
vendored
Normal file
150
vendor/github.com/containerd/containerd/container_restore_opts.go
generated
vendored
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*
|
||||||
|
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 containerd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/containerd/containerd/containers"
|
||||||
|
"github.com/containerd/containerd/content"
|
||||||
|
"github.com/containerd/containerd/images"
|
||||||
|
"github.com/containerd/containerd/platforms"
|
||||||
|
"github.com/gogo/protobuf/proto"
|
||||||
|
ptypes "github.com/gogo/protobuf/types"
|
||||||
|
"github.com/opencontainers/image-spec/identity"
|
||||||
|
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrImageNameNotFoundInIndex is returned when the image name is not found in the index
|
||||||
|
ErrImageNameNotFoundInIndex = errors.New("image name not found in index")
|
||||||
|
// ErrRuntimeNameNotFoundInIndex is returned when the runtime is not found in the index
|
||||||
|
ErrRuntimeNameNotFoundInIndex = errors.New("runtime not found in index")
|
||||||
|
// ErrSnapshotterNameNotFoundInIndex is returned when the snapshotter is not found in the index
|
||||||
|
ErrSnapshotterNameNotFoundInIndex = errors.New("snapshotter not found in index")
|
||||||
|
)
|
||||||
|
|
||||||
|
// RestoreOpts are options to manage the restore operation
|
||||||
|
type RestoreOpts func(context.Context, string, *Client, Image, *imagespec.Index) NewContainerOpts
|
||||||
|
|
||||||
|
// WithRestoreImage restores the image for the container
|
||||||
|
func WithRestoreImage(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
||||||
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
|
name, ok := index.Annotations[checkpointImageNameLabel]
|
||||||
|
if !ok || name == "" {
|
||||||
|
return ErrRuntimeNameNotFoundInIndex
|
||||||
|
}
|
||||||
|
snapshotter, ok := index.Annotations[checkpointSnapshotterNameLabel]
|
||||||
|
if !ok || name == "" {
|
||||||
|
return ErrSnapshotterNameNotFoundInIndex
|
||||||
|
}
|
||||||
|
i, err := client.GetImage(ctx, name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
diffIDs, err := i.(*image).i.RootFS(ctx, client.ContentStore(), platforms.Default())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
parent := identity.ChainID(diffIDs).String()
|
||||||
|
if _, err := client.SnapshotService(snapshotter).Prepare(ctx, id, parent); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.Image = i.Name()
|
||||||
|
c.SnapshotKey = id
|
||||||
|
c.Snapshotter = snapshotter
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRestoreRuntime restores the runtime for the container
|
||||||
|
func WithRestoreRuntime(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
||||||
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
|
name, ok := index.Annotations[checkpointRuntimeNameLabel]
|
||||||
|
if !ok {
|
||||||
|
return ErrRuntimeNameNotFoundInIndex
|
||||||
|
}
|
||||||
|
|
||||||
|
// restore options if present
|
||||||
|
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointRuntimeOptions)
|
||||||
|
if err != nil {
|
||||||
|
if err != ErrMediaTypeNotFound {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var options *ptypes.Any
|
||||||
|
if m != nil {
|
||||||
|
store := client.ContentStore()
|
||||||
|
data, err := content.ReadBlob(ctx, store, *m)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unable to read checkpoint runtime")
|
||||||
|
}
|
||||||
|
if err := proto.Unmarshal(data, options); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Runtime = containers.RuntimeInfo{
|
||||||
|
Name: name,
|
||||||
|
Options: options,
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRestoreSpec restores the spec from the checkpoint for the container
|
||||||
|
func WithRestoreSpec(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
||||||
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
|
m, err := GetIndexByMediaType(index, images.MediaTypeContainerd1CheckpointConfig)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
store := client.ContentStore()
|
||||||
|
data, err := content.ReadBlob(ctx, store, *m)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "unable to read checkpoint config")
|
||||||
|
}
|
||||||
|
var any ptypes.Any
|
||||||
|
if err := proto.Unmarshal(data, &any); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
c.Spec = &any
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithRestoreRW restores the rw layer from the checkpoint for the container
|
||||||
|
func WithRestoreRW(ctx context.Context, id string, client *Client, checkpoint Image, index *imagespec.Index) NewContainerOpts {
|
||||||
|
return func(ctx context.Context, client *Client, c *containers.Container) error {
|
||||||
|
// apply rw layer
|
||||||
|
rw, err := GetIndexByMediaType(index, imagespec.MediaTypeImageLayerGzip)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mounts, err := client.SnapshotService(c.Snapshotter).Mounts(ctx, c.SnapshotKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := client.DiffService().Apply(ctx, *rw, mounts); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
2
vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go
generated
vendored
2
vendor/github.com/containerd/containerd/contrib/nvidia/nvidia.go
generated
vendored
@ -90,6 +90,8 @@ func WithGPUs(opts ...Opts) oci.SpecOpts {
|
|||||||
"oci-hook",
|
"oci-hook",
|
||||||
"--",
|
"--",
|
||||||
nvidiaPath,
|
nvidiaPath,
|
||||||
|
// ensures the required kernel modules are properly loaded
|
||||||
|
"--load-kmods",
|
||||||
}, c.args()...),
|
}, c.args()...),
|
||||||
Env: os.Environ(),
|
Env: os.Environ(),
|
||||||
})
|
})
|
||||||
|
4
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go
generated
vendored
4
vendor/github.com/containerd/containerd/contrib/seccomp/seccomp.go
generated
vendored
@ -37,10 +37,10 @@ func WithProfile(profile string) oci.SpecOpts {
|
|||||||
s.Linux.Seccomp = &specs.LinuxSeccomp{}
|
s.Linux.Seccomp = &specs.LinuxSeccomp{}
|
||||||
f, err := ioutil.ReadFile(profile)
|
f, err := ioutil.ReadFile(profile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Cannot load seccomp profile %q: %v", profile, err)
|
return fmt.Errorf("cannot load seccomp profile %q: %v", profile, err)
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(f, s.Linux.Seccomp); err != nil {
|
if err := json.Unmarshal(f, s.Linux.Seccomp); err != nil {
|
||||||
return fmt.Errorf("Decoding seccomp profile failed %q: %v", profile, err)
|
return fmt.Errorf("decoding seccomp profile failed %q: %v", profile, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
2
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
2
vendor/github.com/containerd/containerd/errdefs/grpc.go
generated
vendored
@ -95,7 +95,7 @@ func FromGRPC(err error) error {
|
|||||||
|
|
||||||
msg := rebaseMessage(cls, err)
|
msg := rebaseMessage(cls, err)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
err = errors.Wrapf(cls, msg)
|
err = errors.Wrap(cls, msg)
|
||||||
} else {
|
} else {
|
||||||
err = errors.WithStack(cls)
|
err = errors.WithStack(cls)
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/containerd/containerd/events/exchange/exchange.go
generated
vendored
8
vendor/github.com/containerd/containerd/events/exchange/exchange.go
generated
vendored
@ -138,10 +138,10 @@ func (e *Exchange) Subscribe(ctx context.Context, fs ...string) (ch <-chan *even
|
|||||||
)
|
)
|
||||||
|
|
||||||
closeAll := func() {
|
closeAll := func() {
|
||||||
defer close(errq)
|
channel.Close()
|
||||||
defer e.broadcaster.Remove(dst)
|
queue.Close()
|
||||||
defer queue.Close()
|
e.broadcaster.Remove(dst)
|
||||||
defer channel.Close()
|
close(errq)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = evch
|
ch = evch
|
||||||
|
2
vendor/github.com/containerd/containerd/filters/parser.go
generated
vendored
2
vendor/github.com/containerd/containerd/filters/parser.go
generated
vendored
@ -71,7 +71,7 @@ func ParseAll(ss ...string) (Filter, error) {
|
|||||||
for _, s := range ss {
|
for _, s := range ss {
|
||||||
f, err := Parse(s)
|
f, err := Parse(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error())
|
return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
fs = append(fs, f)
|
fs = append(fs, f)
|
||||||
|
13
vendor/github.com/containerd/containerd/images/mediatypes.go
generated
vendored
13
vendor/github.com/containerd/containerd/images/mediatypes.go
generated
vendored
@ -29,11 +29,14 @@ const (
|
|||||||
MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json"
|
MediaTypeDockerSchema2Manifest = "application/vnd.docker.distribution.manifest.v2+json"
|
||||||
MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
|
MediaTypeDockerSchema2ManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
|
||||||
// Checkpoint/Restore Media Types
|
// Checkpoint/Restore Media Types
|
||||||
MediaTypeContainerd1Checkpoint = "application/vnd.containerd.container.criu.checkpoint.criu.tar"
|
MediaTypeContainerd1Checkpoint = "application/vnd.containerd.container.criu.checkpoint.criu.tar"
|
||||||
MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar"
|
MediaTypeContainerd1CheckpointPreDump = "application/vnd.containerd.container.criu.checkpoint.predump.tar"
|
||||||
MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar"
|
MediaTypeContainerd1Resource = "application/vnd.containerd.container.resource.tar"
|
||||||
MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar"
|
MediaTypeContainerd1RW = "application/vnd.containerd.container.rw.tar"
|
||||||
MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto"
|
MediaTypeContainerd1CheckpointConfig = "application/vnd.containerd.container.checkpoint.config.v1+proto"
|
||||||
|
MediaTypeContainerd1CheckpointOptions = "application/vnd.containerd.container.checkpoint.options.v1+proto"
|
||||||
|
MediaTypeContainerd1CheckpointRuntimeName = "application/vnd.containerd.container.checkpoint.runtime.name"
|
||||||
|
MediaTypeContainerd1CheckpointRuntimeOptions = "application/vnd.containerd.container.checkpoint.runtime.options+proto"
|
||||||
// Legacy Docker schema1 manifest
|
// Legacy Docker schema1 manifest
|
||||||
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
|
MediaTypeDockerSchema1Manifest = "application/vnd.docker.distribution.manifest.v1+prettyjws"
|
||||||
)
|
)
|
||||||
|
2
vendor/github.com/containerd/containerd/metadata/containers.go
generated
vendored
2
vendor/github.com/containerd/containerd/metadata/containers.go
generated
vendored
@ -72,7 +72,7 @@ func (s *containerStore) List(ctx context.Context, fs ...string) ([]containers.C
|
|||||||
|
|
||||||
filter, err := filters.ParseAll(fs...)
|
filter, err := filters.ParseAll(fs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error())
|
return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
bkt := getContainersBucket(s.tx, namespace)
|
bkt := getContainersBucket(s.tx, namespace)
|
||||||
|
2
vendor/github.com/containerd/containerd/metadata/images.go
generated
vendored
2
vendor/github.com/containerd/containerd/metadata/images.go
generated
vendored
@ -84,7 +84,7 @@ func (s *imageStore) List(ctx context.Context, fs ...string) ([]images.Image, er
|
|||||||
|
|
||||||
filter, err := filters.ParseAll(fs...)
|
filter, err := filters.ParseAll(fs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error())
|
return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var m []images.Image
|
var m []images.Image
|
||||||
|
2
vendor/github.com/containerd/containerd/metadata/leases.go
generated
vendored
2
vendor/github.com/containerd/containerd/metadata/leases.go
generated
vendored
@ -122,7 +122,7 @@ func (lm *LeaseManager) List(ctx context.Context, fs ...string) ([]leases.Lease,
|
|||||||
|
|
||||||
filter, err := filters.ParseAll(fs...)
|
filter, err := filters.ParseAll(fs...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(errdefs.ErrInvalidArgument, err.Error())
|
return nil, errors.Wrap(errdefs.ErrInvalidArgument, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
var ll []leases.Lease
|
var ll []leases.Lease
|
||||||
|
8
vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
generated
vendored
8
vendor/github.com/containerd/containerd/mount/mountinfo_linux.go
generated
vendored
@ -68,7 +68,7 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
|
|||||||
numFields := len(fields)
|
numFields := len(fields)
|
||||||
if numFields < 10 {
|
if numFields < 10 {
|
||||||
// should be at least 10 fields
|
// should be at least 10 fields
|
||||||
return nil, fmt.Errorf("Parsing '%s' failed: not enough fields (%d)", text, numFields)
|
return nil, fmt.Errorf("parsing '%s' failed: not enough fields (%d)", text, numFields)
|
||||||
}
|
}
|
||||||
p := Info{}
|
p := Info{}
|
||||||
// ignore any numbers parsing errors, as there should not be any
|
// ignore any numbers parsing errors, as there should not be any
|
||||||
@ -76,7 +76,7 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
|
|||||||
p.Parent, _ = strconv.Atoi(fields[1])
|
p.Parent, _ = strconv.Atoi(fields[1])
|
||||||
mm := strings.Split(fields[2], ":")
|
mm := strings.Split(fields[2], ":")
|
||||||
if len(mm) != 2 {
|
if len(mm) != 2 {
|
||||||
return nil, fmt.Errorf("Parsing '%s' failed: unexpected minor:major pair %s", text, mm)
|
return nil, fmt.Errorf("parsing '%s' failed: unexpected minor:major pair %s", text, mm)
|
||||||
}
|
}
|
||||||
p.Major, _ = strconv.Atoi(mm[0])
|
p.Major, _ = strconv.Atoi(mm[0])
|
||||||
p.Minor, _ = strconv.Atoi(mm[1])
|
p.Minor, _ = strconv.Atoi(mm[1])
|
||||||
@ -101,11 +101,11 @@ func parseInfoFile(r io.Reader) ([]Info, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if i == numFields {
|
if i == numFields {
|
||||||
return nil, fmt.Errorf("Parsing '%s' failed: missing separator ('-')", text)
|
return nil, fmt.Errorf("parsing '%s' failed: missing separator ('-')", text)
|
||||||
}
|
}
|
||||||
// There should be 3 fields after the separator...
|
// There should be 3 fields after the separator...
|
||||||
if i+4 > numFields {
|
if i+4 > numFields {
|
||||||
return nil, fmt.Errorf("Parsing '%s' failed: not enough fields after a separator", text)
|
return nil, fmt.Errorf("parsing '%s' failed: not enough fields after a separator", text)
|
||||||
}
|
}
|
||||||
// ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
|
// ... but in Linux <= 3.9 mounting a cifs with spaces in a share name
|
||||||
// (like "//serv/My Documents") _may_ end up having a space in the last field
|
// (like "//serv/My Documents") _may_ end up having a space in the last field
|
||||||
|
2
vendor/github.com/containerd/containerd/oci/spec.go
generated
vendored
2
vendor/github.com/containerd/containerd/oci/spec.go
generated
vendored
@ -209,6 +209,7 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error {
|
|||||||
Linux: &specs.Linux{
|
Linux: &specs.Linux{
|
||||||
MaskedPaths: []string{
|
MaskedPaths: []string{
|
||||||
"/proc/acpi",
|
"/proc/acpi",
|
||||||
|
"/proc/asound",
|
||||||
"/proc/kcore",
|
"/proc/kcore",
|
||||||
"/proc/keys",
|
"/proc/keys",
|
||||||
"/proc/latency_stats",
|
"/proc/latency_stats",
|
||||||
@ -219,7 +220,6 @@ func populateDefaultUnixSpec(ctx context.Context, s *Spec, id string) error {
|
|||||||
"/proc/scsi",
|
"/proc/scsi",
|
||||||
},
|
},
|
||||||
ReadonlyPaths: []string{
|
ReadonlyPaths: []string{
|
||||||
"/proc/asound",
|
|
||||||
"/proc/bus",
|
"/proc/bus",
|
||||||
"/proc/fs",
|
"/proc/fs",
|
||||||
"/proc/irq",
|
"/proc/irq",
|
||||||
|
2
vendor/github.com/containerd/containerd/remotes/docker/authorizer.go
generated
vendored
2
vendor/github.com/containerd/containerd/remotes/docker/authorizer.go
generated
vendored
@ -81,7 +81,7 @@ func (a *dockerAuthorizer) AddResponses(ctx context.Context, responses []*http.R
|
|||||||
// TODO(dmcg): Store challenge, not token
|
// TODO(dmcg): Store challenge, not token
|
||||||
// Move token fetching to authorize
|
// Move token fetching to authorize
|
||||||
return a.setTokenAuth(ctx, host, c.parameters)
|
return a.setTokenAuth(ctx, host, c.parameters)
|
||||||
} else if c.scheme == basicAuth {
|
} else if c.scheme == basicAuth && a.credentials != nil {
|
||||||
// TODO: Resolve credentials on authorize
|
// TODO: Resolve credentials on authorize
|
||||||
username, secret, err := a.credentials(host)
|
username, secret, err := a.credentials(host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
29
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
29
vendor/github.com/containerd/containerd/remotes/docker/resolver.go
generated
vendored
@ -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/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"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -75,13 +76,16 @@ type ResolverOptions struct {
|
|||||||
|
|
||||||
// Credentials provides username and secret given a host.
|
// Credentials provides username and secret given a host.
|
||||||
// If username is empty but a secret is given, that secret
|
// If username is empty but a secret is given, that secret
|
||||||
// is interpretted as a long lived token.
|
// is interpreted as a long lived token.
|
||||||
// Deprecated: use Authorizer
|
// Deprecated: use Authorizer
|
||||||
Credentials func(string) (string, string, error)
|
Credentials func(string) (string, string, error)
|
||||||
|
|
||||||
// Host provides the hostname given a namespace.
|
// Host provides the hostname given a namespace.
|
||||||
Host func(string) (string, error)
|
Host func(string) (string, error)
|
||||||
|
|
||||||
|
// Headers are the HTTP request header fields sent by the resolver
|
||||||
|
Headers http.Header
|
||||||
|
|
||||||
// PlainHTTP specifies to use plain http and not https
|
// PlainHTTP specifies to use plain http and not https
|
||||||
PlainHTTP bool
|
PlainHTTP bool
|
||||||
|
|
||||||
@ -105,6 +109,7 @@ func DefaultHost(ns string) (string, error) {
|
|||||||
type dockerResolver struct {
|
type dockerResolver struct {
|
||||||
auth Authorizer
|
auth Authorizer
|
||||||
host func(string) (string, error)
|
host func(string) (string, error)
|
||||||
|
headers http.Header
|
||||||
plainHTTP bool
|
plainHTTP bool
|
||||||
client *http.Client
|
client *http.Client
|
||||||
tracker StatusTracker
|
tracker StatusTracker
|
||||||
@ -118,12 +123,27 @@ func NewResolver(options ResolverOptions) remotes.Resolver {
|
|||||||
if options.Host == nil {
|
if options.Host == nil {
|
||||||
options.Host = DefaultHost
|
options.Host = DefaultHost
|
||||||
}
|
}
|
||||||
|
if options.Headers == nil {
|
||||||
|
options.Headers = make(http.Header)
|
||||||
|
}
|
||||||
|
if _, ok := options.Headers["Accept"]; !ok {
|
||||||
|
// set headers for all the types we support for resolution.
|
||||||
|
options.Headers.Set("Accept", strings.Join([]string{
|
||||||
|
images.MediaTypeDockerSchema2Manifest,
|
||||||
|
images.MediaTypeDockerSchema2ManifestList,
|
||||||
|
ocispec.MediaTypeImageManifest,
|
||||||
|
ocispec.MediaTypeImageIndex, "*"}, ", "))
|
||||||
|
}
|
||||||
|
if _, ok := options.Headers["User-Agent"]; !ok {
|
||||||
|
options.Headers.Set("User-Agent", "containerd/"+version.Version)
|
||||||
|
}
|
||||||
if options.Authorizer == nil {
|
if options.Authorizer == nil {
|
||||||
options.Authorizer = NewAuthorizer(options.Client, options.Credentials)
|
options.Authorizer = NewAuthorizer(options.Client, options.Credentials)
|
||||||
}
|
}
|
||||||
return &dockerResolver{
|
return &dockerResolver{
|
||||||
auth: options.Authorizer,
|
auth: options.Authorizer,
|
||||||
host: options.Host,
|
host: options.Host,
|
||||||
|
headers: options.Headers,
|
||||||
plainHTTP: options.PlainHTTP,
|
plainHTTP: options.PlainHTTP,
|
||||||
client: options.Client,
|
client: options.Client,
|
||||||
tracker: options.Tracker,
|
tracker: options.Tracker,
|
||||||
@ -182,12 +202,7 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
|
|||||||
return "", ocispec.Descriptor{}, err
|
return "", ocispec.Descriptor{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// set headers for all the types we support for resolution.
|
req.Header = r.headers
|
||||||
req.Header.Set("Accept", strings.Join([]string{
|
|
||||||
images.MediaTypeDockerSchema2Manifest,
|
|
||||||
images.MediaTypeDockerSchema2ManifestList,
|
|
||||||
ocispec.MediaTypeImageManifest,
|
|
||||||
ocispec.MediaTypeImageIndex, "*"}, ", "))
|
|
||||||
|
|
||||||
log.G(ctx).Debug("resolving")
|
log.G(ctx).Debug("resolving")
|
||||||
resp, err := fetcher.doRequestWithRetries(ctx, req, nil)
|
resp, err := fetcher.doRequestWithRetries(ctx, req, nil)
|
||||||
|
5
vendor/github.com/containerd/containerd/runtime/proc/proc.go
generated
vendored
5
vendor/github.com/containerd/containerd/runtime/proc/proc.go
generated
vendored
@ -40,7 +40,6 @@ func (s Stdio) IsNull() bool {
|
|||||||
|
|
||||||
// Process on a system
|
// Process on a system
|
||||||
type Process interface {
|
type Process interface {
|
||||||
State
|
|
||||||
// ID returns the id for the process
|
// ID returns the id for the process
|
||||||
ID() string
|
ID() string
|
||||||
// Pid returns the pid for the process
|
// Pid returns the pid for the process
|
||||||
@ -57,10 +56,6 @@ type Process interface {
|
|||||||
Status(context.Context) (string, error)
|
Status(context.Context) (string, error)
|
||||||
// Wait blocks until the process has exited
|
// Wait blocks until the process has exited
|
||||||
Wait()
|
Wait()
|
||||||
}
|
|
||||||
|
|
||||||
// State of a process
|
|
||||||
type State interface {
|
|
||||||
// Resize resizes the process console
|
// Resize resizes the process console
|
||||||
Resize(ws console.WinSize) error
|
Resize(ws console.WinSize) error
|
||||||
// Start execution of the process
|
// Start execution of the process
|
||||||
|
4
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
generated
vendored
4
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/deleted_state.go
generated
vendored
@ -69,3 +69,7 @@ func (s *deletedState) SetExited(status int) {
|
|||||||
func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *deletedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
return nil, errors.Errorf("cannot exec in a deleted state")
|
return nil, errors.Errorf("cannot exec in a deleted state")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *deletedState) Pid() int {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
43
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
generated
vendored
43
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec.go
generated
vendored
@ -41,7 +41,7 @@ import (
|
|||||||
type execProcess struct {
|
type execProcess struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
|
|
||||||
proc.State
|
execState execState
|
||||||
|
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
id string
|
id string
|
||||||
@ -69,8 +69,10 @@ func (e *execProcess) ID() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (e *execProcess) Pid() int {
|
func (e *execProcess) Pid() int {
|
||||||
e.mu.Lock()
|
return e.execState.Pid()
|
||||||
defer e.mu.Unlock()
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) pidv() int {
|
||||||
return e.pid
|
return e.pid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +88,13 @@ func (e *execProcess) ExitedAt() time.Time {
|
|||||||
return e.exited
|
return e.exited
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) SetExited(status int) {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
e.execState.SetExited(status)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) setExited(status int) {
|
func (e *execProcess) setExited(status int) {
|
||||||
e.status = status
|
e.status = status
|
||||||
e.exited = time.Now()
|
e.exited = time.Now()
|
||||||
@ -93,6 +102,13 @@ func (e *execProcess) setExited(status int) {
|
|||||||
close(e.waitBlock)
|
close(e.waitBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) Delete(ctx context.Context) error {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
return e.execState.Delete(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) delete(ctx context.Context) error {
|
func (e *execProcess) delete(ctx context.Context) error {
|
||||||
e.wg.Wait()
|
e.wg.Wait()
|
||||||
if e.io != nil {
|
if e.io != nil {
|
||||||
@ -107,6 +123,13 @@ func (e *execProcess) delete(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) Resize(ws console.WinSize) error {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
return e.execState.Resize(ws)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) resize(ws console.WinSize) error {
|
func (e *execProcess) resize(ws console.WinSize) error {
|
||||||
if e.console == nil {
|
if e.console == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -114,6 +137,13 @@ func (e *execProcess) resize(ws console.WinSize) error {
|
|||||||
return e.console.Resize(ws)
|
return e.console.Resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) Kill(ctx context.Context, sig uint32, _ bool) error {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
return e.execState.Kill(ctx, sig, false)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
|
func (e *execProcess) kill(ctx context.Context, sig uint32, _ bool) error {
|
||||||
pid := e.pid
|
pid := e.pid
|
||||||
if pid != 0 {
|
if pid != 0 {
|
||||||
@ -132,6 +162,13 @@ func (e *execProcess) Stdio() proc.Stdio {
|
|||||||
return e.stdio
|
return e.stdio
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *execProcess) Start(ctx context.Context) error {
|
||||||
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
|
return e.execState.Start(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (e *execProcess) start(ctx context.Context) (err error) {
|
func (e *execProcess) start(ctx context.Context) (err error) {
|
||||||
var (
|
var (
|
||||||
socket *runc.Socket
|
socket *runc.Socket
|
||||||
|
76
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go
generated
vendored
76
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/exec_state.go
generated
vendored
@ -25,6 +25,15 @@ import (
|
|||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type execState interface {
|
||||||
|
Resize(console.WinSize) error
|
||||||
|
Start(context.Context) error
|
||||||
|
Delete(context.Context) error
|
||||||
|
Kill(context.Context, uint32, bool) error
|
||||||
|
SetExited(int)
|
||||||
|
Pid() int
|
||||||
|
}
|
||||||
|
|
||||||
type execCreatedState struct {
|
type execCreatedState struct {
|
||||||
p *execProcess
|
p *execProcess
|
||||||
}
|
}
|
||||||
@ -32,11 +41,11 @@ type execCreatedState struct {
|
|||||||
func (s *execCreatedState) transition(name string) error {
|
func (s *execCreatedState) transition(name string) error {
|
||||||
switch name {
|
switch name {
|
||||||
case "running":
|
case "running":
|
||||||
s.p.State = &execRunningState{p: s.p}
|
s.p.execState = &execRunningState{p: s.p}
|
||||||
case "stopped":
|
case "stopped":
|
||||||
s.p.State = &execStoppedState{p: s.p}
|
s.p.execState = &execStoppedState{p: s.p}
|
||||||
case "deleted":
|
case "deleted":
|
||||||
s.p.State = &deletedState{}
|
s.p.execState = &deletedState{}
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
||||||
}
|
}
|
||||||
@ -44,15 +53,10 @@ func (s *execCreatedState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *execCreatedState) Resize(ws console.WinSize) error {
|
func (s *execCreatedState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execCreatedState) Start(ctx context.Context) error {
|
func (s *execCreatedState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
if err := s.p.start(ctx); err != nil {
|
if err := s.p.start(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -63,22 +67,15 @@ func (s *execCreatedState) Delete(ctx context.Context) error {
|
|||||||
if err := s.p.delete(ctx); err != nil {
|
if err := s.p.delete(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
return s.transition("deleted")
|
return s.transition("deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *execCreatedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execCreatedState) SetExited(status int) {
|
func (s *execCreatedState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
@ -86,6 +83,12 @@ func (s *execCreatedState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *execCreatedState) Pid() int {
|
||||||
|
s.p.mu.Lock()
|
||||||
|
defer s.p.mu.Unlock()
|
||||||
|
return s.p.pidv()
|
||||||
|
}
|
||||||
|
|
||||||
type execRunningState struct {
|
type execRunningState struct {
|
||||||
p *execProcess
|
p *execProcess
|
||||||
}
|
}
|
||||||
@ -93,7 +96,7 @@ type execRunningState struct {
|
|||||||
func (s *execRunningState) transition(name string) error {
|
func (s *execRunningState) transition(name string) error {
|
||||||
switch name {
|
switch name {
|
||||||
case "stopped":
|
case "stopped":
|
||||||
s.p.State = &execStoppedState{p: s.p}
|
s.p.execState = &execStoppedState{p: s.p}
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
||||||
}
|
}
|
||||||
@ -101,37 +104,22 @@ func (s *execRunningState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *execRunningState) Resize(ws console.WinSize) error {
|
func (s *execRunningState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execRunningState) Start(ctx context.Context) error {
|
func (s *execRunningState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot start a running process")
|
return errors.Errorf("cannot start a running process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execRunningState) Delete(ctx context.Context) error {
|
func (s *execRunningState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot delete a running process")
|
return errors.Errorf("cannot delete a running process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *execRunningState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execRunningState) SetExited(status int) {
|
func (s *execRunningState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
@ -139,6 +127,12 @@ func (s *execRunningState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *execRunningState) Pid() int {
|
||||||
|
s.p.mu.Lock()
|
||||||
|
defer s.p.mu.Unlock()
|
||||||
|
return s.p.pidv()
|
||||||
|
}
|
||||||
|
|
||||||
type execStoppedState struct {
|
type execStoppedState struct {
|
||||||
p *execProcess
|
p *execProcess
|
||||||
}
|
}
|
||||||
@ -146,7 +140,7 @@ type execStoppedState struct {
|
|||||||
func (s *execStoppedState) transition(name string) error {
|
func (s *execStoppedState) transition(name string) error {
|
||||||
switch name {
|
switch name {
|
||||||
case "deleted":
|
case "deleted":
|
||||||
s.p.State = &deletedState{}
|
s.p.execState = &deletedState{}
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
return errors.Errorf("invalid state transition %q to %q", stateName(s), name)
|
||||||
}
|
}
|
||||||
@ -154,16 +148,10 @@ func (s *execStoppedState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *execStoppedState) Resize(ws console.WinSize) error {
|
func (s *execStoppedState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resize a stopped container")
|
return errors.Errorf("cannot resize a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execStoppedState) Start(ctx context.Context) error {
|
func (s *execStoppedState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot start a stopped process")
|
return errors.Errorf("cannot start a stopped process")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,18 +159,18 @@ func (s *execStoppedState) Delete(ctx context.Context) error {
|
|||||||
if err := s.p.delete(ctx); err != nil {
|
if err := s.p.delete(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
return s.transition("deleted")
|
return s.transition("deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *execStoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *execStoppedState) SetExited(status int) {
|
func (s *execStoppedState) SetExited(status int) {
|
||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *execStoppedState) Pid() int {
|
||||||
|
return s.p.pidv()
|
||||||
|
}
|
||||||
|
127
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
127
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init.go
generated
vendored
@ -46,8 +46,8 @@ const InitPidFile = "init.pid"
|
|||||||
|
|
||||||
// Init represents an initial process for a container
|
// Init represents an initial process for a container
|
||||||
type Init struct {
|
type Init struct {
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
initState
|
initState initState
|
||||||
|
|
||||||
// mu is used to ensure that `Start()` and `Exited()` calls return in
|
// mu is used to ensure that `Start()` and `Exited()` calls return in
|
||||||
// the right order when invoked in separate go routines.
|
// the right order when invoked in separate go routines.
|
||||||
@ -212,6 +212,7 @@ func (p *Init) Pid() int {
|
|||||||
func (p *Init) ExitStatus() int {
|
func (p *Init) ExitStatus() int {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
return p.status
|
return p.status
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +220,7 @@ func (p *Init) ExitStatus() int {
|
|||||||
func (p *Init) ExitedAt() time.Time {
|
func (p *Init) ExitedAt() time.Time {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
return p.exited
|
return p.exited
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,6 +228,7 @@ func (p *Init) ExitedAt() time.Time {
|
|||||||
func (p *Init) Status(ctx context.Context) (string, error) {
|
func (p *Init) Status(ctx context.Context) (string, error) {
|
||||||
p.mu.Lock()
|
p.mu.Lock()
|
||||||
defer p.mu.Unlock()
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
c, err := p.runtime.State(ctx, p.id)
|
c, err := p.runtime.State(ctx, p.id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "does not exist") {
|
if strings.Contains(err.Error(), "does not exist") {
|
||||||
@ -236,11 +239,27 @@ func (p *Init) Status(ctx context.Context) (string, error) {
|
|||||||
return c.Status, nil
|
return c.Status, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) start(context context.Context) error {
|
// Start the init process
|
||||||
err := p.runtime.Start(context, p.id)
|
func (p *Init) Start(ctx context.Context) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Start(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) start(ctx context.Context) error {
|
||||||
|
err := p.runtime.Start(ctx, p.id)
|
||||||
return p.runtimeError(err, "OCI runtime start failed")
|
return p.runtimeError(err, "OCI runtime start failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetExited of the init process with the next status
|
||||||
|
func (p *Init) SetExited(status int) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
p.initState.SetExited(status)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Init) setExited(status int) {
|
func (p *Init) setExited(status int) {
|
||||||
p.exited = time.Now()
|
p.exited = time.Now()
|
||||||
p.status = status
|
p.status = status
|
||||||
@ -248,9 +267,17 @@ func (p *Init) setExited(status int) {
|
|||||||
close(p.waitBlock)
|
close(p.waitBlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) delete(context context.Context) error {
|
// Delete the init process
|
||||||
|
func (p *Init) Delete(ctx context.Context) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Delete(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) delete(ctx context.Context) error {
|
||||||
p.wg.Wait()
|
p.wg.Wait()
|
||||||
err := p.runtime.Delete(context, p.id, nil)
|
err := p.runtime.Delete(ctx, p.id, nil)
|
||||||
// ignore errors if a runtime has already deleted the process
|
// ignore errors if a runtime has already deleted the process
|
||||||
// but we still hold metadata and pipes
|
// but we still hold metadata and pipes
|
||||||
//
|
//
|
||||||
@ -270,7 +297,7 @@ func (p *Init) delete(context context.Context) error {
|
|||||||
p.io.Close()
|
p.io.Close()
|
||||||
}
|
}
|
||||||
if err2 := mount.UnmountAll(p.Rootfs, 0); err2 != nil {
|
if err2 := mount.UnmountAll(p.Rootfs, 0); err2 != nil {
|
||||||
log.G(context).WithError(err2).Warn("failed to cleanup rootfs mount")
|
log.G(ctx).WithError(err2).Warn("failed to cleanup rootfs mount")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = errors.Wrap(err2, "failed rootfs umount")
|
err = errors.Wrap(err2, "failed rootfs umount")
|
||||||
}
|
}
|
||||||
@ -278,6 +305,17 @@ func (p *Init) delete(context context.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resize the init processes console
|
||||||
|
func (p *Init) Resize(ws console.WinSize) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
if p.console == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return p.console.Resize(ws)
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Init) resize(ws console.WinSize) error {
|
func (p *Init) resize(ws console.WinSize) error {
|
||||||
if p.console == nil {
|
if p.console == nil {
|
||||||
return nil
|
return nil
|
||||||
@ -285,26 +323,43 @@ func (p *Init) resize(ws console.WinSize) error {
|
|||||||
return p.console.Resize(ws)
|
return p.console.Resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) pause(context context.Context) error {
|
// Pause the init process and all its child processes
|
||||||
err := p.runtime.Pause(context, p.id)
|
func (p *Init) Pause(ctx context.Context) error {
|
||||||
return p.runtimeError(err, "OCI runtime pause failed")
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Pause(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) resume(context context.Context) error {
|
// Resume the init process and all its child processes
|
||||||
err := p.runtime.Resume(context, p.id)
|
func (p *Init) Resume(ctx context.Context) error {
|
||||||
return p.runtimeError(err, "OCI runtime resume failed")
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Resume(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) kill(context context.Context, signal uint32, all bool) error {
|
// Kill the init process
|
||||||
err := p.runtime.Kill(context, p.id, int(signal), &runc.KillOpts{
|
func (p *Init) Kill(ctx context.Context, signal uint32, all bool) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Kill(ctx, signal, all)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) kill(ctx context.Context, signal uint32, all bool) error {
|
||||||
|
err := p.runtime.Kill(ctx, p.id, int(signal), &runc.KillOpts{
|
||||||
All: all,
|
All: all,
|
||||||
})
|
})
|
||||||
return checkKillError(err)
|
return checkKillError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// KillAll processes belonging to the init process
|
// KillAll processes belonging to the init process
|
||||||
func (p *Init) KillAll(context context.Context) error {
|
func (p *Init) KillAll(ctx context.Context) error {
|
||||||
err := p.runtime.Kill(context, p.id, int(syscall.SIGKILL), &runc.KillOpts{
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
err := p.runtime.Kill(ctx, p.id, int(syscall.SIGKILL), &runc.KillOpts{
|
||||||
All: true,
|
All: true,
|
||||||
})
|
})
|
||||||
return p.runtimeError(err, "OCI runtime killall failed")
|
return p.runtimeError(err, "OCI runtime killall failed")
|
||||||
@ -320,8 +375,16 @@ func (p *Init) Runtime() *runc.Runc {
|
|||||||
return p.runtime
|
return p.runtime
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Exec returns a new child process
|
||||||
|
func (p *Init) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Exec(ctx, path, r)
|
||||||
|
}
|
||||||
|
|
||||||
// exec returns a new exec'd process
|
// exec returns a new exec'd process
|
||||||
func (p *Init) exec(context context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (p *Init) exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
// process exec request
|
// process exec request
|
||||||
var spec specs.Process
|
var spec specs.Process
|
||||||
if err := json.Unmarshal(r.Spec.Value, &spec); err != nil {
|
if err := json.Unmarshal(r.Spec.Value, &spec); err != nil {
|
||||||
@ -342,18 +405,26 @@ func (p *Init) exec(context context.Context, path string, r *ExecConfig) (proc.P
|
|||||||
},
|
},
|
||||||
waitBlock: make(chan struct{}),
|
waitBlock: make(chan struct{}),
|
||||||
}
|
}
|
||||||
e.State = &execCreatedState{p: e}
|
e.execState = &execCreatedState{p: e}
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) checkpoint(context context.Context, r *CheckpointConfig) error {
|
// Checkpoint the init process
|
||||||
|
func (p *Init) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Checkpoint(ctx, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
var actions []runc.CheckpointAction
|
var actions []runc.CheckpointAction
|
||||||
if !r.Exit {
|
if !r.Exit {
|
||||||
actions = append(actions, runc.LeaveRunning)
|
actions = append(actions, runc.LeaveRunning)
|
||||||
}
|
}
|
||||||
work := filepath.Join(p.WorkDir, "criu-work")
|
work := filepath.Join(p.WorkDir, "criu-work")
|
||||||
defer os.RemoveAll(work)
|
defer os.RemoveAll(work)
|
||||||
if err := p.runtime.Checkpoint(context, p.id, &runc.CheckpointOpts{
|
if err := p.runtime.Checkpoint(ctx, p.id, &runc.CheckpointOpts{
|
||||||
WorkDir: work,
|
WorkDir: work,
|
||||||
ImagePath: r.Path,
|
ImagePath: r.Path,
|
||||||
AllowOpenTCP: r.AllowOpenTCP,
|
AllowOpenTCP: r.AllowOpenTCP,
|
||||||
@ -364,19 +435,27 @@ func (p *Init) checkpoint(context context.Context, r *CheckpointConfig) error {
|
|||||||
}, actions...); err != nil {
|
}, actions...); err != nil {
|
||||||
dumpLog := filepath.Join(p.Bundle, "criu-dump.log")
|
dumpLog := filepath.Join(p.Bundle, "criu-dump.log")
|
||||||
if cerr := copyFile(dumpLog, filepath.Join(work, "dump.log")); cerr != nil {
|
if cerr := copyFile(dumpLog, filepath.Join(work, "dump.log")); cerr != nil {
|
||||||
log.G(context).Error(err)
|
log.G(ctx).Error(err)
|
||||||
}
|
}
|
||||||
return fmt.Errorf("%s path= %s", criuError(err), dumpLog)
|
return fmt.Errorf("%s path= %s", criuError(err), dumpLog)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Init) update(context context.Context, r *google_protobuf.Any) error {
|
// Update the processes resource configuration
|
||||||
|
func (p *Init) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
|
p.mu.Lock()
|
||||||
|
defer p.mu.Unlock()
|
||||||
|
|
||||||
|
return p.initState.Update(ctx, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Init) update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
var resources specs.LinuxResources
|
var resources specs.LinuxResources
|
||||||
if err := json.Unmarshal(r.Value, &resources); err != nil {
|
if err := json.Unmarshal(r.Value, &resources); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return p.runtime.Update(context, p.id, &resources)
|
return p.runtime.Update(ctx, p.id, &resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stdio of the process
|
// Stdio of the process
|
||||||
|
183
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
183
vendor/github.com/containerd/containerd/runtime/v1/linux/proc/init_state.go
generated
vendored
@ -24,22 +24,25 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"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"
|
||||||
"github.com/containerd/fifo"
|
"github.com/containerd/fifo"
|
||||||
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"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
type initState interface {
|
type initState interface {
|
||||||
proc.State
|
Resize(console.WinSize) error
|
||||||
|
Start(context.Context) error
|
||||||
|
Delete(context.Context) error
|
||||||
Pause(context.Context) error
|
Pause(context.Context) error
|
||||||
Resume(context.Context) error
|
Resume(context.Context) error
|
||||||
Update(context.Context, *google_protobuf.Any) error
|
Update(context.Context, *google_protobuf.Any) error
|
||||||
Checkpoint(context.Context, *CheckpointConfig) error
|
Checkpoint(context.Context, *CheckpointConfig) error
|
||||||
Exec(context.Context, string, *ExecConfig) (proc.Process, error)
|
Exec(context.Context, string, *ExecConfig) (proc.Process, error)
|
||||||
|
Kill(context.Context, uint32, bool) error
|
||||||
|
SetExited(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
type createdState struct {
|
type createdState struct {
|
||||||
@ -61,43 +64,26 @@ func (s *createdState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Pause(ctx context.Context) error {
|
func (s *createdState) Pause(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot pause task in created state")
|
return errors.Errorf("cannot pause task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Resume(ctx context.Context) error {
|
func (s *createdState) Resume(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resume task in created state")
|
return errors.Errorf("cannot resume task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Update(context context.Context, r *google_protobuf.Any) error {
|
func (s *createdState) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
s.p.mu.Lock()
|
return s.p.update(ctx, r)
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.update(context, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Checkpoint(context context.Context, r *CheckpointConfig) error {
|
func (s *createdState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
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 {
|
func (s *createdState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Start(ctx context.Context) error {
|
func (s *createdState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
if err := s.p.start(ctx); err != nil {
|
if err := s.p.start(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -105,8 +91,6 @@ func (s *createdState) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Delete(ctx context.Context) error {
|
func (s *createdState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
if err := s.p.delete(ctx); err != nil {
|
if err := s.p.delete(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -114,16 +98,10 @@ func (s *createdState) Delete(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *createdState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) SetExited(status int) {
|
func (s *createdState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
@ -132,8 +110,6 @@ func (s *createdState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *createdState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
return s.p.exec(ctx, path, r)
|
return s.p.exec(ctx, path, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,43 +133,26 @@ func (s *createdCheckpointState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Pause(ctx context.Context) error {
|
func (s *createdCheckpointState) Pause(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot pause task in created state")
|
return errors.Errorf("cannot pause task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Resume(ctx context.Context) error {
|
func (s *createdCheckpointState) Resume(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resume task in created state")
|
return errors.Errorf("cannot resume task in created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Update(context context.Context, r *google_protobuf.Any) error {
|
func (s *createdCheckpointState) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
s.p.mu.Lock()
|
return s.p.update(ctx, r)
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.update(context, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Checkpoint(context context.Context, r *CheckpointConfig) error {
|
func (s *createdCheckpointState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
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 {
|
func (s *createdCheckpointState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Start(ctx context.Context) error {
|
func (s *createdCheckpointState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
p := s.p
|
p := s.p
|
||||||
sio := p.stdio
|
sio := p.stdio
|
||||||
|
|
||||||
@ -247,8 +206,6 @@ func (s *createdCheckpointState) Start(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Delete(ctx context.Context) error {
|
func (s *createdCheckpointState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
if err := s.p.delete(ctx); err != nil {
|
if err := s.p.delete(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -256,16 +213,10 @@ func (s *createdCheckpointState) Delete(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *createdCheckpointState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) SetExited(status int) {
|
func (s *createdCheckpointState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
@ -274,9 +225,6 @@ func (s *createdCheckpointState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *createdCheckpointState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return nil, errors.Errorf("cannot exec in a created state")
|
return nil, errors.Errorf("cannot exec in a created state")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,67 +245,42 @@ func (s *runningState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Pause(ctx context.Context) error {
|
func (s *runningState) Pause(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
if err := s.p.runtime.Pause(ctx, s.p.id); err != nil {
|
||||||
defer s.p.mu.Unlock()
|
return s.p.runtimeError(err, "OCI runtime pause failed")
|
||||||
if err := s.p.pause(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.transition("paused")
|
return s.transition("paused")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Resume(ctx context.Context) error {
|
func (s *runningState) Resume(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resume a running process")
|
return errors.Errorf("cannot resume a running process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Update(context context.Context, r *google_protobuf.Any) error {
|
func (s *runningState) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
s.p.mu.Lock()
|
return s.p.update(ctx, r)
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.update(context, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
func (s *runningState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.checkpoint(ctx, r)
|
return s.p.checkpoint(ctx, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Resize(ws console.WinSize) error {
|
func (s *runningState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Start(ctx context.Context) error {
|
func (s *runningState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot start a running process")
|
return errors.Errorf("cannot start a running process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Delete(ctx context.Context) error {
|
func (s *runningState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot delete a running process")
|
return errors.Errorf("cannot delete a running process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *runningState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) SetExited(status int) {
|
func (s *runningState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
@ -366,8 +289,6 @@ func (s *runningState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *runningState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
return s.p.exec(ctx, path, r)
|
return s.p.exec(ctx, path, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,79 +309,54 @@ func (s *pausedState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Pause(ctx context.Context) error {
|
func (s *pausedState) Pause(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot pause a paused container")
|
return errors.Errorf("cannot pause a paused container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Resume(ctx context.Context) error {
|
func (s *pausedState) Resume(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
if err := s.p.runtime.Resume(ctx, s.p.id); err != nil {
|
||||||
defer s.p.mu.Unlock()
|
return s.p.runtimeError(err, "OCI runtime resume failed")
|
||||||
|
|
||||||
if err := s.p.resume(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.transition("running")
|
return s.transition("running")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Update(context context.Context, r *google_protobuf.Any) error {
|
func (s *pausedState) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
s.p.mu.Lock()
|
return s.p.update(ctx, r)
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.update(context, r)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
func (s *pausedState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.checkpoint(ctx, r)
|
return s.p.checkpoint(ctx, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Resize(ws console.WinSize) error {
|
func (s *pausedState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.resize(ws)
|
return s.p.resize(ws)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Start(ctx context.Context) error {
|
func (s *pausedState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot start a paused process")
|
return errors.Errorf("cannot start a paused process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Delete(ctx context.Context) error {
|
func (s *pausedState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot delete a paused process")
|
return errors.Errorf("cannot delete a paused process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *pausedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return s.p.kill(ctx, sig, all)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) SetExited(status int) {
|
func (s *pausedState) SetExited(status int) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
s.p.setExited(status)
|
s.p.setExited(status)
|
||||||
|
|
||||||
|
if err := s.p.runtime.Resume(context.Background(), s.p.id); err != nil {
|
||||||
|
logrus.WithError(err).Error("resuming exited container from paused state")
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.transition("stopped"); err != nil {
|
if err := s.transition("stopped"); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *pausedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return nil, errors.Errorf("cannot exec in a paused state")
|
return nil, errors.Errorf("cannot exec in a paused state")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -479,50 +375,30 @@ func (s *stoppedState) transition(name string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Pause(ctx context.Context) error {
|
func (s *stoppedState) Pause(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot pause a stopped container")
|
return errors.Errorf("cannot pause a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Resume(ctx context.Context) error {
|
func (s *stoppedState) Resume(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resume a stopped container")
|
return errors.Errorf("cannot resume a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Update(context context.Context, r *google_protobuf.Any) error {
|
func (s *stoppedState) Update(ctx context.Context, r *google_protobuf.Any) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot update a stopped container")
|
return errors.Errorf("cannot update a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
func (s *stoppedState) Checkpoint(ctx context.Context, r *CheckpointConfig) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot checkpoint a stopped container")
|
return errors.Errorf("cannot checkpoint a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Resize(ws console.WinSize) error {
|
func (s *stoppedState) Resize(ws console.WinSize) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot resize a stopped container")
|
return errors.Errorf("cannot resize a stopped container")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Start(ctx context.Context) error {
|
func (s *stoppedState) Start(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return errors.Errorf("cannot start a stopped process")
|
return errors.Errorf("cannot start a stopped process")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Delete(ctx context.Context) error {
|
func (s *stoppedState) Delete(ctx context.Context) error {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
if err := s.p.delete(ctx); err != nil {
|
if err := s.p.delete(ctx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -530,7 +406,7 @@ func (s *stoppedState) Delete(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
func (s *stoppedState) Kill(ctx context.Context, sig uint32, all bool) error {
|
||||||
return errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s not found", s.p.id)
|
return s.p.kill(ctx, sig, all)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) SetExited(status int) {
|
func (s *stoppedState) SetExited(status int) {
|
||||||
@ -538,8 +414,5 @@ func (s *stoppedState) SetExited(status int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
func (s *stoppedState) Exec(ctx context.Context, path string, r *ExecConfig) (proc.Process, error) {
|
||||||
s.p.mu.Lock()
|
|
||||||
defer s.p.mu.Unlock()
|
|
||||||
|
|
||||||
return nil, errors.Errorf("cannot exec in a stopped state")
|
return nil, errors.Errorf("cannot exec in a stopped state")
|
||||||
}
|
}
|
||||||
|
26
vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
generated
vendored
26
vendor/github.com/containerd/containerd/runtime/v1/linux/runtime.go
generated
vendored
@ -21,6 +21,7 @@ package linux
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -40,6 +41,7 @@ import (
|
|||||||
"github.com/containerd/containerd/plugin"
|
"github.com/containerd/containerd/plugin"
|
||||||
"github.com/containerd/containerd/runtime"
|
"github.com/containerd/containerd/runtime"
|
||||||
"github.com/containerd/containerd/runtime/linux/runctypes"
|
"github.com/containerd/containerd/runtime/linux/runctypes"
|
||||||
|
"github.com/containerd/containerd/runtime/v1"
|
||||||
"github.com/containerd/containerd/runtime/v1/linux/proc"
|
"github.com/containerd/containerd/runtime/v1/linux/proc"
|
||||||
shim "github.com/containerd/containerd/runtime/v1/shim/v1"
|
shim "github.com/containerd/containerd/runtime/v1/shim/v1"
|
||||||
runc "github.com/containerd/go-runc"
|
runc "github.com/containerd/go-runc"
|
||||||
@ -341,6 +343,30 @@ func (r *Runtime) loadTasks(ctx context.Context, ns string) ([]*Task, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logDirPath := filepath.Join(r.root, ns, id)
|
||||||
|
|
||||||
|
shimStdoutLog, err := v1.OpenShimStdoutLog(ctx, logDirPath)
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
||||||
|
"id": id,
|
||||||
|
"namespace": ns,
|
||||||
|
"logDirPath": logDirPath,
|
||||||
|
}).Error("opening shim stdout log pipe")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go io.Copy(os.Stdout, shimStdoutLog)
|
||||||
|
|
||||||
|
shimStderrLog, err := v1.OpenShimStderrLog(ctx, logDirPath)
|
||||||
|
if err != nil {
|
||||||
|
log.G(ctx).WithError(err).WithFields(logrus.Fields{
|
||||||
|
"id": id,
|
||||||
|
"namespace": ns,
|
||||||
|
"logDirPath": logDirPath,
|
||||||
|
}).Error("opening shim stderr log pipe")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
go io.Copy(os.Stderr, 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 {
|
||||||
log.G(ctx).WithError(err).Error("loading task type")
|
log.G(ctx).WithError(err).Error("loading task type")
|
||||||
|
38
vendor/github.com/containerd/containerd/runtime/v1/shim.go
generated
vendored
Normal file
38
vendor/github.com/containerd/containerd/runtime/v1/shim.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// +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 v1
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/containerd/fifo"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
// OpenShimStdoutLog opens the shim log for reading
|
||||||
|
func OpenShimStdoutLog(ctx context.Context, logDirPath string) (io.ReadWriteCloser, error) {
|
||||||
|
return fifo.OpenFifo(ctx, filepath.Join(logDirPath, "shim.stdout.log"), unix.O_RDWR|unix.O_CREAT|unix.O_NONBLOCK, 0700)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenShimStderrLog opens the shim log
|
||||||
|
func OpenShimStderrLog(ctx context.Context, logDirPath string) (io.ReadWriteCloser, error) {
|
||||||
|
return fifo.OpenFifo(ctx, filepath.Join(logDirPath, "shim.stderr.log"), unix.O_RDWR|unix.O_CREAT|unix.O_NONBLOCK, 0700)
|
||||||
|
}
|
34
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
34
vendor/github.com/containerd/containerd/runtime/v1/shim/client/client.go
generated
vendored
@ -37,6 +37,7 @@ import (
|
|||||||
|
|
||||||
"github.com/containerd/containerd/events"
|
"github.com/containerd/containerd/events"
|
||||||
"github.com/containerd/containerd/log"
|
"github.com/containerd/containerd/log"
|
||||||
|
v1 "github.com/containerd/containerd/runtime/v1"
|
||||||
"github.com/containerd/containerd/runtime/v1/shim"
|
"github.com/containerd/containerd/runtime/v1/shim"
|
||||||
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
|
shimapi "github.com/containerd/containerd/runtime/v1/shim/v1"
|
||||||
"github.com/containerd/containerd/sys"
|
"github.com/containerd/containerd/sys"
|
||||||
@ -62,7 +63,24 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
cmd, err := newCommand(binary, daemonAddress, debug, config, f)
|
var stdoutLog io.ReadWriteCloser
|
||||||
|
var stderrLog io.ReadWriteCloser
|
||||||
|
if debug {
|
||||||
|
stdoutLog, err = v1.OpenShimStdoutLog(ctx, config.WorkDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, errors.Wrapf(err, "failed to create stdout log")
|
||||||
|
}
|
||||||
|
|
||||||
|
stderrLog, err = v1.OpenShimStderrLog(ctx, config.WorkDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, errors.Wrapf(err, "failed to create stderr log")
|
||||||
|
}
|
||||||
|
|
||||||
|
go io.Copy(os.Stdout, stdoutLog)
|
||||||
|
go io.Copy(os.Stderr, stderrLog)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd, err := newCommand(binary, daemonAddress, debug, config, f, stdoutLog, stderrLog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
@ -77,6 +95,12 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
go func() {
|
go func() {
|
||||||
cmd.Wait()
|
cmd.Wait()
|
||||||
exitHandler()
|
exitHandler()
|
||||||
|
if stdoutLog != nil {
|
||||||
|
stderrLog.Close()
|
||||||
|
}
|
||||||
|
if stdoutLog != nil {
|
||||||
|
stderrLog.Close()
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
log.G(ctx).WithFields(logrus.Fields{
|
log.G(ctx).WithFields(logrus.Fields{
|
||||||
"pid": cmd.Process.Pid,
|
"pid": cmd.Process.Pid,
|
||||||
@ -104,7 +128,7 @@ func WithStart(binary, address, daemonAddress, cgroup string, debug bool, exitHa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newCommand(binary, daemonAddress string, debug bool, config shim.Config, socket *os.File) (*exec.Cmd, error) {
|
func newCommand(binary, daemonAddress string, debug bool, config shim.Config, socket *os.File, stdout, stderr io.Writer) (*exec.Cmd, error) {
|
||||||
selfExe, err := os.Executable()
|
selfExe, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -137,10 +161,8 @@ func newCommand(binary, daemonAddress string, debug bool, config shim.Config, so
|
|||||||
cmd.SysProcAttr = getSysProcAttr()
|
cmd.SysProcAttr = getSysProcAttr()
|
||||||
cmd.ExtraFiles = append(cmd.ExtraFiles, socket)
|
cmd.ExtraFiles = append(cmd.ExtraFiles, socket)
|
||||||
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
||||||
if debug {
|
cmd.Stdout = stdout
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stderr = stderr
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
}
|
|
||||||
return cmd, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
3
vendor/github.com/containerd/containerd/runtime/v1/shim/reaper.go
generated
vendored
3
vendor/github.com/containerd/containerd/runtime/v1/shim/reaper.go
generated
vendored
@ -31,7 +31,7 @@ import (
|
|||||||
// ErrNoSuchProcess is returned when the process no longer exists
|
// ErrNoSuchProcess is returned when the process no longer exists
|
||||||
var ErrNoSuchProcess = errors.New("no such process")
|
var ErrNoSuchProcess = errors.New("no such process")
|
||||||
|
|
||||||
const bufferSize = 32
|
const bufferSize = 2048
|
||||||
|
|
||||||
// Reap should be called when the process receives an SIGCHLD. Reap will reap
|
// Reap should be called when the process receives an SIGCHLD. Reap will reap
|
||||||
// all exited processes and close their wait channels
|
// all exited processes and close their wait channels
|
||||||
@ -47,7 +47,6 @@ func Reap() error {
|
|||||||
Status: e.Status,
|
Status: e.Status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Default.Unlock()
|
Default.Unlock()
|
||||||
return err
|
return err
|
||||||
|
156
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
156
vendor/github.com/containerd/containerd/runtime/v1/shim/service.go
generated
vendored
@ -114,9 +114,6 @@ type Service struct {
|
|||||||
|
|
||||||
// Create a new initial process and container with the underlying OCI runtime
|
// Create a new initial process and container with the underlying OCI runtime
|
||||||
func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *shimapi.CreateTaskResponse, err error) {
|
func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *shimapi.CreateTaskResponse, err error) {
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
var mounts []proc.Mount
|
var mounts []proc.Mount
|
||||||
for _, m := range r.Rootfs {
|
for _, m := range r.Rootfs {
|
||||||
mounts = append(mounts, proc.Mount{
|
mounts = append(mounts, proc.Mount{
|
||||||
@ -158,6 +155,10 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
|
|||||||
return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
|
return nil, errors.Wrapf(err, "failed to mount rootfs component %v", m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
process, err := newInit(
|
process, err := newInit(
|
||||||
ctx,
|
ctx,
|
||||||
s.config.Path,
|
s.config.Path,
|
||||||
@ -187,11 +188,9 @@ func (s *Service) Create(ctx context.Context, r *shimapi.CreateTaskRequest) (_ *
|
|||||||
|
|
||||||
// Start a process
|
// Start a process
|
||||||
func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi.StartResponse, error) {
|
func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi.StartResponse, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getExecProcess(r.ID)
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[r.ID]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s", r.ID)
|
|
||||||
}
|
}
|
||||||
if err := p.Start(ctx); err != nil {
|
if err := p.Start(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -204,16 +203,16 @@ func (s *Service) Start(ctx context.Context, r *shimapi.StartRequest) (*shimapi.
|
|||||||
|
|
||||||
// Delete the initial process and container
|
// Delete the initial process and container
|
||||||
func (s *Service) Delete(ctx context.Context, r *ptypes.Empty) (*shimapi.DeleteResponse, error) {
|
func (s *Service) Delete(ctx context.Context, r *ptypes.Empty) (*shimapi.DeleteResponse, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
if err := p.Delete(ctx); err != nil {
|
if err := p.Delete(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
s.mu.Lock()
|
||||||
delete(s.processes, s.id)
|
delete(s.processes, s.id)
|
||||||
|
s.mu.Unlock()
|
||||||
s.platform.Close()
|
s.platform.Close()
|
||||||
return &shimapi.DeleteResponse{
|
return &shimapi.DeleteResponse{
|
||||||
ExitStatus: uint32(p.ExitStatus()),
|
ExitStatus: uint32(p.ExitStatus()),
|
||||||
@ -227,11 +226,9 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
|
|||||||
if r.ID == s.id {
|
if r.ID == s.id {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess")
|
return nil, status.Errorf(codes.InvalidArgument, "cannot delete init process with DeleteProcess")
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
p, err := s.getExecProcess(r.ID)
|
||||||
p := s.processes[r.ID]
|
if err != nil {
|
||||||
s.mu.Unlock()
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "process %s", r.ID)
|
|
||||||
}
|
}
|
||||||
if err := p.Delete(ctx); err != nil {
|
if err := p.Delete(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -249,13 +246,14 @@ func (s *Service) DeleteProcess(ctx context.Context, r *shimapi.DeleteProcessReq
|
|||||||
// Exec an additional process inside the container
|
// Exec an additional process inside the container
|
||||||
func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*ptypes.Empty, error) {
|
func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
|
||||||
|
|
||||||
if p := s.processes[r.ID]; p != nil {
|
if p := s.processes[r.ID]; p != nil {
|
||||||
|
s.mu.Unlock()
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrAlreadyExists, "id %s", r.ID)
|
return nil, errdefs.ToGRPCf(errdefs.ErrAlreadyExists, "id %s", r.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
p := s.processes[s.id]
|
p := s.processes[s.id]
|
||||||
|
s.mu.Unlock()
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||||
}
|
}
|
||||||
@ -271,14 +269,14 @@ func (s *Service) Exec(ctx context.Context, r *shimapi.ExecProcessRequest) (*pty
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
|
s.mu.Lock()
|
||||||
s.processes[r.ID] = process
|
s.processes[r.ID] = process
|
||||||
|
s.mu.Unlock()
|
||||||
return empty, nil
|
return empty, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResizePty of a process
|
// ResizePty of a process
|
||||||
func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*ptypes.Empty, error) {
|
func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
if r.ID == "" {
|
if r.ID == "" {
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided")
|
return nil, errdefs.ToGRPCf(errdefs.ErrInvalidArgument, "id not provided")
|
||||||
}
|
}
|
||||||
@ -286,7 +284,9 @@ func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*
|
|||||||
Width: uint16(r.Width),
|
Width: uint16(r.Width),
|
||||||
Height: uint16(r.Height),
|
Height: uint16(r.Height),
|
||||||
}
|
}
|
||||||
|
s.mu.Lock()
|
||||||
p := s.processes[r.ID]
|
p := s.processes[r.ID]
|
||||||
|
s.mu.Unlock()
|
||||||
if p == nil {
|
if p == nil {
|
||||||
return nil, errors.Errorf("process does not exist %s", r.ID)
|
return nil, errors.Errorf("process does not exist %s", r.ID)
|
||||||
}
|
}
|
||||||
@ -298,11 +298,9 @@ func (s *Service) ResizePty(ctx context.Context, r *shimapi.ResizePtyRequest) (*
|
|||||||
|
|
||||||
// State returns runtime state information for a process
|
// State returns runtime state information for a process
|
||||||
func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.StateResponse, error) {
|
func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.StateResponse, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getExecProcess(r.ID)
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[r.ID]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s", r.ID)
|
|
||||||
}
|
}
|
||||||
st, err := p.Status(ctx)
|
st, err := p.Status(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -338,11 +336,9 @@ func (s *Service) State(ctx context.Context, r *shimapi.StateRequest) (*shimapi.
|
|||||||
|
|
||||||
// Pause the container
|
// Pause the container
|
||||||
func (s *Service) Pause(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
|
func (s *Service) Pause(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
if err := p.(*proc.Init).Pause(ctx); err != nil {
|
if err := p.(*proc.Init).Pause(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -352,11 +348,9 @@ func (s *Service) Pause(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, er
|
|||||||
|
|
||||||
// Resume the container
|
// Resume the container
|
||||||
func (s *Service) Resume(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
|
func (s *Service) Resume(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
if err := p.(*proc.Init).Resume(ctx); err != nil {
|
if err := p.(*proc.Init).Resume(ctx); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -366,12 +360,10 @@ func (s *Service) Resume(ctx context.Context, r *ptypes.Empty) (*ptypes.Empty, e
|
|||||||
|
|
||||||
// Kill a process with the provided signal
|
// Kill a process with the provided signal
|
||||||
func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*ptypes.Empty, error) {
|
func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
|
||||||
defer s.mu.Unlock()
|
|
||||||
if r.ID == "" {
|
if r.ID == "" {
|
||||||
p := s.processes[s.id]
|
p, err := s.getInitProcess()
|
||||||
if p == nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := p.Kill(ctx, r.Signal, r.All); err != nil {
|
if err := p.Kill(ctx, r.Signal, r.All); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
@ -379,9 +371,9 @@ func (s *Service) Kill(ctx context.Context, r *shimapi.KillRequest) (*ptypes.Emp
|
|||||||
return empty, nil
|
return empty, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
p := s.processes[r.ID]
|
p, err := s.getExecProcess(r.ID)
|
||||||
if p == nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process id %s not found", r.ID)
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := p.Kill(ctx, r.Signal, r.All); err != nil {
|
if err := p.Kill(ctx, r.Signal, r.All); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
@ -422,11 +414,9 @@ func (s *Service) ListPids(ctx context.Context, r *shimapi.ListPidsRequest) (*sh
|
|||||||
|
|
||||||
// CloseIO of a process
|
// CloseIO of a process
|
||||||
func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*ptypes.Empty, error) {
|
func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getExecProcess(r.ID)
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[r.ID]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process does not exist %s", r.ID)
|
|
||||||
}
|
}
|
||||||
if stdin := p.Stdin(); stdin != nil {
|
if stdin := p.Stdin(); stdin != nil {
|
||||||
if err := stdin.Close(); err != nil {
|
if err := stdin.Close(); err != nil {
|
||||||
@ -438,11 +428,9 @@ func (s *Service) CloseIO(ctx context.Context, r *shimapi.CloseIORequest) (*ptyp
|
|||||||
|
|
||||||
// Checkpoint the container
|
// Checkpoint the container
|
||||||
func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskRequest) (*ptypes.Empty, error) {
|
func (s *Service) Checkpoint(ctx context.Context, r *shimapi.CheckpointTaskRequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
var options runctypes.CheckpointOptions
|
var options runctypes.CheckpointOptions
|
||||||
if r.Options != nil {
|
if r.Options != nil {
|
||||||
@ -475,11 +463,9 @@ func (s *Service) ShimInfo(ctx context.Context, r *ptypes.Empty) (*shimapi.ShimI
|
|||||||
|
|
||||||
// Update a running container
|
// Update a running container
|
||||||
func (s *Service) Update(ctx context.Context, r *shimapi.UpdateTaskRequest) (*ptypes.Empty, error) {
|
func (s *Service) Update(ctx context.Context, r *shimapi.UpdateTaskRequest) (*ptypes.Empty, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
if err := p.(*proc.Init).Update(ctx, r.Resources); err != nil {
|
if err := p.(*proc.Init).Update(ctx, r.Resources); err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
@ -489,11 +475,9 @@ func (s *Service) Update(ctx context.Context, r *shimapi.UpdateTaskRequest) (*pt
|
|||||||
|
|
||||||
// Wait for a process to exit
|
// Wait for a process to exit
|
||||||
func (s *Service) Wait(ctx context.Context, r *shimapi.WaitRequest) (*shimapi.WaitResponse, error) {
|
func (s *Service) Wait(ctx context.Context, r *shimapi.WaitRequest) (*shimapi.WaitResponse, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getExecProcess(r.ID)
|
||||||
p := s.processes[r.ID]
|
if err != nil {
|
||||||
s.mu.Unlock()
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
p.Wait()
|
p.Wait()
|
||||||
|
|
||||||
@ -509,16 +493,24 @@ func (s *Service) processExits() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) checkProcesses(e runc.Exit) {
|
func (s *Service) allProcesses() []rproc.Process {
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
defer s.mu.Unlock()
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
res := make([]rproc.Process, 0, len(s.processes))
|
||||||
|
for _, p := range s.processes {
|
||||||
|
res = append(res, p)
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) checkProcesses(e runc.Exit) {
|
||||||
shouldKillAll, err := shouldKillAllOnExit(s.bundle)
|
shouldKillAll, err := shouldKillAllOnExit(s.bundle)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(s.context).WithError(err).Error("failed to check shouldKillAll")
|
log.G(s.context).WithError(err).Error("failed to check shouldKillAll")
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range s.processes {
|
for _, p := range s.allProcesses() {
|
||||||
if p.Pid() == e.Pid {
|
if p.Pid() == e.Pid {
|
||||||
|
|
||||||
if shouldKillAll {
|
if shouldKillAll {
|
||||||
@ -563,11 +555,9 @@ func shouldKillAllOnExit(bundlePath string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) {
|
func (s *Service) getContainerPids(ctx context.Context, id string) ([]uint32, error) {
|
||||||
s.mu.Lock()
|
p, err := s.getInitProcess()
|
||||||
defer s.mu.Unlock()
|
if err != nil {
|
||||||
p := s.processes[s.id]
|
return nil, err
|
||||||
if p == nil {
|
|
||||||
return nil, errors.Wrapf(errdefs.ErrFailedPrecondition, "container must be created")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ps, err := p.(*proc.Init).Runtime().Ps(ctx, id)
|
ps, err := p.(*proc.Init).Runtime().Ps(ctx, id)
|
||||||
@ -589,6 +579,30 @@ func (s *Service) forward(publisher events.Publisher) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getInitProcess returns initial process
|
||||||
|
func (s *Service) getInitProcess() (rproc.Process, error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
p := s.processes[s.id]
|
||||||
|
if p == nil {
|
||||||
|
return nil, errdefs.ToGRPCf(errdefs.ErrFailedPrecondition, "container must be created")
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// getExecProcess returns exec process
|
||||||
|
func (s *Service) getExecProcess(id string) (rproc.Process, error) {
|
||||||
|
s.mu.Lock()
|
||||||
|
defer s.mu.Unlock()
|
||||||
|
|
||||||
|
p := s.processes[id]
|
||||||
|
if p == nil {
|
||||||
|
return nil, errdefs.ToGRPCf(errdefs.ErrNotFound, "process %s does not exist", id)
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
func getTopic(ctx context.Context, e interface{}) string {
|
func getTopic(ctx context.Context, e interface{}) string {
|
||||||
switch e.(type) {
|
switch e.(type) {
|
||||||
case *eventstypes.TaskCreate:
|
case *eventstypes.TaskCreate:
|
||||||
|
8
vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
generated
vendored
8
vendor/github.com/containerd/containerd/runtime/v1/shim/service_linux.go
generated
vendored
@ -49,9 +49,11 @@ func (p *linuxPlatform) CopyConsole(ctx context.Context, console console.Console
|
|||||||
cwg.Add(1)
|
cwg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
cwg.Done()
|
cwg.Done()
|
||||||
p := bufPool.Get().(*[]byte)
|
bp := bufPool.Get().(*[]byte)
|
||||||
defer bufPool.Put(p)
|
defer bufPool.Put(bp)
|
||||||
io.CopyBuffer(epollConsole, in, *p)
|
io.CopyBuffer(epollConsole, in, *bp)
|
||||||
|
// we need to shutdown epollConsole when pipe broken
|
||||||
|
epollConsole.Shutdown(p.epoller.CloseConsole)
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
// +build windows,windows_v2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright The containerd Authors.
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
@ -16,20 +14,4 @@
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package tasks
|
package options
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/containerd/containerd/plugin"
|
|
||||||
"github.com/containerd/containerd/runtime"
|
|
||||||
)
|
|
||||||
|
|
||||||
var tasksServiceRequires = []plugin.Type{
|
|
||||||
plugin.RuntimePluginV2,
|
|
||||||
plugin.MetadataPlugin,
|
|
||||||
plugin.TaskMonitorPlugin,
|
|
||||||
}
|
|
||||||
|
|
||||||
// loadV1Runtimes on Windows V2 returns an empty map. There are no v1 runtimes
|
|
||||||
func loadV1Runtimes(ic *plugin.InitContext) (map[string]runtime.PlatformRuntime, error) {
|
|
||||||
return make(map[string]runtime.PlatformRuntime), nil
|
|
||||||
}
|
|
418
vendor/github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.pb.go
generated
vendored
Normal file
418
vendor/github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.pb.go
generated
vendored
Normal file
@ -0,0 +1,418 @@
|
|||||||
|
// Code generated by protoc-gen-gogo. DO NOT EDIT.
|
||||||
|
// source: github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.proto
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package options is a generated protocol buffer package.
|
||||||
|
|
||||||
|
It is generated from these files:
|
||||||
|
github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.proto
|
||||||
|
|
||||||
|
It has these top-level messages:
|
||||||
|
Options
|
||||||
|
*/
|
||||||
|
package options
|
||||||
|
|
||||||
|
import proto "github.com/gogo/protobuf/proto"
|
||||||
|
import fmt "fmt"
|
||||||
|
import math "math"
|
||||||
|
|
||||||
|
// skipping weak import gogoproto "github.com/gogo/protobuf/gogoproto"
|
||||||
|
|
||||||
|
import strings "strings"
|
||||||
|
import reflect "reflect"
|
||||||
|
|
||||||
|
import io "io"
|
||||||
|
|
||||||
|
// Reference imports to suppress errors if they are not otherwise used.
|
||||||
|
var _ = proto.Marshal
|
||||||
|
var _ = fmt.Errorf
|
||||||
|
var _ = math.Inf
|
||||||
|
|
||||||
|
// This is a compile-time assertion to ensure that this generated file
|
||||||
|
// is compatible with the proto package it is being compiled against.
|
||||||
|
// A compilation error at this line likely means your copy of the
|
||||||
|
// proto package needs to be updated.
|
||||||
|
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
|
||||||
|
|
||||||
|
type Options_DebugType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
Options_NPIPE Options_DebugType = 0
|
||||||
|
Options_FILE Options_DebugType = 1
|
||||||
|
)
|
||||||
|
|
||||||
|
var Options_DebugType_name = map[int32]string{
|
||||||
|
0: "NPIPE",
|
||||||
|
1: "FILE",
|
||||||
|
}
|
||||||
|
var Options_DebugType_value = map[string]int32{
|
||||||
|
"NPIPE": 0,
|
||||||
|
"FILE": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x Options_DebugType) String() string {
|
||||||
|
return proto.EnumName(Options_DebugType_name, int32(x))
|
||||||
|
}
|
||||||
|
func (Options_DebugType) EnumDescriptor() ([]byte, []int) { return fileDescriptorRunhcs, []int{0, 0} }
|
||||||
|
|
||||||
|
type Options struct {
|
||||||
|
// enable debug tracing
|
||||||
|
Debug bool `protobuf:"varint,1,opt,name=debug,proto3" json:"debug,omitempty"`
|
||||||
|
// debug tracing output type
|
||||||
|
DebugType Options_DebugType `protobuf:"varint,2,opt,name=debug_type,json=debugType,proto3,enum=containerd.runhcs.v1.Options_DebugType" json:"debug_type,omitempty"`
|
||||||
|
// registry key root for storage of the runhcs container state
|
||||||
|
RegistryRoot string `protobuf:"bytes,3,opt,name=registry_root,json=registryRoot,proto3" json:"registry_root,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Options) Reset() { *m = Options{} }
|
||||||
|
func (*Options) ProtoMessage() {}
|
||||||
|
func (*Options) Descriptor() ([]byte, []int) { return fileDescriptorRunhcs, []int{0} }
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterType((*Options)(nil), "containerd.runhcs.v1.Options")
|
||||||
|
proto.RegisterEnum("containerd.runhcs.v1.Options_DebugType", Options_DebugType_name, Options_DebugType_value)
|
||||||
|
}
|
||||||
|
func (m *Options) Marshal() (dAtA []byte, err error) {
|
||||||
|
size := m.Size()
|
||||||
|
dAtA = make([]byte, size)
|
||||||
|
n, err := m.MarshalTo(dAtA)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return dAtA[:n], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Options) MarshalTo(dAtA []byte) (int, error) {
|
||||||
|
var i int
|
||||||
|
_ = i
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
if m.Debug {
|
||||||
|
dAtA[i] = 0x8
|
||||||
|
i++
|
||||||
|
if m.Debug {
|
||||||
|
dAtA[i] = 1
|
||||||
|
} else {
|
||||||
|
dAtA[i] = 0
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if m.DebugType != 0 {
|
||||||
|
dAtA[i] = 0x10
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunhcs(dAtA, i, uint64(m.DebugType))
|
||||||
|
}
|
||||||
|
if len(m.RegistryRoot) > 0 {
|
||||||
|
dAtA[i] = 0x1a
|
||||||
|
i++
|
||||||
|
i = encodeVarintRunhcs(dAtA, i, uint64(len(m.RegistryRoot)))
|
||||||
|
i += copy(dAtA[i:], m.RegistryRoot)
|
||||||
|
}
|
||||||
|
return i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func encodeVarintRunhcs(dAtA []byte, offset int, v uint64) int {
|
||||||
|
for v >= 1<<7 {
|
||||||
|
dAtA[offset] = uint8(v&0x7f | 0x80)
|
||||||
|
v >>= 7
|
||||||
|
offset++
|
||||||
|
}
|
||||||
|
dAtA[offset] = uint8(v)
|
||||||
|
return offset + 1
|
||||||
|
}
|
||||||
|
func (m *Options) Size() (n int) {
|
||||||
|
var l int
|
||||||
|
_ = l
|
||||||
|
if m.Debug {
|
||||||
|
n += 2
|
||||||
|
}
|
||||||
|
if m.DebugType != 0 {
|
||||||
|
n += 1 + sovRunhcs(uint64(m.DebugType))
|
||||||
|
}
|
||||||
|
l = len(m.RegistryRoot)
|
||||||
|
if l > 0 {
|
||||||
|
n += 1 + l + sovRunhcs(uint64(l))
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func sovRunhcs(x uint64) (n int) {
|
||||||
|
for {
|
||||||
|
n++
|
||||||
|
x >>= 7
|
||||||
|
if x == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
func sozRunhcs(x uint64) (n int) {
|
||||||
|
return sovRunhcs(uint64((x << 1) ^ uint64((int64(x) >> 63))))
|
||||||
|
}
|
||||||
|
func (this *Options) String() string {
|
||||||
|
if this == nil {
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
s := strings.Join([]string{`&Options{`,
|
||||||
|
`Debug:` + fmt.Sprintf("%v", this.Debug) + `,`,
|
||||||
|
`DebugType:` + fmt.Sprintf("%v", this.DebugType) + `,`,
|
||||||
|
`RegistryRoot:` + fmt.Sprintf("%v", this.RegistryRoot) + `,`,
|
||||||
|
`}`,
|
||||||
|
}, "")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
func valueToStringRunhcs(v interface{}) string {
|
||||||
|
rv := reflect.ValueOf(v)
|
||||||
|
if rv.IsNil() {
|
||||||
|
return "nil"
|
||||||
|
}
|
||||||
|
pv := reflect.Indirect(rv).Interface()
|
||||||
|
return fmt.Sprintf("*%v", pv)
|
||||||
|
}
|
||||||
|
func (m *Options) Unmarshal(dAtA []byte) error {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
preIndex := iNdEx
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fieldNum := int32(wire >> 3)
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
if wireType == 4 {
|
||||||
|
return fmt.Errorf("proto: Options: wiretype end group for non-group")
|
||||||
|
}
|
||||||
|
if fieldNum <= 0 {
|
||||||
|
return fmt.Errorf("proto: Options: illegal tag %d (wire type %d)", fieldNum, wire)
|
||||||
|
}
|
||||||
|
switch fieldNum {
|
||||||
|
case 1:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field Debug", wireType)
|
||||||
|
}
|
||||||
|
var v int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
v |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.Debug = bool(v != 0)
|
||||||
|
case 2:
|
||||||
|
if wireType != 0 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field DebugType", wireType)
|
||||||
|
}
|
||||||
|
m.DebugType = 0
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
m.DebugType |= (Options_DebugType(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case 3:
|
||||||
|
if wireType != 2 {
|
||||||
|
return fmt.Errorf("proto: wrong wireType = %d for field RegistryRoot", wireType)
|
||||||
|
}
|
||||||
|
var stringLen uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
stringLen |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
intStringLen := int(stringLen)
|
||||||
|
if intStringLen < 0 {
|
||||||
|
return ErrInvalidLengthRunhcs
|
||||||
|
}
|
||||||
|
postIndex := iNdEx + intStringLen
|
||||||
|
if postIndex > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
m.RegistryRoot = string(dAtA[iNdEx:postIndex])
|
||||||
|
iNdEx = postIndex
|
||||||
|
default:
|
||||||
|
iNdEx = preIndex
|
||||||
|
skippy, err := skipRunhcs(dAtA[iNdEx:])
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if skippy < 0 {
|
||||||
|
return ErrInvalidLengthRunhcs
|
||||||
|
}
|
||||||
|
if (iNdEx + skippy) > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx += skippy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if iNdEx > l {
|
||||||
|
return io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func skipRunhcs(dAtA []byte) (n int, err error) {
|
||||||
|
l := len(dAtA)
|
||||||
|
iNdEx := 0
|
||||||
|
for iNdEx < l {
|
||||||
|
var wire uint64
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
wire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wireType := int(wire & 0x7)
|
||||||
|
switch wireType {
|
||||||
|
case 0:
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
iNdEx++
|
||||||
|
if dAtA[iNdEx-1] < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 1:
|
||||||
|
iNdEx += 8
|
||||||
|
return iNdEx, nil
|
||||||
|
case 2:
|
||||||
|
var length int
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
length |= (int(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iNdEx += length
|
||||||
|
if length < 0 {
|
||||||
|
return 0, ErrInvalidLengthRunhcs
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 3:
|
||||||
|
for {
|
||||||
|
var innerWire uint64
|
||||||
|
var start int = iNdEx
|
||||||
|
for shift := uint(0); ; shift += 7 {
|
||||||
|
if shift >= 64 {
|
||||||
|
return 0, ErrIntOverflowRunhcs
|
||||||
|
}
|
||||||
|
if iNdEx >= l {
|
||||||
|
return 0, io.ErrUnexpectedEOF
|
||||||
|
}
|
||||||
|
b := dAtA[iNdEx]
|
||||||
|
iNdEx++
|
||||||
|
innerWire |= (uint64(b) & 0x7F) << shift
|
||||||
|
if b < 0x80 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
innerWireType := int(innerWire & 0x7)
|
||||||
|
if innerWireType == 4 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
next, err := skipRunhcs(dAtA[start:])
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
iNdEx = start + next
|
||||||
|
}
|
||||||
|
return iNdEx, nil
|
||||||
|
case 4:
|
||||||
|
return iNdEx, nil
|
||||||
|
case 5:
|
||||||
|
iNdEx += 4
|
||||||
|
return iNdEx, nil
|
||||||
|
default:
|
||||||
|
return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrInvalidLengthRunhcs = fmt.Errorf("proto: negative length found during unmarshaling")
|
||||||
|
ErrIntOverflowRunhcs = fmt.Errorf("proto: integer overflow")
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
proto.RegisterFile("github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.proto", fileDescriptorRunhcs)
|
||||||
|
}
|
||||||
|
|
||||||
|
var fileDescriptorRunhcs = []byte{
|
||||||
|
// 265 bytes of a gzipped FileDescriptorProto
|
||||||
|
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x72, 0x4f, 0xcf, 0x2c, 0xc9,
|
||||||
|
0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xce, 0xcf, 0x2b, 0x49, 0xcc, 0xcc, 0x4b, 0x2d,
|
||||||
|
0x4a, 0x41, 0x66, 0x16, 0x95, 0xe6, 0x95, 0x64, 0xe6, 0xa6, 0xea, 0x97, 0x19, 0x81, 0x98, 0x19,
|
||||||
|
0xc9, 0xc5, 0xfa, 0xf9, 0x05, 0x25, 0x99, 0xf9, 0x79, 0xc5, 0x50, 0xae, 0x5e, 0x41, 0x51, 0x7e,
|
||||||
|
0x49, 0xbe, 0x90, 0x08, 0x42, 0x8b, 0x1e, 0x54, 0xa2, 0xcc, 0x50, 0x4a, 0x24, 0x3d, 0x3f, 0x3d,
|
||||||
|
0x1f, 0xac, 0x40, 0x1f, 0xc4, 0x82, 0xa8, 0x55, 0x5a, 0xc7, 0xc8, 0xc5, 0xee, 0x0f, 0x31, 0x44,
|
||||||
|
0x48, 0x84, 0x8b, 0x35, 0x25, 0x35, 0xa9, 0x34, 0x5d, 0x82, 0x51, 0x81, 0x51, 0x83, 0x23, 0x08,
|
||||||
|
0xc2, 0x11, 0x72, 0xe3, 0xe2, 0x02, 0x33, 0xe2, 0x4b, 0x2a, 0x0b, 0x52, 0x25, 0x98, 0x14, 0x18,
|
||||||
|
0x35, 0xf8, 0x8c, 0xd4, 0xf5, 0xb0, 0x59, 0xa1, 0x07, 0x35, 0x48, 0xcf, 0x05, 0xa4, 0x3e, 0xa4,
|
||||||
|
0xb2, 0x20, 0x35, 0x88, 0x33, 0x05, 0xc6, 0x14, 0x52, 0xe6, 0xe2, 0x2d, 0x4a, 0x4d, 0xcf, 0x2c,
|
||||||
|
0x2e, 0x29, 0xaa, 0x8c, 0x2f, 0xca, 0xcf, 0x2f, 0x91, 0x60, 0x56, 0x60, 0xd4, 0xe0, 0x0c, 0xe2,
|
||||||
|
0x81, 0x09, 0x06, 0xe5, 0xe7, 0x97, 0x28, 0x29, 0x70, 0x71, 0xc2, 0x35, 0x0b, 0x71, 0x72, 0xb1,
|
||||||
|
0xfa, 0x05, 0x78, 0x06, 0xb8, 0x0a, 0x30, 0x08, 0x71, 0x70, 0xb1, 0xb8, 0x79, 0xfa, 0xb8, 0x0a,
|
||||||
|
0x30, 0x3a, 0xc5, 0x9c, 0x78, 0x28, 0xc7, 0x70, 0xe3, 0xa1, 0x1c, 0x43, 0xc3, 0x23, 0x39, 0xc6,
|
||||||
|
0x13, 0x8f, 0xe4, 0x18, 0x2f, 0x3c, 0x92, 0x63, 0x7c, 0xf0, 0x48, 0x8e, 0x31, 0xca, 0x89, 0xfc,
|
||||||
|
0xf0, 0xb3, 0x86, 0xd2, 0x11, 0x0c, 0x49, 0x6c, 0xe0, 0x70, 0x31, 0x06, 0x04, 0x00, 0x00, 0xff,
|
||||||
|
0xff, 0x91, 0x7a, 0xda, 0xa5, 0x8e, 0x01, 0x00, 0x00,
|
||||||
|
}
|
20
vendor/github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.proto
generated
vendored
Normal file
20
vendor/github.com/containerd/containerd/runtime/v2/runhcs/options/runhcs.proto
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
syntax = "proto3";
|
||||||
|
|
||||||
|
package containerd.runhcs.v1;
|
||||||
|
|
||||||
|
import weak "gogoproto/gogo.proto";
|
||||||
|
|
||||||
|
option go_package = "github.com/containerd/containerd/runtime/v2/runhcs/options;options";
|
||||||
|
|
||||||
|
message Options {
|
||||||
|
// enable debug tracing
|
||||||
|
bool debug = 1;
|
||||||
|
enum DebugType {
|
||||||
|
NPIPE = 0;
|
||||||
|
FILE = 1;
|
||||||
|
}
|
||||||
|
// debug tracing output type
|
||||||
|
DebugType debug_type = 2;
|
||||||
|
// registry key root for storage of the runhcs container state
|
||||||
|
string registry_root = 3;
|
||||||
|
}
|
3
vendor/github.com/containerd/containerd/runtime/v2/shim/reaper_unix.go
generated
vendored
3
vendor/github.com/containerd/containerd/runtime/v2/shim/reaper_unix.go
generated
vendored
@ -31,7 +31,7 @@ import (
|
|||||||
// ErrNoSuchProcess is returned when the process no longer exists
|
// ErrNoSuchProcess is returned when the process no longer exists
|
||||||
var ErrNoSuchProcess = errors.New("no such process")
|
var ErrNoSuchProcess = errors.New("no such process")
|
||||||
|
|
||||||
const bufferSize = 32
|
const bufferSize = 2048
|
||||||
|
|
||||||
// Reap should be called when the process receives an SIGCHLD. Reap will reap
|
// Reap should be called when the process receives an SIGCHLD. Reap will reap
|
||||||
// all exited processes and close their wait channels
|
// all exited processes and close their wait channels
|
||||||
@ -47,7 +47,6 @@ func Reap() error {
|
|||||||
Status: e.Status,
|
Status: e.Status,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Default.Unlock()
|
Default.Unlock()
|
||||||
return err
|
return err
|
||||||
|
2
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
2
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_unix.go
generated
vendored
@ -87,7 +87,7 @@ func handleSignals(logger *logrus.Entry, signals chan os.Signal) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
func openLog(ctx context.Context, _ string) (io.Writer, error) {
|
||||||
return fifo.OpenFifo(context.Background(), "log", unix.O_WRONLY, 0700)
|
return fifo.OpenFifo(ctx, "log", unix.O_WRONLY, 0700)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error {
|
func (l *remoteEventsPublisher) Publish(ctx context.Context, topic string, event events.Event) error {
|
||||||
|
7
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
7
vendor/github.com/containerd/containerd/runtime/v2/shim/shim_windows.go
generated
vendored
@ -27,7 +27,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
winio "github.com/Microsoft/go-winio"
|
winio "github.com/Microsoft/go-winio"
|
||||||
@ -40,10 +39,6 @@ import (
|
|||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
errorConnectionAborted syscall.Errno = 1236
|
|
||||||
)
|
|
||||||
|
|
||||||
// setupSignals creates a new signal handler for all signals
|
// setupSignals creates a new signal handler for all signals
|
||||||
func setupSignals() (chan os.Signal, error) {
|
func setupSignals() (chan os.Signal, error) {
|
||||||
signals := make(chan os.Signal, 32)
|
signals := make(chan os.Signal, 32)
|
||||||
@ -209,7 +204,7 @@ func (dswl *deferredShimWriteLogger) beginAccept() {
|
|||||||
dswl.mu.Unlock()
|
dswl.mu.Unlock()
|
||||||
|
|
||||||
c, err := dswl.l.Accept()
|
c, err := dswl.l.Accept()
|
||||||
if err == errorConnectionAborted {
|
if err == winio.ErrPipeListenerClosed {
|
||||||
dswl.mu.Lock()
|
dswl.mu.Lock()
|
||||||
dswl.aborted = true
|
dswl.aborted = true
|
||||||
dswl.l.Close()
|
dswl.l.Close()
|
||||||
|
32
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
32
vendor/github.com/containerd/containerd/runtime/v2/shim/util.go
generated
vendored
@ -24,6 +24,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
@ -32,6 +33,8 @@ import (
|
|||||||
|
|
||||||
const shimBinaryFormat = "containerd-shim-%s-%s"
|
const shimBinaryFormat = "containerd-shim-%s-%s"
|
||||||
|
|
||||||
|
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, cmdArgs ...string) (*exec.Cmd, error) {
|
||||||
ns, err := namespaces.NamespaceRequired(ctx)
|
ns, err := namespaces.NamespaceRequired(ctx)
|
||||||
@ -52,19 +55,30 @@ func Command(ctx context.Context, runtime, containerdAddress, path string, cmdAr
|
|||||||
if name == "" {
|
if name == "" {
|
||||||
return nil, fmt.Errorf("invalid runtime name %s, correct runtime name should format like io.containerd.runc.v1", runtime)
|
return nil, fmt.Errorf("invalid runtime name %s, correct runtime name should format like io.containerd.runc.v1", runtime)
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmdPath string
|
var cmdPath string
|
||||||
var lerr error
|
cmdPathI, cmdPathFound := runtimePaths.Load(name)
|
||||||
if cmdPath, lerr = exec.LookPath(name); lerr != nil {
|
if cmdPathFound {
|
||||||
if eerr, ok := lerr.(*exec.Error); ok {
|
cmdPath = cmdPathI.(string)
|
||||||
if eerr.Err == exec.ErrNotFound {
|
} else {
|
||||||
return nil, errors.Wrapf(os.ErrNotExist, "runtime %q binary not installed %q", runtime, name)
|
var lerr error
|
||||||
|
if cmdPath, lerr = exec.LookPath(name); lerr != nil {
|
||||||
|
if eerr, ok := lerr.(*exec.Error); ok {
|
||||||
|
if eerr.Err == exec.ErrNotFound {
|
||||||
|
return nil, errors.Wrapf(os.ErrNotExist, "runtime %q binary not installed %q", runtime, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cmdPath, err = filepath.Abs(cmdPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if cmdPathI, cmdPathFound = runtimePaths.LoadOrStore(name, cmdPath); cmdPathFound {
|
||||||
|
// We didn't store cmdPath we loaded an already cached value. Use it.
|
||||||
|
cmdPath = cmdPathI.(string)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cmdPath, err = filepath.Abs(cmdPath)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
cmd := exec.Command(cmdPath, args...)
|
cmd := exec.Command(cmdPath, args...)
|
||||||
cmd.Dir = path
|
cmd.Dir = path
|
||||||
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
cmd.Env = append(os.Environ(), "GOMAXPROCS=2")
|
||||||
|
27
vendor/github.com/containerd/containerd/services/server/server.go
generated
vendored
27
vendor/github.com/containerd/containerd/services/server/server.go
generated
vendored
@ -50,23 +50,28 @@ import (
|
|||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New creates and initializes a new containerd server
|
// CreateTopLevelDirectories creates the top-level root and state directories.
|
||||||
func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
func CreateTopLevelDirectories(config *srvconfig.Config) error {
|
||||||
switch {
|
switch {
|
||||||
case config.Root == "":
|
case config.Root == "":
|
||||||
return nil, errors.New("root must be specified")
|
return errors.New("root must be specified")
|
||||||
case config.State == "":
|
case config.State == "":
|
||||||
return nil, errors.New("state must be specified")
|
return errors.New("state must be specified")
|
||||||
case config.Root == config.State:
|
case config.Root == config.State:
|
||||||
return nil, errors.New("root and state must be different paths")
|
return errors.New("root and state must be different paths")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.MkdirAll(config.Root, 0711); err != nil {
|
if err := os.MkdirAll(config.Root, 0711); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
if err := os.MkdirAll(config.State, 0711); err != nil {
|
if err := os.MkdirAll(config.State, 0711); err != nil {
|
||||||
return nil, err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates and initializes a new containerd server
|
||||||
|
func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
||||||
if err := apply(ctx, config); err != nil {
|
if err := apply(ctx, config); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -125,7 +130,7 @@ func New(ctx context.Context, config *srvconfig.Config) (*Server, error) {
|
|||||||
instance, err := result.Instance()
|
instance, err := result.Instance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if plugin.IsSkipPlugin(err) {
|
if plugin.IsSkipPlugin(err) {
|
||||||
log.G(ctx).WithField("type", p.Type).Infof("skip loading plugin %q...", id)
|
log.G(ctx).WithError(err).WithField("type", p.Type).Infof("skip loading plugin %q...", id)
|
||||||
} 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)
|
||||||
}
|
}
|
||||||
@ -251,8 +256,10 @@ func LoadPlugins(ctx context.Context, config *srvconfig.Config) ([]*plugin.Regis
|
|||||||
for name, sn := range snapshottersRaw {
|
for name, sn := range snapshottersRaw {
|
||||||
sn, err := sn.Instance()
|
sn, err := sn.Instance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.G(ic.Context).WithError(err).
|
if !plugin.IsSkipPlugin(err) {
|
||||||
Warnf("could not use snapshotter %v in metadata plugin", name)
|
log.G(ic.Context).WithError(err).
|
||||||
|
Warnf("could not use snapshotter %v in metadata plugin", name)
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
snapshotters[name] = sn.(snapshots.Snapshotter)
|
snapshotters[name] = sn.(snapshots.Snapshotter)
|
||||||
|
9
vendor/github.com/containerd/containerd/services/tasks/local.go
generated
vendored
9
vendor/github.com/containerd/containerd/services/tasks/local.go
generated
vendored
@ -173,11 +173,14 @@ func (l *local) Create(ctx context.Context, r *api.CreateTaskRequest, _ ...grpc.
|
|||||||
Options: m.Options,
|
Options: m.Options,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
runtime, err := l.getRuntime(container.Runtime.Name)
|
rtime, err := l.getRuntime(container.Runtime.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c, err := runtime.Create(ctx, r.ContainerID, opts)
|
if _, err := rtime.Get(ctx, r.ContainerID); err != runtime.ErrTaskNotExists {
|
||||||
|
return nil, errdefs.ToGRPC(fmt.Errorf("task %s already exists", r.ContainerID))
|
||||||
|
}
|
||||||
|
c, err := rtime.Create(ctx, r.ContainerID, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errdefs.ToGRPC(err)
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
@ -460,7 +463,7 @@ func (l *local) CloseIO(ctx context.Context, r *api.CloseIORequest, _ ...grpc.Ca
|
|||||||
}
|
}
|
||||||
if r.Stdin {
|
if r.Stdin {
|
||||||
if err := p.CloseIO(ctx); err != nil {
|
if err := p.CloseIO(ctx); err != nil {
|
||||||
return nil, err
|
return nil, errdefs.ToGRPC(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return empty, nil
|
return empty, nil
|
||||||
|
2
vendor/github.com/containerd/containerd/services/tasks/local_unix.go
generated
vendored
2
vendor/github.com/containerd/containerd/services/tasks/local_unix.go
generated
vendored
@ -1,5 +1,3 @@
|
|||||||
// +build !windows_v2
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copyright The containerd Authors.
|
Copyright The containerd Authors.
|
||||||
|
|
||||||
|
10
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
10
vendor/github.com/containerd/containerd/vendor.conf
generated
vendored
@ -20,8 +20,8 @@ github.com/gogo/protobuf v1.0.0
|
|||||||
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
github.com/gogo/googleapis 08a7655d27152912db7aaf4f983275eaf8d128ef
|
||||||
github.com/golang/protobuf v1.1.0
|
github.com/golang/protobuf v1.1.0
|
||||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
||||||
github.com/opencontainers/runc 58592df56734acf62e574865fe40b9e53e967910
|
github.com/opencontainers/runc v1.0.0-rc6
|
||||||
github.com/sirupsen/logrus v1.0.0
|
github.com/sirupsen/logrus v1.0.3
|
||||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||||
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
golang.org/x/net b3756b4b77d7b13260a0a2ec658753cf48922eac
|
||||||
google.golang.org/grpc v1.12.0
|
google.golang.org/grpc v1.12.0
|
||||||
@ -33,7 +33,7 @@ golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
|||||||
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
|
||||||
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
github.com/grpc-ecosystem/go-grpc-prometheus 6b7015e65d366bf3f19b2b2a000a831940f0f7e0
|
||||||
github.com/Microsoft/go-winio v0.4.11
|
github.com/Microsoft/go-winio v0.4.11
|
||||||
github.com/Microsoft/hcsshim v0.7.12
|
github.com/Microsoft/hcsshim v0.8.2
|
||||||
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
google.golang.org/genproto d80a6e20e776b0b17a324d0ba1ab50a39c8e8944
|
||||||
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
golang.org/x/text 19e51611da83d6be54ddafce4a4af510cb3e9ea4
|
||||||
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
|
github.com/containerd/ttrpc 2a805f71863501300ae1976d29f0454ae003e85a
|
||||||
@ -81,9 +81,9 @@ k8s.io/kubernetes v1.12.0
|
|||||||
k8s.io/utils cd34563cd63c2bd7c6fe88a73c4dcf34ed8a67cb
|
k8s.io/utils cd34563cd63c2bd7c6fe88a73c4dcf34ed8a67cb
|
||||||
|
|
||||||
# zfs dependencies
|
# zfs dependencies
|
||||||
github.com/containerd/zfs 9a0b8b8b5982014b729cd34eb7cd7a11062aa6ec
|
github.com/containerd/zfs 9f6ef3b1fe5144bd91fe5855b4eba81bc0d17d03
|
||||||
github.com/mistifyio/go-zfs 166add352731e515512690329794ee593f1aaff2
|
github.com/mistifyio/go-zfs 166add352731e515512690329794ee593f1aaff2
|
||||||
github.com/pborman/uuid c65b2f87fee37d1c7854c9164a450713c28d50cd
|
github.com/pborman/uuid c65b2f87fee37d1c7854c9164a450713c28d50cd
|
||||||
|
|
||||||
# aufs dependencies
|
# aufs dependencies
|
||||||
github.com/containerd/aufs ffa39970e26ad01d81f540b21e65f9c1841a5f92
|
github.com/containerd/aufs da3cf16bfbe68ba8f114f1536a05c01528a25434
|
||||||
|
5
vendor/github.com/opencontainers/runc/README.md
generated
vendored
5
vendor/github.com/opencontainers/runc/README.md
generated
vendored
@ -68,6 +68,7 @@ make BUILDTAGS='seccomp apparmor'
|
|||||||
| selinux | selinux process and mount labeling | <none> |
|
| selinux | selinux process and mount labeling | <none> |
|
||||||
| apparmor | apparmor profile support | <none> |
|
| apparmor | apparmor profile support | <none> |
|
||||||
| ambient | ambient capability support | kernel 4.3 |
|
| ambient | ambient capability support | kernel 4.3 |
|
||||||
|
| nokmem | disable kernel memory account | <none> |
|
||||||
|
|
||||||
|
|
||||||
### Running the test suite
|
### Running the test suite
|
||||||
@ -263,3 +264,7 @@ PIDFile=/run/mycontainerid.pid
|
|||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The code and docs are released under the [Apache 2.0 license](LICENSE).
|
||||||
|
8
vendor/github.com/opencontainers/runc/libcontainer/README.md
generated
vendored
8
vendor/github.com/opencontainers/runc/libcontainer/README.md
generated
vendored
@ -148,6 +148,7 @@ config := &configs.Config{
|
|||||||
{Type: configs.NEWPID},
|
{Type: configs.NEWPID},
|
||||||
{Type: configs.NEWUSER},
|
{Type: configs.NEWUSER},
|
||||||
{Type: configs.NEWNET},
|
{Type: configs.NEWNET},
|
||||||
|
{Type: configs.NEWCGROUP},
|
||||||
}),
|
}),
|
||||||
Cgroups: &configs.Cgroup{
|
Cgroups: &configs.Cgroup{
|
||||||
Name: "test-container",
|
Name: "test-container",
|
||||||
@ -323,6 +324,7 @@ generated when building libcontainer with docker.
|
|||||||
|
|
||||||
## Copyright and license
|
## Copyright and license
|
||||||
|
|
||||||
Code and documentation copyright 2014 Docker, inc. Code released under the Apache 2.0 license.
|
Code and documentation copyright 2014 Docker, inc.
|
||||||
Docs released under Creative commons.
|
The code and documentation are released under the [Apache 2.0 license](../LICENSE).
|
||||||
|
The documentation is also released under Creative Commons Attribution 4.0 International License.
|
||||||
|
You may obtain a copy of the license, titled CC-BY-4.0, at http://creativecommons.org/licenses/by/4.0/.
|
||||||
|
13
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
13
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go
generated
vendored
@ -272,26 +272,23 @@ func (hooks Hooks) MarshalJSON() ([]byte, error) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// HookState is the payload provided to a hook on execution.
|
|
||||||
type HookState specs.State
|
|
||||||
|
|
||||||
type Hook interface {
|
type Hook interface {
|
||||||
// Run executes the hook with the provided state.
|
// Run executes the hook with the provided state.
|
||||||
Run(HookState) error
|
Run(*specs.State) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFunctionHook will call the provided function when the hook is run.
|
// NewFunctionHook will call the provided function when the hook is run.
|
||||||
func NewFunctionHook(f func(HookState) error) FuncHook {
|
func NewFunctionHook(f func(*specs.State) error) FuncHook {
|
||||||
return FuncHook{
|
return FuncHook{
|
||||||
run: f,
|
run: f,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FuncHook struct {
|
type FuncHook struct {
|
||||||
run func(HookState) error
|
run func(*specs.State) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f FuncHook) Run(s HookState) error {
|
func (f FuncHook) Run(s *specs.State) error {
|
||||||
return f.run(s)
|
return f.run(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +311,7 @@ type CommandHook struct {
|
|||||||
Command
|
Command
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Command) Run(s HookState) error {
|
func (c Command) Run(s *specs.State) error {
|
||||||
b, err := json.Marshal(s)
|
b, err := json.Marshal(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
16
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
generated
vendored
16
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_linux.go
generated
vendored
@ -7,12 +7,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NEWNET NamespaceType = "NEWNET"
|
NEWNET NamespaceType = "NEWNET"
|
||||||
NEWPID NamespaceType = "NEWPID"
|
NEWPID NamespaceType = "NEWPID"
|
||||||
NEWNS NamespaceType = "NEWNS"
|
NEWNS NamespaceType = "NEWNS"
|
||||||
NEWUTS NamespaceType = "NEWUTS"
|
NEWUTS NamespaceType = "NEWUTS"
|
||||||
NEWIPC NamespaceType = "NEWIPC"
|
NEWIPC NamespaceType = "NEWIPC"
|
||||||
NEWUSER NamespaceType = "NEWUSER"
|
NEWUSER NamespaceType = "NEWUSER"
|
||||||
|
NEWCGROUP NamespaceType = "NEWCGROUP"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -35,6 +36,8 @@ func NsName(ns NamespaceType) string {
|
|||||||
return "user"
|
return "user"
|
||||||
case NEWUTS:
|
case NEWUTS:
|
||||||
return "uts"
|
return "uts"
|
||||||
|
case NEWCGROUP:
|
||||||
|
return "cgroup"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@ -68,6 +71,7 @@ func NamespaceTypes() []NamespaceType {
|
|||||||
NEWNET,
|
NEWNET,
|
||||||
NEWPID,
|
NEWPID,
|
||||||
NEWNS,
|
NEWNS,
|
||||||
|
NEWCGROUP,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
13
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go
generated
vendored
13
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_syscall.go
generated
vendored
@ -9,12 +9,13 @@ func (n *Namespace) Syscall() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var namespaceInfo = map[NamespaceType]int{
|
var namespaceInfo = map[NamespaceType]int{
|
||||||
NEWNET: unix.CLONE_NEWNET,
|
NEWNET: unix.CLONE_NEWNET,
|
||||||
NEWNS: unix.CLONE_NEWNS,
|
NEWNS: unix.CLONE_NEWNS,
|
||||||
NEWUSER: unix.CLONE_NEWUSER,
|
NEWUSER: unix.CLONE_NEWUSER,
|
||||||
NEWIPC: unix.CLONE_NEWIPC,
|
NEWIPC: unix.CLONE_NEWIPC,
|
||||||
NEWUTS: unix.CLONE_NEWUTS,
|
NEWUTS: unix.CLONE_NEWUTS,
|
||||||
NEWPID: unix.CLONE_NEWPID,
|
NEWPID: unix.CLONE_NEWPID,
|
||||||
|
NEWCGROUP: unix.CLONE_NEWCGROUP,
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloneFlags parses the container's Namespaces options to set the correct
|
// CloneFlags parses the container's Namespaces options to set the correct
|
||||||
|
63
vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
generated
vendored
63
vendor/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c
generated
vendored
@ -42,6 +42,12 @@ enum sync_t {
|
|||||||
SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
|
SYNC_ERR = 0xFF, /* Fatal error, no turning back. The error code follows. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Synchronisation value for cgroup namespace setup.
|
||||||
|
* The same constant is defined in process_linux.go as "createCgroupns".
|
||||||
|
*/
|
||||||
|
#define CREATECGROUPNS 0x80
|
||||||
|
|
||||||
/* longjmp() arguments. */
|
/* longjmp() arguments. */
|
||||||
#define JUMP_PARENT 0x00
|
#define JUMP_PARENT 0x00
|
||||||
#define JUMP_CHILD 0xA0
|
#define JUMP_CHILD 0xA0
|
||||||
@ -640,7 +646,6 @@ void nsexec(void)
|
|||||||
case JUMP_PARENT:{
|
case JUMP_PARENT:{
|
||||||
int len;
|
int len;
|
||||||
pid_t child, first_child = -1;
|
pid_t child, first_child = -1;
|
||||||
char buf[JSON_MAX];
|
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
|
|
||||||
/* For debugging. */
|
/* For debugging. */
|
||||||
@ -716,6 +721,18 @@ void nsexec(void)
|
|||||||
kill(child, SIGKILL);
|
kill(child, SIGKILL);
|
||||||
bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
|
bail("failed to sync with child: write(SYNC_RECVPID_ACK)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Send the init_func pid back to our parent.
|
||||||
|
*
|
||||||
|
* Send the init_func pid and the pid of the first child back to our parent.
|
||||||
|
* We need to send both back because we can't reap the first child we created (CLONE_PARENT).
|
||||||
|
* It becomes the responsibility of our parent to reap the first child.
|
||||||
|
*/
|
||||||
|
len = dprintf(pipenum, "{\"pid\": %d, \"pid_first\": %d}\n", child, first_child);
|
||||||
|
if (len < 0) {
|
||||||
|
kill(child, SIGKILL);
|
||||||
|
bail("unable to generate JSON for child pid");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SYNC_CHILD_READY:
|
case SYNC_CHILD_READY:
|
||||||
@ -759,23 +776,6 @@ void nsexec(void)
|
|||||||
bail("unexpected sync value: %u", s);
|
bail("unexpected sync value: %u", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Send the init_func pid and the pid of the first child back to our parent.
|
|
||||||
*
|
|
||||||
* We need to send both back because we can't reap the first child we created (CLONE_PARENT).
|
|
||||||
* It becomes the responsibility of our parent to reap the first child.
|
|
||||||
*/
|
|
||||||
len = snprintf(buf, JSON_MAX, "{\"pid\": %d, \"pid_first\": %d}\n", child, first_child);
|
|
||||||
if (len < 0) {
|
|
||||||
kill(child, SIGKILL);
|
|
||||||
bail("unable to generate JSON for child pid");
|
|
||||||
}
|
|
||||||
if (write(pipenum, buf, len) != len) {
|
|
||||||
kill(child, SIGKILL);
|
|
||||||
bail("unable to send child pid to bootstrapper");
|
|
||||||
}
|
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -862,14 +862,17 @@ void nsexec(void)
|
|||||||
if (setresuid(0, 0, 0) < 0)
|
if (setresuid(0, 0, 0) < 0)
|
||||||
bail("failed to become root in user namespace");
|
bail("failed to become root in user namespace");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unshare all of the namespaces. Note that we don't merge this
|
* Unshare all of the namespaces. Now, it should be noted that this
|
||||||
* with clone() because there were some old kernel versions where
|
* ordering might break in the future (especially with rootless
|
||||||
* clone(CLONE_PARENT | CLONE_NEWPID) was broken, so we'll just do
|
* containers). But for now, it's not possible to split this into
|
||||||
* it the long way.
|
* CLONE_NEWUSER + [the rest] because of some RHEL SELinux issues.
|
||||||
|
*
|
||||||
|
* Note that we don't merge this with clone() because there were
|
||||||
|
* some old kernel versions where clone(CLONE_PARENT | CLONE_NEWPID)
|
||||||
|
* was broken, so we'll just do it the long way anyway.
|
||||||
*/
|
*/
|
||||||
if (unshare(config.cloneflags) < 0)
|
if (unshare(config.cloneflags & ~CLONE_NEWCGROUP) < 0)
|
||||||
bail("failed to unshare namespaces");
|
bail("failed to unshare namespaces");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -958,6 +961,18 @@ void nsexec(void)
|
|||||||
bail("setgroups failed");
|
bail("setgroups failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ... wait until our topmost parent has finished cgroup setup in p.manager.Apply() ... */
|
||||||
|
if (config.cloneflags & CLONE_NEWCGROUP) {
|
||||||
|
uint8_t value;
|
||||||
|
if (read(pipenum, &value, sizeof(value)) != sizeof(value))
|
||||||
|
bail("read synchronisation value failed");
|
||||||
|
if (value == CREATECGROUPNS) {
|
||||||
|
if (unshare(CLONE_NEWCGROUP) < 0)
|
||||||
|
bail("failed to unshare cgroup namespace");
|
||||||
|
} else
|
||||||
|
bail("received unknown synchronisation value");
|
||||||
|
}
|
||||||
|
|
||||||
s = SYNC_CHILD_READY;
|
s = SYNC_CHILD_READY;
|
||||||
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
|
if (write(syncfd, &s, sizeof(s)) != sizeof(s))
|
||||||
bail("failed to sync with patent: write(SYNC_CHILD_READY)");
|
bail("failed to sync with patent: write(SYNC_CHILD_READY)");
|
||||||
|
32
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
32
vendor/github.com/sirupsen/logrus/README.md
generated
vendored
@ -1,22 +1,24 @@
|
|||||||
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
|
# Logrus <img src="http://i.imgur.com/hTeVwmJ.png" width="40" height="40" alt=":walrus:" class="emoji" title=":walrus:"/> [](https://travis-ci.org/sirupsen/logrus) [](https://godoc.org/github.com/sirupsen/logrus)
|
||||||
|
|
||||||
Logrus is a structured logger for Go (golang), completely API compatible with
|
Logrus is a structured logger for Go (golang), completely API compatible with
|
||||||
the standard library logger. [Godoc][godoc]. **Please note the Logrus API is not
|
the standard library logger.
|
||||||
yet stable (pre 1.0). Logrus itself is completely stable and has been used in
|
|
||||||
many large deployments. The core API is unlikely to change much but please
|
|
||||||
version control your Logrus to make sure you aren't fetching latest `master` on
|
|
||||||
every build.**
|
|
||||||
|
|
||||||
**Seeing weird case-sensitive problems?** Unfortunately, the author failed to
|
**Seeing weird case-sensitive problems?** It's in the past been possible to
|
||||||
realize the consequences of renaming to lower-case. Due to the Go package
|
import Logrus as both upper- and lower-case. Due to the Go package environment,
|
||||||
environment, this caused issues. Regretfully, there's no turning back now.
|
this caused issues in the community and we needed a standard. Some environments
|
||||||
|
experienced problems with the upper-case variant, so the lower-case was decided.
|
||||||
Everything using `logrus` will need to use the lower-case:
|
Everything using `logrus` will need to use the lower-case:
|
||||||
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
`github.com/sirupsen/logrus`. Any package that isn't, should be changed.
|
||||||
|
|
||||||
I am terribly sorry for this inconvenience. Logrus strives hard for backwards
|
To fix Glide, see [these
|
||||||
compatibility, and the author failed to realize the cascading consequences of
|
|
||||||
such a name-change. To fix Glide, see [these
|
|
||||||
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437).
|
||||||
|
For an in-depth explanation of the casing issue, see [this
|
||||||
|
comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276).
|
||||||
|
|
||||||
|
**Are you interested in assisting in maintaining Logrus?** Currently I have a
|
||||||
|
lot of obligations, and I am unable to provide Logrus with the maintainership it
|
||||||
|
needs. If you'd like to help, please reach out to me at `simon at author's
|
||||||
|
username dot com`.
|
||||||
|
|
||||||
Nicely color-coded in development (when a TTY is attached, otherwise just
|
Nicely color-coded in development (when a TTY is attached, otherwise just
|
||||||
plain text):
|
plain text):
|
||||||
@ -266,6 +268,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
|||||||
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
| [Logrusly](https://github.com/sebest/logrusly) | Send logs to [Loggly](https://www.loggly.com/) |
|
||||||
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
| [Logstash](https://github.com/bshuster-repo/logrus-logstash-hook) | Hook for logging to [Logstash](https://www.elastic.co/products/logstash) |
|
||||||
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
| [Mail](https://github.com/zbindenren/logrus_mail) | Hook for sending exceptions via mail |
|
||||||
|
| [Mattermost](https://github.com/shuLhan/mattermost-integration/tree/master/hooks/logrus) | Hook for logging to [Mattermost](https://mattermost.com/) |
|
||||||
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
| [Mongodb](https://github.com/weekface/mgorus) | Hook for logging to mongodb |
|
||||||
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
| [NATS-Hook](https://github.com/rybit/nats_logrus_hook) | Hook for logging to [NATS](https://nats.io) |
|
||||||
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
| [Octokit](https://github.com/dorajistyle/logrus-octokit-hook) | Hook for logging to github via octokit |
|
||||||
@ -280,7 +283,7 @@ Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/v
|
|||||||
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
| [Slackrus](https://github.com/johntdyer/slackrus) | Hook for Slack chat. |
|
||||||
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
| [Stackdriver](https://github.com/knq/sdhook) | Hook for logging to [Google Stackdriver](https://cloud.google.com/logging/) |
|
||||||
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
| [Sumorus](https://github.com/doublefree/sumorus) | Hook for logging to [SumoLogic](https://www.sumologic.com/)|
|
||||||
| [Syslog](https://github.com/Sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
| [Syslog](https://github.com/sirupsen/logrus/blob/master/hooks/syslog/syslog.go) | Send errors to remote syslog server. Uses standard library `log/syslog` behind the scenes. |
|
||||||
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
| [Syslog TLS](https://github.com/shinji62/logrus-syslog-ng) | Send errors to remote syslog server with TLS support. |
|
||||||
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
| [TraceView](https://github.com/evalphobia/logrus_appneta) | Hook for logging to [AppNeta TraceView](https://www.appneta.com/products/traceview/) |
|
||||||
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
| [Typetalk](https://github.com/dragon3/logrus-typetalk-hook) | Hook for logging to [Typetalk](https://www.typetalk.in/) |
|
||||||
@ -369,6 +372,7 @@ The built-in logging formatters are:
|
|||||||
|
|
||||||
Third party logging formatters:
|
Third party logging formatters:
|
||||||
|
|
||||||
|
* [`FluentdFormatter`](https://github.com/joonix/log). Formats entries that can by parsed by Kubernetes and Google Container Engine.
|
||||||
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
* [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events.
|
||||||
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
* [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout.
|
||||||
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦.
|
||||||
@ -449,13 +453,13 @@ Logrus has a built in facility for asserting the presence of log messages. This
|
|||||||
```go
|
```go
|
||||||
import(
|
import(
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"github.com/sirupsen/logrus/hooks/null"
|
"github.com/sirupsen/logrus/hooks/test"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSomething(t*testing.T){
|
func TestSomething(t*testing.T){
|
||||||
logger, hook := null.NewNullLogger()
|
logger, hook := test.NewNullLogger()
|
||||||
logger.Error("Helloerror")
|
logger.Error("Helloerror")
|
||||||
|
|
||||||
assert.Equal(t, 1, len(hook.Entries))
|
assert.Equal(t, 1, len(hook.Entries))
|
||||||
|
1
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
1
vendor/github.com/sirupsen/logrus/entry.go
generated
vendored
@ -35,6 +35,7 @@ type Entry struct {
|
|||||||
Time time.Time
|
Time time.Time
|
||||||
|
|
||||||
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
// Level the log entry was logged at: Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
// This field will be set on entry firing and the value will be equal to the one in Logger struct field.
|
||||||
Level Level
|
Level Level
|
||||||
|
|
||||||
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
// Message passed to Debug, Info, Warn, Error, Fatal or Panic
|
||||||
|
2
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/exported.go
generated
vendored
@ -31,7 +31,7 @@ func SetFormatter(formatter Formatter) {
|
|||||||
func SetLevel(level Level) {
|
func SetLevel(level Level) {
|
||||||
std.mu.Lock()
|
std.mu.Lock()
|
||||||
defer std.mu.Unlock()
|
defer std.mu.Unlock()
|
||||||
std.setLevel(level)
|
std.SetLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetLevel returns the standard logger level.
|
// GetLevel returns the standard logger level.
|
||||||
|
2
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
2
vendor/github.com/sirupsen/logrus/formatter.go
generated
vendored
@ -2,7 +2,7 @@ package logrus
|
|||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
const DefaultTimestampFormat = time.RFC3339
|
const defaultTimestampFormat = time.RFC3339
|
||||||
|
|
||||||
// The Formatter interface is used to implement a custom Formatter. It takes an
|
// The Formatter interface is used to implement a custom Formatter. It takes an
|
||||||
// `Entry`. It exposes all the fields, including the default ones:
|
// `Entry`. It exposes all the fields, including the default ones:
|
||||||
|
9
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
9
vendor/github.com/sirupsen/logrus/json_formatter.go
generated
vendored
@ -6,8 +6,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type fieldKey string
|
type fieldKey string
|
||||||
|
|
||||||
|
// FieldMap allows customization of the key names for default fields.
|
||||||
type FieldMap map[fieldKey]string
|
type FieldMap map[fieldKey]string
|
||||||
|
|
||||||
|
// Default key names for the default fields
|
||||||
const (
|
const (
|
||||||
FieldKeyMsg = "msg"
|
FieldKeyMsg = "msg"
|
||||||
FieldKeyLevel = "level"
|
FieldKeyLevel = "level"
|
||||||
@ -22,6 +25,7 @@ func (f FieldMap) resolve(key fieldKey) string {
|
|||||||
return string(key)
|
return string(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JSONFormatter formats logs into parsable json
|
||||||
type JSONFormatter struct {
|
type JSONFormatter struct {
|
||||||
// TimestampFormat sets the format used for marshaling timestamps.
|
// TimestampFormat sets the format used for marshaling timestamps.
|
||||||
TimestampFormat string
|
TimestampFormat string
|
||||||
@ -29,7 +33,7 @@ type JSONFormatter struct {
|
|||||||
// DisableTimestamp allows disabling automatic timestamps in output
|
// DisableTimestamp allows disabling automatic timestamps in output
|
||||||
DisableTimestamp bool
|
DisableTimestamp bool
|
||||||
|
|
||||||
// FieldMap allows users to customize the names of keys for various fields.
|
// FieldMap allows users to customize the names of keys for default fields.
|
||||||
// As an example:
|
// As an example:
|
||||||
// formatter := &JSONFormatter{
|
// formatter := &JSONFormatter{
|
||||||
// FieldMap: FieldMap{
|
// FieldMap: FieldMap{
|
||||||
@ -41,6 +45,7 @@ type JSONFormatter struct {
|
|||||||
FieldMap FieldMap
|
FieldMap FieldMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
data := make(Fields, len(entry.Data)+3)
|
data := make(Fields, len(entry.Data)+3)
|
||||||
for k, v := range entry.Data {
|
for k, v := range entry.Data {
|
||||||
@ -57,7 +62,7 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
|
|
||||||
if !f.DisableTimestamp {
|
if !f.DisableTimestamp {
|
||||||
|
4
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
4
vendor/github.com/sirupsen/logrus/logger.go
generated
vendored
@ -25,7 +25,7 @@ type Logger struct {
|
|||||||
Formatter Formatter
|
Formatter Formatter
|
||||||
// The logging level the logger should log at. This is typically (and defaults
|
// The logging level the logger should log at. This is typically (and defaults
|
||||||
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
// to) `logrus.Info`, which allows Info(), Warn(), Error() and Fatal() to be
|
||||||
// logged. `logrus.Debug` is useful in
|
// logged.
|
||||||
Level Level
|
Level Level
|
||||||
// Used to sync writing to the log. Locking is enabled by Default
|
// Used to sync writing to the log. Locking is enabled by Default
|
||||||
mu MutexWrap
|
mu MutexWrap
|
||||||
@ -312,6 +312,6 @@ func (logger *Logger) level() Level {
|
|||||||
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
return Level(atomic.LoadUint32((*uint32)(&logger.Level)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (logger *Logger) setLevel(level Level) {
|
func (logger *Logger) SetLevel(level Level) {
|
||||||
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
atomic.StoreUint32((*uint32)(&logger.Level), uint32(level))
|
||||||
}
|
}
|
||||||
|
10
vendor/github.com/sirupsen/logrus/terminal_appengine.go
generated
vendored
10
vendor/github.com/sirupsen/logrus/terminal_appengine.go
generated
vendored
@ -1,10 +0,0 @@
|
|||||||
// +build appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import "io"
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
return true
|
|
||||||
}
|
|
6
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
6
vendor/github.com/sirupsen/logrus/terminal_bsd.go
generated
vendored
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TIOCGETA
|
const ioctlReadTermios = unix.TIOCGETA
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
6
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
6
vendor/github.com/sirupsen/logrus/terminal_linux.go
generated
vendored
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
package logrus
|
package logrus
|
||||||
|
|
||||||
import "syscall"
|
import "golang.org/x/sys/unix"
|
||||||
|
|
||||||
const ioctlReadTermios = syscall.TCGETS
|
const ioctlReadTermios = unix.TCGETS
|
||||||
|
|
||||||
type Termios syscall.Termios
|
type Termios unix.Termios
|
||||||
|
28
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
28
vendor/github.com/sirupsen/logrus/terminal_notwindows.go
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
// Based on ssh/terminal:
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build linux darwin freebsd openbsd netbsd dragonfly
|
|
||||||
// +build !appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
var termios Termios
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(v.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
|
|
||||||
return err == 0
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/github.com/sirupsen/logrus/terminal_solaris.go
generated
vendored
21
vendor/github.com/sirupsen/logrus/terminal_solaris.go
generated
vendored
@ -1,21 +0,0 @@
|
|||||||
// +build solaris,!appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"golang.org/x/sys/unix"
|
|
||||||
)
|
|
||||||
|
|
||||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
_, err := unix.IoctlGetTermios(int(v.Fd()), unix.TCGETA)
|
|
||||||
return err == nil
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
82
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
82
vendor/github.com/sirupsen/logrus/terminal_windows.go
generated
vendored
@ -1,82 +0,0 @@
|
|||||||
// Based on ssh/terminal:
|
|
||||||
// Copyright 2011 The Go Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style
|
|
||||||
// license that can be found in the LICENSE file.
|
|
||||||
|
|
||||||
// +build windows,!appengine
|
|
||||||
|
|
||||||
package logrus
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
||||||
|
|
||||||
var (
|
|
||||||
procGetConsoleMode = kernel32.NewProc("GetConsoleMode")
|
|
||||||
procSetConsoleMode = kernel32.NewProc("SetConsoleMode")
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
enableProcessedOutput = 0x0001
|
|
||||||
enableWrapAtEolOutput = 0x0002
|
|
||||||
enableVirtualTerminalProcessing = 0x0004
|
|
||||||
)
|
|
||||||
|
|
||||||
func getVersion() (float64, error) {
|
|
||||||
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
||||||
cmd := exec.Command("cmd", "ver")
|
|
||||||
cmd.Stdout = stdout
|
|
||||||
cmd.Stderr = stderr
|
|
||||||
err := cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
return -1, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// The output should be like "Microsoft Windows [Version XX.X.XXXXXX]"
|
|
||||||
version := strings.Replace(stdout.String(), "\n", "", -1)
|
|
||||||
version = strings.Replace(version, "\r\n", "", -1)
|
|
||||||
|
|
||||||
x1 := strings.Index(version, "[Version")
|
|
||||||
|
|
||||||
if x1 == -1 || strings.Index(version, "]") == -1 {
|
|
||||||
return -1, errors.New("Can't determine Windows version")
|
|
||||||
}
|
|
||||||
|
|
||||||
return strconv.ParseFloat(version[x1+9:x1+13], 64)
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
ver, err := getVersion()
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Activate Virtual Processing for Windows CMD
|
|
||||||
// Info: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
|
|
||||||
if ver >= 10 {
|
|
||||||
handle := syscall.Handle(os.Stderr.Fd())
|
|
||||||
procSetConsoleMode.Call(uintptr(handle), enableProcessedOutput|enableWrapAtEolOutput|enableVirtualTerminalProcessing)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal returns true if stderr's file descriptor is a terminal.
|
|
||||||
func IsTerminal(f io.Writer) bool {
|
|
||||||
switch v := f.(type) {
|
|
||||||
case *os.File:
|
|
||||||
var st uint32
|
|
||||||
r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(v.Fd()), uintptr(unsafe.Pointer(&st)), 0)
|
|
||||||
return r != 0 && e == 0
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
60
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
60
vendor/github.com/sirupsen/logrus/text_formatter.go
generated
vendored
@ -3,10 +3,14 @@ package logrus
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -14,7 +18,7 @@ const (
|
|||||||
red = 31
|
red = 31
|
||||||
green = 32
|
green = 32
|
||||||
yellow = 33
|
yellow = 33
|
||||||
blue = 34
|
blue = 36
|
||||||
gray = 37
|
gray = 37
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,6 +30,7 @@ func init() {
|
|||||||
baseTimestamp = time.Now()
|
baseTimestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TextFormatter formats logs into text
|
||||||
type TextFormatter struct {
|
type TextFormatter struct {
|
||||||
// Set to true to bypass checking for a TTY before outputting colors.
|
// Set to true to bypass checking for a TTY before outputting colors.
|
||||||
ForceColors bool
|
ForceColors bool
|
||||||
@ -52,10 +57,6 @@ type TextFormatter struct {
|
|||||||
// QuoteEmptyFields will wrap empty fields in quotes if true
|
// QuoteEmptyFields will wrap empty fields in quotes if true
|
||||||
QuoteEmptyFields bool
|
QuoteEmptyFields bool
|
||||||
|
|
||||||
// QuoteCharacter can be set to the override the default quoting character "
|
|
||||||
// with something else. For example: ', or `.
|
|
||||||
QuoteCharacter string
|
|
||||||
|
|
||||||
// Whether the logger's out is to a terminal
|
// Whether the logger's out is to a terminal
|
||||||
isTerminal bool
|
isTerminal bool
|
||||||
|
|
||||||
@ -63,14 +64,21 @@ type TextFormatter struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) init(entry *Entry) {
|
func (f *TextFormatter) init(entry *Entry) {
|
||||||
if len(f.QuoteCharacter) == 0 {
|
|
||||||
f.QuoteCharacter = "\""
|
|
||||||
}
|
|
||||||
if entry.Logger != nil {
|
if entry.Logger != nil {
|
||||||
f.isTerminal = IsTerminal(entry.Logger.Out)
|
f.isTerminal = f.checkIfTerminal(entry.Logger.Out)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *TextFormatter) checkIfTerminal(w io.Writer) bool {
|
||||||
|
switch v := w.(type) {
|
||||||
|
case *os.File:
|
||||||
|
return terminal.IsTerminal(int(v.Fd()))
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format renders a single log entry
|
||||||
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
||||||
var b *bytes.Buffer
|
var b *bytes.Buffer
|
||||||
keys := make([]string, 0, len(entry.Data))
|
keys := make([]string, 0, len(entry.Data))
|
||||||
@ -95,7 +103,7 @@ func (f *TextFormatter) Format(entry *Entry) ([]byte, error) {
|
|||||||
|
|
||||||
timestampFormat := f.TimestampFormat
|
timestampFormat := f.TimestampFormat
|
||||||
if timestampFormat == "" {
|
if timestampFormat == "" {
|
||||||
timestampFormat = DefaultTimestampFormat
|
timestampFormat = defaultTimestampFormat
|
||||||
}
|
}
|
||||||
if isColored {
|
if isColored {
|
||||||
f.printColored(b, entry, keys, timestampFormat)
|
f.printColored(b, entry, keys, timestampFormat)
|
||||||
@ -153,7 +161,7 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
|||||||
if !((ch >= 'a' && ch <= 'z') ||
|
if !((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
(ch >= '0' && ch <= '9') ||
|
(ch >= '0' && ch <= '9') ||
|
||||||
ch == '-' || ch == '.') {
|
ch == '-' || ch == '.' || ch == '_' || ch == '/' || ch == '@' || ch == '^' || ch == '+') {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -161,29 +169,23 @@ func (f *TextFormatter) needsQuoting(text string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
func (f *TextFormatter) appendKeyValue(b *bytes.Buffer, key string, value interface{}) {
|
||||||
|
if b.Len() > 0 {
|
||||||
|
b.WriteByte(' ')
|
||||||
|
}
|
||||||
b.WriteString(key)
|
b.WriteString(key)
|
||||||
b.WriteByte('=')
|
b.WriteByte('=')
|
||||||
f.appendValue(b, value)
|
f.appendValue(b, value)
|
||||||
b.WriteByte(' ')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
func (f *TextFormatter) appendValue(b *bytes.Buffer, value interface{}) {
|
||||||
switch value := value.(type) {
|
stringVal, ok := value.(string)
|
||||||
case string:
|
if !ok {
|
||||||
if !f.needsQuoting(value) {
|
stringVal = fmt.Sprint(value)
|
||||||
b.WriteString(value)
|
}
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, value, f.QuoteCharacter)
|
if !f.needsQuoting(stringVal) {
|
||||||
}
|
b.WriteString(stringVal)
|
||||||
case error:
|
} else {
|
||||||
errmsg := value.Error()
|
b.WriteString(fmt.Sprintf("%q", stringVal))
|
||||||
if !f.needsQuoting(errmsg) {
|
|
||||||
b.WriteString(errmsg)
|
|
||||||
} else {
|
|
||||||
fmt.Fprintf(b, "%s%v%s", f.QuoteCharacter, errmsg, f.QuoteCharacter)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
fmt.Fprint(b, value)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
198
vendor/golang.org/x/sys/windows/registry/key.go
generated
vendored
Normal file
198
vendor/golang.org/x/sys/windows/registry/key.go
generated
vendored
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Package registry provides access to the Windows registry.
|
||||||
|
//
|
||||||
|
// Here is a simple example, opening a registry key and reading a string value from it.
|
||||||
|
//
|
||||||
|
// k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// defer k.Close()
|
||||||
|
//
|
||||||
|
// s, _, err := k.GetStringValue("SystemRoot")
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
// fmt.Printf("Windows system root is %q\n", s)
|
||||||
|
//
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Registry key security and access rights.
|
||||||
|
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms724878.aspx
|
||||||
|
// for details.
|
||||||
|
ALL_ACCESS = 0xf003f
|
||||||
|
CREATE_LINK = 0x00020
|
||||||
|
CREATE_SUB_KEY = 0x00004
|
||||||
|
ENUMERATE_SUB_KEYS = 0x00008
|
||||||
|
EXECUTE = 0x20019
|
||||||
|
NOTIFY = 0x00010
|
||||||
|
QUERY_VALUE = 0x00001
|
||||||
|
READ = 0x20019
|
||||||
|
SET_VALUE = 0x00002
|
||||||
|
WOW64_32KEY = 0x00200
|
||||||
|
WOW64_64KEY = 0x00100
|
||||||
|
WRITE = 0x20006
|
||||||
|
)
|
||||||
|
|
||||||
|
// Key is a handle to an open Windows registry key.
|
||||||
|
// Keys can be obtained by calling OpenKey; there are
|
||||||
|
// also some predefined root keys such as CURRENT_USER.
|
||||||
|
// Keys can be used directly in the Windows API.
|
||||||
|
type Key syscall.Handle
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Windows defines some predefined root keys that are always open.
|
||||||
|
// An application can use these keys as entry points to the registry.
|
||||||
|
// Normally these keys are used in OpenKey to open new keys,
|
||||||
|
// but they can also be used anywhere a Key is required.
|
||||||
|
CLASSES_ROOT = Key(syscall.HKEY_CLASSES_ROOT)
|
||||||
|
CURRENT_USER = Key(syscall.HKEY_CURRENT_USER)
|
||||||
|
LOCAL_MACHINE = Key(syscall.HKEY_LOCAL_MACHINE)
|
||||||
|
USERS = Key(syscall.HKEY_USERS)
|
||||||
|
CURRENT_CONFIG = Key(syscall.HKEY_CURRENT_CONFIG)
|
||||||
|
PERFORMANCE_DATA = Key(syscall.HKEY_PERFORMANCE_DATA)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Close closes open key k.
|
||||||
|
func (k Key) Close() error {
|
||||||
|
return syscall.RegCloseKey(syscall.Handle(k))
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenKey opens a new key with path name relative to key k.
|
||||||
|
// It accepts any open key, including CURRENT_USER and others,
|
||||||
|
// and returns the new key and an error.
|
||||||
|
// The access parameter specifies desired access rights to the
|
||||||
|
// key to be opened.
|
||||||
|
func OpenKey(k Key, path string, access uint32) (Key, error) {
|
||||||
|
p, err := syscall.UTF16PtrFromString(path)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
var subkey syscall.Handle
|
||||||
|
err = syscall.RegOpenKeyEx(syscall.Handle(k), p, 0, access, &subkey)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return Key(subkey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenRemoteKey opens a predefined registry key on another
|
||||||
|
// computer pcname. The key to be opened is specified by k, but
|
||||||
|
// can only be one of LOCAL_MACHINE, PERFORMANCE_DATA or USERS.
|
||||||
|
// If pcname is "", OpenRemoteKey returns local computer key.
|
||||||
|
func OpenRemoteKey(pcname string, k Key) (Key, error) {
|
||||||
|
var err error
|
||||||
|
var p *uint16
|
||||||
|
if pcname != "" {
|
||||||
|
p, err = syscall.UTF16PtrFromString(`\\` + pcname)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var remoteKey syscall.Handle
|
||||||
|
err = regConnectRegistry(p, syscall.Handle(k), &remoteKey)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return Key(remoteKey), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadSubKeyNames returns the names of subkeys of key k.
|
||||||
|
// The parameter n controls the number of returned names,
|
||||||
|
// analogous to the way os.File.Readdirnames works.
|
||||||
|
func (k Key) ReadSubKeyNames(n int) ([]string, error) {
|
||||||
|
names := make([]string, 0)
|
||||||
|
// Registry key size limit is 255 bytes and described there:
|
||||||
|
// https://msdn.microsoft.com/library/windows/desktop/ms724872.aspx
|
||||||
|
buf := make([]uint16, 256) //plus extra room for terminating zero byte
|
||||||
|
loopItems:
|
||||||
|
for i := uint32(0); ; i++ {
|
||||||
|
if n > 0 {
|
||||||
|
if len(names) == n {
|
||||||
|
return names, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l := uint32(len(buf))
|
||||||
|
for {
|
||||||
|
err := syscall.RegEnumKeyEx(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err == syscall.ERROR_MORE_DATA {
|
||||||
|
// Double buffer size and try again.
|
||||||
|
l = uint32(2 * len(buf))
|
||||||
|
buf = make([]uint16, l)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err == _ERROR_NO_MORE_ITEMS {
|
||||||
|
break loopItems
|
||||||
|
}
|
||||||
|
return names, err
|
||||||
|
}
|
||||||
|
names = append(names, syscall.UTF16ToString(buf[:l]))
|
||||||
|
}
|
||||||
|
if n > len(names) {
|
||||||
|
return names, io.EOF
|
||||||
|
}
|
||||||
|
return names, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateKey creates a key named path under open key k.
|
||||||
|
// CreateKey returns the new key and a boolean flag that reports
|
||||||
|
// whether the key already existed.
|
||||||
|
// The access parameter specifies the access rights for the key
|
||||||
|
// to be created.
|
||||||
|
func CreateKey(k Key, path string, access uint32) (newk Key, openedExisting bool, err error) {
|
||||||
|
var h syscall.Handle
|
||||||
|
var d uint32
|
||||||
|
err = regCreateKeyEx(syscall.Handle(k), syscall.StringToUTF16Ptr(path),
|
||||||
|
0, nil, _REG_OPTION_NON_VOLATILE, access, nil, &h, &d)
|
||||||
|
if err != nil {
|
||||||
|
return 0, false, err
|
||||||
|
}
|
||||||
|
return Key(h), d == _REG_OPENED_EXISTING_KEY, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteKey deletes the subkey path of key k and its values.
|
||||||
|
func DeleteKey(k Key, path string) error {
|
||||||
|
return regDeleteKey(syscall.Handle(k), syscall.StringToUTF16Ptr(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
// A KeyInfo describes the statistics of a key. It is returned by Stat.
|
||||||
|
type KeyInfo struct {
|
||||||
|
SubKeyCount uint32
|
||||||
|
MaxSubKeyLen uint32 // size of the key's subkey with the longest name, in Unicode characters, not including the terminating zero byte
|
||||||
|
ValueCount uint32
|
||||||
|
MaxValueNameLen uint32 // size of the key's longest value name, in Unicode characters, not including the terminating zero byte
|
||||||
|
MaxValueLen uint32 // longest data component among the key's values, in bytes
|
||||||
|
lastWriteTime syscall.Filetime
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModTime returns the key's last write time.
|
||||||
|
func (ki *KeyInfo) ModTime() time.Time {
|
||||||
|
return time.Unix(0, ki.lastWriteTime.Nanoseconds())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stat retrieves information about the open key k.
|
||||||
|
func (k Key) Stat() (*KeyInfo, error) {
|
||||||
|
var ki KeyInfo
|
||||||
|
err := syscall.RegQueryInfoKey(syscall.Handle(k), nil, nil, nil,
|
||||||
|
&ki.SubKeyCount, &ki.MaxSubKeyLen, nil, &ki.ValueCount,
|
||||||
|
&ki.MaxValueNameLen, &ki.MaxValueLen, nil, &ki.lastWriteTime)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ki, nil
|
||||||
|
}
|
7
vendor/golang.org/x/sys/windows/registry/mksyscall.go
generated
vendored
Normal file
7
vendor/golang.org/x/sys/windows/registry/mksyscall.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
//go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -output zsyscall_windows.go syscall.go
|
32
vendor/golang.org/x/sys/windows/registry/syscall.go
generated
vendored
Normal file
32
vendor/golang.org/x/sys/windows/registry/syscall.go
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
const (
|
||||||
|
_REG_OPTION_NON_VOLATILE = 0
|
||||||
|
|
||||||
|
_REG_CREATED_NEW_KEY = 1
|
||||||
|
_REG_OPENED_EXISTING_KEY = 2
|
||||||
|
|
||||||
|
_ERROR_NO_MORE_ITEMS syscall.Errno = 259
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoadRegLoadMUIString() error {
|
||||||
|
return procRegLoadMUIStringW.Find()
|
||||||
|
}
|
||||||
|
|
||||||
|
//sys regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) = advapi32.RegCreateKeyExW
|
||||||
|
//sys regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) = advapi32.RegDeleteKeyW
|
||||||
|
//sys regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) = advapi32.RegSetValueExW
|
||||||
|
//sys regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) = advapi32.RegEnumValueW
|
||||||
|
//sys regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) = advapi32.RegDeleteValueW
|
||||||
|
//sys regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) = advapi32.RegLoadMUIStringW
|
||||||
|
//sys regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) = advapi32.RegConnectRegistryW
|
||||||
|
|
||||||
|
//sys expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) = kernel32.ExpandEnvironmentStringsW
|
384
vendor/golang.org/x/sys/windows/registry/value.go
generated
vendored
Normal file
384
vendor/golang.org/x/sys/windows/registry/value.go
generated
vendored
Normal file
@ -0,0 +1,384 @@
|
|||||||
|
// Copyright 2015 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"syscall"
|
||||||
|
"unicode/utf16"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Registry value types.
|
||||||
|
NONE = 0
|
||||||
|
SZ = 1
|
||||||
|
EXPAND_SZ = 2
|
||||||
|
BINARY = 3
|
||||||
|
DWORD = 4
|
||||||
|
DWORD_BIG_ENDIAN = 5
|
||||||
|
LINK = 6
|
||||||
|
MULTI_SZ = 7
|
||||||
|
RESOURCE_LIST = 8
|
||||||
|
FULL_RESOURCE_DESCRIPTOR = 9
|
||||||
|
RESOURCE_REQUIREMENTS_LIST = 10
|
||||||
|
QWORD = 11
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrShortBuffer is returned when the buffer was too short for the operation.
|
||||||
|
ErrShortBuffer = syscall.ERROR_MORE_DATA
|
||||||
|
|
||||||
|
// ErrNotExist is returned when a registry key or value does not exist.
|
||||||
|
ErrNotExist = syscall.ERROR_FILE_NOT_FOUND
|
||||||
|
|
||||||
|
// ErrUnexpectedType is returned by Get*Value when the value's type was unexpected.
|
||||||
|
ErrUnexpectedType = errors.New("unexpected key value type")
|
||||||
|
)
|
||||||
|
|
||||||
|
// GetValue retrieves the type and data for the specified value associated
|
||||||
|
// with an open key k. It fills up buffer buf and returns the retrieved
|
||||||
|
// byte count n. If buf is too small to fit the stored value it returns
|
||||||
|
// ErrShortBuffer error along with the required buffer size n.
|
||||||
|
// If no buffer is provided, it returns true and actual buffer size n.
|
||||||
|
// If no buffer is provided, GetValue returns the value's type only.
|
||||||
|
// If the value does not exist, the error returned is ErrNotExist.
|
||||||
|
//
|
||||||
|
// GetValue is a low level function. If value's type is known, use the appropriate
|
||||||
|
// Get*Value function instead.
|
||||||
|
func (k Key) GetValue(name string, buf []byte) (n int, valtype uint32, err error) {
|
||||||
|
pname, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return 0, 0, err
|
||||||
|
}
|
||||||
|
var pbuf *byte
|
||||||
|
if len(buf) > 0 {
|
||||||
|
pbuf = (*byte)(unsafe.Pointer(&buf[0]))
|
||||||
|
}
|
||||||
|
l := uint32(len(buf))
|
||||||
|
err = syscall.RegQueryValueEx(syscall.Handle(k), pname, nil, &valtype, pbuf, &l)
|
||||||
|
if err != nil {
|
||||||
|
return int(l), valtype, err
|
||||||
|
}
|
||||||
|
return int(l), valtype, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) getValue(name string, buf []byte) (date []byte, valtype uint32, err error) {
|
||||||
|
p, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
var t uint32
|
||||||
|
n := uint32(len(buf))
|
||||||
|
for {
|
||||||
|
err = syscall.RegQueryValueEx(syscall.Handle(k), p, nil, &t, (*byte)(unsafe.Pointer(&buf[0])), &n)
|
||||||
|
if err == nil {
|
||||||
|
return buf[:n], t, nil
|
||||||
|
}
|
||||||
|
if err != syscall.ERROR_MORE_DATA {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
if n <= uint32(len(buf)) {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
buf = make([]byte, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringValue retrieves the string value for the specified
|
||||||
|
// value name associated with an open key k. It also returns the value's type.
|
||||||
|
// If value does not exist, GetStringValue returns ErrNotExist.
|
||||||
|
// If value is not SZ or EXPAND_SZ, it will return the correct value
|
||||||
|
// type and ErrUnexpectedType.
|
||||||
|
func (k Key) GetStringValue(name string) (val string, valtype uint32, err error) {
|
||||||
|
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||||
|
if err2 != nil {
|
||||||
|
return "", typ, err2
|
||||||
|
}
|
||||||
|
switch typ {
|
||||||
|
case SZ, EXPAND_SZ:
|
||||||
|
default:
|
||||||
|
return "", typ, ErrUnexpectedType
|
||||||
|
}
|
||||||
|
if len(data) == 0 {
|
||||||
|
return "", typ, nil
|
||||||
|
}
|
||||||
|
u := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:]
|
||||||
|
return syscall.UTF16ToString(u), typ, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMUIStringValue retrieves the localized string value for
|
||||||
|
// the specified value name associated with an open key k.
|
||||||
|
// If the value name doesn't exist or the localized string value
|
||||||
|
// can't be resolved, GetMUIStringValue returns ErrNotExist.
|
||||||
|
// GetMUIStringValue panics if the system doesn't support
|
||||||
|
// regLoadMUIString; use LoadRegLoadMUIString to check if
|
||||||
|
// regLoadMUIString is supported before calling this function.
|
||||||
|
func (k Key) GetMUIStringValue(name string) (string, error) {
|
||||||
|
pname, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
buf := make([]uint16, 1024)
|
||||||
|
var buflen uint32
|
||||||
|
var pdir *uint16
|
||||||
|
|
||||||
|
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||||
|
if err == syscall.ERROR_FILE_NOT_FOUND { // Try fallback path
|
||||||
|
|
||||||
|
// Try to resolve the string value using the system directory as
|
||||||
|
// a DLL search path; this assumes the string value is of the form
|
||||||
|
// @[path]\dllname,-strID but with no path given, e.g. @tzres.dll,-320.
|
||||||
|
|
||||||
|
// This approach works with tzres.dll but may have to be revised
|
||||||
|
// in the future to allow callers to provide custom search paths.
|
||||||
|
|
||||||
|
var s string
|
||||||
|
s, err = ExpandString("%SystemRoot%\\system32\\")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
pdir, err = syscall.UTF16PtrFromString(s)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
for err == syscall.ERROR_MORE_DATA { // Grow buffer if needed
|
||||||
|
if buflen <= uint32(len(buf)) {
|
||||||
|
break // Buffer not growing, assume race; break
|
||||||
|
}
|
||||||
|
buf = make([]uint16, buflen)
|
||||||
|
err = regLoadMUIString(syscall.Handle(k), pname, &buf[0], uint32(len(buf)), &buflen, 0, pdir)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return syscall.UTF16ToString(buf), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExpandString expands environment-variable strings and replaces
|
||||||
|
// them with the values defined for the current user.
|
||||||
|
// Use ExpandString to expand EXPAND_SZ strings.
|
||||||
|
func ExpandString(value string) (string, error) {
|
||||||
|
if value == "" {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
p, err := syscall.UTF16PtrFromString(value)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
r := make([]uint16, 100)
|
||||||
|
for {
|
||||||
|
n, err := expandEnvironmentStrings(p, &r[0], uint32(len(r)))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
if n <= uint32(len(r)) {
|
||||||
|
u := (*[1 << 29]uint16)(unsafe.Pointer(&r[0]))[:]
|
||||||
|
return syscall.UTF16ToString(u), nil
|
||||||
|
}
|
||||||
|
r = make([]uint16, n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetStringsValue retrieves the []string value for the specified
|
||||||
|
// value name associated with an open key k. It also returns the value's type.
|
||||||
|
// If value does not exist, GetStringsValue returns ErrNotExist.
|
||||||
|
// If value is not MULTI_SZ, it will return the correct value
|
||||||
|
// type and ErrUnexpectedType.
|
||||||
|
func (k Key) GetStringsValue(name string) (val []string, valtype uint32, err error) {
|
||||||
|
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, typ, err2
|
||||||
|
}
|
||||||
|
if typ != MULTI_SZ {
|
||||||
|
return nil, typ, ErrUnexpectedType
|
||||||
|
}
|
||||||
|
if len(data) == 0 {
|
||||||
|
return nil, typ, nil
|
||||||
|
}
|
||||||
|
p := (*[1 << 29]uint16)(unsafe.Pointer(&data[0]))[:len(data)/2]
|
||||||
|
if len(p) == 0 {
|
||||||
|
return nil, typ, nil
|
||||||
|
}
|
||||||
|
if p[len(p)-1] == 0 {
|
||||||
|
p = p[:len(p)-1] // remove terminating null
|
||||||
|
}
|
||||||
|
val = make([]string, 0, 5)
|
||||||
|
from := 0
|
||||||
|
for i, c := range p {
|
||||||
|
if c == 0 {
|
||||||
|
val = append(val, string(utf16.Decode(p[from:i])))
|
||||||
|
from = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return val, typ, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetIntegerValue retrieves the integer value for the specified
|
||||||
|
// value name associated with an open key k. It also returns the value's type.
|
||||||
|
// If value does not exist, GetIntegerValue returns ErrNotExist.
|
||||||
|
// If value is not DWORD or QWORD, it will return the correct value
|
||||||
|
// type and ErrUnexpectedType.
|
||||||
|
func (k Key) GetIntegerValue(name string) (val uint64, valtype uint32, err error) {
|
||||||
|
data, typ, err2 := k.getValue(name, make([]byte, 8))
|
||||||
|
if err2 != nil {
|
||||||
|
return 0, typ, err2
|
||||||
|
}
|
||||||
|
switch typ {
|
||||||
|
case DWORD:
|
||||||
|
if len(data) != 4 {
|
||||||
|
return 0, typ, errors.New("DWORD value is not 4 bytes long")
|
||||||
|
}
|
||||||
|
return uint64(*(*uint32)(unsafe.Pointer(&data[0]))), DWORD, nil
|
||||||
|
case QWORD:
|
||||||
|
if len(data) != 8 {
|
||||||
|
return 0, typ, errors.New("QWORD value is not 8 bytes long")
|
||||||
|
}
|
||||||
|
return uint64(*(*uint64)(unsafe.Pointer(&data[0]))), QWORD, nil
|
||||||
|
default:
|
||||||
|
return 0, typ, ErrUnexpectedType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBinaryValue retrieves the binary value for the specified
|
||||||
|
// value name associated with an open key k. It also returns the value's type.
|
||||||
|
// If value does not exist, GetBinaryValue returns ErrNotExist.
|
||||||
|
// If value is not BINARY, it will return the correct value
|
||||||
|
// type and ErrUnexpectedType.
|
||||||
|
func (k Key) GetBinaryValue(name string) (val []byte, valtype uint32, err error) {
|
||||||
|
data, typ, err2 := k.getValue(name, make([]byte, 64))
|
||||||
|
if err2 != nil {
|
||||||
|
return nil, typ, err2
|
||||||
|
}
|
||||||
|
if typ != BINARY {
|
||||||
|
return nil, typ, ErrUnexpectedType
|
||||||
|
}
|
||||||
|
return data, typ, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) setValue(name string, valtype uint32, data []byte) error {
|
||||||
|
p, err := syscall.UTF16PtrFromString(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(data) == 0 {
|
||||||
|
return regSetValueEx(syscall.Handle(k), p, 0, valtype, nil, 0)
|
||||||
|
}
|
||||||
|
return regSetValueEx(syscall.Handle(k), p, 0, valtype, &data[0], uint32(len(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDWordValue sets the data and type of a name value
|
||||||
|
// under key k to value and DWORD.
|
||||||
|
func (k Key) SetDWordValue(name string, value uint32) error {
|
||||||
|
return k.setValue(name, DWORD, (*[4]byte)(unsafe.Pointer(&value))[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetQWordValue sets the data and type of a name value
|
||||||
|
// under key k to value and QWORD.
|
||||||
|
func (k Key) SetQWordValue(name string, value uint64) error {
|
||||||
|
return k.setValue(name, QWORD, (*[8]byte)(unsafe.Pointer(&value))[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func (k Key) setStringValue(name string, valtype uint32, value string) error {
|
||||||
|
v, err := syscall.UTF16FromString(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
|
||||||
|
return k.setValue(name, valtype, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStringValue sets the data and type of a name value
|
||||||
|
// under key k to value and SZ. The value must not contain a zero byte.
|
||||||
|
func (k Key) SetStringValue(name, value string) error {
|
||||||
|
return k.setStringValue(name, SZ, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExpandStringValue sets the data and type of a name value
|
||||||
|
// under key k to value and EXPAND_SZ. The value must not contain a zero byte.
|
||||||
|
func (k Key) SetExpandStringValue(name, value string) error {
|
||||||
|
return k.setStringValue(name, EXPAND_SZ, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetStringsValue sets the data and type of a name value
|
||||||
|
// under key k to value and MULTI_SZ. The value strings
|
||||||
|
// must not contain a zero byte.
|
||||||
|
func (k Key) SetStringsValue(name string, value []string) error {
|
||||||
|
ss := ""
|
||||||
|
for _, s := range value {
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
if s[i] == 0 {
|
||||||
|
return errors.New("string cannot have 0 inside")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ss += s + "\x00"
|
||||||
|
}
|
||||||
|
v := utf16.Encode([]rune(ss + "\x00"))
|
||||||
|
buf := (*[1 << 29]byte)(unsafe.Pointer(&v[0]))[:len(v)*2]
|
||||||
|
return k.setValue(name, MULTI_SZ, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBinaryValue sets the data and type of a name value
|
||||||
|
// under key k to value and BINARY.
|
||||||
|
func (k Key) SetBinaryValue(name string, value []byte) error {
|
||||||
|
return k.setValue(name, BINARY, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteValue removes a named value from the key k.
|
||||||
|
func (k Key) DeleteValue(name string) error {
|
||||||
|
return regDeleteValue(syscall.Handle(k), syscall.StringToUTF16Ptr(name))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadValueNames returns the value names of key k.
|
||||||
|
// The parameter n controls the number of returned names,
|
||||||
|
// analogous to the way os.File.Readdirnames works.
|
||||||
|
func (k Key) ReadValueNames(n int) ([]string, error) {
|
||||||
|
ki, err := k.Stat()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
names := make([]string, 0, ki.ValueCount)
|
||||||
|
buf := make([]uint16, ki.MaxValueNameLen+1) // extra room for terminating null character
|
||||||
|
loopItems:
|
||||||
|
for i := uint32(0); ; i++ {
|
||||||
|
if n > 0 {
|
||||||
|
if len(names) == n {
|
||||||
|
return names, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
l := uint32(len(buf))
|
||||||
|
for {
|
||||||
|
err := regEnumValue(syscall.Handle(k), i, &buf[0], &l, nil, nil, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err == syscall.ERROR_MORE_DATA {
|
||||||
|
// Double buffer size and try again.
|
||||||
|
l = uint32(2 * len(buf))
|
||||||
|
buf = make([]uint16, l)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err == _ERROR_NO_MORE_ITEMS {
|
||||||
|
break loopItems
|
||||||
|
}
|
||||||
|
return names, err
|
||||||
|
}
|
||||||
|
names = append(names, syscall.UTF16ToString(buf[:l]))
|
||||||
|
}
|
||||||
|
if n > len(names) {
|
||||||
|
return names, io.EOF
|
||||||
|
}
|
||||||
|
return names, nil
|
||||||
|
}
|
120
vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
generated
vendored
Normal file
120
vendor/golang.org/x/sys/windows/registry/zsyscall_windows.go
generated
vendored
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// Code generated by 'go generate'; DO NOT EDIT.
|
||||||
|
|
||||||
|
package registry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ unsafe.Pointer
|
||||||
|
|
||||||
|
// Do the interface allocations only once for common
|
||||||
|
// Errno values.
|
||||||
|
const (
|
||||||
|
errnoERROR_IO_PENDING = 997
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
|
||||||
|
)
|
||||||
|
|
||||||
|
// errnoErr returns common boxed Errno values, to prevent
|
||||||
|
// allocations at runtime.
|
||||||
|
func errnoErr(e syscall.Errno) error {
|
||||||
|
switch e {
|
||||||
|
case 0:
|
||||||
|
return nil
|
||||||
|
case errnoERROR_IO_PENDING:
|
||||||
|
return errERROR_IO_PENDING
|
||||||
|
}
|
||||||
|
// TODO: add more here, after collecting data on the common
|
||||||
|
// error values see on Windows. (perhaps when running
|
||||||
|
// all.bat?)
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
modadvapi32 = windows.NewLazySystemDLL("advapi32.dll")
|
||||||
|
modkernel32 = windows.NewLazySystemDLL("kernel32.dll")
|
||||||
|
|
||||||
|
procRegCreateKeyExW = modadvapi32.NewProc("RegCreateKeyExW")
|
||||||
|
procRegDeleteKeyW = modadvapi32.NewProc("RegDeleteKeyW")
|
||||||
|
procRegSetValueExW = modadvapi32.NewProc("RegSetValueExW")
|
||||||
|
procRegEnumValueW = modadvapi32.NewProc("RegEnumValueW")
|
||||||
|
procRegDeleteValueW = modadvapi32.NewProc("RegDeleteValueW")
|
||||||
|
procRegLoadMUIStringW = modadvapi32.NewProc("RegLoadMUIStringW")
|
||||||
|
procRegConnectRegistryW = modadvapi32.NewProc("RegConnectRegistryW")
|
||||||
|
procExpandEnvironmentStringsW = modkernel32.NewProc("ExpandEnvironmentStringsW")
|
||||||
|
)
|
||||||
|
|
||||||
|
func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regDeleteKey(key syscall.Handle, subkey *uint16) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRegDeleteKeyW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(subkey)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regSetValueEx(key syscall.Handle, valueName *uint16, reserved uint32, vtype uint32, buf *byte, bufsize uint32) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall6(procRegSetValueExW.Addr(), 6, uintptr(key), uintptr(unsafe.Pointer(valueName)), uintptr(reserved), uintptr(vtype), uintptr(unsafe.Pointer(buf)), uintptr(bufsize))
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regEnumValue(key syscall.Handle, index uint32, name *uint16, nameLen *uint32, reserved *uint32, valtype *uint32, buf *byte, buflen *uint32) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procRegEnumValueW.Addr(), 8, uintptr(key), uintptr(index), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameLen)), uintptr(unsafe.Pointer(reserved)), uintptr(unsafe.Pointer(valtype)), uintptr(unsafe.Pointer(buf)), uintptr(unsafe.Pointer(buflen)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regDeleteValue(key syscall.Handle, name *uint16) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRegDeleteValueW.Addr(), 2, uintptr(key), uintptr(unsafe.Pointer(name)), 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regLoadMUIString(key syscall.Handle, name *uint16, buf *uint16, buflen uint32, buflenCopied *uint32, flags uint32, dir *uint16) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall9(procRegLoadMUIStringW.Addr(), 7, uintptr(key), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buf)), uintptr(buflen), uintptr(unsafe.Pointer(buflenCopied)), uintptr(flags), uintptr(unsafe.Pointer(dir)), 0, 0)
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func regConnectRegistry(machinename *uint16, key syscall.Handle, result *syscall.Handle) (regerrno error) {
|
||||||
|
r0, _, _ := syscall.Syscall(procRegConnectRegistryW.Addr(), 3, uintptr(unsafe.Pointer(machinename)), uintptr(key), uintptr(unsafe.Pointer(result)))
|
||||||
|
if r0 != 0 {
|
||||||
|
regerrno = syscall.Errno(r0)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func expandEnvironmentStrings(src *uint16, dst *uint16, size uint32) (n uint32, err error) {
|
||||||
|
r0, _, e1 := syscall.Syscall(procExpandEnvironmentStringsW.Addr(), 3, uintptr(unsafe.Pointer(src)), uintptr(unsafe.Pointer(dst)), uintptr(size))
|
||||||
|
n = uint32(r0)
|
||||||
|
if n == 0 {
|
||||||
|
if e1 != 0 {
|
||||||
|
err = errnoErr(e1)
|
||||||
|
} else {
|
||||||
|
err = syscall.EINVAL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
56
vendor/golang.org/x/sys/windows/svc/debug/log.go
generated
vendored
Normal file
56
vendor/golang.org/x/sys/windows/svc/debug/log.go
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package debug
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log interface allows different log implementations to be used.
|
||||||
|
type Log interface {
|
||||||
|
Close() error
|
||||||
|
Info(eid uint32, msg string) error
|
||||||
|
Warning(eid uint32, msg string) error
|
||||||
|
Error(eid uint32, msg string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConsoleLog provides access to the console.
|
||||||
|
type ConsoleLog struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates new ConsoleLog.
|
||||||
|
func New(source string) *ConsoleLog {
|
||||||
|
return &ConsoleLog{Name: source}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes console log l.
|
||||||
|
func (l *ConsoleLog) Close() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *ConsoleLog) report(kind string, eid uint32, msg string) error {
|
||||||
|
s := l.Name + "." + kind + "(" + strconv.Itoa(int(eid)) + "): " + msg + "\n"
|
||||||
|
_, err := os.Stdout.Write([]byte(s))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info writes an information event msg with event id eid to the console l.
|
||||||
|
func (l *ConsoleLog) Info(eid uint32, msg string) error {
|
||||||
|
return l.report("info", eid, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning writes an warning event msg with event id eid to the console l.
|
||||||
|
func (l *ConsoleLog) Warning(eid uint32, msg string) error {
|
||||||
|
return l.report("warn", eid, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error writes an error event msg with event id eid to the console l.
|
||||||
|
func (l *ConsoleLog) Error(eid uint32, msg string) error {
|
||||||
|
return l.report("error", eid, msg)
|
||||||
|
}
|
45
vendor/golang.org/x/sys/windows/svc/debug/service.go
generated
vendored
Normal file
45
vendor/golang.org/x/sys/windows/svc/debug/service.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Package debug provides facilities to execute svc.Handler on console.
|
||||||
|
//
|
||||||
|
package debug
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Run executes service name by calling appropriate handler function.
|
||||||
|
// The process is running on console, unlike real service. Use Ctrl+C to
|
||||||
|
// send "Stop" command to your service.
|
||||||
|
func Run(name string, handler svc.Handler) error {
|
||||||
|
cmds := make(chan svc.ChangeRequest)
|
||||||
|
changes := make(chan svc.Status)
|
||||||
|
|
||||||
|
sig := make(chan os.Signal)
|
||||||
|
signal.Notify(sig)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
status := svc.Status{State: svc.Stopped}
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-sig:
|
||||||
|
cmds <- svc.ChangeRequest{Cmd: svc.Stop, CurrentStatus: status}
|
||||||
|
case status = <-changes:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, errno := handler.Execute([]string{name}, cmds, changes)
|
||||||
|
if errno != 0 {
|
||||||
|
return syscall.Errno(errno)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
80
vendor/golang.org/x/sys/windows/svc/eventlog/install.go
generated
vendored
Normal file
80
vendor/golang.org/x/sys/windows/svc/eventlog/install.go
generated
vendored
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package eventlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Log levels.
|
||||||
|
Info = windows.EVENTLOG_INFORMATION_TYPE
|
||||||
|
Warning = windows.EVENTLOG_WARNING_TYPE
|
||||||
|
Error = windows.EVENTLOG_ERROR_TYPE
|
||||||
|
)
|
||||||
|
|
||||||
|
const addKeyName = `SYSTEM\CurrentControlSet\Services\EventLog\Application`
|
||||||
|
|
||||||
|
// Install modifies PC registry to allow logging with an event source src.
|
||||||
|
// It adds all required keys and values to the event log registry key.
|
||||||
|
// Install uses msgFile as the event message file. If useExpandKey is true,
|
||||||
|
// the event message file is installed as REG_EXPAND_SZ value,
|
||||||
|
// otherwise as REG_SZ. Use bitwise of log.Error, log.Warning and
|
||||||
|
// log.Info to specify events supported by the new event source.
|
||||||
|
func Install(src, msgFile string, useExpandKey bool, eventsSupported uint32) error {
|
||||||
|
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.CREATE_SUB_KEY)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer appkey.Close()
|
||||||
|
|
||||||
|
sk, alreadyExist, err := registry.CreateKey(appkey, src, registry.SET_VALUE)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer sk.Close()
|
||||||
|
if alreadyExist {
|
||||||
|
return errors.New(addKeyName + `\` + src + " registry key already exists")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = sk.SetDWordValue("CustomSource", 1)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if useExpandKey {
|
||||||
|
err = sk.SetExpandStringValue("EventMessageFile", msgFile)
|
||||||
|
} else {
|
||||||
|
err = sk.SetStringValue("EventMessageFile", msgFile)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = sk.SetDWordValue("TypesSupported", eventsSupported)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// InstallAsEventCreate is the same as Install, but uses
|
||||||
|
// %SystemRoot%\System32\EventCreate.exe as the event message file.
|
||||||
|
func InstallAsEventCreate(src string, eventsSupported uint32) error {
|
||||||
|
return Install(src, "%SystemRoot%\\System32\\EventCreate.exe", true, eventsSupported)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove deletes all registry elements installed by the correspondent Install.
|
||||||
|
func Remove(src string) error {
|
||||||
|
appkey, err := registry.OpenKey(registry.LOCAL_MACHINE, addKeyName, registry.SET_VALUE)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer appkey.Close()
|
||||||
|
return registry.DeleteKey(appkey, src)
|
||||||
|
}
|
70
vendor/golang.org/x/sys/windows/svc/eventlog/log.go
generated
vendored
Normal file
70
vendor/golang.org/x/sys/windows/svc/eventlog/log.go
generated
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Package eventlog implements access to Windows event log.
|
||||||
|
//
|
||||||
|
package eventlog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Log provides access to the system log.
|
||||||
|
type Log struct {
|
||||||
|
Handle windows.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open retrieves a handle to the specified event log.
|
||||||
|
func Open(source string) (*Log, error) {
|
||||||
|
return OpenRemote("", source)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenRemote does the same as Open, but on different computer host.
|
||||||
|
func OpenRemote(host, source string) (*Log, error) {
|
||||||
|
if source == "" {
|
||||||
|
return nil, errors.New("Specify event log source")
|
||||||
|
}
|
||||||
|
var s *uint16
|
||||||
|
if host != "" {
|
||||||
|
s = syscall.StringToUTF16Ptr(host)
|
||||||
|
}
|
||||||
|
h, err := windows.RegisterEventSource(s, syscall.StringToUTF16Ptr(source))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Log{Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close closes event log l.
|
||||||
|
func (l *Log) Close() error {
|
||||||
|
return windows.DeregisterEventSource(l.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *Log) report(etype uint16, eid uint32, msg string) error {
|
||||||
|
ss := []*uint16{syscall.StringToUTF16Ptr(msg)}
|
||||||
|
return windows.ReportEvent(l.Handle, etype, 0, eid, 0, 1, 0, &ss[0], nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Info writes an information event msg with event id eid to the end of event log l.
|
||||||
|
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||||
|
func (l *Log) Info(eid uint32, msg string) error {
|
||||||
|
return l.report(windows.EVENTLOG_INFORMATION_TYPE, eid, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warning writes an warning event msg with event id eid to the end of event log l.
|
||||||
|
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||||
|
func (l *Log) Warning(eid uint32, msg string) error {
|
||||||
|
return l.report(windows.EVENTLOG_WARNING_TYPE, eid, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error writes an error event msg with event id eid to the end of event log l.
|
||||||
|
// When EventCreate.exe is used, eid must be between 1 and 1000.
|
||||||
|
func (l *Log) Error(eid uint32, msg string) error {
|
||||||
|
return l.report(windows.EVENTLOG_ERROR_TYPE, eid, msg)
|
||||||
|
}
|
145
vendor/golang.org/x/sys/windows/svc/mgr/config.go
generated
vendored
Normal file
145
vendor/golang.org/x/sys/windows/svc/mgr/config.go
generated
vendored
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package mgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unicode/utf16"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Service start types.
|
||||||
|
StartManual = windows.SERVICE_DEMAND_START // the service must be started manually
|
||||||
|
StartAutomatic = windows.SERVICE_AUTO_START // the service will start by itself whenever the computer reboots
|
||||||
|
StartDisabled = windows.SERVICE_DISABLED // the service cannot be started
|
||||||
|
|
||||||
|
// The severity of the error, and action taken,
|
||||||
|
// if this service fails to start.
|
||||||
|
ErrorCritical = windows.SERVICE_ERROR_CRITICAL
|
||||||
|
ErrorIgnore = windows.SERVICE_ERROR_IGNORE
|
||||||
|
ErrorNormal = windows.SERVICE_ERROR_NORMAL
|
||||||
|
ErrorSevere = windows.SERVICE_ERROR_SEVERE
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(brainman): Password is not returned by windows.QueryServiceConfig, not sure how to get it.
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
ServiceType uint32
|
||||||
|
StartType uint32
|
||||||
|
ErrorControl uint32
|
||||||
|
BinaryPathName string // fully qualified path to the service binary file, can also include arguments for an auto-start service
|
||||||
|
LoadOrderGroup string
|
||||||
|
TagId uint32
|
||||||
|
Dependencies []string
|
||||||
|
ServiceStartName string // name of the account under which the service should run
|
||||||
|
DisplayName string
|
||||||
|
Password string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
func toString(p *uint16) string {
|
||||||
|
if p == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return syscall.UTF16ToString((*[4096]uint16)(unsafe.Pointer(p))[:])
|
||||||
|
}
|
||||||
|
|
||||||
|
func toStringSlice(ps *uint16) []string {
|
||||||
|
if ps == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
r := make([]string, 0)
|
||||||
|
for from, i, p := 0, 0, (*[1 << 24]uint16)(unsafe.Pointer(ps)); true; i++ {
|
||||||
|
if p[i] == 0 {
|
||||||
|
// empty string marks the end
|
||||||
|
if i <= from {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
r = append(r, string(utf16.Decode(p[from:i])))
|
||||||
|
from = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config retrieves service s configuration paramteres.
|
||||||
|
func (s *Service) Config() (Config, error) {
|
||||||
|
var p *windows.QUERY_SERVICE_CONFIG
|
||||||
|
n := uint32(1024)
|
||||||
|
for {
|
||||||
|
b := make([]byte, n)
|
||||||
|
p = (*windows.QUERY_SERVICE_CONFIG)(unsafe.Pointer(&b[0]))
|
||||||
|
err := windows.QueryServiceConfig(s.Handle, p, n, &n)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
if n <= uint32(len(b)) {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_DESCRIPTION)
|
||||||
|
if err != nil {
|
||||||
|
return Config{}, err
|
||||||
|
}
|
||||||
|
p2 := (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
|
||||||
|
|
||||||
|
return Config{
|
||||||
|
ServiceType: p.ServiceType,
|
||||||
|
StartType: p.StartType,
|
||||||
|
ErrorControl: p.ErrorControl,
|
||||||
|
BinaryPathName: toString(p.BinaryPathName),
|
||||||
|
LoadOrderGroup: toString(p.LoadOrderGroup),
|
||||||
|
TagId: p.TagId,
|
||||||
|
Dependencies: toStringSlice(p.Dependencies),
|
||||||
|
ServiceStartName: toString(p.ServiceStartName),
|
||||||
|
DisplayName: toString(p.DisplayName),
|
||||||
|
Description: toString(p2.Description),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateDescription(handle windows.Handle, desc string) error {
|
||||||
|
d := windows.SERVICE_DESCRIPTION{Description: toPtr(desc)}
|
||||||
|
return windows.ChangeServiceConfig2(handle,
|
||||||
|
windows.SERVICE_CONFIG_DESCRIPTION, (*byte)(unsafe.Pointer(&d)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateConfig updates service s configuration parameters.
|
||||||
|
func (s *Service) UpdateConfig(c Config) error {
|
||||||
|
err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
|
||||||
|
c.ErrorControl, toPtr(c.BinaryPathName), toPtr(c.LoadOrderGroup),
|
||||||
|
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName),
|
||||||
|
toPtr(c.Password), toPtr(c.DisplayName))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return updateDescription(s.Handle, c.Description)
|
||||||
|
}
|
||||||
|
|
||||||
|
// queryServiceConfig2 calls Windows QueryServiceConfig2 with infoLevel parameter and returns retrieved service configuration information.
|
||||||
|
func (s *Service) queryServiceConfig2(infoLevel uint32) ([]byte, error) {
|
||||||
|
n := uint32(1024)
|
||||||
|
for {
|
||||||
|
b := make([]byte, n)
|
||||||
|
err := windows.QueryServiceConfig2(s.Handle, infoLevel, &b[0], n, &n)
|
||||||
|
if err == nil {
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
if err.(syscall.Errno) != syscall.ERROR_INSUFFICIENT_BUFFER {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n <= uint32(len(b)) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
162
vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
generated
vendored
Normal file
162
vendor/golang.org/x/sys/windows/svc/mgr/mgr.go
generated
vendored
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
// Package mgr can be used to manage Windows service programs.
|
||||||
|
// It can be used to install and remove them. It can also start,
|
||||||
|
// stop and pause them. The package can query / change current
|
||||||
|
// service state and config parameters.
|
||||||
|
//
|
||||||
|
package mgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unicode/utf16"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Mgr is used to manage Windows service.
|
||||||
|
type Mgr struct {
|
||||||
|
Handle windows.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect establishes a connection to the service control manager.
|
||||||
|
func Connect() (*Mgr, error) {
|
||||||
|
return ConnectRemote("")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectRemote establishes a connection to the
|
||||||
|
// service control manager on computer named host.
|
||||||
|
func ConnectRemote(host string) (*Mgr, error) {
|
||||||
|
var s *uint16
|
||||||
|
if host != "" {
|
||||||
|
s = syscall.StringToUTF16Ptr(host)
|
||||||
|
}
|
||||||
|
h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Mgr{Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disconnect closes connection to the service control manager m.
|
||||||
|
func (m *Mgr) Disconnect() error {
|
||||||
|
return windows.CloseServiceHandle(m.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func toPtr(s string) *uint16 {
|
||||||
|
if len(s) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return syscall.StringToUTF16Ptr(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// toStringBlock terminates strings in ss with 0, and then
|
||||||
|
// concatenates them together. It also adds extra 0 at the end.
|
||||||
|
func toStringBlock(ss []string) *uint16 {
|
||||||
|
if len(ss) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t := ""
|
||||||
|
for _, s := range ss {
|
||||||
|
if s != "" {
|
||||||
|
t += s + "\x00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if t == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
t += "\x00"
|
||||||
|
return &utf16.Encode([]rune(t))[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateService installs new service name on the system.
|
||||||
|
// The service will be executed by running exepath binary.
|
||||||
|
// Use config c to specify service parameters.
|
||||||
|
// Any args will be passed as command-line arguments when
|
||||||
|
// the service is started; these arguments are distinct from
|
||||||
|
// the arguments passed to Service.Start or via the "Start
|
||||||
|
// parameters" field in the service's Properties dialog box.
|
||||||
|
func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) {
|
||||||
|
if c.StartType == 0 {
|
||||||
|
c.StartType = StartManual
|
||||||
|
}
|
||||||
|
if c.ErrorControl == 0 {
|
||||||
|
c.ErrorControl = ErrorNormal
|
||||||
|
}
|
||||||
|
if c.ServiceType == 0 {
|
||||||
|
c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS
|
||||||
|
}
|
||||||
|
s := syscall.EscapeArg(exepath)
|
||||||
|
for _, v := range args {
|
||||||
|
s += " " + syscall.EscapeArg(v)
|
||||||
|
}
|
||||||
|
h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
|
||||||
|
windows.SERVICE_ALL_ACCESS, c.ServiceType,
|
||||||
|
c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup),
|
||||||
|
nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if c.Description != "" {
|
||||||
|
err = updateDescription(h, c.Description)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &Service{Name: name, Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// OpenService retrieves access to service name, so it can
|
||||||
|
// be interrogated and controlled.
|
||||||
|
func (m *Mgr) OpenService(name string) (*Service, error) {
|
||||||
|
h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Service{Name: name, Handle: h}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListServices enumerates services in the specified
|
||||||
|
// service control manager database m.
|
||||||
|
// If the caller does not have the SERVICE_QUERY_STATUS
|
||||||
|
// access right to a service, the service is silently
|
||||||
|
// omitted from the list of services returned.
|
||||||
|
func (m *Mgr) ListServices() ([]string, error) {
|
||||||
|
var err error
|
||||||
|
var bytesNeeded, servicesReturned uint32
|
||||||
|
var buf []byte
|
||||||
|
for {
|
||||||
|
var p *byte
|
||||||
|
if len(buf) > 0 {
|
||||||
|
p = &buf[0]
|
||||||
|
}
|
||||||
|
err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
|
||||||
|
windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
|
||||||
|
p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != syscall.ERROR_MORE_DATA {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if bytesNeeded <= uint32(len(buf)) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
buf = make([]byte, bytesNeeded)
|
||||||
|
}
|
||||||
|
if servicesReturned == 0 {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned]
|
||||||
|
var names []string
|
||||||
|
for _, s := range services {
|
||||||
|
name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
|
||||||
|
names = append(names, name)
|
||||||
|
}
|
||||||
|
return names, nil
|
||||||
|
}
|
96
vendor/golang.org/x/sys/windows/svc/mgr/recovery.go
generated
vendored
Normal file
96
vendor/golang.org/x/sys/windows/svc/mgr/recovery.go
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// Copyright 2018 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package mgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Possible recovery actions that the service control manager can perform.
|
||||||
|
NoAction = windows.SC_ACTION_NONE // no action
|
||||||
|
ComputerReboot = windows.SC_ACTION_REBOOT // reboot the computer
|
||||||
|
ServiceRestart = windows.SC_ACTION_RESTART // restart the service
|
||||||
|
RunCommand = windows.SC_ACTION_RUN_COMMAND // run a command
|
||||||
|
)
|
||||||
|
|
||||||
|
// RecoveryAction represents an action that the service control manager can perform when service fails.
|
||||||
|
// A service is considered failed when it terminates without reporting a status of SERVICE_STOPPED to the service controller.
|
||||||
|
type RecoveryAction struct {
|
||||||
|
Type int // one of NoAction, ComputerReboot, ServiceRestart or RunCommand
|
||||||
|
Delay time.Duration // the time to wait before performing the specified action
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetRecoveryActions sets actions that service controller performs when service fails and
|
||||||
|
// the time after which to reset the service failure count to zero if there are no failures, in seconds.
|
||||||
|
// Specify INFINITE to indicate that service failure count should never be reset.
|
||||||
|
func (s *Service) SetRecoveryActions(recoveryActions []RecoveryAction, resetPeriod uint32) error {
|
||||||
|
if recoveryActions == nil {
|
||||||
|
return errors.New("recoveryActions cannot be nil")
|
||||||
|
}
|
||||||
|
actions := []windows.SC_ACTION{}
|
||||||
|
for _, a := range recoveryActions {
|
||||||
|
action := windows.SC_ACTION{
|
||||||
|
Type: uint32(a.Type),
|
||||||
|
Delay: uint32(a.Delay.Nanoseconds() / 1000000),
|
||||||
|
}
|
||||||
|
actions = append(actions, action)
|
||||||
|
}
|
||||||
|
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||||
|
ActionsCount: uint32(len(actions)),
|
||||||
|
Actions: &actions[0],
|
||||||
|
ResetPeriod: resetPeriod,
|
||||||
|
}
|
||||||
|
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// RecoveryActions returns actions that service controller performs when service fails.
|
||||||
|
// The service control manager counts the number of times service s has failed since the system booted.
|
||||||
|
// The count is reset to 0 if the service has not failed for ResetPeriod seconds.
|
||||||
|
// When the service fails for the Nth time, the service controller performs the action specified in element [N-1] of returned slice.
|
||||||
|
// If N is greater than slice length, the service controller repeats the last action in the slice.
|
||||||
|
func (s *Service) RecoveryActions() ([]RecoveryAction, error) {
|
||||||
|
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||||
|
if p.Actions == nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var recoveryActions []RecoveryAction
|
||||||
|
actions := (*[1024]windows.SC_ACTION)(unsafe.Pointer(p.Actions))[:p.ActionsCount]
|
||||||
|
for _, action := range actions {
|
||||||
|
recoveryActions = append(recoveryActions, RecoveryAction{Type: int(action.Type), Delay: time.Duration(action.Delay) * time.Millisecond})
|
||||||
|
}
|
||||||
|
return recoveryActions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetRecoveryActions deletes both reset period and array of failure actions.
|
||||||
|
func (s *Service) ResetRecoveryActions() error {
|
||||||
|
actions := make([]windows.SC_ACTION, 1)
|
||||||
|
rActions := windows.SERVICE_FAILURE_ACTIONS{
|
||||||
|
Actions: &actions[0],
|
||||||
|
}
|
||||||
|
return windows.ChangeServiceConfig2(s.Handle, windows.SERVICE_CONFIG_FAILURE_ACTIONS, (*byte)(unsafe.Pointer(&rActions)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPeriod is the time after which to reset the service failure
|
||||||
|
// count to zero if there are no failures, in seconds.
|
||||||
|
func (s *Service) ResetPeriod() (uint32, error) {
|
||||||
|
b, err := s.queryServiceConfig2(windows.SERVICE_CONFIG_FAILURE_ACTIONS)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
p := (*windows.SERVICE_FAILURE_ACTIONS)(unsafe.Pointer(&b[0]))
|
||||||
|
return p.ResetPeriod, nil
|
||||||
|
}
|
72
vendor/golang.org/x/sys/windows/svc/mgr/service.go
generated
vendored
Normal file
72
vendor/golang.org/x/sys/windows/svc/mgr/service.go
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
// Copyright 2012 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package mgr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows"
|
||||||
|
"golang.org/x/sys/windows/svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO(brainman): Use EnumDependentServices to enumerate dependent services.
|
||||||
|
|
||||||
|
// Service is used to access Windows service.
|
||||||
|
type Service struct {
|
||||||
|
Name string
|
||||||
|
Handle windows.Handle
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete marks service s for deletion from the service control manager database.
|
||||||
|
func (s *Service) Delete() error {
|
||||||
|
return windows.DeleteService(s.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close relinquish access to the service s.
|
||||||
|
func (s *Service) Close() error {
|
||||||
|
return windows.CloseServiceHandle(s.Handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start starts service s.
|
||||||
|
// args will be passed to svc.Handler.Execute.
|
||||||
|
func (s *Service) Start(args ...string) error {
|
||||||
|
var p **uint16
|
||||||
|
if len(args) > 0 {
|
||||||
|
vs := make([]*uint16, len(args))
|
||||||
|
for i := range vs {
|
||||||
|
vs[i] = syscall.StringToUTF16Ptr(args[i])
|
||||||
|
}
|
||||||
|
p = &vs[0]
|
||||||
|
}
|
||||||
|
return windows.StartService(s.Handle, uint32(len(args)), p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Control sends state change request c to the servce s.
|
||||||
|
func (s *Service) Control(c svc.Cmd) (svc.Status, error) {
|
||||||
|
var t windows.SERVICE_STATUS
|
||||||
|
err := windows.ControlService(s.Handle, uint32(c), &t)
|
||||||
|
if err != nil {
|
||||||
|
return svc.Status{}, err
|
||||||
|
}
|
||||||
|
return svc.Status{
|
||||||
|
State: svc.State(t.CurrentState),
|
||||||
|
Accepts: svc.Accepted(t.ControlsAccepted),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query returns current status of service s.
|
||||||
|
func (s *Service) Query() (svc.Status, error) {
|
||||||
|
var t windows.SERVICE_STATUS
|
||||||
|
err := windows.QueryServiceStatus(s.Handle, &t)
|
||||||
|
if err != nil {
|
||||||
|
return svc.Status{}, err
|
||||||
|
}
|
||||||
|
return svc.Status{
|
||||||
|
State: svc.State(t.CurrentState),
|
||||||
|
Accepts: svc.Accepted(t.ControlsAccepted),
|
||||||
|
}, nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user