containers / podlet

Generate Podman Quadlet files from a Podman command, compose file, or existing object
https://crates.io/crates/podlet
Mozilla Public License 2.0
400 stars 12 forks source link

Container command arguments treated as arguments to `podman run` #97

Open Viktor45 opened 1 month ago

Viktor45 commented 1 month ago

Podlet parses all arguments as podman arguments, instead to parse it like podman container arguments.

Here is the example.

Command to run container with extra container arguments.

podman run --replace --net=host \
--cap-add=NET_ADMIN --cap-add=SYS_ADMIN --cap-add=CAP_MKNOD --security-opt="label=disable" \
-v /var/app/list.txt:/list.txt:z \
--device=/dev/net/tun --device=/dev/null \
--name cdpi -d localhost/my-cdpi:latest -d 1 -s 1 -H /list.txt

Note the extra container arguments -d 1 -s 1 -H /list.txt.

Command to generate podlet from running containers podlet generate container cdpi

Got error:

Error: 0: error creating Quadlet file(s) from an existing object 1: error parsing Podman container command from ["podman", "run", "--replace", "--net=host", "--cap-add=NET_ADMIN", "--cap-add=SYS_ADMIN", "--cap-add=CAP_MKNOD", "--security-opt=label=disable", "-v", "/var/app/list.txt:/list.txt:z", "--device=/dev/net/tun", "--device=/dev/null", "--name", "cdpi", "-d", "localhost/my-cdpi:latest", "-d", "1", "-s", "1", "-H", "/list.txt"] 2: error: the argument '--detach' cannot be used multiple times

2: Usage: podlet [OPTIONS] [COMMAND]...

  For more information, try '--help'.

2:

Location: src/cli/generate.rs:152

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⋮ 1 frame hidden ⋮ 2: ::ext_report::h8eff283722d67991 at : 3: podlet::cli::generate::ContainerParser::from_container::hd917c4d329b2876c at : 4: podlet::cli::generate::Generate::try_into_quadlet_files::hdb29da458a256c5d at : 5: podlet::cli::Cli::try_into_files::h272c29d01695c5cd at : 6: podlet::cli::Cli::print_or_write_files::h7a108ecbab21c253 at : 7: podlet::main::hcdc3a3cc51275317 at : 8: std::sys_common::backtrace::rust_begin_short_backtrace::hbb3b36e6fe2a6b73 at : 9: std::rt::lang_start::{{closure}}::hdcdbeec9943261a6 at : 10: core::ops::function::impls::<impl core::ops::function::FnOnce for &F>::call_once::h52f5991f9ab8b369 at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/core/src/ops/function.rs:284 11: std::panicking::try::do_call::h0ac4bee9a397a1bf at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:552 12: std::panicking::try::hc005decaf198d0ed at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:516 13: std::panic::catch_unwind::hb0f967d870b2a382 at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panic.rs:146 14: std::rt::lang_start_internal::{{closure}}::hd140b84b0efe534b at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:148 15: std::panicking::try::do_call::h1ddfaf1d0d576c38 at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:552 16: std::panicking::try::hdd4bdf855547659f at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panicking.rs:516 17: std::panic::catch_unwind::h276ba91c7706110c at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/panic.rs:146 18: std::rt::lang_start_internal::h103c42a9c4e95084 at /rustc/9b00956e56009bab2aa15d7bff10916599e3d6d6/library/std/src/rt.rs:148 19: main at : 20: __libc_start_call_main at : 21: libc_start_main_impl at : 22: _start at :

k9withabone commented 2 days ago

Due to the way clap is parsing arguments for the container command (set to a trailing_var_arg, see cli::container::Container) and that you have -d as the first argument after the image, it's being treated as a second --detach. It's not "all arguments" as you claimed. This can be confirmed with the following command, switching -d 1 and -s 1:

podlet podman run --replace --net=host \
  --cap-add=NET_ADMIN --cap-add=SYS_ADMIN --cap-add=CAP_MKNOD --security-opt="label=disable" \
  -v /var/app/list.txt:/list.txt:z \
  --device=/dev/net/tun --device=/dev/null \
  --name cdpi -d localhost/my-cdpi:latest -s 1 -d 1 -H /list.txt

Which successfully generates the .container file:

# cdpi.container
[Container]
AddCapability=NET_ADMIN SYS_ADMIN CAP_MKNOD
AddDevice=/dev/net/tun
AddDevice=/dev/null
ContainerName=cdpi
Exec=-s 1 -d 1 -H /list.txt
Image=localhost/my-cdpi:latest
Network=host
SecurityLabelDisable=true
Volume=/var/app/list.txt:/list.txt:z

trailing_var_arg positional arguments (with allow_hyphen_values set) start collecting values at the first unrecognized argument (-s in the above example) or after -- (e.g., podlet podman run image -- command).

Unfortunately, I can't think of a good solution to this problem. The only thing I can think of is to combine the image and command fields/arguments in cli::container::Container (also removing allow_hyphen_values) and then separate out the image in the conversion. However, that screws up the usage and arguments in the help for podlet podman run, so that's no good. Hopefully someone can come up with a better solution.