diff options
Diffstat (limited to 'pkg/specgenutil')
-rw-r--r-- | pkg/specgenutil/ports_test.go | 57 | ||||
-rw-r--r-- | pkg/specgenutil/specgen.go | 4 | ||||
-rw-r--r-- | pkg/specgenutil/specgenutil_test.go | 77 | ||||
-rw-r--r-- | pkg/specgenutil/util.go | 1 | ||||
-rw-r--r-- | pkg/specgenutil/util_test.go | 146 | ||||
-rw-r--r-- | pkg/specgenutil/volumes.go | 21 | ||||
-rw-r--r-- | pkg/specgenutil/volumes_test.go | 68 |
7 files changed, 364 insertions, 10 deletions
diff --git a/pkg/specgenutil/ports_test.go b/pkg/specgenutil/ports_test.go new file mode 100644 index 000000000..3f62c619c --- /dev/null +++ b/pkg/specgenutil/ports_test.go @@ -0,0 +1,57 @@ +package specgenutil + +import "testing" + +func Test_verifyExpose(t *testing.T) { + type args struct { + expose []string + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "single port with tcp", + args: args{ + expose: []string{"53/tcp"}, + }, + wantErr: false, + }, + { + name: "single port with udp", + args: args{ + expose: []string{"53/udp"}, + }, + wantErr: false, + }, + { + name: "good port range", + args: args{ + expose: []string{"100-133"}, + }, + wantErr: false, + }, + { + name: "high to low should fail", + args: args{ + expose: []string{"100-99"}, + }, + wantErr: true, + }, + { + name: "range with protocol", + args: args{ + expose: []string{"53/tcp-55/tcp"}, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := verifyExpose(tt.args.expose); (err != nil) != tt.wantErr { + t.Errorf("verifyExpose() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/specgenutil/specgen.go b/pkg/specgenutil/specgen.go index 00de99817..f0dfcac1a 100644 --- a/pkg/specgenutil/specgen.go +++ b/pkg/specgenutil/specgen.go @@ -136,7 +136,7 @@ func LimitToSwap(memory *specs.LinuxMemory, swap string, ml int64) { } } -func getMemoryLimits(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) { +func getMemoryLimits(c *entities.ContainerCreateOptions) (*specs.LinuxMemory, error) { var err error memory := &specs.LinuxMemory{} hasLimits := false @@ -497,7 +497,7 @@ func FillOutSpecGen(s *specgen.SpecGenerator, c *entities.ContainerCreateOptions } if s.ResourceLimits.Memory == nil || (len(c.Memory) != 0 || len(c.MemoryReservation) != 0 || len(c.MemorySwap) != 0 || c.MemorySwappiness != 0) { - s.ResourceLimits.Memory, err = getMemoryLimits(s, c) + s.ResourceLimits.Memory, err = getMemoryLimits(c) if err != nil { return err } diff --git a/pkg/specgenutil/specgenutil_test.go b/pkg/specgenutil/specgenutil_test.go new file mode 100644 index 000000000..5867b0ae0 --- /dev/null +++ b/pkg/specgenutil/specgenutil_test.go @@ -0,0 +1,77 @@ +//go:build linux +// +build linux + +package specgenutil + +import ( + "testing" + + "github.com/containers/common/pkg/machine" + "github.com/containers/podman/v4/pkg/domain/entities" + "github.com/containers/podman/v4/pkg/specgen" + "github.com/stretchr/testify/assert" +) + +func TestWinPath(t *testing.T) { + const ( + fail = false + pass = true + ) + tests := []struct { + vol string + source string + dest string + isN bool + outcome bool + mach string + }{ + {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"}, + {`C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, fail, ""}, + {`\\?\C:\Foo:/blah`, "/mnt/c/Foo", "/blah", false, pass, "wsl"}, + {`/c/bar:/blah`, "/mnt/c/bar", "/blah", false, pass, "wsl"}, + {`/c/bar:/blah`, "/c/bar", "/blah", false, pass, ""}, + {`/test/this:/blah`, "/test/this", "/blah", false, pass, "wsl"}, + {`c:/bar/something:/other`, "/mnt/c/bar/something", "/other", false, pass, "wsl"}, + {`c:/foo:ro`, "c", "/foo", true, pass, ""}, + {`\\computer\loc:/dest`, "", "", false, fail, "wsl"}, + {`\\.\drive\loc:/target`, "/mnt/wsl/drive/loc", "/target", false, pass, "wsl"}, + } + + f := func(vol string, mach string) (*specgen.SpecGenerator, error) { + machine := machine.GetMachineMarker() + oldEnable, oldType := machine.Enabled, machine.Type + machine.Enabled, machine.Type = len(mach) > 0, mach + sg := specgen.NewSpecGenerator("nothing", false) + err := FillOutSpecGen(sg, &entities.ContainerCreateOptions{ + ImageVolume: "ignore", + Volume: []string{vol}}, []string{}, + ) + machine.Enabled, machine.Type = oldEnable, oldType + return sg, err + } + + for _, test := range tests { + msg := "Checking: " + test.vol + sg, err := f(test.vol, test.mach) + if test.outcome == fail { + assert.NotNil(t, err, msg) + continue + } + if !assert.Nil(t, err, msg) { + continue + } + if test.isN { + if !assert.Equal(t, 1, len(sg.Volumes), msg) { + continue + } + assert.Equal(t, test.source, sg.Volumes[0].Name, msg) + assert.Equal(t, test.dest, sg.Volumes[0].Dest, msg) + } else { + if !assert.Equal(t, 1, len(sg.Mounts), msg) { + continue + } + assert.Equal(t, test.source, sg.Mounts[0].Source, msg) + assert.Equal(t, test.dest, sg.Mounts[0].Destination, msg) + } + } +} diff --git a/pkg/specgenutil/util.go b/pkg/specgenutil/util.go index 80d31398b..fa2e90457 100644 --- a/pkg/specgenutil/util.go +++ b/pkg/specgenutil/util.go @@ -281,6 +281,7 @@ func CreateExitCommandArgs(storageConfig storageTypes.StoreOptions, config *conf "--tmpdir", config.Engine.TmpDir, "--network-config-dir", config.Network.NetworkConfigDir, "--network-backend", config.Network.NetworkBackend, + "--volumepath", config.Engine.VolumePath, } if config.Engine.OCIRuntime != "" { command = append(command, []string{"--runtime", config.Engine.OCIRuntime}...) diff --git a/pkg/specgenutil/util_test.go b/pkg/specgenutil/util_test.go new file mode 100644 index 000000000..79d60d335 --- /dev/null +++ b/pkg/specgenutil/util_test.go @@ -0,0 +1,146 @@ +package specgenutil + +import ( + "reflect" + "testing" +) + +func TestCreateExpose(t *testing.T) { + single := make(map[uint16]string, 0) + single[99] = "tcp" + + simpleRange := make(map[uint16]string, 0) + simpleRange[99] = "tcp" + simpleRange[100] = "tcp" + + simpleRangeUDP := make(map[uint16]string, 0) + simpleRangeUDP[99] = "udp" + simpleRangeUDP[100] = "udp" + type args struct { + expose []string + } + tests := []struct { + name string + args args + want map[uint16]string + wantErr bool + }{ + { + name: "single port", + args: args{ + expose: []string{"99"}, + }, + want: single, + wantErr: false, + }, + { + name: "simple range tcp", + args: args{ + expose: []string{"99-100"}, + }, + want: simpleRange, + wantErr: false, + }, + { + name: "simple range udp", + args: args{ + expose: []string{"99-100/udp"}, + }, + want: simpleRangeUDP, + wantErr: false, + }, + { + name: "range inverted should fail", + args: args{ + expose: []string{"100-99"}, + }, + want: nil, + wantErr: true, + }, + { + name: "specifying protocol twice should fail", + args: args{ + expose: []string{"99/tcp-100/tcp"}, + }, + want: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := CreateExpose(tt.args.expose) + if (err != nil) != tt.wantErr { + t.Errorf("CreateExpose() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("CreateExpose() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_parseAndValidatePort(t *testing.T) { + type args struct { + port string + } + tests := []struct { + name string + args args + want uint16 + wantErr bool + }{ + { + name: "0 should fail", + args: args{ + port: "0", + }, + want: 0, + wantErr: true, + }, + { + name: "over 65535 should fail", + args: args{ + port: "66666", + }, + want: 0, + wantErr: true, + }, + { + name: "", + args: args{ + port: "99", + }, + want: 99, + wantErr: false, + }, + { + name: "negative values should fail", + args: args{ + port: "-1", + }, + want: 0, + wantErr: true, + }, + { + name: "protocol should fail", + args: args{ + port: "99/tcp", + }, + want: 0, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseAndValidatePort(tt.args.port) + if (err != nil) != tt.wantErr { + t.Errorf("parseAndValidatePort() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("parseAndValidatePort() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/specgenutil/volumes.go b/pkg/specgenutil/volumes.go index 95ce420f8..50d745380 100644 --- a/pkg/specgenutil/volumes.go +++ b/pkg/specgenutil/volumes.go @@ -3,7 +3,7 @@ package specgenutil import ( "encoding/csv" "fmt" - "path/filepath" + "path" "strings" "github.com/containers/common/pkg/parse" @@ -123,7 +123,7 @@ func parseVolumes(volumeFlag, mountFlag, tmpfsFlag []string, addReadOnlyTmpfs bo finalMounts := make([]spec.Mount, 0, len(unifiedMounts)) for _, mount := range unifiedMounts { if mount.Type == define.TypeBind { - absSrc, err := filepath.Abs(mount.Source) + absSrc, err := specgen.ConvertWinMountPath(mount.Source) if err != nil { return nil, nil, nil, nil, errors.Wrapf(err, "error getting absolute path of %s", mount.Source) } @@ -334,7 +334,7 @@ func getBindMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true case "relabel": if setRelabel { @@ -456,7 +456,7 @@ func getTmpfsMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true case "U", "chown": if setOwnership { @@ -507,7 +507,7 @@ func getDevptsMount(args []string) (spec.Mount, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return newMount, err } - newMount.Destination = filepath.Clean(kv[1]) + newMount.Destination = unixPathClean(kv[1]) setDest = true default: return newMount, errors.Wrapf(util.ErrBadMntOption, "%s", kv[0]) @@ -572,7 +572,7 @@ func getNamedVolume(args []string) (*specgen.NamedVolume, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return nil, err } - newVolume.Dest = filepath.Clean(kv[1]) + newVolume.Dest = unixPathClean(kv[1]) setDest = true case "U", "chown": if setOwnership { @@ -624,7 +624,7 @@ func getImageVolume(args []string) (*specgen.ImageVolume, error) { if err := parse.ValidateVolumeCtrDir(kv[1]); err != nil { return nil, err } - newVolume.Destination = filepath.Clean(kv[1]) + newVolume.Destination = unixPathClean(kv[1]) case "rw", "readwrite": switch kv[1] { case "true": @@ -670,7 +670,7 @@ func getTmpfsMounts(tmpfsFlag []string) (map[string]spec.Mount, error) { } mount := spec.Mount{ - Destination: filepath.Clean(destPath), + Destination: unixPathClean(destPath), Type: define.TypeTmpfs, Options: options, Source: define.TypeTmpfs, @@ -700,3 +700,8 @@ func validChownFlag(flag string) (bool, error) { return true, nil } + +// Use path instead of filepath to preserve Unix style paths on Windows +func unixPathClean(p string) string { + return path.Clean(p) +} diff --git a/pkg/specgenutil/volumes_test.go b/pkg/specgenutil/volumes_test.go new file mode 100644 index 000000000..fc6caf83c --- /dev/null +++ b/pkg/specgenutil/volumes_test.go @@ -0,0 +1,68 @@ +package specgenutil + +import "testing" + +func Test_validChownFlag(t *testing.T) { + type args struct { + flag string + } + tests := []struct { + name string + args args + want bool + wantErr bool + }{ + { + name: "U true", + args: args{ + flag: "U=true", + }, + want: true, + wantErr: false, + }, + { + name: "U true case doesnt matter", + args: args{ + flag: "u=True", + }, + want: true, + wantErr: false, + }, + { + name: "U is false", + args: args{ + flag: "U=false", + }, + want: false, + wantErr: false, + }, + { + name: "chown should also work", + args: args{ + flag: "chown=true", + }, + want: true, + wantErr: false, + }, + { + name: "garbage value should fail", + args: args{ + flag: "U=foobar", + }, + want: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := validChownFlag(tt.args.flag) + if (err != nil) != tt.wantErr { + t.Errorf("validChownFlag() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("validChownFlag() got = %v, want %v", got, tt.want) + } + }) + } +} |