Merge pull request #3403 from mxpv/labels

Better default label handling
This commit is contained in:
Phil Estes 2019-07-11 16:17:53 -04:00 committed by GitHub
commit f2b6c31d0f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 91 additions and 55 deletions

View File

@ -87,13 +87,15 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
if copts.timeout == 0 {
copts.timeout = 10 * time.Second
}
rt := fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS)
c := &Client{}
if copts.defaultRuntime != "" {
rt = copts.defaultRuntime
}
c := &Client{
runtime: rt,
c.runtime = copts.defaultRuntime
} else {
c.runtime = fmt.Sprintf("%s.%s", plugin.RuntimePlugin, runtime.GOOS)
}
if copts.services != nil {
c.services = *copts.services
}
@ -140,14 +142,11 @@ func New(address string, opts ...ClientOpt) (*Client, error) {
// check namespace labels for default runtime
if copts.defaultRuntime == "" && copts.defaultns != "" {
namespaces := c.NamespaceService()
ctx := context.Background()
if labels, err := namespaces.Labels(ctx, copts.defaultns); err == nil {
if defaultRuntime, ok := labels[defaults.DefaultRuntimeNSLabel]; ok {
c.runtime = defaultRuntime
}
} else {
ctx := namespaces.WithNamespace(context.Background(), copts.defaultns)
if label, err := c.GetLabel(ctx, defaults.DefaultRuntimeNSLabel); err != nil {
return nil, err
} else if label != "" {
c.runtime = label
}
}
@ -170,14 +169,11 @@ func NewWithConn(conn *grpc.ClientConn, opts ...ClientOpt) (*Client, error) {
// check namespace labels for default runtime
if copts.defaultRuntime == "" && copts.defaultns != "" {
namespaces := c.NamespaceService()
ctx := context.Background()
if labels, err := namespaces.Labels(ctx, copts.defaultns); err == nil {
if defaultRuntime, ok := labels[defaults.DefaultRuntimeNSLabel]; ok {
c.runtime = defaultRuntime
}
} else {
ctx := namespaces.WithNamespace(context.Background(), copts.defaultns)
if label, err := c.GetLabel(ctx, defaults.DefaultRuntimeNSLabel); err != nil {
return nil, err
} else if label != "" {
c.runtime = label
}
}
@ -340,7 +336,6 @@ func defaultRemoteContext() *RemoteContext {
Resolver: docker.NewResolver(docker.ResolverOptions{
Client: http.DefaultClient,
}),
Snapshotter: DefaultSnapshotter,
}
}
@ -491,6 +486,24 @@ func writeIndex(ctx context.Context, index *ocispec.Index, client *Client, ref s
return writeContent(ctx, client.ContentStore(), ocispec.MediaTypeImageIndex, ref, bytes.NewReader(data), content.WithLabels(labels))
}
// GetLabel gets a label value from namespace store
// If there is no default label, an empty string returned with nil error
func (c *Client) GetLabel(ctx context.Context, label string) (string, error) {
ns, err := namespaces.NamespaceRequired(ctx)
if err != nil {
return "", err
}
srv := c.NamespaceService()
labels, err := srv.Labels(ctx, ns)
if err != nil {
return "", err
}
value := labels[label]
return value, nil
}
// 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
@ -656,11 +669,34 @@ func (c *Client) Version(ctx context.Context) (Version, error) {
}, nil
}
func (c *Client) getSnapshotter(name string) (snapshots.Snapshotter, error) {
func (c *Client) resolveSnapshotterName(ctx context.Context, name string) (string, error) {
if name == "" {
label, err := c.GetLabel(ctx, defaults.DefaultSnapshotterNSLabel)
if err != nil {
return "", err
}
if label != "" {
name = label
} else {
name = DefaultSnapshotter
}
}
return name, nil
}
func (c *Client) getSnapshotter(ctx context.Context, name string) (snapshots.Snapshotter, error) {
name, err := c.resolveSnapshotterName(ctx, name)
if err != nil {
return nil, err
}
s := c.SnapshotService(name)
if s == nil {
return nil, errors.Wrapf(errdefs.ErrNotFound, "snapshotter %s was not found", name)
}
return s, nil
}

View File

@ -24,7 +24,6 @@ import (
"runtime"
"strings"
"github.com/containerd/containerd"
"github.com/urfave/cli"
)
@ -34,7 +33,6 @@ var (
cli.StringFlag{
Name: "snapshotter",
Usage: "snapshotter name. Empty value stands for the default value.",
Value: containerd.DefaultSnapshotter,
EnvVar: "CONTAINERD_SNAPSHOTTER",
},
}

View File

@ -33,7 +33,7 @@ import (
// Command is the cli command for managing namespaces
var Command = cli.Command{
Name: "namespaces",
Aliases: []string{"namespace"},
Aliases: []string{"namespace", "ns"},
Usage: "manage namespaces",
Subcommands: cli.Commands{
createCommand,
@ -45,6 +45,7 @@ var Command = cli.Command{
var createCommand = cli.Command{
Name: "create",
Aliases: []string{"c"},
Usage: "create a new namespace",
ArgsUsage: "<name> [<key>=<value]",
Description: "create a new namespace. it must be unique",

View File

@ -233,7 +233,7 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
}
// get the rootfs from the snapshotter and add it to the request
s, err := c.client.getSnapshotter(r.Snapshotter)
s, err := c.client.getSnapshotter(ctx, r.Snapshotter)
if err != nil {
return nil, err
}

View File

@ -20,9 +20,7 @@ import (
"context"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/defaults"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/namespaces"
"github.com/containerd/containerd/oci"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/snapshots"
@ -118,9 +116,13 @@ func WithSnapshotter(name string) NewContainerOpts {
// WithSnapshot uses an existing root filesystem for the container
func WithSnapshot(id string) NewContainerOpts {
return func(ctx context.Context, client *Client, c *containers.Container) error {
setSnapshotterIfEmpty(ctx, client, c)
// check that the snapshot exists, if not, fail on creation
s, err := client.getSnapshotter(c.Snapshotter)
var err error
c.Snapshotter, err = client.resolveSnapshotterName(ctx, c.Snapshotter)
if err != nil {
return err
}
s, err := client.getSnapshotter(ctx, c.Snapshotter)
if err != nil {
return err
}
@ -140,9 +142,13 @@ func WithNewSnapshot(id string, i Image, opts ...snapshots.Opt) NewContainerOpts
if err != nil {
return err
}
setSnapshotterIfEmpty(ctx, client, c)
parent := identity.ChainID(diffIDs).String()
s, err := client.getSnapshotter(c.Snapshotter)
c.Snapshotter, err = client.resolveSnapshotterName(ctx, c.Snapshotter)
if err != nil {
return err
}
s, err := client.getSnapshotter(ctx, c.Snapshotter)
if err != nil {
return err
}
@ -161,7 +167,7 @@ func WithSnapshotCleanup(ctx context.Context, client *Client, c containers.Conta
if c.Snapshotter == "" {
return errors.Wrapf(errdefs.ErrInvalidArgument, "container.Snapshotter must be set to cleanup rootfs snapshot")
}
s, err := client.getSnapshotter(c.Snapshotter)
s, err := client.getSnapshotter(ctx, c.Snapshotter)
if err != nil {
return err
}
@ -178,9 +184,13 @@ func WithNewSnapshotView(id string, i Image, opts ...snapshots.Opt) NewContainer
if err != nil {
return err
}
setSnapshotterIfEmpty(ctx, client, c)
parent := identity.ChainID(diffIDs).String()
s, err := client.getSnapshotter(c.Snapshotter)
c.Snapshotter, err = client.resolveSnapshotterName(ctx, c.Snapshotter)
if err != nil {
return err
}
s, err := client.getSnapshotter(ctx, c.Snapshotter)
if err != nil {
return err
}
@ -193,21 +203,6 @@ func WithNewSnapshotView(id string, i Image, opts ...snapshots.Opt) NewContainer
}
}
func setSnapshotterIfEmpty(ctx context.Context, client *Client, c *containers.Container) {
if c.Snapshotter == "" {
defaultSnapshotter := DefaultSnapshotter
namespaceService := client.NamespaceService()
if ns, err := namespaces.NamespaceRequired(ctx); err == nil {
if labels, err := namespaceService.Labels(ctx, ns); err == nil {
if snapshotLabel, ok := labels[defaults.DefaultSnapshotterNSLabel]; ok {
defaultSnapshotter = snapshotLabel
}
}
}
c.Snapshotter = defaultSnapshotter
}
}
// WithContainerExtension appends extension data to the container object.
// Use this to decorate the container object with additional data for the client
// integration.

View File

@ -50,13 +50,15 @@ func withRemappedSnapshotBase(id string, i Image, uid, gid uint32, readonly bool
return err
}
setSnapshotterIfEmpty(ctx, client, c)
var (
parent = identity.ChainID(diffIDs).String()
usernsID = fmt.Sprintf("%s-%d-%d", parent, uid, gid)
)
snapshotter, err := client.getSnapshotter(c.Snapshotter)
c.Snapshotter, err = client.resolveSnapshotterName(ctx, c.Snapshotter)
if err != nil {
return err
}
snapshotter, err := client.getSnapshotter(ctx, c.Snapshotter)
if err != nil {
return err
}

View File

@ -25,7 +25,7 @@ import (
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
"github.com/containerd/containerd/rootfs"
digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/identity"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@ -108,7 +108,7 @@ func (i *image) Config(ctx context.Context) (ocispec.Descriptor, error) {
}
func (i *image) IsUnpacked(ctx context.Context, snapshotterName string) (bool, error) {
sn, err := i.client.getSnapshotter(snapshotterName)
sn, err := i.client.getSnapshotter(ctx, snapshotterName)
if err != nil {
return false, err
}
@ -149,7 +149,11 @@ func (i *image) Unpack(ctx context.Context, snapshotterName string) error {
chain []digest.Digest
unpacked bool
)
sn, err := i.client.getSnapshotter(snapshotterName)
snapshotterName, err = i.client.resolveSnapshotterName(ctx, snapshotterName)
if err != nil {
return err
}
sn, err := i.client.getSnapshotter(ctx, snapshotterName)
if err != nil {
return err
}