Skip to content

Commit

Permalink
Merge pull request #693 from AkihiroSuda/meaningful-name
Browse files Browse the repository at this point in the history
run: automatically generate a container name from image ref
  • Loading branch information
AkihiroSuda authored Jan 12, 2022
2 parents a0d4294 + 262a1b9 commit 0ddaffd
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 3 deletions.
10 changes: 10 additions & 0 deletions cmd/nerdctl/ps.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,11 @@ import (
"time"

"github.com/containerd/containerd"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/nerdctl/pkg/formatter"
"github.com/containerd/nerdctl/pkg/labels"
"github.com/containerd/nerdctl/pkg/labels/k8slabels"
"github.com/sirupsen/logrus"

"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -158,11 +160,19 @@ func printContainers(ctx context.Context, cmd *cobra.Command, containers []conta
for _, c := range containers {
info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata)
if err != nil {
if errdefs.IsNotFound(err) {
logrus.Warn(err)
continue
}
return err
}

spec, err := c.Spec(ctx)
if err != nil {
if errdefs.IsNotFound(err) {
logrus.Warn(err)
continue
}
return err
}

Expand Down
9 changes: 9 additions & 0 deletions cmd/nerdctl/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
"github.com/containerd/nerdctl/pkg/netutil/nettype"
"github.com/containerd/nerdctl/pkg/platformutil"
"github.com/containerd/nerdctl/pkg/portutil"
"github.com/containerd/nerdctl/pkg/referenceutil"
"github.com/containerd/nerdctl/pkg/resolvconf"
"github.com/containerd/nerdctl/pkg/rootlessutil"
"github.com/containerd/nerdctl/pkg/strutil"
Expand Down Expand Up @@ -523,6 +524,14 @@ func createContainer(cmd *cobra.Command, ctx context.Context, client *containerd
if err != nil {
return nil, "", nil, err
}
if name == "" && !cmd.Flags().Changed("name") {
// Automatically set the container name, unless `--name=""` was explicitly specified.
var imageRef string
if ensuredImage != nil {
imageRef = ensuredImage.Ref
}
name = referenceutil.SuggestContainerName(imageRef, id)
}
if name != "" {
containerNameStore, err = namestore.New(dataStore, ns)
if err != nil {
Expand Down
37 changes: 34 additions & 3 deletions pkg/referenceutil/referenceutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package referenceutil

import (
"fmt"
"path"
"strings"

refdocker "github.com/containerd/containerd/reference/docker"
Expand All @@ -35,8 +36,8 @@ type Reference interface {
// If the ref has IPFS scheme or can be parsed as CID, it's parsed as an IPFS reference.
// Otherwise it's parsed as a docker reference.
func ParseAny(rawRef string) (Reference, error) {
if _, ref, err := ParseIPFSRefWithScheme(rawRef); err == nil {
return stringRef{ref}, nil
if scheme, ref, err := ParseIPFSRefWithScheme(rawRef); err == nil {
return stringRef{scheme: scheme, s: ref}, nil
}
if c, err := cid.Decode(rawRef); err == nil {
return c, nil
Expand All @@ -58,9 +59,39 @@ func ParseIPFSRefWithScheme(name string) (scheme, ref string, err error) {
}

type stringRef struct {
s string
scheme string
s string
}

func (s stringRef) String() string {
return s.s
}

// SuggestContainerName generates a container name from name.
// The result MUST NOT be parsed.
func SuggestContainerName(rawRef, containerID string) string {
const shortIDLength = 5
if len(containerID) < shortIDLength {
panic(fmt.Errorf("got too short (< %d) container ID: %q", shortIDLength, containerID))
}
name := "untitled-" + containerID[:shortIDLength]
if rawRef != "" {
r, err := ParseAny(rawRef)
if err == nil {
switch rr := r.(type) {
case refdocker.Named:
if rrName := rr.Name(); rrName != "" {
imageNameBased := path.Base(rrName)
if imageNameBased != "" {
name = imageNameBased + "-" + containerID[:shortIDLength]
}
}
case cid.Cid:
name = "ipfs" + "-" + rr.String()[:shortIDLength] + "-" + containerID[:shortIDLength]
case stringRef:
name = rr.scheme + "-" + rr.s[:shortIDLength] + "-" + containerID[:shortIDLength]
}
}
}
return name
}
35 changes: 35 additions & 0 deletions pkg/referenceutil/referenceutil_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
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 referenceutil

import (
"testing"

"gotest.tools/v3/assert"
)

func TestSuggestContainerName(t *testing.T) {
const containerID = "16f6d167d4f4743e48affb86e7097222b7992b34a29dab5f8c10cd6a90cdd990"
assert.Equal(t, "alpine-16f6d", SuggestContainerName("alpine", containerID))
assert.Equal(t, "alpine-16f6d", SuggestContainerName("alpine:3.15", containerID))
assert.Equal(t, "alpine-16f6d", SuggestContainerName("docker.io/library/alpine:3.15", containerID))
assert.Equal(t, "alpine-16f6d", SuggestContainerName("docker.io/library/alpine:latest", containerID))
assert.Equal(t, "ipfs-bafkr-16f6d", SuggestContainerName("bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze", containerID))
assert.Equal(t, "ipfs-bafkr-16f6d", SuggestContainerName("ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze", containerID))
assert.Equal(t, "untitled-16f6d", SuggestContainerName("invalid://alpine", containerID))
assert.Equal(t, "untitled-16f6d", SuggestContainerName("", containerID))
}

0 comments on commit 0ddaffd

Please sign in to comment.