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
318 stars 10 forks source link

error: unexpected argument '--infra-conmon-pidfile' found #86

Open strzinek opened 1 month ago

strzinek commented 1 month ago

I am trying podlet to generate quadlet files from an existing pod running as systemd service that was created by the older podman generate systemd command. The command I am using is podlet pod generate <pod-name>, and it fails with this error message:

error: unexpected argument '--infra-conmon-pidfile' found
k9withabone commented 1 month ago

The podlet generate pod command essentially uses the podlet podman pod create command internally to parse the CreateCommand from the output of podman inspect pod. podlet podman pod create deliberately does not implement the --infra-conmon-pidfile and --pod-id-file options as they are set by Quadlet. I'm not 100% certain that this is the best way to handle it, and I'm open to suggestions.

strzinek commented 1 month ago

Well, I was hoping that Podlet would solve my problem of converting existing containers from the original systemd approach to the new quadlet approach. If Podlet doesn't support this, then it kind of misses the point for me. Of course, I can create all the quadlet definition files manually, but I was hoping that Podlet would save me from that. It might as well support it by ignoring this parameter altogether.

k9withabone commented 1 month ago

If Podlet doesn't support this, then it kind of misses the point for me.

You could write a script that removes the --infra-conmon-pidfile argument from the CreateCommand and give the rest of the arguments to podlet podman pod create.

It might as well support it by ignoring this parameter altogether.

I don't think that's a good idea. If someone runs podman pod create --infra-conmon-pidfile /path/to/some/file test and then podlet generate pod test, they would expect:

# test.pod
[Pod]
PodmanArgs=--infra-conmon-pidfile /path/to/some/file

That test.pod file wouldn't work because --infra-conmon-pidfile is set by Quadlet in the generated test-pod.service and --infra-conmon-pidfile can only be set once.

Just ignoring the argument would violate the principle of least surprise.

strzinek commented 1 month ago

If Podlet doesn't support this, then it kind of misses the point for me.

You could write a script that removes the --infra-conmon-pidfile argument from the CreateCommand and give the rest of the arguments to podlet podman pod create.

It might as well support it by ignoring this parameter altogether.

I don't think that's a good idea. If someone runs podman pod create --infra-conmon-pidfile /path/to/some/file test and then podlet generate pod test, they would expect:

# test.pod
[Pod]
PodmanArgs=--infra-conmon-pidfile /path/to/some/file

That test.pod file wouldn't work because --infra-conmon-pidfile is set by Quadlet in the generated test-pod.service and --infra-conmon-pidfile can only be set once.

Just ignoring the argument would violate the principle of least surprise.

The thing is, the --infra-conmon-pidfile argument is added by the podman generate systemd command, not by the user when creating the actual container beforehand with podman create.

Having to parse all the generated systemd container definitions means that I don't actually need the podlet at all, I can generate complete quadlet files once I process them.

k9withabone commented 4 weeks ago

The thing is, the --infra-conmon-pidfile argument is added by the podman generate systemd command, not by the user when creating the actual container beforehand with podman create.

But there is no way to differentiate from between the two from Podlet's point of view.

Having to parse all the generated systemd container definitions means that I don't actually need the podlet at all, I can generate complete quadlet files once I process them.

Why would you need to parse the .service files? You can use podman pod inspect. Here's an example of a script (written in Rust because that's what I'm most comfortable with) that I was talking about:

Cargo.toml

[package]
name = "podman-pod-inspect-script"
version = "0.1.0"
edition = "2021"

[dependencies]
color-eyre = "0.6.3"
serde = { version = "1.0.203", features = ["derive"] }
serde_json = "1.0.117"

src/main.rs

use std::process::Command;

use color_eyre::eyre::{OptionExt, WrapErr};
use serde::Deserialize;

fn main() -> color_eyre::Result<()> {
    color_eyre::install()?;

    let pod = std::env::args().nth(1).ok_or_eyre("missing pod name arg")?;

    let PodmanPodInspect { create_command } = PodmanPodInspect::from_pod(&pod)?;

    let mut pidfile_arg_seen = false;
    let args = create_command.into_iter().filter(|arg| {
        if pidfile_arg_seen {
            pidfile_arg_seen = false;
            false
        } else if arg == "--infra-conmon-pidfile" {
            pidfile_arg_seen = true;
            false
        } else {
            true
        }
    });

    Command::new("podlet")
        .args(args)
        .spawn()
        .wrap_err("error running Podlet")?
        .wait()?;

    Ok(())
}

/// Selected output of `podman pod inspect`.
#[derive(Deserialize, Debug)]
#[serde(rename_all = "PascalCase")]
struct PodmanPodInspect {
    /// Full command and arguments that created the pod.
    create_command: Vec<String>,
}

impl PodmanPodInspect {
    fn from_pod(pod: &str) -> color_eyre::Result<Self> {
        let output = Command::new("podman")
            .args(["pod", "inspect", pod])
            .output()
            .wrap_err("error running `podman pod inspect`")?;

        let stdout = String::from_utf8(output.stdout)
            .wrap_err("`podman pod inspect` output was not UTF-8")?;

        // `podman pod inspect` returns an array
        serde_json::from_str::<Vec<_>>(&stdout)
            .wrap_err("error deserializing `podman pod inspect` output")?
            .into_iter()
            .next()
            .ok_or_eyre("unknown pod")
    }
}
strzinek commented 3 weeks ago

I came to Podlet because I was looking for a tool that would help me avoid scripting.

I just have a bunch of systemd pods and containers on several hosts that I would like to convert to quadlets, as the "old" way is deprecated. It seemed to me that Podlet was made for just that. Maybe it was not, so what the heck...

rapus95 commented 4 days ago

How about introducing an --ignore-infra-conmon-pidfile argument for podlet pod generate? (And likewise for the other deliberately unsupported argument. That certainly would not violate the principle of least surprise and still allow converting old configurations. Advantage is, the parsing is already part of the tool, so sliding a check in that disables the erroring if the argument was set, seems like a very small change