Repository: containerd/containerd
File: pkg/oci/spec_opts.go (Go)

Code before:

			// Use a read-only mount when trying to get user/group information
			// from the container's rootfs. Since the option does read operation
			// only, we append ReadOnly mount option to prevent the Linux kernel
			// from syncing whole filesystem in umount syscall.
			return withReadonlyFS(ctx, client, mounts, f)
		default:
			return fmt.Errorf("invalid USER value %s", userstr)
		}
	}
}

// WithUIDGID allows the UID and GID for the Process to be set
func WithUIDGID(uid, gid uint32) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		defer ensureAdditionalGids(s)
		setProcess(s)
		s.Process.User.AdditionalGids = nil
		s.Process.User.UID = uid
		s.Process.User.GID = gid
		return nil
	}
}

// WithUmask sets the process user's umask in the OCI spec's Process.User.Umask
func WithUmask(umask int) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		setProcess(s)
		u := uint32(umask)
		s.Process.User.Umask = &u
		return nil
	}
}

// WithUserID sets the correct UID and GID for the container based
// on the image's /etc/passwd contents. If /etc/passwd does not exist,
// or uid is not found in /etc/passwd, it sets the requested uid,
// additionally sets the gid to 0, and does not return an error.
func WithUserID(uid uint32) SpecOpts {
	return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
		defer ensureAdditionalGids(s)
		setProcess(s)
		s.Process.User.AdditionalGids = nil
		setUser := func(root fs.FS) error {
			usr, err := UserFromFS(root, func(u user.User) bool {
				return u.Uid == int(uid)
			})
			if err != nil {
				if os.IsNotExist(err) || errors.Is(err, ErrNoUsersFound) {
					s.Process.User.UID, s.Process.User.GID = uid, 0
					return nil

Review comment (suggestion):
```suggestion
func WithUmask(umask uint32) SpecOpts {
```

Code after:

			// Use a read-only mount when trying to get user/group information
			// from the container's rootfs. Since the option does read operation
			// only, we append ReadOnly mount option to prevent the Linux kernel
			// from syncing whole filesystem in umount syscall.
			return withReadonlyFS(ctx, client, mounts, f)
		default:
			return fmt.Errorf("invalid USER value %s", userstr)
		}
	}
}

// WithUIDGID allows the UID and GID for the Process to be set
func WithUIDGID(uid, gid uint32) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		defer ensureAdditionalGids(s)
		setProcess(s)
		s.Process.User.AdditionalGids = nil
		s.Process.User.UID = uid
		s.Process.User.GID = gid
		return nil
	}
}

// WithUmask sets the process user's umask in the OCI spec's Process.User.Umask
func WithUmask(umask uint32) SpecOpts {
	return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
		setProcess(s)
		u := umask
		s.Process.User.Umask = &u
		return nil
	}
}

// WithUserID sets the correct UID and GID for the container based
// on the image's /etc/passwd contents. If /etc/passwd does not exist,
// or uid is not found in /etc/passwd, it sets the requested uid,
// additionally sets the gid to 0, and does not return an error.
func WithUserID(uid uint32) SpecOpts {
	return func(ctx context.Context, client Client, c *containers.Container, s *Spec) (err error) {
		defer ensureAdditionalGids(s)
		setProcess(s)
		s.Process.User.AdditionalGids = nil
		setUser := func(root fs.FS) error {
			usr, err := UserFromFS(root, func(u user.User) bool {
				return u.Uid == int(uid)
			})
			if err != nil {
				if os.IsNotExist(err) || errors.Is(err, ErrNoUsersFound) {
					s.Process.User.UID, s.Process.User.GID = uid, 0
					return nil