Skip to content

Commit 13f36e6

Browse files
AkihiroSudacrazy-max
authored andcommitted
dockerfile: implement ADD --checksum=COMMIT_HASH GIT_URL
Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp> (cherry picked from commit 8ee2cf5)
1 parent 8e1bbed commit 13f36e6

File tree

3 files changed

+47
-29
lines changed

3 files changed

+47
-29
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -937,27 +937,21 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
937937
case *instructions.WorkdirCommand:
938938
err = dispatchWorkdir(d, c, true, &opt)
939939
case *instructions.AddCommand:
940-
var checksum digest.Digest
941-
if c.Checksum != "" {
942-
checksum, err = digest.Parse(c.Checksum)
943-
}
944-
if err == nil {
945-
err = dispatchCopy(d, copyConfig{
946-
params: c.SourcesAndDest,
947-
excludePatterns: c.ExcludePatterns,
948-
source: opt.buildContext,
949-
isAddCommand: true,
950-
cmdToPrint: c,
951-
chown: c.Chown,
952-
chmod: c.Chmod,
953-
link: c.Link,
954-
keepGitDir: c.KeepGitDir,
955-
checksum: checksum,
956-
location: c.Location(),
957-
ignoreMatcher: opt.dockerIgnoreMatcher,
958-
opt: opt,
959-
})
960-
}
940+
err = dispatchCopy(d, copyConfig{
941+
params: c.SourcesAndDest,
942+
excludePatterns: c.ExcludePatterns,
943+
source: opt.buildContext,
944+
isAddCommand: true,
945+
cmdToPrint: c,
946+
chown: c.Chown,
947+
chmod: c.Chmod,
948+
link: c.Link,
949+
keepGitDir: c.KeepGitDir,
950+
checksum: c.Checksum,
951+
location: c.Location(),
952+
ignoreMatcher: opt.dockerIgnoreMatcher,
953+
opt: opt,
954+
})
961955
if err == nil {
962956
for _, src := range c.SourcePaths {
963957
if !strings.HasPrefix(src, "http://") && !strings.HasPrefix(src, "https://") {
@@ -1470,8 +1464,8 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
14701464
if len(cfg.params.SourcePaths) != 1 {
14711465
return errors.New("checksum can't be specified for multiple sources")
14721466
}
1473-
if !isHTTPSource(cfg.params.SourcePaths[0]) {
1474-
return errors.New("checksum can't be specified for non-HTTP(S) sources")
1467+
if !isHTTPSource(cfg.params.SourcePaths[0]) && !isGitSource(cfg.params.SourcePaths[0]) {
1468+
return errors.New("checksum requires HTTP(S) or Git sources")
14751469
}
14761470
}
14771471

@@ -1519,6 +1513,9 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
15191513
if cfg.keepGitDir {
15201514
gitOptions = append(gitOptions, llb.KeepGitDir())
15211515
}
1516+
if cfg.checksum != "" {
1517+
gitOptions = append(gitOptions, llb.GitChecksum(cfg.checksum))
1518+
}
15221519
st := llb.Git(gitRef.Remote, commit, gitOptions...)
15231520
opts := append([]llb.CopyOption{&llb.CopyInfo{
15241521
Mode: chopt,
@@ -1547,7 +1544,15 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
15471544
}
15481545
}
15491546

1550-
st := llb.HTTP(src, llb.Filename(f), llb.WithCustomName(pgName), llb.Checksum(cfg.checksum), dfCmd(cfg.params))
1547+
var checksum digest.Digest
1548+
if cfg.checksum != "" {
1549+
checksum, err = digest.Parse(cfg.checksum)
1550+
if err != nil {
1551+
return err
1552+
}
1553+
}
1554+
1555+
st := llb.HTTP(src, llb.Filename(f), llb.WithCustomName(pgName), llb.Checksum(checksum), dfCmd(cfg.params))
15511556

15521557
opts := append([]llb.CopyOption{&llb.CopyInfo{
15531558
Mode: chopt,
@@ -1674,7 +1679,7 @@ type copyConfig struct {
16741679
chmod string
16751680
link bool
16761681
keepGitDir bool
1677-
checksum digest.Digest
1682+
checksum string
16781683
parents bool
16791684
location []parser.Range
16801685
ignoreMatcher *patternmatcher.PatternMatcher
@@ -2265,11 +2270,15 @@ func isHTTPSource(src string) bool {
22652270
if !strings.HasPrefix(src, "http://") && !strings.HasPrefix(src, "https://") {
22662271
return false
22672272
}
2273+
return !isGitSource(src)
2274+
}
2275+
2276+
func isGitSource(src string) bool {
22682277
// https://github.com/ORG/REPO.git is a git source, not an http source
22692278
if gitRef, gitErr := gitutil.ParseGitRef(src); gitRef != nil && gitErr == nil {
2270-
return false
2279+
return true
22712280
}
2272-
return true
2281+
return false
22732282
}
22742283

22752284
func isEnabledForStage(stage string, value string) bool {

frontend/dockerfile/dockerfile_addchecksum_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,6 @@ ADD --checksum=%s foo /tmp/foo
162162
dockerui.DefaultLocalNameContext: dir,
163163
},
164164
}, nil)
165-
require.Error(t, err, "checksum can't be specified for non-HTTP(S) sources")
165+
require.Error(t, err, "checksum requires HTTP(S) or Git sources")
166166
})
167167
}

frontend/dockerfile/dockerfile_addgit_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import (
55
"net/http"
66
"net/http/httptest"
77
"os"
8+
"os/exec"
89
"path/filepath"
10+
"strings"
911
"testing"
1012
"text/template"
1113

@@ -52,6 +54,12 @@ func testAddGit(t *testing.T, sb integration.Sandbox) {
5254
err = runShell(gitDir, gitCommands...)
5355
require.NoError(t, err)
5456

57+
revParseCmd := exec.Command("git", "rev-parse", "v0.0.2")
58+
revParseCmd.Dir = gitDir
59+
commitHashB, err := revParseCmd.Output()
60+
require.NoError(t, err)
61+
commitHash := strings.TrimSpace(string(commitHashB))
62+
5563
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Clean(gitDir))))
5664
defer server.Close()
5765
serverURL := server.URL
@@ -68,7 +76,7 @@ RUN cd /x && \
6876
# Complicated case
6977
ARG REPO="{{.ServerURL}}/.git"
7078
ARG TAG="v0.0.2"
71-
ADD --keep-git-dir=true --chown=4242:8484 ${REPO}#${TAG} /buildkit-chowned
79+
ADD --keep-git-dir=true --chown=4242:8484 --checksum={{.Checksum}} ${REPO}#${TAG} /buildkit-chowned
7280
RUN apk add git
7381
USER 4242
7482
RUN cd /buildkit-chowned && \
@@ -78,6 +86,7 @@ RUN cd /buildkit-chowned && \
7886
[ -z "$(git status -s)" ]
7987
`, map[string]string{
8088
"ServerURL": serverURL,
89+
"Checksum": commitHash,
8190
})
8291
require.NoError(t, err)
8392
t.Logf("dockerfile=%s", dockerfile)

0 commit comments

Comments
 (0)