Skip to content

Commit 1a7ef66

Browse files
[wanda] Add contextOwner type and parser (#479)
Add the contextOwner struct and parseContextOwner function for parsing "uid:gid" strings. This will be used to allow wanda specs to override file ownership in the build context tar. Topic: add-context-owner Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: andrew <andrew@anyscale.com> Signed-off-by: andrew <andrew@anyscale.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent ee2e396 commit 1a7ef66

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

wanda/tar_meta.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package wanda
22

33
import (
4+
"fmt"
45
"os"
6+
"strconv"
7+
"strings"
58
)
69

710
type tarMeta struct {
@@ -18,3 +21,43 @@ func tarMetaFromFileInfo(info os.FileInfo) *tarMeta {
1821
GroupID: rootUser,
1922
}
2023
}
24+
25+
// contextOwner holds a uid:gid pair parsed from a wanda spec.
26+
type contextOwner struct {
27+
UserID int
28+
GroupID int
29+
}
30+
31+
// parseContextOwner parses a "uid:gid" string.
32+
func parseContextOwner(s string) (*contextOwner, error) {
33+
parts := strings.SplitN(s, ":", 2)
34+
if len(parts) != 2 {
35+
return nil, fmt.Errorf(
36+
"context_owner %q: expected uid:gid format",
37+
s,
38+
)
39+
}
40+
uid, err := strconv.Atoi(parts[0])
41+
if err != nil {
42+
return nil, fmt.Errorf(
43+
"context_owner uid %q: %w", parts[0], err,
44+
)
45+
}
46+
if uid < 0 {
47+
return nil, fmt.Errorf(
48+
"context_owner uid %q: must be non-negative", parts[0],
49+
)
50+
}
51+
gid, err := strconv.Atoi(parts[1])
52+
if err != nil {
53+
return nil, fmt.Errorf(
54+
"context_owner gid %q: %w", parts[1], err,
55+
)
56+
}
57+
if gid < 0 {
58+
return nil, fmt.Errorf(
59+
"context_owner gid %q: must be non-negative", parts[1],
60+
)
61+
}
62+
return &contextOwner{UserID: uid, GroupID: gid}, nil
63+
}

wanda/tar_meta_test.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,34 @@ import (
88
"path/filepath"
99
)
1010

11+
func TestParseContextOwner(t *testing.T) {
12+
owner, err := parseContextOwner("2000:100")
13+
if err != nil {
14+
t.Fatalf("parseContextOwner: %v", err)
15+
}
16+
if owner.UserID != 2000 {
17+
t.Errorf("got uid %d, want %d", owner.UserID, 2000)
18+
}
19+
if owner.GroupID != 100 {
20+
t.Errorf("got gid %d, want %d", owner.GroupID, 100)
21+
}
22+
}
23+
24+
func TestParseContextOwnerInvalid(t *testing.T) {
25+
for _, input := range []string{
26+
"", "2000", "abc:100", "2000:xyz",
27+
"-1:100", "100:-1", "100:200:300", " 100:200",
28+
} {
29+
_, err := parseContextOwner(input)
30+
if err == nil {
31+
t.Errorf(
32+
"parseContextOwner(%q) = nil error, want error",
33+
input,
34+
)
35+
}
36+
}
37+
}
38+
1139
func TestTarMetaFromFileInfo(t *testing.T) {
1240
tmp := t.TempDir()
1341

0 commit comments

Comments
 (0)