Skip to content

Commit dafb45d

Browse files
authored
Merge pull request #2005 from AkihiroSuda/fix-user-1.0
[release/1.0] fix running a container with config.User
2 parents 0a2c2a2 + 2eb4408 commit dafb45d

2 files changed

Lines changed: 16 additions & 13 deletions

File tree

cmd/ctr/commands/run/run_unix.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ func newContainer(ctx gocontext.Context, client *containerd.Client, context *cli
7272
if context.Bool("net-host") {
7373
opts = append(opts, oci.WithHostNamespace(specs.NetworkNamespace), oci.WithHostHostsFile, oci.WithHostResolvconf)
7474
}
75-
cOpts = append([]containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}, cOpts...)
75+
// oci.WithImageConfig (WithUsername, WithUserID) depends on rootfs snapshot for resolving /etc/passwd.
76+
// So cOpts needs to have precedence over opts.
77+
// TODO: WithUsername, WithUserID should additionally support non-snapshot rootfs
78+
cOpts = append(cOpts, []containerd.NewContainerOpts{containerd.WithNewSpec(opts...)}...)
7679
return client.NewContainer(ctx, id, cOpts...)
7780
}

oci/spec_opts_unix.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -96,22 +96,25 @@ func WithImageConfig(image Image) SpecOpts {
9696
s.Process.Env = append(s.Process.Env, config.Env...)
9797
cmd := config.Cmd
9898
s.Process.Args = append(config.Entrypoint, cmd...)
99+
cwd := config.WorkingDir
100+
if cwd == "" {
101+
cwd = "/"
102+
}
103+
s.Process.Cwd = cwd
99104
if config.User != "" {
105+
// According to OCI Image Spec v1.0.0, the following are valid for Linux:
106+
// user, uid, user:group, uid:gid, uid:group, user:gid
100107
parts := strings.Split(config.User, ":")
101108
switch len(parts) {
102109
case 1:
103110
v, err := strconv.Atoi(parts[0])
104111
if err != nil {
105112
// if we cannot parse as a uint they try to see if it is a username
106-
if err := WithUsername(config.User)(ctx, client, c, s); err != nil {
107-
return err
108-
}
109-
return err
110-
}
111-
if err := WithUserID(uint32(v))(ctx, client, c, s); err != nil {
112-
return err
113+
return WithUsername(config.User)(ctx, client, c, s)
113114
}
115+
return WithUserID(uint32(v))(ctx, client, c, s)
114116
case 2:
117+
// TODO: support username and groupname
115118
v, err := strconv.Atoi(parts[0])
116119
if err != nil {
117120
return errors.Wrapf(err, "parse uid %s", parts[0])
@@ -126,11 +129,6 @@ func WithImageConfig(image Image) SpecOpts {
126129
return fmt.Errorf("invalid USER value %s", config.User)
127130
}
128131
}
129-
cwd := config.WorkingDir
130-
if cwd == "" {
131-
cwd = "/"
132-
}
133-
s.Process.Cwd = cwd
134132
return nil
135133
}
136134
}
@@ -260,6 +258,7 @@ func WithUIDGID(uid, gid uint32) SpecOpts {
260258
// uid, and not returns error.
261259
func WithUserID(uid uint32) SpecOpts {
262260
return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) {
261+
// TODO: support non-snapshot rootfs
263262
if c.Snapshotter == "" {
264263
return errors.Errorf("no snapshotter set for container")
265264
}
@@ -322,6 +321,7 @@ func WithUserID(uid uint32) SpecOpts {
322321
// does not exist, or the username is not found in /etc/passwd,
323322
// it returns error.
324323
func WithUsername(username string) SpecOpts {
324+
// TODO: support non-snapshot rootfs
325325
return func(ctx context.Context, client Client, c *containers.Container, s *specs.Spec) (err error) {
326326
if c.Snapshotter == "" {
327327
return errors.Errorf("no snapshotter set for container")

0 commit comments

Comments
 (0)