Skip to content

Commit

Permalink
refactor: reduce duplicate code
Browse files Browse the repository at this point in the history
Signed-off-by: Ye Sijun <[email protected]>
(cherry picked from commit 1ab42be)
> Conflicts:
>	oci/spec_opts.go
>	oci/spec_opts_linux_test.go
Signed-off-by: Akihiro Suda <[email protected]>
  • Loading branch information
junnplus authored and AkihiroSuda committed Feb 10, 2023
1 parent 6a7b761 commit 356672c
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 36 deletions.
53 changes: 18 additions & 35 deletions oci/spec_opts.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,11 +618,8 @@ func WithUIDGID(uid, gid uint32) SpecOpts {
func WithUserID(uid uint32) SpecOpts {
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
setProcess(s)
if c.Snapshotter == "" && c.SnapshotKey == "" {
if !isRootfsAbs(s.Root.Path) {
return errors.Errorf("rootfs absolute path is required")
}
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
setUser := func(root string) error {
user, err := UserFromPath(root, func(u user.User) bool {
return u.Uid == int(uid)
})
if err != nil {
Expand All @@ -634,7 +631,12 @@ func WithUserID(uid uint32) SpecOpts {
}
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil

}
if c.Snapshotter == "" && c.SnapshotKey == "" {
if !isRootfsAbs(s.Root.Path) {
return errors.New("rootfs absolute path is required")
}
return setUser(s.Root.Path)
}
if c.Snapshotter == "" {
return errors.Errorf("no snapshotter set for container")
Expand All @@ -649,20 +651,7 @@ func WithUserID(uid uint32) SpecOpts {
}

mounts = tryReadonlyMounts(mounts)
return mount.WithTempMount(ctx, mounts, func(root string) error {
user, err := UserFromPath(root, func(u user.User) bool {
return u.Uid == int(uid)
})
if err != nil {
if os.IsNotExist(err) || err == ErrNoUsersFound {
s.Process.User.UID, s.Process.User.GID = uid, 0
return nil
}
return err
}
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil
})
return mount.WithTempMount(ctx, mounts, setUser)
}
}

Expand All @@ -674,11 +663,8 @@ func WithUsername(username string) SpecOpts {
return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
setProcess(s)
if s.Linux != nil {
if c.Snapshotter == "" && c.SnapshotKey == "" {
if !isRootfsAbs(s.Root.Path) {
return errors.Errorf("rootfs absolute path is required")
}
user, err := UserFromPath(s.Root.Path, func(u user.User) bool {
setUser := func(root string) error {
user, err := UserFromPath(root, func(u user.User) bool {
return u.Name == username
})
if err != nil {
Expand All @@ -687,6 +673,12 @@ func WithUsername(username string) SpecOpts {
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil
}
if c.Snapshotter == "" && c.SnapshotKey == "" {
if !isRootfsAbs(s.Root.Path) {
return errors.New("rootfs absolute path is required")
}
return setUser(s.Root.Path)
}
if c.Snapshotter == "" {
return errors.Errorf("no snapshotter set for container")
}
Expand All @@ -700,16 +692,7 @@ func WithUsername(username string) SpecOpts {
}

mounts = tryReadonlyMounts(mounts)
return mount.WithTempMount(ctx, mounts, func(root string) error {
user, err := UserFromPath(root, func(u user.User) bool {
return u.Name == username
})
if err != nil {
return err
}
s.Process.User.UID, s.Process.User.GID = uint32(user.Uid), uint32(user.Gid)
return nil
})
return mount.WithTempMount(ctx, mounts, setUser)
} else if s.Windows != nil {
s.Process.User.Username = username
} else {
Expand Down
119 changes: 118 additions & 1 deletion oci/spec_opts_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package oci

import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
Expand All @@ -31,6 +32,123 @@ import (
"golang.org/x/sys/unix"
)

// nolint:gosec
func TestWithUserID(t *testing.T) {
t.Parallel()

expectedPasswd := `root:x:0:0:root:/root:/bin/ash
guest:x:405:100:guest:/dev/null:/sbin/nologin
`
td := t.TempDir()
apply := fstest.Apply(
fstest.CreateDir("/etc", 0777),
fstest.CreateFile("/etc/passwd", []byte(expectedPasswd), 0777),
)
if err := apply.Apply(td); err != nil {
t.Fatalf("failed to apply: %v", err)
}
c := containers.Container{ID: t.Name()}
testCases := []struct {
userID uint32
expectedUID uint32
expectedGID uint32
}{
{
userID: 0,
expectedUID: 0,
expectedGID: 0,
},
{
userID: 405,
expectedUID: 405,
expectedGID: 100,
},
{
userID: 1000,
expectedUID: 1000,
expectedGID: 0,
},
}
for _, testCase := range testCases {
t.Run(fmt.Sprintf("user %d", testCase.userID), func(t *testing.T) {
t.Parallel()
s := Spec{
Version: specs.Version,
Root: &specs.Root{
Path: td,
},
Linux: &specs.Linux{},
}
err := WithUserID(testCase.userID)(context.Background(), nil, &c, &s)
assert.NoError(t, err)
assert.Equal(t, testCase.expectedUID, s.Process.User.UID)
assert.Equal(t, testCase.expectedGID, s.Process.User.GID)
})
}
}

// nolint:gosec
func TestWithUsername(t *testing.T) {
t.Parallel()

expectedPasswd := `root:x:0:0:root:/root:/bin/ash
guest:x:405:100:guest:/dev/null:/sbin/nologin
`
td := t.TempDir()
apply := fstest.Apply(
fstest.CreateDir("/etc", 0777),
fstest.CreateFile("/etc/passwd", []byte(expectedPasswd), 0777),
)
if err := apply.Apply(td); err != nil {
t.Fatalf("failed to apply: %v", err)
}
c := containers.Container{ID: t.Name()}
testCases := []struct {
user string
expectedUID uint32
expectedGID uint32
err string
}{
{
user: "root",
expectedUID: 0,
expectedGID: 0,
},
{
user: "guest",
expectedUID: 405,
expectedGID: 100,
},
{
user: "1000",
err: "no users found",
},
{
user: "unknown",
err: "no users found",
},
}
for _, testCase := range testCases {
t.Run(testCase.user, func(t *testing.T) {
t.Parallel()
s := Spec{
Version: specs.Version,
Root: &specs.Root{
Path: td,
},
Linux: &specs.Linux{},
}
err := WithUsername(testCase.user)(context.Background(), nil, &c, &s)
if err != nil {
assert.EqualError(t, err, testCase.err)
}
assert.Equal(t, testCase.expectedUID, s.Process.User.UID)
assert.Equal(t, testCase.expectedGID, s.Process.User.GID)
})
}

}

// nolint:gosec
func TestWithAdditionalGIDs(t *testing.T) {
t.Parallel()
Expand All @@ -55,7 +173,6 @@ sys:x:3:root,bin,adm
c := containers.Container{ID: t.Name()}

testCases := []struct {
name string
user string
expected []uint32
}{
Expand Down

0 comments on commit 356672c

Please sign in to comment.