mirror of https://github.com/docker/cli.git
vendor: github.com/containerd/containerd v1.5.2
- update to v1.5.0 0edc412565
...v1.5.0 (v1.5.0 is last tag on master/main branch)
- update to v1.5.2 https://github.com/containerd/containerd/compare/v1.5.0...v1.5.2
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
12e8782c0c
commit
f647fce891
|
@ -4,7 +4,7 @@ github.com/beorn7/perks 37c8de3658fcb183f997c4e13e83
|
|||
github.com/cespare/xxhash/v2 d7df74196a9e781ede915320c11c378c1b2f3a1f # v2.1.1
|
||||
github.com/containerd/cgroups b9de8a2212026c07cec67baf3323f1fc0121e048 # v1.0.1
|
||||
github.com/containerd/console 2f1e3d2b6afd18e8b2077816c711205a0b4d8769 # v1.0.2
|
||||
github.com/containerd/containerd 0edc412565dcc6e3d6125ff9e4b009ad4b89c638 # master (v1.5.0-dev)
|
||||
github.com/containerd/containerd 36cc874494a56a253cd181a1a685b44b58a2e34a # v1.5.2
|
||||
github.com/containerd/continuity bce1c3f9669b6f3e7f6656ee715b0b4d75fa64a6 # v0.1.0
|
||||
github.com/containerd/typeurl 5e43fb8b75ed2f2305fc04e6918c8d10636771bc # v1.0.2
|
||||
github.com/coreos/etcd 2c834459e1aab78a5d5219c7dfe42335fc4b617a # v3.3.25
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/containerd)](https://pkg.go.dev/github.com/containerd/containerd)
|
||||
[![Build Status](https://github.com/containerd/containerd/workflows/CI/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ACI)
|
||||
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/github/containerd/containerd?branch=master&svg=true)](https://ci.appveyor.com/project/mlaventure/containerd-3g73f?branch=master)
|
||||
[![Nightlies](https://github.com/containerd/containerd/workflows/Nightly/badge.svg)](https://github.com/containerd/containerd/actions?query=workflow%3ANightly)
|
||||
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fcontainerd%2Fcontainerd?ref=badge_shield)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/containerd)](https://goreportcard.com/report/github.com/containerd/containerd)
|
||||
|
@ -44,13 +43,14 @@ If you are interested in trying out containerd see our example at [Getting Start
|
|||
There are nightly builds available for download [here](https://github.com/containerd/containerd/actions?query=workflow%3ANightly).
|
||||
Binaries are generated from `master` branch every night for `Linux` and `Windows`.
|
||||
|
||||
Please be aware: nightly builds might have critical bugs, it's not recommended for use in prodution and no support provided.
|
||||
Please be aware: nightly builds might have critical bugs, it's not recommended for use in production and no support provided.
|
||||
|
||||
## Runtime Requirements
|
||||
|
||||
Runtime requirements for containerd are very minimal. Most interactions with
|
||||
the Linux and Windows container feature sets are handled via [runc](https://github.com/opencontainers/runc) and/or
|
||||
OS-specific libraries (e.g. [hcsshim](https://github.com/Microsoft/hcsshim) for Microsoft). The current required version of `runc` is always listed in [RUNC.md](/RUNC.md).
|
||||
OS-specific libraries (e.g. [hcsshim](https://github.com/Microsoft/hcsshim) for Microsoft).
|
||||
The current required version of `runc` is described in [RUNC.md](docs/RUNC.md).
|
||||
|
||||
There are specific features
|
||||
used by containerd core code and snapshotters that will require a minimum kernel
|
||||
|
@ -140,7 +140,7 @@ redis, err := client.NewContainer(context, "redis-master", containerd.WithNewSpe
|
|||
|
||||
### Root Filesystems
|
||||
|
||||
containerd allows you to use overlay or snapshot filesystems with your containers. It comes with builtin support for overlayfs and btrfs.
|
||||
containerd allows you to use overlay or snapshot filesystems with your containers. It comes with built in support for overlayfs and btrfs.
|
||||
|
||||
```go
|
||||
// pull an image and unpack it into the configured snapshotter
|
||||
|
@ -171,7 +171,7 @@ Taking a container object and turning it into a runnable process on a system is
|
|||
task, err := redis.NewTask(context, cio.NewCreator(cio.WithStdio))
|
||||
defer task.Delete(context)
|
||||
|
||||
// the task is now running and has a pid that can be use to setup networking
|
||||
// the task is now running and has a pid that can be used to setup networking
|
||||
// or other runtime settings outside of containerd
|
||||
pid := task.Pid()
|
||||
|
||||
|
@ -184,7 +184,7 @@ status, err := task.Wait(context)
|
|||
|
||||
### Checkpoint and Restore
|
||||
|
||||
If you have [criu](https://criu.org/Main_Page) installed on your machine you can checkpoint and restore containers and their tasks. This allow you to clone and/or live migrate containers to other machines.
|
||||
If you have [criu](https://criu.org/Main_Page) installed on your machine you can checkpoint and restore containers and their tasks. This allows you to clone and/or live migrate containers to other machines.
|
||||
|
||||
```go
|
||||
// checkpoint the task then push it to a registry
|
||||
|
@ -224,7 +224,7 @@ effect.
|
|||
address = "/var/run/mysnapshotter.sock"
|
||||
```
|
||||
|
||||
See [PLUGINS.md](PLUGINS.md) for how to create plugins
|
||||
See [PLUGINS.md](/docs/PLUGINS.md) for how to create plugins
|
||||
|
||||
### Releases and API Stability
|
||||
|
||||
|
@ -232,8 +232,7 @@ Please see [RELEASES.md](RELEASES.md) for details on versioning and stability
|
|||
of containerd components.
|
||||
|
||||
Downloadable 64-bit Intel/AMD binaries of all official releases are available on
|
||||
our [releases page](https://github.com/containerd/containerd/releases), as well as
|
||||
auto-published to the [cri-containerd-release storage bucket](https://console.cloud.google.com/storage/browser/cri-containerd-release?pli=1).
|
||||
our [releases page](https://github.com/containerd/containerd/releases).
|
||||
|
||||
For other architectures and distribution support, you will find that many
|
||||
Linux distributions package their own containerd and provide it across several
|
||||
|
@ -259,6 +258,39 @@ Provide documentation to users to `source` this file into their shell if
|
|||
you don't place the autocomplete file in a location where it is automatically
|
||||
loaded for the user's shell environment.
|
||||
|
||||
### CRI
|
||||
|
||||
`cri` is a [containerd](https://containerd.io/) plugin implementation of the Kubernetes [container runtime interface (CRI)](https://github.com/kubernetes/cri-api/blob/master/pkg/apis/runtime/v1alpha2/api.proto). With it, you are able to use containerd as the container runtime for a Kubernetes cluster.
|
||||
|
||||
![cri](./docs/cri/cri.png)
|
||||
|
||||
#### CRI Status
|
||||
|
||||
`cri` is a native plugin of containerd. Since containerd 1.1, the cri plugin is built into the release binaries and enabled by default.
|
||||
|
||||
> **Note:** As of containerd 1.5, the `cri` plugin is merged into the containerd/containerd repo. For example, the source code previously stored under [`containerd/cri/pkg`](https://github.com/containerd/cri/tree/release/1.4/pkg)
|
||||
was moved to [`containerd/containerd/pkg/cri` package](https://github.com/containerd/containerd/tree/master/pkg/cri).
|
||||
|
||||
The `cri` plugin has reached GA status, representing that it is:
|
||||
* Feature complete
|
||||
* Works with Kubernetes 1.10 and above
|
||||
* Passes all [CRI validation tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-validation.md).
|
||||
* Passes all [node e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/e2e-node-tests.md).
|
||||
* Passes all [e2e tests](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-testing/e2e-tests.md).
|
||||
|
||||
See results on the containerd k8s [test dashboard](https://k8s-testgrid.appspot.com/sig-node-containerd)
|
||||
|
||||
#### Validating Your `cri` Setup
|
||||
A Kubernetes incubator project, [cri-tools](https://github.com/kubernetes-sigs/cri-tools), includes programs for exercising CRI implementations. More importantly, cri-tools includes the program `critest` which is used for running [CRI Validation Testing](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-node/cri-validation.md).
|
||||
|
||||
#### CRI Guides
|
||||
* [Installing with Ansible and Kubeadm](contrib/ansible/README.md)
|
||||
* [For Non-Ansible Users, Preforming a Custom Installation Using the Release Tarball and Kubeadm](docs/cri/installation.md)
|
||||
* [CRI Plugin Testing Guide](./docs/cri/testing.md)
|
||||
* [Debugging Pods, Containers, and Images with `crictl`](./docs/cri/crictl.md)
|
||||
* [Configuring `cri` Plugins](./docs/cri/config.md)
|
||||
* [Configuring containerd](https://github.com/containerd/containerd/blob/master/docs/man/containerd-config.8.md)
|
||||
|
||||
### Communication
|
||||
|
||||
For async communication and long running discussions please use issues and pull requests on the github repo.
|
||||
|
|
|
@ -3280,7 +3280,7 @@ func (m *Info) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > postIndex {
|
||||
|
@ -3297,10 +3297,7 @@ func (m *Info) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3383,10 +3380,7 @@ func (m *InfoRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3470,10 +3464,7 @@ func (m *InfoResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3593,10 +3584,7 @@ func (m *UpdateRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3680,10 +3668,7 @@ func (m *UpdateResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3766,10 +3751,7 @@ func (m *ListContentRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3854,10 +3836,7 @@ func (m *ListContentResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -3940,10 +3919,7 @@ func (m *DeleteContentRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4064,10 +4040,7 @@ func (m *ReadContentRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4171,10 +4144,7 @@ func (m *ReadContentResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4393,10 +4363,7 @@ func (m *Status) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4479,10 +4446,7 @@ func (m *StatusRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4569,10 +4533,7 @@ func (m *StatusResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4655,10 +4616,7 @@ func (m *ListStatusesRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -4743,10 +4701,7 @@ func (m *ListStatusesResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -5062,7 +5017,7 @@ func (m *WriteContentRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > postIndex {
|
||||
|
@ -5079,10 +5034,7 @@ func (m *WriteContentRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -5288,10 +5240,7 @@ func (m *WriteContentResponse) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
@ -5374,10 +5323,7 @@ func (m *AbortRequest) Unmarshal(dAtA []byte) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if skippy < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) < 0 {
|
||||
if (skippy < 0) || (iNdEx+skippy) < 0 {
|
||||
return ErrInvalidLengthContent
|
||||
}
|
||||
if (iNdEx + skippy) > l {
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package containerd.services.content.v1;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
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 content
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/filters"
|
||||
)
|
||||
|
||||
// AdaptInfo returns `filters.Adaptor` that handles `content.Info`.
|
||||
func AdaptInfo(info Info) filters.Adaptor {
|
||||
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
|
||||
if len(fieldpath) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
switch fieldpath[0] {
|
||||
case "digest":
|
||||
return info.Digest.String(), true
|
||||
case "size":
|
||||
// TODO: support size based filtering
|
||||
case "labels":
|
||||
return checkMap(fieldpath[1:], info.Labels)
|
||||
}
|
||||
|
||||
return "", false
|
||||
})
|
||||
}
|
||||
|
||||
func checkMap(fieldpath []string, m map[string]string) (string, bool) {
|
||||
if len(m) == 0 {
|
||||
return "", false
|
||||
}
|
||||
|
||||
value, ok := m[strings.Join(fieldpath, ".")]
|
||||
return value, ok
|
||||
}
|
|
@ -37,7 +37,7 @@ type Provider interface {
|
|||
// ReaderAt only requires desc.Digest to be set.
|
||||
// Other fields in the descriptor may be used internally for resolving
|
||||
// the location of the actual data.
|
||||
ReaderAt(ctx context.Context, dec ocispec.Descriptor) (ReaderAt, error)
|
||||
ReaderAt(ctx context.Context, desc ocispec.Descriptor) (ReaderAt, error)
|
||||
}
|
||||
|
||||
// Ingester writes content
|
||||
|
|
|
@ -18,6 +18,7 @@ package local
|
|||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/pkg/errors"
|
||||
|
@ -25,9 +26,13 @@ import (
|
|||
|
||||
// Handles locking references
|
||||
|
||||
type lock struct {
|
||||
since time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
// locks lets us lock in process
|
||||
locks = map[string]struct{}{}
|
||||
locks = make(map[string]*lock)
|
||||
locksMu sync.Mutex
|
||||
)
|
||||
|
||||
|
@ -35,11 +40,11 @@ func tryLock(ref string) error {
|
|||
locksMu.Lock()
|
||||
defer locksMu.Unlock()
|
||||
|
||||
if _, ok := locks[ref]; ok {
|
||||
return errors.Wrapf(errdefs.ErrUnavailable, "ref %s locked", ref)
|
||||
if v, ok := locks[ref]; ok {
|
||||
return errors.Wrapf(errdefs.ErrUnavailable, "ref %s locked since %s", ref, v.since)
|
||||
}
|
||||
|
||||
locks[ref] = struct{}{}
|
||||
locks[ref] = &lock{time.Now()}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,11 @@ package local
|
|||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/containerd/containerd/content"
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
)
|
||||
|
||||
// readerat implements io.ReaderAt in a completely stateless manner by opening
|
||||
|
@ -27,6 +32,29 @@ type sizeReaderAt struct {
|
|||
fp *os.File
|
||||
}
|
||||
|
||||
// OpenReader creates ReaderAt from a file
|
||||
func OpenReader(p string) (content.ReaderAt, error) {
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found")
|
||||
}
|
||||
|
||||
fp, err := os.Open(p)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.Wrap(errdefs.ErrNotFound, "blob not found")
|
||||
}
|
||||
|
||||
return sizeReaderAt{size: fi.Size(), fp: fp}, nil
|
||||
}
|
||||
|
||||
func (ra sizeReaderAt) ReadAt(p []byte, offset int64) (int, error) {
|
||||
return ra.fp.ReadAt(p, offset)
|
||||
}
|
||||
|
|
|
@ -131,25 +131,13 @@ func (s *store) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.
|
|||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "calculating blob path for ReaderAt")
|
||||
}
|
||||
fi, err := os.Stat(p)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "blob %s expected at %s", desc.Digest, p)
|
||||
reader, err := OpenReader(p)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "blob %s expected at %s", desc.Digest, p)
|
||||
}
|
||||
|
||||
fp, err := os.Open(p)
|
||||
if err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return nil, errors.Wrapf(errdefs.ErrNotFound, "blob %s expected at %s", desc.Digest, p)
|
||||
}
|
||||
|
||||
return sizeReaderAt{size: fi.Size(), fp: fp}, nil
|
||||
return reader, nil
|
||||
}
|
||||
|
||||
// Delete removes a blob by its digest.
|
||||
|
@ -240,9 +228,14 @@ func (s *store) Update(ctx context.Context, info content.Info, fieldpaths ...str
|
|||
return info, nil
|
||||
}
|
||||
|
||||
func (s *store) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error {
|
||||
// TODO: Support filters
|
||||
func (s *store) Walk(ctx context.Context, fn content.WalkFunc, fs ...string) error {
|
||||
root := filepath.Join(s.root, "blobs")
|
||||
|
||||
filter, err := filters.ParseAll(fs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var alg digest.Algorithm
|
||||
return filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
|
@ -286,7 +279,12 @@ func (s *store) Walk(ctx context.Context, fn content.WalkFunc, filters ...string
|
|||
return err
|
||||
}
|
||||
}
|
||||
return fn(s.info(dgst, fi, labels))
|
||||
|
||||
info := s.info(dgst, fi, labels)
|
||||
if !filter.Match(content.AdaptInfo(info)) {
|
||||
return nil
|
||||
}
|
||||
return fn(info)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -467,7 +465,6 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
|
|||
}
|
||||
var lockErr error
|
||||
for count := uint64(0); count < 10; count++ {
|
||||
time.Sleep(time.Millisecond * time.Duration(rand.Intn(1<<count)))
|
||||
if err := tryLock(wOpts.Ref); err != nil {
|
||||
if !errdefs.IsUnavailable(err) {
|
||||
return nil, err
|
||||
|
@ -478,6 +475,7 @@ func (s *store) Writer(ctx context.Context, opts ...content.WriterOpt) (content.
|
|||
lockErr = nil
|
||||
break
|
||||
}
|
||||
time.Sleep(time.Millisecond * time.Duration(rand.Intn(1<<count)))
|
||||
}
|
||||
|
||||
if lockErr != nil {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// +build linux solaris darwin freebsd netbsd
|
||||
// +build linux solaris darwin freebsd netbsd openbsd
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
|
|
@ -97,7 +97,14 @@ func (rw *remoteWriter) Write(p []byte) (n int, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error {
|
||||
func (rw *remoteWriter) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) (err error) {
|
||||
defer func() {
|
||||
err1 := rw.Close()
|
||||
if err == nil {
|
||||
err = err1
|
||||
}
|
||||
}()
|
||||
|
||||
var base content.Info
|
||||
for _, opt := range opts {
|
||||
if err := opt(&base); err != nil {
|
||||
|
|
|
@ -34,4 +34,6 @@ const (
|
|||
DefaultFIFODir = "/run/containerd/fifo"
|
||||
// DefaultRuntime is the default linux runtime
|
||||
DefaultRuntime = "io.containerd.runc.v2"
|
||||
// DefaultConfigDir is the default location for config files.
|
||||
DefaultConfigDir = "/etc/containerd"
|
||||
)
|
||||
|
|
|
@ -30,6 +30,9 @@ var (
|
|||
// DefaultStateDir is the default location used by containerd to store
|
||||
// transient data
|
||||
DefaultStateDir = filepath.Join(os.Getenv("ProgramData"), "containerd", "state")
|
||||
|
||||
// DefaultConfigDir is the default location for config files.
|
||||
DefaultConfigDir = filepath.Join(os.Getenv("programfiles"), "containerd")
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
module github.com/containerd/containerd
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.4.17
|
||||
github.com/Microsoft/hcsshim v0.8.16
|
||||
github.com/containerd/aufs v1.0.0
|
||||
github.com/containerd/btrfs v1.0.0
|
||||
github.com/containerd/cgroups v1.0.1
|
||||
github.com/containerd/console v1.0.2
|
||||
github.com/containerd/continuity v0.1.0
|
||||
github.com/containerd/fifo v1.0.0
|
||||
github.com/containerd/go-cni v1.0.2
|
||||
github.com/containerd/go-runc v1.0.0
|
||||
github.com/containerd/imgcrypt v1.1.1
|
||||
github.com/containerd/nri v0.1.0
|
||||
github.com/containerd/ttrpc v1.0.2
|
||||
github.com/containerd/typeurl v1.0.2
|
||||
github.com/containerd/zfs v1.0.0
|
||||
github.com/containernetworking/plugins v0.9.1
|
||||
github.com/coreos/go-systemd/v22 v22.1.0
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c
|
||||
github.com/docker/go-metrics v0.0.1
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
github.com/gogo/googleapis v1.4.0
|
||||
github.com/gogo/protobuf v1.3.2
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/google/go-cmp v0.5.4
|
||||
github.com/google/uuid v1.2.0
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/klauspost/compress v1.11.13
|
||||
github.com/moby/locker v1.0.1
|
||||
github.com/moby/sys/mountinfo v0.4.1
|
||||
github.com/moby/sys/symlink v0.1.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc v1.0.0-rc93
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d
|
||||
github.com/opencontainers/selinux v1.8.0
|
||||
github.com/pelletier/go-toml v1.8.1
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/prometheus/procfs v0.6.0 // indirect; temporarily force v0.6.0, which was previously defined in imgcrypt as explicit version
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/tchap/go-patricia v2.2.6+incompatible
|
||||
github.com/urfave/cli v1.22.2
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492
|
||||
google.golang.org/grpc v1.33.2
|
||||
gotest.tools/v3 v3.0.3
|
||||
k8s.io/api v0.20.6
|
||||
k8s.io/apimachinery v0.20.6
|
||||
k8s.io/apiserver v0.20.6
|
||||
k8s.io/client-go v0.20.6
|
||||
k8s.io/component-base v0.20.6
|
||||
k8s.io/cri-api v0.20.6
|
||||
k8s.io/klog/v2 v2.4.0
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920
|
||||
)
|
||||
|
||||
// When updating replace rules, make sure to also update the rules in integration/client/go.mod
|
||||
replace (
|
||||
// prevent transitional dependencies due to containerd having a circular
|
||||
// dependency on itself through plugins. see .empty-mod/go.mod for details
|
||||
github.com/containerd/containerd => ./.empty-mod/
|
||||
github.com/gogo/googleapis => github.com/gogo/googleapis v1.3.2
|
||||
github.com/golang/protobuf => github.com/golang/protobuf v1.3.5
|
||||
// urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
|
||||
github.com/urfave/cli => github.com/urfave/cli v1.22.1
|
||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||
)
|
|
@ -37,9 +37,17 @@ type (
|
|||
loggerKey struct{}
|
||||
)
|
||||
|
||||
// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
|
||||
// ensure the formatted time is always the same number of characters.
|
||||
const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
|
||||
const (
|
||||
// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
|
||||
// ensure the formatted time is always the same number of characters.
|
||||
RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
|
||||
|
||||
// TextFormat represents the text logging format
|
||||
TextFormat = "text"
|
||||
|
||||
// JSONFormat represents the JSON logging format
|
||||
JSONFormat = "json"
|
||||
)
|
||||
|
||||
// WithLogger returns a new context with the provided logger. Use in
|
||||
// combination with logger.WithField(s) for great effect.
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sys
|
||||
package userns
|
||||
|
||||
import (
|
||||
"bufio"
|
|
@ -16,7 +16,7 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sys
|
||||
package userns
|
||||
|
||||
// RunningInUserNS is a stub for non-Linux systems
|
||||
// Always returns false
|
|
@ -16,7 +16,12 @@
|
|||
|
||||
package platforms
|
||||
|
||||
import specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
// MatchComparer is able to match and compare platforms to
|
||||
// filter and sort platforms.
|
||||
|
@ -26,103 +31,70 @@ type MatchComparer interface {
|
|||
Less(specs.Platform, specs.Platform) bool
|
||||
}
|
||||
|
||||
// platformVector returns an (ordered) vector of appropriate specs.Platform
|
||||
// objects to try matching for the given platform object (see platforms.Only).
|
||||
func platformVector(platform specs.Platform) []specs.Platform {
|
||||
vector := []specs.Platform{platform}
|
||||
|
||||
switch platform.Architecture {
|
||||
case "amd64":
|
||||
vector = append(vector, specs.Platform{
|
||||
Architecture: "386",
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: platform.Variant,
|
||||
})
|
||||
case "arm":
|
||||
if armVersion, err := strconv.Atoi(strings.TrimPrefix(platform.Variant, "v")); err == nil && armVersion > 5 {
|
||||
for armVersion--; armVersion >= 5; armVersion-- {
|
||||
vector = append(vector, specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v" + strconv.Itoa(armVersion),
|
||||
})
|
||||
}
|
||||
}
|
||||
case "arm64":
|
||||
variant := platform.Variant
|
||||
if variant == "" {
|
||||
variant = "v8"
|
||||
}
|
||||
vector = append(vector, platformVector(specs.Platform{
|
||||
Architecture: "arm",
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: variant,
|
||||
})...)
|
||||
}
|
||||
|
||||
return vector
|
||||
}
|
||||
|
||||
// Only returns a match comparer for a single platform
|
||||
// using default resolution logic for the platform.
|
||||
//
|
||||
// For ARMv8, will also match ARMv7, ARMv6 and ARMv5 (for 32bit runtimes)
|
||||
// For ARMv7, will also match ARMv6 and ARMv5
|
||||
// For ARMv6, will also match ARMv5
|
||||
// For arm/v8, will also match arm/v7, arm/v6 and arm/v5
|
||||
// For arm/v7, will also match arm/v6 and arm/v5
|
||||
// For arm/v6, will also match arm/v5
|
||||
// For amd64, will also match 386
|
||||
func Only(platform specs.Platform) MatchComparer {
|
||||
platform = Normalize(platform)
|
||||
if platform.Architecture == "arm" {
|
||||
if platform.Variant == "v8" {
|
||||
return orderedPlatformComparer{
|
||||
matchers: []Matcher{
|
||||
&matcher{
|
||||
Platform: platform,
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v7",
|
||||
},
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v6",
|
||||
},
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v5",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
if platform.Variant == "v7" {
|
||||
return orderedPlatformComparer{
|
||||
matchers: []Matcher{
|
||||
&matcher{
|
||||
Platform: platform,
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v6",
|
||||
},
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v5",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
if platform.Variant == "v6" {
|
||||
return orderedPlatformComparer{
|
||||
matchers: []Matcher{
|
||||
&matcher{
|
||||
Platform: platform,
|
||||
},
|
||||
&matcher{
|
||||
Platform: specs.Platform{
|
||||
Architecture: platform.Architecture,
|
||||
OS: platform.OS,
|
||||
OSVersion: platform.OSVersion,
|
||||
OSFeatures: platform.OSFeatures,
|
||||
Variant: "v5",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
return Ordered(platformVector(Normalize(platform))...)
|
||||
}
|
||||
|
||||
return singlePlatformComparer{
|
||||
Matcher: &matcher{
|
||||
Platform: platform,
|
||||
},
|
||||
}
|
||||
// OnlyStrict returns a match comparer for a single platform.
|
||||
//
|
||||
// Unlike Only, OnlyStrict does not match sub platforms.
|
||||
// So, "arm/vN" will not match "arm/vM" where M < N,
|
||||
// and "amd64" will not also match "386".
|
||||
//
|
||||
// OnlyStrict matches non-canonical forms.
|
||||
// So, "arm64" matches "arm/64/v8".
|
||||
func OnlyStrict(platform specs.Platform) MatchComparer {
|
||||
return Ordered(Normalize(platform))
|
||||
}
|
||||
|
||||
// Ordered returns a platform MatchComparer which matches any of the platforms
|
||||
|
@ -153,14 +125,6 @@ func Any(platforms ...specs.Platform) MatchComparer {
|
|||
// with preference for ordering.
|
||||
var All MatchComparer = allPlatformComparer{}
|
||||
|
||||
type singlePlatformComparer struct {
|
||||
Matcher
|
||||
}
|
||||
|
||||
func (c singlePlatformComparer) Less(p1, p2 specs.Platform) bool {
|
||||
return c.Match(p1) && !c.Match(p2)
|
||||
}
|
||||
|
||||
type orderedPlatformComparer struct {
|
||||
matchers []Matcher
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/containerd/log"
|
||||
|
@ -28,14 +29,18 @@ import (
|
|||
)
|
||||
|
||||
// Present the ARM instruction set architecture, eg: v7, v8
|
||||
var cpuVariant string
|
||||
// Don't use this value directly; call cpuVariant() instead.
|
||||
var cpuVariantValue string
|
||||
|
||||
func init() {
|
||||
if isArmArch(runtime.GOARCH) {
|
||||
cpuVariant = getCPUVariant()
|
||||
} else {
|
||||
cpuVariant = ""
|
||||
}
|
||||
var cpuVariantOnce sync.Once
|
||||
|
||||
func cpuVariant() string {
|
||||
cpuVariantOnce.Do(func() {
|
||||
if isArmArch(runtime.GOARCH) {
|
||||
cpuVariantValue = getCPUVariant()
|
||||
}
|
||||
})
|
||||
return cpuVariantValue
|
||||
}
|
||||
|
||||
// For Linux, the kernel has already detected the ABI, ISA and Features.
|
||||
|
@ -107,12 +112,7 @@ func getCPUVariant() string {
|
|||
|
||||
switch strings.ToLower(variant) {
|
||||
case "8", "aarch64":
|
||||
// special case: if running a 32-bit userspace on aarch64, the variant should be "v7"
|
||||
if runtime.GOARCH == "arm" {
|
||||
variant = "v7"
|
||||
} else {
|
||||
variant = "v8"
|
||||
}
|
||||
variant = "v8"
|
||||
case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)":
|
||||
variant = "v7"
|
||||
case "6", "6tej":
|
||||
|
|
|
@ -33,6 +33,11 @@ func DefaultSpec() specs.Platform {
|
|||
OS: runtime.GOOS,
|
||||
Architecture: runtime.GOARCH,
|
||||
// The Variant field will be empty if arch != ARM.
|
||||
Variant: cpuVariant,
|
||||
Variant: cpuVariant(),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultStrict returns strict form of Default.
|
||||
func DefaultStrict() MatchComparer {
|
||||
return OnlyStrict(DefaultSpec())
|
||||
}
|
||||
|
|
|
@ -19,13 +19,63 @@
|
|||
package platforms
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// Default returns the default matcher for the platform.
|
||||
func Default() MatchComparer {
|
||||
return Ordered(DefaultSpec(), specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: "amd64",
|
||||
})
|
||||
type matchComparer struct {
|
||||
defaults Matcher
|
||||
osVersionPrefix string
|
||||
}
|
||||
|
||||
// Match matches platform with the same windows major, minor
|
||||
// and build version.
|
||||
func (m matchComparer) Match(p imagespec.Platform) bool {
|
||||
if m.defaults.Match(p) {
|
||||
// TODO(windows): Figure out whether OSVersion is deprecated.
|
||||
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Less sorts matched platforms in front of other platforms.
|
||||
// For matched platforms, it puts platforms with larger revision
|
||||
// number in front.
|
||||
func (m matchComparer) Less(p1, p2 imagespec.Platform) bool {
|
||||
m1, m2 := m.Match(p1), m.Match(p2)
|
||||
if m1 && m2 {
|
||||
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion)
|
||||
return r1 > r2
|
||||
}
|
||||
return m1 && !m2
|
||||
}
|
||||
|
||||
func revision(v string) int {
|
||||
parts := strings.Split(v, ".")
|
||||
if len(parts) < 4 {
|
||||
return 0
|
||||
}
|
||||
r, err := strconv.Atoi(parts[3])
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// Default returns the current platform's default platform specification.
|
||||
func Default() MatchComparer {
|
||||
major, minor, build := windows.RtlGetNtVersionNumbers()
|
||||
return matchComparer{
|
||||
defaults: Ordered(DefaultSpec(), specs.Platform{
|
||||
OS: "linux",
|
||||
Architecture: runtime.GOARCH,
|
||||
}),
|
||||
osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -189,8 +189,8 @@ func Parse(specifier string) (specs.Platform, error) {
|
|||
if isKnownOS(p.OS) {
|
||||
// picks a default architecture
|
||||
p.Architecture = runtime.GOARCH
|
||||
if p.Architecture == "arm" && cpuVariant != "v7" {
|
||||
p.Variant = cpuVariant
|
||||
if p.Architecture == "arm" && cpuVariant() != "v7" {
|
||||
p.Variant = cpuVariant()
|
||||
}
|
||||
|
||||
return p, nil
|
||||
|
|
|
@ -65,7 +65,7 @@ func GenerateTokenOptions(ctx context.Context, host, username, secret string, c
|
|||
return to, nil
|
||||
}
|
||||
|
||||
// TokenOptions are optios for requesting a token
|
||||
// TokenOptions are options for requesting a token
|
||||
type TokenOptions struct {
|
||||
Realm string
|
||||
Service string
|
||||
|
|
|
@ -27,9 +27,10 @@ var _ error = ErrUnexpectedStatus{}
|
|||
|
||||
// ErrUnexpectedStatus is returned if a registry API request returned with unexpected HTTP status
|
||||
type ErrUnexpectedStatus struct {
|
||||
Status string
|
||||
StatusCode int
|
||||
Body []byte
|
||||
Status string
|
||||
StatusCode int
|
||||
Body []byte
|
||||
RequestURL, RequestMethod string
|
||||
}
|
||||
|
||||
func (e ErrUnexpectedStatus) Error() string {
|
||||
|
@ -42,5 +43,14 @@ func NewUnexpectedStatusErr(resp *http.Response) error {
|
|||
if resp.Body != nil {
|
||||
b, _ = ioutil.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB
|
||||
}
|
||||
return ErrUnexpectedStatus{Status: resp.Status, StatusCode: resp.StatusCode, Body: b}
|
||||
err := ErrUnexpectedStatus{
|
||||
Body: b,
|
||||
Status: resp.Status,
|
||||
StatusCode: resp.StatusCode,
|
||||
RequestMethod: resp.Request.Method,
|
||||
}
|
||||
if resp.Request.URL != nil {
|
||||
err.RequestURL = resp.Request.URL.String()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package sys
|
||||
|
||||
import "os"
|
||||
|
||||
// IsFifo checks if a file is a (named pipe) fifo
|
||||
// if the file does not exist then it returns false
|
||||
func IsFifo(path string) (bool, error) {
|
||||
stat, err := os.Stat(path)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if stat.Mode()&os.ModeNamedPipe == os.ModeNamedPipe {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
|
@ -22,11 +22,14 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"github.com/Microsoft/hcsshim"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
|
@ -257,12 +260,71 @@ func windowsOpenSequential(path string, mode int, _ uint32) (fd windows.Handle,
|
|||
return h, e
|
||||
}
|
||||
|
||||
// ForceRemoveAll is the same as os.RemoveAll, but uses hcsshim.DestroyLayer in order
|
||||
// to delete container layers.
|
||||
// ForceRemoveAll is the same as os.RemoveAll, but is aware of io.containerd.snapshotter.v1.windows
|
||||
// and uses hcsshim to unmount and delete container layers contained therein, in the correct order,
|
||||
// when passed a containerd root data directory (i.e. the `--root` directory for containerd).
|
||||
func ForceRemoveAll(path string) error {
|
||||
info := hcsshim.DriverInfo{
|
||||
HomeDir: filepath.Dir(path),
|
||||
// snapshots/windows/windows.go init()
|
||||
const snapshotPlugin = "io.containerd.snapshotter.v1" + "." + "windows"
|
||||
// snapshots/windows/windows.go NewSnapshotter()
|
||||
snapshotDir := filepath.Join(path, snapshotPlugin, "snapshots")
|
||||
if stat, err := os.Stat(snapshotDir); err == nil && stat.IsDir() {
|
||||
if err := cleanupWCOWLayers(snapshotDir); err != nil {
|
||||
return errors.Wrapf(err, "failed to cleanup WCOW layers in %s", snapshotDir)
|
||||
}
|
||||
}
|
||||
|
||||
return hcsshim.DestroyLayer(info, filepath.Base(path))
|
||||
return os.RemoveAll(path)
|
||||
}
|
||||
|
||||
func cleanupWCOWLayers(root string) error {
|
||||
// See snapshots/windows/windows.go getSnapshotDir()
|
||||
var layerNums []int
|
||||
if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||
if path != root && info.IsDir() {
|
||||
if layerNum, err := strconv.Atoi(filepath.Base(path)); err == nil {
|
||||
layerNums = append(layerNums, layerNum)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sort.Sort(sort.Reverse(sort.IntSlice(layerNums)))
|
||||
|
||||
for _, layerNum := range layerNums {
|
||||
if err := cleanupWCOWLayer(filepath.Join(root, strconv.Itoa(layerNum))); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cleanupWCOWLayer(layerPath string) error {
|
||||
info := hcsshim.DriverInfo{
|
||||
HomeDir: filepath.Dir(layerPath),
|
||||
}
|
||||
|
||||
// ERROR_DEV_NOT_EXIST is returned if the layer is not currently prepared.
|
||||
if err := hcsshim.UnprepareLayer(info, filepath.Base(layerPath)); err != nil {
|
||||
if hcserror, ok := err.(*hcsshim.HcsError); !ok || hcserror.Err != windows.ERROR_DEV_NOT_EXIST {
|
||||
return errors.Wrapf(err, "failed to unprepare %s", layerPath)
|
||||
}
|
||||
}
|
||||
|
||||
if err := hcsshim.DeactivateLayer(info, filepath.Base(layerPath)); err != nil {
|
||||
return errors.Wrapf(err, "failed to deactivate %s", layerPath)
|
||||
}
|
||||
|
||||
if err := hcsshim.DestroyLayer(info, filepath.Base(layerPath)); err != nil {
|
||||
return errors.Wrapf(err, "failed to destroy %s", layerPath)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
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 sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/containerd/containerd/pkg/userns"
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
const (
|
||||
// OOMScoreAdjMin is from OOM_SCORE_ADJ_MIN https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L9
|
||||
OOMScoreAdjMin = -1000
|
||||
// OOMScoreAdjMax is from OOM_SCORE_ADJ_MAX https://github.com/torvalds/linux/blob/v5.10/include/uapi/linux/oom.h#L10
|
||||
OOMScoreAdjMax = 1000
|
||||
)
|
||||
|
||||
// AdjustOOMScore sets the oom score for the provided pid. If the provided score
|
||||
// is out of range (-1000 - 1000), it is clipped to the min/max value.
|
||||
func AdjustOOMScore(pid, score int) error {
|
||||
if score > OOMScoreAdjMax {
|
||||
score = OOMScoreAdjMax
|
||||
} else if score < OOMScoreAdjMin {
|
||||
score = OOMScoreAdjMin
|
||||
}
|
||||
return SetOOMScore(pid, score)
|
||||
}
|
||||
|
||||
// SetOOMScore sets the oom score for the provided pid
|
||||
func SetOOMScore(pid, score int) error {
|
||||
if score > OOMScoreAdjMax || score < OOMScoreAdjMin {
|
||||
return fmt.Errorf("value out of range (%d): OOM score must be between %d and %d", score, OOMScoreAdjMin, OOMScoreAdjMax)
|
||||
}
|
||||
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
|
||||
f, err := os.OpenFile(path, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
|
||||
if os.IsPermission(err) && (!runningPrivileged() || userns.RunningInUserNS()) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetOOMScoreAdj gets the oom score for a process. It returns 0 (zero) if either
|
||||
// no oom score is set, or a sore is set to 0.
|
||||
func GetOOMScoreAdj(pid int) (int, error) {
|
||||
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(strings.TrimSpace(string(data)))
|
||||
}
|
||||
|
||||
// runningPrivileged returns true if the effective user ID of the
|
||||
// calling process is 0
|
||||
func runningPrivileged() bool {
|
||||
return unix.Geteuid() == 0
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build !linux
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -18,40 +18,31 @@
|
|||
|
||||
package sys
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
const (
|
||||
// OOMScoreMaxKillable is not implemented on non Linux
|
||||
OOMScoreMaxKillable = 0
|
||||
// OOMScoreAdjMax is not implemented on non Linux
|
||||
OOMScoreAdjMax = 0
|
||||
)
|
||||
|
||||
// OOMScoreMaxKillable is the maximum score keeping the process killable by the oom killer
|
||||
const OOMScoreMaxKillable = -999
|
||||
// AdjustOOMScore sets the oom score for the provided pid. If the provided score
|
||||
// is out of range (-1000 - 1000), it is clipped to the min/max value.
|
||||
//
|
||||
// Not implemented on Windows
|
||||
func AdjustOOMScore(pid, score int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetOOMScore sets the oom score for the provided pid
|
||||
// SetOOMScore sets the oom score for the process
|
||||
//
|
||||
// Not implemented on Windows
|
||||
func SetOOMScore(pid, score int) error {
|
||||
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
|
||||
f, err := os.OpenFile(path, os.O_WRONLY, 0)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if _, err = f.WriteString(strconv.Itoa(score)); err != nil {
|
||||
if os.IsPermission(err) && (RunningInUserNS() || RunningUnprivileged()) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetOOMScoreAdj gets the oom score for a process
|
||||
//
|
||||
// Not implemented on Windows
|
||||
func GetOOMScoreAdj(pid int) (int, error) {
|
||||
path := fmt.Sprintf("/proc/%d/oom_score_adj", pid)
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return strconv.Atoi(strings.TrimSpace(string(data)))
|
||||
return 0, nil
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !windows
|
||||
// +build openbsd
|
||||
|
||||
/*
|
||||
Copyright The containerd Authors.
|
||||
|
@ -18,16 +18,28 @@
|
|||
|
||||
package sys
|
||||
|
||||
import "golang.org/x/sys/unix"
|
||||
import (
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
|
||||
// RunningPrivileged returns true if the effective user ID of the
|
||||
// calling process is 0
|
||||
func RunningPrivileged() bool {
|
||||
return unix.Geteuid() == 0
|
||||
// StatAtime returns the Atim
|
||||
func StatAtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Atim
|
||||
}
|
||||
|
||||
// RunningUnprivileged returns true if the effective user ID of the
|
||||
// calling process is not 0
|
||||
func RunningUnprivileged() bool {
|
||||
return !RunningPrivileged()
|
||||
// StatCtime returns the Ctim
|
||||
func StatCtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Ctim
|
||||
}
|
||||
|
||||
// StatMtime returns the Mtim
|
||||
func StatMtime(st *syscall.Stat_t) syscall.Timespec {
|
||||
return st.Mtim
|
||||
}
|
||||
|
||||
// StatATimeAsTime returns st.Atim as a time.Time
|
||||
func StatATimeAsTime(st *syscall.Stat_t) time.Time {
|
||||
// The int64 conversions ensure the line compiles for 32-bit systems as well.
|
||||
return time.Unix(int64(st.Atim.Sec), int64(st.Atim.Nsec)) // nolint: unconvert
|
||||
}
|
|
@ -16,16 +16,8 @@
|
|||
|
||||
package sys
|
||||
|
||||
// SetOOMScore sets the oom score for the process
|
||||
//
|
||||
// Not implemented on Windows
|
||||
func SetOOMScore(pid, score int) error {
|
||||
return nil
|
||||
}
|
||||
import "github.com/containerd/containerd/pkg/userns"
|
||||
|
||||
// GetOOMScoreAdj gets the oom score for a process
|
||||
//
|
||||
// Not implemented on Windows
|
||||
func GetOOMScoreAdj(pid int) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
// RunningInUserNS detects whether we are currently running in a user namespace.
|
||||
// Deprecated: use github.com/containerd/containerd/pkg/userns.RunningInUserNS instead.
|
||||
var RunningInUserNS = userns.RunningInUserNS
|
|
@ -1,107 +0,0 @@
|
|||
github.com/beorn7/perks v1.0.1
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/cespare/xxhash/v2 v2.1.1
|
||||
github.com/containerd/btrfs 404b9149801e455c8076f615b06dc0abee0a977a
|
||||
github.com/containerd/cgroups 0b889c03f102012f1d93a97ddd3ef71cd6f4f510
|
||||
github.com/containerd/console v1.0.1
|
||||
github.com/containerd/continuity efbc4488d8fe1bdc16bde3b2d2990d9b3a899165
|
||||
github.com/containerd/fifo 0724c46b320cf96bb172a0550c19a4b1fca4dacb
|
||||
github.com/containerd/go-runc 7016d3ce2328dd2cb1192b2076ebd565c4e8df0c
|
||||
github.com/containerd/nri eb1350a75164f76de48e3605389e7a3fbc85d06e
|
||||
github.com/containerd/ttrpc v1.0.2
|
||||
github.com/containerd/typeurl v1.0.1
|
||||
github.com/coreos/go-systemd/v22 v22.1.0
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0
|
||||
github.com/docker/go-events e31b211e4f1cd09aa76fe4ac244571fab96ae47f
|
||||
github.com/docker/go-metrics v0.0.1
|
||||
github.com/docker/go-units v0.4.0
|
||||
github.com/godbus/dbus/v5 v5.0.3
|
||||
github.com/gogo/googleapis v1.3.2
|
||||
github.com/gogo/protobuf v1.3.1
|
||||
github.com/golang/protobuf v1.3.5
|
||||
github.com/google/go-cmp v0.2.0
|
||||
github.com/google/uuid v1.1.1
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
|
||||
github.com/hashicorp/errwrap v1.0.0
|
||||
github.com/hashicorp/go-multierror v1.0.0
|
||||
github.com/hashicorp/golang-lru v0.5.3
|
||||
github.com/imdario/mergo v0.3.7
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||
github.com/Microsoft/go-winio v0.4.14
|
||||
github.com/Microsoft/hcsshim v0.8.10
|
||||
github.com/moby/sys symlink/v0.1.0
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc v1.0.0-rc92
|
||||
github.com/opencontainers/runtime-spec 4d89ac9fbff6c455f46a5bb59c6b1bb7184a5e43 # v1.0.3-0.20200728170252-4d89ac9fbff6
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.6.0
|
||||
github.com/prometheus/client_model v0.2.0
|
||||
github.com/prometheus/common v0.9.1
|
||||
github.com/prometheus/procfs v0.0.11
|
||||
github.com/russross/blackfriday/v2 v2.0.1
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
github.com/syndtr/gocapability d98352740cb2c55f81556b63d4a1ec64c5a319c2
|
||||
github.com/urfave/cli v1.22.1 # NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
|
||||
go.etcd.io/bbolt v1.3.5
|
||||
go.opencensus.io v0.22.0
|
||||
golang.org/x/net ab34263943818b32f575efc978a3d24e80b04bd7
|
||||
golang.org/x/sync 42b317875d0fa942474b76e1b46a6060d720ae6e
|
||||
golang.org/x/sys 0aaa2718063a42560507fce2cc04508608ca23b3
|
||||
golang.org/x/text v0.3.3
|
||||
google.golang.org/genproto e50cd9704f63023d62cd06a1994b98227fc4d21a
|
||||
google.golang.org/grpc v1.27.1
|
||||
gotest.tools/v3 v3.0.2
|
||||
|
||||
# cgroups dependencies
|
||||
github.com/cilium/ebpf 1c8d4c9ef7759622653a1d319284a44652333b28
|
||||
|
||||
# cri dependencies
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/docker/spdystream 449fdfce4d962303d702fec724ef0ad181c92528
|
||||
github.com/emicklei/go-restful v2.9.5
|
||||
github.com/go-logr/logr v0.2.0
|
||||
github.com/google/gofuzz v1.1.0
|
||||
github.com/json-iterator/go v1.1.10
|
||||
github.com/modern-go/concurrent 1.0.3
|
||||
github.com/modern-go/reflect2 v1.0.1
|
||||
github.com/opencontainers/selinux v1.6.0
|
||||
github.com/pmezard/go-difflib v1.0.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/tchap/go-patricia v2.2.6
|
||||
github.com/willf/bitset v1.1.11
|
||||
golang.org/x/crypto 75b288015ac94e66e3d6715fb68a9b41bf046ec2
|
||||
golang.org/x/oauth2 858c2ad4c8b6c5d10852cb89079f6ca1c7309787
|
||||
golang.org/x/time 555d28b269f0569763d25dbe1a237ae74c6bcc82
|
||||
gopkg.in/inf.v0 v0.9.1
|
||||
gopkg.in/yaml.v2 v2.2.8
|
||||
k8s.io/api v0.19.4
|
||||
k8s.io/apimachinery v0.19.4
|
||||
k8s.io/apiserver v0.19.4
|
||||
k8s.io/client-go v0.19.4
|
||||
k8s.io/component-base v0.19.4
|
||||
k8s.io/cri-api v0.19.4
|
||||
k8s.io/klog/v2 v2.2.0
|
||||
k8s.io/utils d5654de09c73da55eb19ae4ab4f734f7a61747a6
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.1
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
|
||||
# cni dependencies
|
||||
github.com/containerd/go-cni v1.0.1
|
||||
github.com/containernetworking/cni v0.8.0
|
||||
github.com/containernetworking/plugins v0.8.6
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
|
||||
# image decrypt depedencies
|
||||
github.com/containerd/imgcrypt v1.0.1
|
||||
github.com/containers/ocicrypt v1.0.1
|
||||
github.com/fullsailor/pkcs7 8306686428a5fe132eac8cb7c4848af725098bd4
|
||||
gopkg.in/square/go-jose.v2 v2.3.1
|
||||
|
||||
# zfs dependencies
|
||||
github.com/containerd/zfs 0a33824f23a2ab8ec84166f47b571ecb793b0354
|
||||
github.com/mistifyio/go-zfs f784269be439d704d3dfa1906f45dd848fed2beb
|
||||
|
||||
# aufs dependencies
|
||||
github.com/containerd/aufs dab0cbea06f43329c07667afe1a70411ad555a86
|
Loading…
Reference in New Issue