Skip to content

Commit 3d22d76

Browse files
committed
source: http: make sure we set a source path for mounts
In the sources refactor we neglected to set a source path when mounting http sources, as such they end up getting mounted as directories instead of files. Signed-off-by: Brian Goff <cpuguy83@gmail.com>
1 parent 169cab4 commit 3d22d76

2 files changed

Lines changed: 81 additions & 16 deletions

File tree

source_http.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ func (src *SourceHTTP) IsDir() bool {
7575
}
7676

7777
func (src *SourceHTTP) toMount(opts fetchOptions) (llb.State, []llb.MountOption) {
78+
if isRoot(opts.Rename) {
79+
opts.Rename = internalMountSourceName
80+
}
81+
7882
st := src.toState(opts)
7983
// This is always a file, so to make sure we always mount a file instead of
8084
// a directory we need to add a mount opt pointing at the file name.

source_test.go

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -916,15 +916,10 @@ func stubListener(t *testing.T) net.Addr {
916916
return l.Addr()
917917
}
918918

919-
// 1. Generates the LLB for a source using Source2LLBGetter (the function we are testing)
920-
// 2. Marshals the LLB to a protobuf (since we don't have access to the data in LLB directly)
921-
// 3. Unmarshals the protobuf to get the [pb.Op]s which is what buildkit would act on to get the actual source data during build.
922-
func getSourceOp(ctx context.Context, t *testing.T, src Source) []*pb.Op {
919+
func prepareGetSourceOp(ctx context.Context, t *testing.T, src *Source) SourceOpts {
923920
t.Helper()
924921

925-
s := &src
926-
s.fillDefaults()
927-
src = *s
922+
src.fillDefaults()
928923

929924
var sOpt SourceOpts
930925
if src.Build != nil {
@@ -946,17 +941,15 @@ func getSourceOp(ctx context.Context, t *testing.T, src Source) []*pb.Op {
946941
st := llb.Local(name, opts...)
947942
return &st, nil
948943
}
944+
return sOpt
945+
}
949946

950-
// The name we pass to `ToState` will be the path that the source is copied to
951-
// For dirs, and the sake of tests, don't use any name so the everything is
952-
// at the root path.
953-
// Files must have a name, so give it a name of "test".
954-
name := ""
955-
if !src.IsDir() {
956-
name = "test"
957-
}
947+
// 1. Generates the LLB for a source using Source2LLBGetter (the function we are testing)
948+
// 2. Marshals the LLB to a protobuf (since we don't have access to the data in LLB directly)
949+
// 3. Unmarshals the protobuf to get the [pb.Op]s which is what buildkit would act on to get the actual source data during build.
950+
func sourceOpsFromState(ctx context.Context, t *testing.T, st llb.State) []*pb.Op {
951+
t.Helper()
958952

959-
st := src.ToState(name, sOpt)
960953
def, err := st.Marshal(ctx)
961954
if err != nil {
962955
t.Fatal(err)
@@ -977,6 +970,43 @@ func getSourceOp(ctx context.Context, t *testing.T, src Source) []*pb.Op {
977970
return out
978971
}
979972

973+
func getSourceOp(ctx context.Context, t *testing.T, src Source) []*pb.Op {
974+
t.Helper()
975+
976+
s := &src
977+
sOpt := prepareGetSourceOp(ctx, t, s)
978+
src = *s
979+
980+
// The name we pass to `ToState` will be the path that the source is copied to
981+
// For dirs, and the sake of tests, don't use any name so the everything is
982+
// at the root path.
983+
// Files must have a name, so give it a name of "test".
984+
name := ""
985+
if !src.IsDir() {
986+
name = "test"
987+
}
988+
989+
st := src.ToState(name, sOpt)
990+
return sourceOpsFromState(ctx, t, st)
991+
}
992+
993+
func getMountOp(ctx context.Context, t *testing.T, src Source, target string) []*pb.Op {
994+
t.Helper()
995+
996+
s := &src
997+
sOpt := prepareGetSourceOp(ctx, t, s)
998+
src = *s
999+
1000+
srcSt, mountOpts := src.ToMount(sOpt)
1001+
1002+
st := llb.Scratch().Run(
1003+
llb.Args([]string{"true"}),
1004+
llb.AddMount(target, srcSt, mountOpts...),
1005+
).Root()
1006+
1007+
return sourceOpsFromState(ctx, t, st)
1008+
}
1009+
9801010
func checkGitOp(t *testing.T, ops []*pb.Op, src *Source) {
9811011
op := ops[0].GetSource()
9821012

@@ -1377,3 +1407,34 @@ func Test_pathHasPrefix(t *testing.T) {
13771407
})
13781408
}
13791409
}
1410+
1411+
func TestSourceToMount(t *testing.T) {
1412+
t.Run("HTTP", func(t *testing.T) {
1413+
src := Source{
1414+
HTTP: &SourceHTTP{
1415+
URL: "https://example.com/file.tar.gz",
1416+
},
1417+
}
1418+
1419+
ctx := context.Background()
1420+
ops := getMountOp(ctx, t, src, "/mnt")
1421+
1422+
if len(ops) == 0 {
1423+
t.Fatal("expected at least 1 op")
1424+
}
1425+
1426+
assert.Assert(t, cmp.Len(ops, 2))
1427+
1428+
srcOp := ops[0].GetSource()
1429+
execOp := ops[1].GetExec()
1430+
assert.Assert(t, srcOp != nil)
1431+
assert.Assert(t, execOp != nil)
1432+
assert.Assert(t, cmp.Len(execOp.Mounts, 2)) // rootfs mount and http mount
1433+
1434+
assert.Check(t, cmp.Equal(src.HTTP.URL, srcOp.Identifier))
1435+
assert.Check(t, cmp.Equal(srcOp.Attrs["http.filename"], internalMountSourceName))
1436+
1437+
assert.Check(t, cmp.Equal("/mnt", execOp.Mounts[1].Dest))
1438+
assert.Check(t, cmp.Equal(internalMountSourceName, execOp.Mounts[1].Selector)) // should match the filename we set on the source op
1439+
})
1440+
}

0 commit comments

Comments
 (0)