mirror of
https://github.com/moby/buildkit.git
synced 2025-08-01 02:04:26 +03:00
git: verify checksum early and more tests
Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
committed by
Akihiro Suda
parent
8ee2cf5cab
commit
58f956b807
@ -58,7 +58,13 @@ func testAddGit(t *testing.T, sb integration.Sandbox) {
|
|||||||
revParseCmd.Dir = gitDir
|
revParseCmd.Dir = gitDir
|
||||||
commitHashB, err := revParseCmd.Output()
|
commitHashB, err := revParseCmd.Output()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
commitHash := strings.TrimSpace(string(commitHashB))
|
commitHashV2 := strings.TrimSpace(string(commitHashB))
|
||||||
|
|
||||||
|
revParseCmd = exec.Command("git", "rev-parse", "v0.0.3")
|
||||||
|
revParseCmd.Dir = gitDir
|
||||||
|
commitHashB, err = revParseCmd.Output()
|
||||||
|
require.NoError(t, err)
|
||||||
|
commitHashV3 := strings.TrimSpace(string(commitHashB))
|
||||||
|
|
||||||
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Clean(gitDir))))
|
server := httptest.NewServer(http.FileServer(http.Dir(filepath.Clean(gitDir))))
|
||||||
defer server.Close()
|
defer server.Close()
|
||||||
@ -86,10 +92,9 @@ RUN cd /buildkit-chowned && \
|
|||||||
[ -z "$(git status -s)" ]
|
[ -z "$(git status -s)" ]
|
||||||
`, map[string]string{
|
`, map[string]string{
|
||||||
"ServerURL": serverURL,
|
"ServerURL": serverURL,
|
||||||
"Checksum": commitHash,
|
"Checksum": commitHashV2,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("dockerfile=%s", dockerfile)
|
|
||||||
|
|
||||||
dir := integration.Tmpdir(t,
|
dir := integration.Tmpdir(t,
|
||||||
fstest.CreateFile("Dockerfile", []byte(dockerfile), 0600),
|
fstest.CreateFile("Dockerfile", []byte(dockerfile), 0600),
|
||||||
@ -106,6 +111,137 @@ RUN cd /buildkit-chowned && \
|
|||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Additional test: ADD from Git URL with checksum but without keep-git-dir flag
|
||||||
|
dockerfile2, err := applyTemplate(`
|
||||||
|
FROM alpine
|
||||||
|
ARG REPO="{{.ServerURL}}/.git"
|
||||||
|
ARG TAG="v0.0.3"
|
||||||
|
ADD --checksum={{.Checksum}} ${REPO}#${TAG} /nogitdir
|
||||||
|
RUN [ -f /nogitdir/foo ]
|
||||||
|
RUN [ "$(cat /nogitdir/foo)" = "foo of v0.0.3" ]
|
||||||
|
RUN [ ! -d /nogitdir/.git ]
|
||||||
|
`, map[string]string{
|
||||||
|
"ServerURL": serverURL,
|
||||||
|
"Checksum": commitHashV3,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dir2 := integration.Tmpdir(t,
|
||||||
|
fstest.CreateFile("Dockerfile", []byte(dockerfile2), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
|
||||||
|
LocalMounts: map[string]fsutil.FS{
|
||||||
|
dockerui.DefaultLocalNameDockerfile: dir2,
|
||||||
|
dockerui.DefaultLocalNameContext: dir2,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// access initial ref again that was already pulled
|
||||||
|
dockerfile3, err := applyTemplate(`
|
||||||
|
FROM alpine
|
||||||
|
ARG REPO="{{.ServerURL}}/.git"
|
||||||
|
ARG TAG="v0.0.2"
|
||||||
|
ADD --keep-git-dir --checksum={{.Checksum}} ${REPO}#${TAG} /nogitdir
|
||||||
|
RUN [ -f /nogitdir/foo ]
|
||||||
|
RUN [ "$(cat /nogitdir/foo)" = "foo of v0.0.2" ]
|
||||||
|
RUN [ -d /nogitdir/.git ]
|
||||||
|
`, map[string]string{
|
||||||
|
"ServerURL": serverURL,
|
||||||
|
"Checksum": commitHashV2,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dir3 := integration.Tmpdir(t,
|
||||||
|
fstest.CreateFile("Dockerfile", []byte(dockerfile3), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
|
||||||
|
LocalMounts: map[string]fsutil.FS{
|
||||||
|
dockerui.DefaultLocalNameDockerfile: dir3,
|
||||||
|
dockerui.DefaultLocalNameContext: dir3,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// Additional test: ADD from Git URL using commitHashV3 for both checksum and ref
|
||||||
|
dockerfile4, err := applyTemplate(`
|
||||||
|
FROM alpine
|
||||||
|
ARG REPO="{{.ServerURL}}/.git"
|
||||||
|
ARG COMMIT="{{.Checksum}}"
|
||||||
|
ADD --keep-git-dir=true --checksum={{.Checksum}} ${REPO}#${COMMIT} /commitdir
|
||||||
|
RUN [ -f /commitdir/foo ]
|
||||||
|
RUN [ "$(cat /commitdir/foo)" = "foo of v0.0.3" ]
|
||||||
|
RUN [ -d /commitdir/.git ]
|
||||||
|
`, map[string]string{
|
||||||
|
"ServerURL": serverURL,
|
||||||
|
"Checksum": commitHashV3,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dir4 := integration.Tmpdir(t,
|
||||||
|
fstest.CreateFile("Dockerfile", []byte(dockerfile4), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
|
||||||
|
LocalMounts: map[string]fsutil.FS{
|
||||||
|
dockerui.DefaultLocalNameDockerfile: dir4,
|
||||||
|
dockerui.DefaultLocalNameContext: dir4,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// checksum does not match
|
||||||
|
dockerfile5, err := applyTemplate(`
|
||||||
|
FROM alpine
|
||||||
|
ARG REPO="{{.ServerURL}}/.git"
|
||||||
|
ARG TAG="v0.0.3"
|
||||||
|
ADD --checksum={{.WrongChecksum}} ${REPO}#${TAG} /faildir
|
||||||
|
`, map[string]string{
|
||||||
|
"ServerURL": serverURL,
|
||||||
|
"WrongChecksum": commitHashV2, // v0.0.2 hash, but ref is v0.0.3
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dir5 := integration.Tmpdir(t,
|
||||||
|
fstest.CreateFile("Dockerfile", []byte(dockerfile5), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
|
||||||
|
LocalMounts: map[string]fsutil.FS{
|
||||||
|
dockerui.DefaultLocalNameDockerfile: dir5,
|
||||||
|
dockerui.DefaultLocalNameContext: dir5,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "expected checksum to match")
|
||||||
|
|
||||||
|
// checksum is garbage
|
||||||
|
dockerfile6, err := applyTemplate(`
|
||||||
|
FROM alpine
|
||||||
|
ARG REPO="{{.ServerURL}}/.git"
|
||||||
|
ARG TAG="v0.0.3"
|
||||||
|
ADD --checksum=foobar ${REPO}#${TAG} /faildir
|
||||||
|
`, map[string]string{
|
||||||
|
"ServerURL": serverURL,
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
dir6 := integration.Tmpdir(t,
|
||||||
|
fstest.CreateFile("Dockerfile", []byte(dockerfile6), 0600),
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err = f.Solve(sb.Context(), c, client.SolveOpt{
|
||||||
|
LocalMounts: map[string]fsutil.FS{
|
||||||
|
dockerui.DefaultLocalNameDockerfile: dir6,
|
||||||
|
dockerui.DefaultLocalNameContext: dir6,
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.Contains(t, err.Error(), "invalid checksum")
|
||||||
|
require.Contains(t, err.Error(), "expected hex commit hash")
|
||||||
}
|
}
|
||||||
|
|
||||||
func applyTemplate(tmpl string, x any) (string, error) {
|
func applyTemplate(tmpl string, x any) (string, error) {
|
||||||
|
@ -351,6 +351,13 @@ func (gs *gitSourceHandler) CacheKey(ctx context.Context, g session.Group, index
|
|||||||
gs.locker.Lock(remote)
|
gs.locker.Lock(remote)
|
||||||
defer gs.locker.Unlock(remote)
|
defer gs.locker.Unlock(remote)
|
||||||
|
|
||||||
|
if gs.src.Checksum != "" {
|
||||||
|
matched, err := regexp.MatchString("^[a-fA-F0-9]+$", gs.src.Checksum)
|
||||||
|
if err != nil || !matched {
|
||||||
|
return "", "", nil, false, errors.Errorf("invalid checksum %s for Git URL, expected hex commit hash", gs.src.Checksum)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var refCommitFullHash, ref2 string
|
var refCommitFullHash, ref2 string
|
||||||
if gitutil.IsCommitSHA(gs.src.Checksum) && !gs.src.KeepGitDir {
|
if gitutil.IsCommitSHA(gs.src.Checksum) && !gs.src.KeepGitDir {
|
||||||
refCommitFullHash = gs.src.Checksum
|
refCommitFullHash = gs.src.Checksum
|
||||||
@ -549,7 +556,17 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
|
|||||||
subdir = "."
|
subdir = "."
|
||||||
}
|
}
|
||||||
|
|
||||||
checkedoutRef := "HEAD"
|
if gs.src.Checksum != "" {
|
||||||
|
actualHashBuf, err := git.Run(ctx, "rev-parse", ref)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to rev-parse %s for %s", ref, urlutil.RedactCredentials(gs.src.Remote))
|
||||||
|
}
|
||||||
|
actualHash := strings.TrimSpace(string(actualHashBuf))
|
||||||
|
if !strings.HasPrefix(actualHash, gs.src.Checksum) {
|
||||||
|
return nil, errors.Errorf("expected checksum to match %s, got %s", gs.src.Checksum, actualHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if gs.src.KeepGitDir && subdir == "." {
|
if gs.src.KeepGitDir && subdir == "." {
|
||||||
checkoutDirGit := filepath.Join(checkoutDir, ".git")
|
checkoutDirGit := filepath.Join(checkoutDir, ".git")
|
||||||
if err := os.MkdirAll(checkoutDir, 0711); err != nil {
|
if err := os.MkdirAll(checkoutDir, 0711); err != nil {
|
||||||
@ -619,7 +636,6 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to checkout remote %s", urlutil.RedactCredentials(gs.src.Remote))
|
return nil, errors.Wrapf(err, "failed to checkout remote %s", urlutil.RedactCredentials(gs.src.Remote))
|
||||||
}
|
}
|
||||||
checkedoutRef = ref // HEAD may not exist
|
|
||||||
if subdir != "." {
|
if subdir != "." {
|
||||||
d, err := os.Open(filepath.Join(cd, subdir))
|
d, err := os.Open(filepath.Join(cd, subdir))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -650,16 +666,6 @@ func (gs *gitSourceHandler) Snapshot(ctx context.Context, g session.Group) (out
|
|||||||
}
|
}
|
||||||
|
|
||||||
git = git.New(gitutil.WithWorkTree(checkoutDir), gitutil.WithGitDir(gitDir))
|
git = git.New(gitutil.WithWorkTree(checkoutDir), gitutil.WithGitDir(gitDir))
|
||||||
if gs.src.Checksum != "" {
|
|
||||||
actualHashBuf, err := git.Run(ctx, "rev-parse", checkedoutRef)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "failed to rev-parse %s for %s", checkedoutRef, urlutil.RedactCredentials(gs.src.Remote))
|
|
||||||
}
|
|
||||||
actualHash := strings.TrimSpace(string(actualHashBuf))
|
|
||||||
if !strings.HasPrefix(actualHash, gs.src.Checksum) {
|
|
||||||
return nil, errors.Errorf("expected checksum to match %s, got %s", gs.src.Checksum, actualHash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_, err = git.Run(ctx, "submodule", "update", "--init", "--recursive", "--depth=1")
|
_, err = git.Run(ctx, "submodule", "update", "--init", "--recursive", "--depth=1")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "failed to update submodules for %s", urlutil.RedactCredentials(gs.src.Remote))
|
return nil, errors.Wrapf(err, "failed to update submodules for %s", urlutil.RedactCredentials(gs.src.Remote))
|
||||||
|
Reference in New Issue
Block a user