containers / podman

Podman: A tool for managing OCI containers and pods.
https://podman.io
Apache License 2.0
22.98k stars 2.34k forks source link

Podman run fails to respect command arguments #5562

Closed bbros-dev closed 4 years ago

bbros-dev commented 4 years ago

/kind bug

Description ls /root is respected that /root refers to the container. cp -f /root/vmlinux-* /output not so.

Steps to reproduce the issue:

1. File list shows the file is there:

oci_name=kernel
semver=0.0.8
$ podman run --authfile ${auth_file} \
           --rm \
           --volume ${orig_cwd}/launch/artifacts/firecracker/kernels:/output \
           --entrypoint=busybox \
           yelgeb/${oci_name}:${semver} \
           ls /root
control_port.sh
vmlinux-5.3

The copy command is looking in the host

$ podman run --authfile ${auth_file} \
           --rm \
           --volume ${orig_cwd}/launch/artifacts/firecracker/kernels:/output \
           --entrypoint=busybox \
           yelgeb/${oci_name}:${semver} \
           cp -f /root/vmlinux-* /output
cp: can't stat '/root/vmlinux-*': No such file or directory
  1. Same happens if you remove the --entrypoint flag and use the command busybox ...,

Describe the results you received:

cp: can't stat '/root/vmlinux-*': No such file or directory

Describe the results you expected:

Copy completed.

Additional information you deem important (e.g. issue happens only occasionally):

Output of podman version:

$ podman version
Version:            1.8.1
RemoteAPI Version:  1
Go Version:         go1.10.1
OS/Arch:            linux/amd64

Output of podman info --debug:

debug:
  compiler: gc
  git commit: ""
  go version: go1.10.1
  podman version: 1.8.1
host:
  BuildahVersion: 1.14.2
  CgroupVersion: v1
  Conmon:
    package: 'conmon: /usr/libexec/podman/conmon'
    path: /usr/libexec/podman/conmon
    version: 'conmon version 2.0.11, commit: '
  Distribution:
    distribution: ubuntu
    version: "18.04"
  IDMappings:
    gidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
    uidmap:
    - container_id: 0
      host_id: 1000
      size: 1
    - container_id: 1
      host_id: 100000
      size: 65536
  MemFree: 3505844224
  MemTotal: 16652021760
  OCIRuntime:
    name: runc
    package: 'containerd.io: /usr/bin/runc'
    path: /usr/bin/runc
    version: |-
      runc version 1.0.0-rc10
      commit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
      spec: 1.0.1-dev
  SwapFree: 3666010112
  SwapTotal: 4156551168
  arch: amd64
  cpus: 2
  eventlogger: journald
  hostname: desktop.local.lan
  kernel: 5.3.0-40-generic
  os: linux
  rootless: true
  slirp4netns:
    Executable: /usr/bin/slirp4netns
    Package: 'slirp4netns: /usr/bin/slirp4netns'
    Version: |-
      slirp4netns version 0.4.3
      commit: unknown
  uptime: 118h 45m 3.21s (Approximately 4.92 days)
registries:
  search:
  - docker.io
  - quay.io
store:
  ConfigFile: /home/hedge/.config/containers/storage.conf
  ContainerStore:
    number: 77
  GraphDriverName: vfs
  GraphOptions: {}
  GraphRoot: /home/hedge/.local/share/containers/storage
  GraphStatus: {}
  ImageStore:
    number: 181
  RunRoot: /run/user/1000
  VolumePath: /home/hedge/.local/share/containers/storage/volumes

Package info (e.g. output of rpm -q podman or apt list podman):

$ apt list podman
Listing... Done
podman/unknown,now 1.8.1~1 amd64 [installed]

Additional environment details (AWS, VirtualBox, physical, etc.):

Physical.

mheon commented 4 years ago

Are you sure your shell isn't expanding the wildcard itself? Can you try /bin/sh -c "cp -f /root/vmlinux-* /output" as an alternative command, which should force the wildcard to be expanded by a shell within the container?

bbros-dev commented 4 years ago

Great that works. In general I need to use busybox.
Not sure if it is intended behavior that everything has to go through a shell?
All commands have to be passed in like that?

rhatdan commented 4 years ago

If you enter a command on the command line, the shell is going to interpret it. There is nothing podman or any other tool can do about it. Bash sees the command first and interprets it before handing the arguments to the podman program. This is the way shells work.

bbros-dev commented 4 years ago

@rhatdan. Point taken. My apologies for cutting corners in the original report: The original command I expected to work is:

$ podman run --authfile ${auth_file} \
           --rm \
           --volume ${orig_cwd}/launch/artifacts/firecracker/kernels:/output \
           --entrypoint=busybox \
           yelgeb/${oci_name}:${semver} \
           'cp -f /root/vmlinux-* /output'
: applet not found

Then by trial and error I got to a point where podman at least fed busybox a command busybox understood - the report I opened.

My understanding is that podman currently handles the input for an entrypoint such that you have to provide cp in a way that the host's shell becomes involved. I'll spare you all the permutations of inputs I've tried.

I'm not sure, but I believe the above should work?

Apologies if I have overlooked something obvious.

mheon commented 4 years ago

By making cp -f ... into one large argument by wrapping it with quotes, Busybox is interpreting it in its entirety as the command to invoke (as opposed to command + arguments). Adding sh -c in front will make this work, as Busybox will invoke a shell to interpret the string, not treat it as a single command.

So podman run --entrypoint=busybox $IMG sh -c 'cp -f /root/vmlinux-* output/' should work.