Skip to content

Commit 0ddaffd

Browse files
authored
Merge pull request #693 from AkihiroSuda/meaningful-name
run: automatically generate a container name from image ref
2 parents a0d4294 + 262a1b9 commit 0ddaffd

File tree

4 files changed

+88
-3
lines changed

4 files changed

+88
-3
lines changed

cmd/nerdctl/ps.go

+10
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ import (
3030
"time"
3131

3232
"github.com/containerd/containerd"
33+
"github.com/containerd/containerd/errdefs"
3334
"github.com/containerd/nerdctl/pkg/formatter"
3435
"github.com/containerd/nerdctl/pkg/labels"
3536
"github.com/containerd/nerdctl/pkg/labels/k8slabels"
37+
"github.com/sirupsen/logrus"
3638

3739
"github.com/spf13/cobra"
3840
)
@@ -158,11 +160,19 @@ func printContainers(ctx context.Context, cmd *cobra.Command, containers []conta
158160
for _, c := range containers {
159161
info, err := c.Info(ctx, containerd.WithoutRefreshedMetadata)
160162
if err != nil {
163+
if errdefs.IsNotFound(err) {
164+
logrus.Warn(err)
165+
continue
166+
}
161167
return err
162168
}
163169

164170
spec, err := c.Spec(ctx)
165171
if err != nil {
172+
if errdefs.IsNotFound(err) {
173+
logrus.Warn(err)
174+
continue
175+
}
166176
return err
167177
}
168178

cmd/nerdctl/run.go

+9
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import (
5151
"github.com/containerd/nerdctl/pkg/netutil/nettype"
5252
"github.com/containerd/nerdctl/pkg/platformutil"
5353
"github.com/containerd/nerdctl/pkg/portutil"
54+
"github.com/containerd/nerdctl/pkg/referenceutil"
5455
"github.com/containerd/nerdctl/pkg/resolvconf"
5556
"github.com/containerd/nerdctl/pkg/rootlessutil"
5657
"github.com/containerd/nerdctl/pkg/strutil"
@@ -523,6 +524,14 @@ func createContainer(cmd *cobra.Command, ctx context.Context, client *containerd
523524
if err != nil {
524525
return nil, "", nil, err
525526
}
527+
if name == "" && !cmd.Flags().Changed("name") {
528+
// Automatically set the container name, unless `--name=""` was explicitly specified.
529+
var imageRef string
530+
if ensuredImage != nil {
531+
imageRef = ensuredImage.Ref
532+
}
533+
name = referenceutil.SuggestContainerName(imageRef, id)
534+
}
526535
if name != "" {
527536
containerNameStore, err = namestore.New(dataStore, ns)
528537
if err != nil {

pkg/referenceutil/referenceutil.go

+34-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package referenceutil
1818

1919
import (
2020
"fmt"
21+
"path"
2122
"strings"
2223

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

6061
type stringRef struct {
61-
s string
62+
scheme string
63+
s string
6264
}
6365

6466
func (s stringRef) String() string {
6567
return s.s
6668
}
69+
70+
// SuggestContainerName generates a container name from name.
71+
// The result MUST NOT be parsed.
72+
func SuggestContainerName(rawRef, containerID string) string {
73+
const shortIDLength = 5
74+
if len(containerID) < shortIDLength {
75+
panic(fmt.Errorf("got too short (< %d) container ID: %q", shortIDLength, containerID))
76+
}
77+
name := "untitled-" + containerID[:shortIDLength]
78+
if rawRef != "" {
79+
r, err := ParseAny(rawRef)
80+
if err == nil {
81+
switch rr := r.(type) {
82+
case refdocker.Named:
83+
if rrName := rr.Name(); rrName != "" {
84+
imageNameBased := path.Base(rrName)
85+
if imageNameBased != "" {
86+
name = imageNameBased + "-" + containerID[:shortIDLength]
87+
}
88+
}
89+
case cid.Cid:
90+
name = "ipfs" + "-" + rr.String()[:shortIDLength] + "-" + containerID[:shortIDLength]
91+
case stringRef:
92+
name = rr.scheme + "-" + rr.s[:shortIDLength] + "-" + containerID[:shortIDLength]
93+
}
94+
}
95+
}
96+
return name
97+
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package referenceutil
18+
19+
import (
20+
"testing"
21+
22+
"gotest.tools/v3/assert"
23+
)
24+
25+
func TestSuggestContainerName(t *testing.T) {
26+
const containerID = "16f6d167d4f4743e48affb86e7097222b7992b34a29dab5f8c10cd6a90cdd990"
27+
assert.Equal(t, "alpine-16f6d", SuggestContainerName("alpine", containerID))
28+
assert.Equal(t, "alpine-16f6d", SuggestContainerName("alpine:3.15", containerID))
29+
assert.Equal(t, "alpine-16f6d", SuggestContainerName("docker.io/library/alpine:3.15", containerID))
30+
assert.Equal(t, "alpine-16f6d", SuggestContainerName("docker.io/library/alpine:latest", containerID))
31+
assert.Equal(t, "ipfs-bafkr-16f6d", SuggestContainerName("bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze", containerID))
32+
assert.Equal(t, "ipfs-bafkr-16f6d", SuggestContainerName("ipfs://bafkreicq4dg6nkef5ju422ptedcwfz6kcvpvvhuqeykfrwq5krazf3muze", containerID))
33+
assert.Equal(t, "untitled-16f6d", SuggestContainerName("invalid://alpine", containerID))
34+
assert.Equal(t, "untitled-16f6d", SuggestContainerName("", containerID))
35+
}

0 commit comments

Comments
 (0)