diff options
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | cmd/podman/create.go | 2 | ||||
-rw-r--r-- | cmd/podman/create_cli.go | 8 | ||||
-rw-r--r-- | pkg/namespaces/namespaces.go | 2 | ||||
-rw-r--r-- | pkg/spec/config_linux.go | 50 | ||||
-rw-r--r-- | pkg/spec/parse.go | 2 | ||||
-rw-r--r-- | pkg/spec/spec.go | 4 | ||||
-rw-r--r-- | test/utils/common_function_test.go | 2 | ||||
-rw-r--r-- | troubleshooting.md | 2 |
9 files changed, 62 insertions, 12 deletions
@@ -106,7 +106,7 @@ to be long lived. While Buildah containers are really just created to allow con to be added back to the container image. An easy way to think of it is the `buildah run` command emulates the RUN command in a Dockerfile while the `podman run` command emulates the `docker run` command in functionality. Because of this and their underlying -storage differences, you can not see Podman containers from within Buildah or vice versa. +storage differences, you cannot see Podman containers from within Buildah or vice versa. In short Buildah is an efficient way to create OCI images while Podman allows you to manage and maintain those images and containers in a production environment using diff --git a/cmd/podman/create.go b/cmd/podman/create.go index 2b31a6423..1425892cc 100644 --- a/cmd/podman/create.go +++ b/cmd/podman/create.go @@ -462,7 +462,7 @@ func parseCreateOpts(ctx context.Context, c *cli.Context, runtime *libpod.Runtim tty := c.Bool("tty") if c.Bool("detach") && c.Bool("rm") { - return nil, errors.Errorf("--rm and --detach can not be specified together") + return nil, errors.Errorf("--rm and --detach cannot be specified together") } if c.Int64("cpu-period") != 0 && c.Float64("cpus") > 0 { return nil, errors.Errorf("--cpu-period and --cpus cannot be set together") diff --git a/cmd/podman/create_cli.go b/cmd/podman/create_cli.go index b3a30d185..2a820fa43 100644 --- a/cmd/podman/create_cli.go +++ b/cmd/podman/create_cli.go @@ -144,7 +144,7 @@ func parseMounts(mounts []string) ([]spec.Mount, error) { mountInfo.Options = append(mountInfo.Options, kv[1]) case "src", "source": if mountInfo.Type == "tmpfs" { - return nil, errors.Errorf("can not use src= on a tmpfs file system") + return nil, errors.Errorf("cannot use src= on a tmpfs file system") } if err := validateVolumeHostDir(kv[1]); err != nil { return nil, err @@ -288,7 +288,7 @@ func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, e return warnings, fmt.Errorf("minimum memory reservation allowed is 4MB") } if config.Resources.Memory > 0 && config.Resources.MemoryReservation > 0 && config.Resources.Memory < config.Resources.MemoryReservation { - return warnings, fmt.Errorf("minimum memory limit can not be less than memory reservation limit, see usage") + return warnings, fmt.Errorf("minimum memory limit cannot be less than memory reservation limit, see usage") } if config.Resources.KernelMemory > 0 && !sysInfo.KernelMemory { warnings = addWarning(warnings, "Your kernel does not support kernel memory limit capabilities or the cgroup is not mounted. Limitation discarded.") @@ -318,14 +318,14 @@ func verifyContainerResources(config *cc.CreateConfig, update bool) ([]string, e config.Resources.CPUPeriod = 0 } if config.Resources.CPUPeriod != 0 && (config.Resources.CPUPeriod < 1000 || config.Resources.CPUPeriod > 1000000) { - return warnings, fmt.Errorf("CPU cfs period can not be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)") + return warnings, fmt.Errorf("CPU cfs period cannot be less than 1ms (i.e. 1000) or larger than 1s (i.e. 1000000)") } if config.Resources.CPUQuota > 0 && !sysInfo.CPUCfsQuota { warnings = addWarning(warnings, "Your kernel does not support CPU cfs quota or the cgroup is not mounted. Quota discarded.") config.Resources.CPUQuota = 0 } if config.Resources.CPUQuota > 0 && config.Resources.CPUQuota < 1000 { - return warnings, fmt.Errorf("CPU cfs quota can not be less than 1ms (i.e. 1000)") + return warnings, fmt.Errorf("CPU cfs quota cannot be less than 1ms (i.e. 1000)") } // cpuset subsystem checks and adjustments if (config.Resources.CPUsetCPUs != "" || config.Resources.CPUsetMems != "") && !sysInfo.Cpuset { diff --git a/pkg/namespaces/namespaces.go b/pkg/namespaces/namespaces.go index 832efd554..11b47fec4 100644 --- a/pkg/namespaces/namespaces.go +++ b/pkg/namespaces/namespaces.go @@ -84,7 +84,7 @@ func (n UTSMode) Valid() bool { // IpcMode represents the container ipc stack. type IpcMode string -// IsPrivate indicates whether the container uses its own private ipc namespace which can not be shared. +// IsPrivate indicates whether the container uses its own private ipc namespace which cannot be shared. func (n IpcMode) IsPrivate() bool { return n == "private" } diff --git a/pkg/spec/config_linux.go b/pkg/spec/config_linux.go index 5bf8eff43..f3e200262 100644 --- a/pkg/spec/config_linux.go +++ b/pkg/spec/config_linux.go @@ -3,7 +3,11 @@ package createconfig import ( + "fmt" "io/ioutil" + "os" + "path/filepath" + "strings" "github.com/docker/docker/profiles/seccomp" "github.com/opencontainers/runc/libcontainer/configs" @@ -27,6 +31,52 @@ func Device(d *configs.Device) spec.LinuxDevice { } } +// devicesFromPath computes a list of devices +func devicesFromPath(g *generate.Generator, devicePath string) error { + devs := strings.Split(devicePath, ":") + resolvedDevicePath := devs[0] + // check if it is a symbolic link + if src, err := os.Lstat(resolvedDevicePath); err == nil && src.Mode()&os.ModeSymlink == os.ModeSymlink { + if linkedPathOnHost, err := filepath.EvalSymlinks(resolvedDevicePath); err == nil { + resolvedDevicePath = linkedPathOnHost + } + } + st, err := os.Stat(resolvedDevicePath) + if err != nil { + return errors.Wrapf(err, "cannot stat %s", devicePath) + } + if st.IsDir() { + if len(devs) > 2 { + return errors.Wrapf(unix.EINVAL, "not allowed to specify destination with a directory %s", devicePath) + } + found := false + // mount the internal devices recursively + if err := filepath.Walk(resolvedDevicePath, func(dpath string, f os.FileInfo, e error) error { + + if f.Mode()&os.ModeDevice == os.ModeDevice { + found = true + device := dpath + + if len(devs) > 1 { + device = fmt.Sprintf("%s:%s", dpath, devs[1]) + } + if err := addDevice(g, device); err != nil { + return errors.Wrapf(err, "failed to add %s device", dpath) + } + } + return nil + }); err != nil { + return err + } + if !found { + return errors.Wrapf(unix.EINVAL, "no devices found in %s", devicePath) + } + return nil + } + + return addDevice(g, devicePath) +} + func addDevice(g *generate.Generator, device string) error { src, dst, permissions, err := ParseDevice(device) if err != nil { diff --git a/pkg/spec/parse.go b/pkg/spec/parse.go index 4d20e35d4..d688b8d1b 100644 --- a/pkg/spec/parse.go +++ b/pkg/spec/parse.go @@ -166,7 +166,7 @@ func ParseDevice(device string) (string, string, string, error) { //nolint permissions = arr[1] } else { if arr[1][0] != '/' { - return "", "", "", fmt.Errorf("invalid device mode: %s", arr[2]) + return "", "", "", fmt.Errorf("invalid device mode: %s", arr[1]) } dst = arr[1] } diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go index 05be00864..c90f16f7c 100644 --- a/pkg/spec/spec.go +++ b/pkg/spec/spec.go @@ -235,8 +235,8 @@ func CreateConfigToOCISpec(config *CreateConfig) (*spec.Spec, error) { //nolint } } } else { - for _, device := range config.Devices { - if err := addDevice(&g, device); err != nil { + for _, devicePath := range config.Devices { + if err := devicesFromPath(&g, devicePath); err != nil { return nil, err } } diff --git a/test/utils/common_function_test.go b/test/utils/common_function_test.go index 1648a4899..98cb43188 100644 --- a/test/utils/common_function_test.go +++ b/test/utils/common_function_test.go @@ -36,7 +36,7 @@ var _ = Describe("Common functions test", func() { It("Test SystemExec", func() { session := SystemExec(GoechoPath, []string{}) - Expect(session.Command.Process).ShouldNot(BeNil(), "SystemExec can not start a process") + Expect(session.Command.Process).ShouldNot(BeNil(), "SystemExec cannot start a process") }) It("Test StringInSlice", func() { diff --git a/troubleshooting.md b/troubleshooting.md index 574196a69..030f0af7e 100644 --- a/troubleshooting.md +++ b/troubleshooting.md @@ -18,7 +18,7 @@ and retry your command before reporting the issue. --- ### 2) No such image or Bare keys cannot contain ':' -When doing a `podman pull` or `podman build` command and a "common" image can not be pulled, +When doing a `podman pull` or `podman build` command and a "common" image cannot be pulled, it is likely that the `/etc/containers/registries.conf` file is either not installed or possibly misconfigured. |