Update containerd to 8a7e17ef96

Signed-off-by: Lantao Liu <lantaol@google.com>
This commit is contained in:
Lantao Liu 2018-03-23 22:49:00 +00:00
parent 7f64f9b85c
commit 776929c52e
21 changed files with 254 additions and 132 deletions

View File

@ -4,8 +4,8 @@ github.com/boltdb/bolt e9cf4fae01b5a8ff89d0ec6b32f0d9c9f79aefdd
github.com/BurntSushi/toml a368813c5e648fee92e5f6c30e3944ff9d5e8895
github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
github.com/containerd/console cb7008ab3d8359b78c5f464cb7cf160107ad5925
github.com/containerd/containerd 3c1ef1a714cf5b0104f340f76d539802fc24c75f
github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
github.com/containerd/containerd 8a7e17ef96678507a4b23d2bc66e5bbe5b50ad37
github.com/containerd/continuity 3e8f2ea4b190484acb976a5b378d373429639a1a
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/go-runc bcb223a061a3dd7de1a89c0b402a60f4dd9bd307
github.com/containerd/go-cni f2d7272f12d045b16ed924f50e91f9f9cecc55a7
@ -36,7 +36,7 @@ github.com/Microsoft/go-winio v0.4.5
github.com/Microsoft/hcsshim v0.6.7
github.com/opencontainers/go-digest 21dfd564fd89c944783d00d069f33e3e7123c448
github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
github.com/opencontainers/runtime-spec v1.0.1
github.com/opencontainers/runtime-tools 6073aff4ac61897f75895123f7e24135204a404d
github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206

View File

@ -465,7 +465,10 @@ func (cw *changeWriter) HandleChange(k fs.ChangeKind, p string, f os.FileInfo, e
source = filepath.Join(cw.source, p)
)
if f.Mode()&os.ModeSymlink != 0 {
switch {
case f.Mode()&os.ModeSocket != 0:
return nil // ignore sockets
case f.Mode()&os.ModeSymlink != 0:
if link, err = os.Readlink(source); err != nil {
return err
}

View File

@ -199,7 +199,7 @@ func (c *Client) NewContainer(ctx context.Context, id string, opts ...NewContain
if err != nil {
return nil, err
}
defer done()
defer done(ctx)
container := containers.Container{
ID: id,
@ -284,7 +284,7 @@ func (c *Client) Pull(ctx context.Context, ref string, opts ...RemoteOpt) (Image
if err != nil {
return nil, err
}
defer done()
defer done(ctx)
name, desc, err := pullCtx.Resolver.Resolve(ctx, ref)
if err != nil {
@ -561,7 +561,7 @@ func (c *Client) Import(ctx context.Context, importer images.Importer, reader io
if err != nil {
return nil, err
}
defer done()
defer done(ctx)
imgrecs, err := importer.Import(ctx, c.ContentStore(), reader)
if err != nil {

View File

@ -14,7 +14,7 @@
limitations under the License.
*/
package command
package app
import (
"fmt"
@ -51,8 +51,8 @@ func init() {
}
}
// App returns a *cli.App instance.
func App() *cli.App {
// New returns a *cli.App instance.
func New() *cli.App {
app := cli.NewApp()
app.Name = "ctr"
app.Version = version.Version

View File

@ -16,7 +16,7 @@
limitations under the License.
*/
package command
package app
import "github.com/containerd/containerd/cmd/ctr/commands/shim"

View File

@ -127,7 +127,7 @@ var diffCommand = cli.Command{
if err != nil {
return err
}
defer done()
defer done(ctx)
var desc ocispec.Descriptor
labels := commands.LabelArgs(context.StringSlice("label"))

View File

@ -20,7 +20,9 @@ import (
"context"
"io"
"io/ioutil"
"math/rand"
"sync"
"time"
"github.com/containerd/containerd/errdefs"
"github.com/opencontainers/go-digest"
@ -64,7 +66,7 @@ func ReadBlob(ctx context.Context, provider Provider, dgst digest.Digest) ([]byt
//
// Copy is buffered, so no need to wrap reader in buffered io.
func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size int64, expected digest.Digest, opts ...Opt) error {
cw, err := cs.Writer(ctx, ref, size, expected)
cw, err := OpenWriter(ctx, cs, ref, size, expected)
if err != nil {
if !errdefs.IsAlreadyExists(err) {
return err
@ -77,6 +79,43 @@ func WriteBlob(ctx context.Context, cs Ingester, ref string, r io.Reader, size i
return Copy(ctx, cw, r, size, expected, opts...)
}
// OpenWriter opens a new writer for the given reference, retrying if the writer
// is locked until the reference is available or returns an error.
func OpenWriter(ctx context.Context, cs Ingester, ref string, size int64, expected digest.Digest) (Writer, error) {
var (
cw Writer
err error
retry = 16
)
for {
cw, err = cs.Writer(ctx, ref, size, expected)
if err != nil {
if !errdefs.IsUnavailable(err) {
return nil, err
}
// TODO: Check status to determine if the writer is active,
// continue waiting while active, otherwise return lock
// error or abort. Requires asserting for an ingest manager
select {
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
if retry < 2048 {
retry = retry << 1
}
continue
case <-ctx.Done():
// Propagate lock error
return nil, err
}
}
break
}
return cw, err
}
// Copy copies data with the expected digest from the reader into the
// provided content store writer. This copy commits the writer.
//

View File

@ -91,6 +91,10 @@ func (d *duration) UnmarshalText(text []byte) error {
return nil
}
func (d duration) MarshalText() (text []byte, err error) {
return []byte(time.Duration(d).String()), nil
}
func init() {
plugin.Register(&plugin.Registration{
Type: plugin.GCPlugin,

View File

@ -108,7 +108,7 @@ func (i *image) Unpack(ctx context.Context, snapshotterName string) error {
if err != nil {
return err
}
defer done()
defer done(ctx)
layers, err := i.getLayers(ctx, platforms.Default())
if err != nil {

View File

@ -68,10 +68,10 @@ func (c *Client) ListLeases(ctx context.Context) ([]Lease, error) {
}
// WithLease attaches a lease on the context
func (c *Client) WithLease(ctx context.Context) (context.Context, func() error, error) {
func (c *Client) WithLease(ctx context.Context) (context.Context, func(context.Context) error, error) {
_, ok := leases.Lease(ctx)
if ok {
return ctx, func() error {
return ctx, func(context.Context) error {
return nil
}, nil
}
@ -82,7 +82,7 @@ func (c *Client) WithLease(ctx context.Context) (context.Context, func() error,
}
ctx = leases.WithLease(ctx, l.ID())
return ctx, func() error {
return ctx, func(ctx context.Context) error {
return l.Delete(ctx)
}, nil
}

View File

@ -30,6 +30,8 @@ import (
// Process represents a system process
type Process interface {
// ID of the process
ID() string
// Pid is the system specific process id
Pid() uint32
// Start starts the process executing the user's defined binary

View File

@ -25,7 +25,6 @@ import (
"fmt"
"io"
"io/ioutil"
"math/rand"
"strings"
"sync"
"time"
@ -256,10 +255,9 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
log.G(ctx).Debug("fetch blob")
var (
ref = remotes.MakeRefKey(ctx, desc)
calc = newBlobStateCalculator()
retry = 16
size = desc.Size
ref = remotes.MakeRefKey(ctx, desc)
calc = newBlobStateCalculator()
size = desc.Size
)
// size may be unknown, set to zero for content ingest
@ -267,20 +265,9 @@ func (c *Converter) fetchBlob(ctx context.Context, desc ocispec.Descriptor) erro
size = 0
}
tryit:
cw, err := c.contentStore.Writer(ctx, ref, size, desc.Digest)
cw, err := content.OpenWriter(ctx, c.contentStore, ref, size, desc.Digest)
if err != nil {
if errdefs.IsUnavailable(err) {
select {
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
if retry < 2048 {
retry = retry << 1
}
goto tryit
case <-ctx.Done():
return err
}
} else if !errdefs.IsAlreadyExists(err) {
if !errdefs.IsAlreadyExists(err) {
return err
}

View File

@ -20,10 +20,8 @@ import (
"context"
"fmt"
"io"
"math/rand"
"strings"
"sync"
"time"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
@ -83,38 +81,14 @@ func FetchHandler(ingester content.Ingester, fetcher Fetcher) images.HandlerFunc
func fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {
log.G(ctx).Debug("fetch")
var (
ref = MakeRefKey(ctx, desc)
cw content.Writer
err error
retry = 16
)
for {
cw, err = ingester.Writer(ctx, ref, desc.Size, desc.Digest)
if err != nil {
if errdefs.IsAlreadyExists(err) {
return nil
} else if !errdefs.IsUnavailable(err) {
return err
}
// TODO: On first time locked is encountered, get status
// of writer and abort if not updated recently.
select {
case <-time.After(time.Millisecond * time.Duration(rand.Intn(retry))):
if retry < 2048 {
retry = retry << 1
}
continue
case <-ctx.Done():
// Propagate lock error
return err
}
cw, err := content.OpenWriter(ctx, ingester, MakeRefKey(ctx, desc), desc.Size, desc.Digest)
if err != nil {
if errdefs.IsAlreadyExists(err) {
return nil
}
defer cw.Close()
break
return err
}
defer cw.Close()
ws, err := cw.Status()
if err != nil {

View File

@ -169,6 +169,11 @@ type task struct {
pid uint32
}
// ID of the task
func (t *task) ID() string {
return t.id
}
// Pid returns the pid or process id for the task
func (t *task) Pid() uint32 {
return t.pid
@ -386,7 +391,7 @@ func (t *task) Checkpoint(ctx context.Context, opts ...CheckpointTaskOpts) (Imag
if err != nil {
return nil, err
}
defer done()
defer done(ctx)
request := &tasks.CheckpointTaskRequest{
ContainerID: t.id,

View File

@ -4,7 +4,7 @@ github.com/containerd/cgroups fe281dd265766145e943a034aa41086474ea6130
github.com/containerd/typeurl f6943554a7e7e88b3c14aad190bf05932da84788
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
github.com/containerd/btrfs 2e1aa0ddf94f91fa282b6ed87c23bf0d64911244
github.com/containerd/continuity d8fb8589b0e8e85b8c8bbaa8840226d0dfeb7371
github.com/containerd/continuity 3e8f2ea4b190484acb976a5b378d373429639a1a
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
github.com/docker/go-metrics 4ea375f7759c82740c893fc030bc37088d2ec098
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
@ -19,7 +19,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.0
github.com/gogo/protobuf v0.5
github.com/golang/protobuf 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9
github.com/opencontainers/runtime-spec v1.0.1
github.com/opencontainers/runc a618ab5a0186905949ee463dbb762c3d23e12a80
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
github.com/sirupsen/logrus v1.0.0
github.com/pmezard/go-difflib v1.0.0
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
@ -43,7 +43,7 @@ github.com/gotestyourself/gotestyourself 44dbf532bbf5767611f6f2a61bded572e337010
github.com/google/go-cmp v0.1.0
# cri dependencies
github.com/containerd/cri 0c876040681ebe8a291fa2cebefdcc2796fa3fc8
github.com/containerd/cri fd18145c4b01fffff53cbf350012abe7ff83ebe9 https://github.com/dmcgowan/cri-containerd
github.com/blang/semver v3.1.0
github.com/containernetworking/cni v0.6.0
github.com/containernetworking/plugins v0.6.0
@ -79,3 +79,6 @@ k8s.io/utils 258e2a2fa64568210fbd6267cf1d8fd87c3cb86e
github.com/containerd/zfs 2e6f60521b5690bf2f265c416a42b251c2a3ec8e
github.com/mistifyio/go-zfs 166add352731e515512690329794ee593f1aaff2
github.com/pborman/uuid c65b2f87fee37d1c7854c9164a450713c28d50cd
# aufs dependencies
github.com/containerd/aufs 049ef88d84c1f49e52479d9f5f10d6756dd03a8b

View File

@ -41,8 +41,18 @@ make
sudo make install
```
You can also use `go get` to install to your `GOPATH`, assuming that you have a `github.com` parent folder already created under `src`:
```bash
go get github.com/opencontainers/runc
cd $GOPATH/src/github.com/opencontainers/runc
make
sudo make install
```
`runc` will be installed to `/usr/local/sbin/runc` on your system.
#### Build Tags
`runc` supports optional build tags for compiling support of various features.
@ -204,8 +214,7 @@ runc list
runc delete mycontainerid
```
This adds more complexity but allows higher level systems to manage runc and provides points in the containers creation to setup various settings after the container has created and/or before it is deleted.
This is commonly used to setup the container's network stack after `create` but before `start` where the user's defined process will be running.
This allows higher level systems to augment the containers creation logic with setup of various settings after the container is created and/or before it is deleted. For example, the container's network stack is commonly set up after `create` but before `start`.
#### Rootless containers
`runc` has the ability to run containers without root privileges. This is called `rootless`. You need to pass some parameters to `runc` in order to run rootless containers. See below and compare with the previous version. Run the following commands as an ordinary user:

View File

@ -12,84 +12,30 @@ var (
ErrNoGroupEntries = errors.New("no matching entries in group file")
)
func lookupUser(filter func(u User) bool) (User, error) {
// Get operating system-specific passwd reader-closer.
passwd, err := GetPasswd()
if err != nil {
return User{}, err
}
defer passwd.Close()
// Get the users.
users, err := ParsePasswdFilter(passwd, filter)
if err != nil {
return User{}, err
}
// No user entries found.
if len(users) == 0 {
return User{}, ErrNoPasswdEntries
}
// Assume the first entry is the "correct" one.
return users[0], nil
}
// LookupUser looks up a user by their username in /etc/passwd. If the user
// cannot be found (or there is no /etc/passwd file on the filesystem), then
// LookupUser returns an error.
func LookupUser(username string) (User, error) {
return lookupUser(func(u User) bool {
return u.Name == username
})
return lookupUser(username)
}
// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot
// be found (or there is no /etc/passwd file on the filesystem), then LookupId
// returns an error.
func LookupUid(uid int) (User, error) {
return lookupUser(func(u User) bool {
return u.Uid == uid
})
}
func lookupGroup(filter func(g Group) bool) (Group, error) {
// Get operating system-specific group reader-closer.
group, err := GetGroup()
if err != nil {
return Group{}, err
}
defer group.Close()
// Get the users.
groups, err := ParseGroupFilter(group, filter)
if err != nil {
return Group{}, err
}
// No user entries found.
if len(groups) == 0 {
return Group{}, ErrNoGroupEntries
}
// Assume the first entry is the "correct" one.
return groups[0], nil
return lookupUid(uid)
}
// LookupGroup looks up a group by its name in /etc/group. If the group cannot
// be found (or there is no /etc/group file on the filesystem), then LookupGroup
// returns an error.
func LookupGroup(groupname string) (Group, error) {
return lookupGroup(func(g Group) bool {
return g.Name == groupname
})
return lookupGroup(groupname)
}
// LookupGid looks up a group by its group id in /etc/group. If the group cannot
// be found (or there is no /etc/group file on the filesystem), then LookupGid
// returns an error.
func LookupGid(gid int) (Group, error) {
return lookupGroup(func(g Group) bool {
return g.Gid == gid
})
return lookupGid(gid)
}

View File

@ -15,6 +15,76 @@ const (
unixGroupPath = "/etc/group"
)
func lookupUser(username string) (User, error) {
return lookupUserFunc(func(u User) bool {
return u.Name == username
})
}
func lookupUid(uid int) (User, error) {
return lookupUserFunc(func(u User) bool {
return u.Uid == uid
})
}
func lookupUserFunc(filter func(u User) bool) (User, error) {
// Get operating system-specific passwd reader-closer.
passwd, err := GetPasswd()
if err != nil {
return User{}, err
}
defer passwd.Close()
// Get the users.
users, err := ParsePasswdFilter(passwd, filter)
if err != nil {
return User{}, err
}
// No user entries found.
if len(users) == 0 {
return User{}, ErrNoPasswdEntries
}
// Assume the first entry is the "correct" one.
return users[0], nil
}
func lookupGroup(groupname string) (Group, error) {
return lookupGroupFunc(func(g Group) bool {
return g.Name == groupname
})
}
func lookupGid(gid int) (Group, error) {
return lookupGroupFunc(func(g Group) bool {
return g.Gid == gid
})
}
func lookupGroupFunc(filter func(g Group) bool) (Group, error) {
// Get operating system-specific group reader-closer.
group, err := GetGroup()
if err != nil {
return Group{}, err
}
defer group.Close()
// Get the users.
groups, err := ParseGroupFilter(group, filter)
if err != nil {
return Group{}, err
}
// No user entries found.
if len(groups) == 0 {
return Group{}, ErrNoGroupEntries
}
// Assume the first entry is the "correct" one.
return groups[0], nil
}
func GetPasswdPath() (string, error) {
return unixPasswdPath, nil
}

View File

@ -0,0 +1,40 @@
// +build windows
package user
import (
"fmt"
"os/user"
)
func lookupUser(username string) (User, error) {
u, err := user.Lookup(username)
if err != nil {
return User{}, err
}
return userFromOS(u)
}
func lookupUid(uid int) (User, error) {
u, err := user.LookupId(fmt.Sprintf("%d", uid))
if err != nil {
return User{}, err
}
return userFromOS(u)
}
func lookupGroup(groupname string) (Group, error) {
g, err := user.LookupGroup(groupname)
if err != nil {
return Group{}, err
}
return groupFromOS(g)
}
func lookupGid(gid int) (Group, error) {
g, err := user.LookupGroupId(fmt.Sprintf("%d", gid))
if err != nil {
return Group{}, err
}
return groupFromOS(g)
}

View File

@ -5,6 +5,7 @@ import (
"fmt"
"io"
"os"
"os/user"
"strconv"
"strings"
)
@ -28,6 +29,28 @@ type User struct {
Shell string
}
// userFromOS converts an os/user.(*User) to local User
//
// (This does not include Pass, Shell or Gecos)
func userFromOS(u *user.User) (User, error) {
newUser := User{
Name: u.Username,
Home: u.HomeDir,
}
id, err := strconv.Atoi(u.Uid)
if err != nil {
return newUser, err
}
newUser.Uid = id
id, err = strconv.Atoi(u.Gid)
if err != nil {
return newUser, err
}
newUser.Gid = id
return newUser, nil
}
type Group struct {
Name string
Pass string
@ -35,6 +58,23 @@ type Group struct {
List []string
}
// groupFromOS converts an os/user.(*Group) to local Group
//
// (This does not include Pass, Shell or Gecos)
func groupFromOS(g *user.Group) (Group, error) {
newGroup := Group{
Name: g.Name,
}
id, err := strconv.Atoi(g.Gid)
if err != nil {
return newGroup, err
}
newGroup.Gid = id
return newGroup, nil
}
func parseLine(line string, v ...interface{}) {
if line == "" {
return

View File

@ -21,5 +21,5 @@ github.com/urfave/cli d53eb991652b1d438abdd34ce4bfa3ef1539108e
golang.org/x/sys 7ddbeae9ae08c6a06a59597f0c9edbc5ff2444ce https://github.com/golang/sys
# console dependencies
github.com/containerd/console 84eeaae905fa414d03e07bcd6c8d3f19e7cf180e
github.com/containerd/console 2748ece16665b45a47f884001d5831ec79703880
github.com/pkg/errors v0.8.0