cli/command/container: add create/run --umask

Signed-off-by: Youfu Zhang <zhangyoufu@gmail.com>
This commit is contained in:
Youfu Zhang
2026-09-04 03:23:44 +08:00
parent 51780c0691
commit 09d30a34bf
9 changed files with 197 additions and 0 deletions
+37
View File
@@ -11,6 +11,7 @@ import (
"net"
"path"
"slices"
"strconv"
"strings"
"github.com/docker/cli/internal/lazyregexp"
@@ -477,3 +478,39 @@ func (m *MemSwapBytes) UnmarshalJSON(s []byte) error {
b := MemBytes(*m)
return b.UnmarshalJSON(s)
}
// UmaskOpt is a type for umask values in octal format
type UmaskOpt struct {
ptr *uint32
}
// Set sets the value of the UmaskOpt by passing a string in octal format
func (u *UmaskOpt) Set(s string) error {
v, err := strconv.ParseUint(s, 8, 32)
if err != nil {
return err
}
if u.ptr == nil {
u.ptr = new(uint32)
}
*u.ptr = uint32(v)
return nil
}
// Type returns the type
func (*UmaskOpt) Type() string {
return "umask"
}
// Value returns the uint32 ptr
func (u *UmaskOpt) Value() *uint32 {
return u.ptr
}
// String returns the umask value in octal format, or "<nil>" if the pointer is nil.
func (u *UmaskOpt) String() string {
if u.ptr == nil {
return "<nil>"
}
return fmt.Sprintf("%#04o", uint64(*u.ptr))
}
+63
View File
@@ -428,3 +428,66 @@ func TestParseCPUsReturnZeroOnInvalidValues(t *testing.T) {
resValue, _ = ParseCPUs("1e-32")
assert.Equal(t, z1, resValue)
}
func TestUmaskOpt(t *testing.T) {
t.Run("type", func(t *testing.T) {
var opt UmaskOpt
assert.Equal(t, opt.Type(), "umask")
})
t.Run("nil by default", func(t *testing.T) {
var opt UmaskOpt
assert.Assert(t, opt.Value() == nil)
assert.Equal(t, opt.String(), "<nil>")
})
t.Run("rejects empty string", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("")
assert.Assert(t, err != nil)
assert.Assert(t, opt.Value() == nil)
assert.Equal(t, opt.String(), "<nil>")
})
t.Run("parses zero", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("0")
assert.NilError(t, err)
assert.Equal(t, *opt.Value(), uint32(0))
assert.Equal(t, opt.String(), "0000")
})
t.Run("parses valid octal values", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("022")
assert.NilError(t, err)
assert.Assert(t, opt.Value() != nil)
assert.Equal(t, *opt.Value(), uint32(0o22))
assert.Equal(t, opt.String(), "0022")
})
t.Run("rejects octal values with 0o prefix", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("0o22")
assert.Assert(t, err != nil)
assert.Assert(t, opt.Value() == nil)
assert.Equal(t, opt.String(), "<nil>")
})
t.Run("parses large octal values", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("077777")
assert.NilError(t, err)
assert.Assert(t, opt.Value() != nil)
assert.Equal(t, *opt.Value(), uint32(0o77777))
assert.Equal(t, opt.String(), "077777")
})
t.Run("rejects invalid octal values", func(t *testing.T) {
var opt UmaskOpt
err := opt.Set("9")
assert.Assert(t, err != nil)
assert.Assert(t, opt.Value() == nil)
assert.Equal(t, opt.String(), "<nil>")
})
}