Skip to content

Commit 8f89e4b

Browse files
authored
Fix: image tag normalized to docker spec (#573)
Signed-off-by: Qi Chen <[email protected]>
1 parent 5bf7b80 commit 8f89e4b

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

pkg/app/build.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/urfave/cli/v2"
2525

2626
"github.com/tensorchord/envd/pkg/builder"
27+
"github.com/tensorchord/envd/pkg/docker"
2728
"github.com/tensorchord/envd/pkg/flag"
2829
"github.com/tensorchord/envd/pkg/home"
2930
sshconfig "github.com/tensorchord/envd/pkg/ssh/config"
@@ -101,6 +102,10 @@ func build(clicontext *cli.Context) error {
101102
logrus.Debug("tag not specified, using default")
102103
tag = fmt.Sprintf("%s:%s", fileutil.Base(buildContext), "dev")
103104
}
105+
tag, err = docker.NormalizeNamed(tag)
106+
if err != nil {
107+
return err
108+
}
104109

105110
logger := logrus.WithFields(logrus.Fields{
106111
"build-context": buildContext,

pkg/app/up.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,11 @@ func up(clicontext *cli.Context) error {
125125
logrus.Debug("tag not specified, using default")
126126
tag = fmt.Sprintf("%s:%s", fileutil.Base(buildContext), "dev")
127127
}
128+
// The current container engine is only Docker. It should be expaned to support other container engines.
129+
tag, err = docker.NormalizeNamed(tag)
130+
if err != nil {
131+
return err
132+
}
128133
ctr := fileutil.Base(buildContext)
129134

130135
detach := clicontext.Bool("detach")

pkg/docker/docker.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io"
2222
"os"
2323
"path/filepath"
24+
"regexp"
2425
"strconv"
2526
"strings"
2627
"time"
@@ -46,7 +47,8 @@ const (
4647
)
4748

4849
var (
49-
interval = 1 * time.Second
50+
interval = 1 * time.Second
51+
anchoredIdentifierRegexp = regexp.MustCompile(`^([a-f0-9]{64})$`)
5052
)
5153

5254
type Client interface {
@@ -100,6 +102,31 @@ please visit https://docs.docker.com/engine/install/linux-postinstall/ for more
100102
return generalClient{cli}, nil
101103
}
102104

105+
// Normalize the name accord the spec of docker, It may support normalize imagea and container in the future.
106+
func NormalizeNamed(s string) (string, error) {
107+
if ok := anchoredIdentifierRegexp.MatchString(s); ok {
108+
return "", fmt.Errorf("invalid repository name (%s), cannot specify 64-byte hexadecimal strings, please rename it", s)
109+
}
110+
var remoteName string
111+
var tagSep int
112+
if tagSep = strings.IndexRune(s, ':'); tagSep > -1 {
113+
remoteName = s[:tagSep]
114+
} else {
115+
remoteName = s
116+
}
117+
if strings.ToLower(remoteName) != remoteName {
118+
remoteName = strings.ToLower(remoteName)
119+
if tagSep > -1 {
120+
s = remoteName + s[tagSep:]
121+
} else {
122+
s = remoteName
123+
}
124+
logrus.Warnf("The working direcotry's name is not lowercased: %s, the image built will be lowercased to %s", remoteName, s)
125+
}
126+
return s, nil
127+
128+
}
129+
103130
func (c generalClient) GPUEnabled(ctx context.Context) (bool, error) {
104131
info, err := c.GetInfo(ctx)
105132
if err != nil {

pkg/docker/docker_suite_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright 2022 The envd Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package docker
16+
17+
import (
18+
"testing"
19+
20+
. "github.com/onsi/ginkgo/v2"
21+
. "github.com/onsi/gomega"
22+
)
23+
24+
func TestManager(t *testing.T) {
25+
RegisterFailHandler(Fail)
26+
RunSpecs(t, "Docker Suite")
27+
}

pkg/docker/docker_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// Copyright 2022 The envd Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package docker
16+
17+
import (
18+
"strings"
19+
20+
. "github.com/onsi/ginkgo/v2"
21+
. "github.com/onsi/gomega"
22+
)
23+
24+
var _ = Describe("docker", func() {
25+
When("given the a lowcase tag", func() {
26+
It("should return the tag identically", func() {
27+
tag := "test:test"
28+
newTag, err := NormalizeNamed(tag)
29+
Expect(err).NotTo(HaveOccurred())
30+
Expect(newTag).To(Equal(tag))
31+
})
32+
})
33+
When("given the a uppercase tag", func() {
34+
It("should return the tag lowcased", func() {
35+
tag := "Test:test"
36+
newTag, err := NormalizeNamed(tag)
37+
Expect(err).NotTo(HaveOccurred())
38+
Expect(newTag).NotTo(Equal(tag))
39+
Expect(newTag).To(Equal(strings.ToLower(tag)))
40+
})
41+
})
42+
})

0 commit comments

Comments
 (0)