linkdd / tricorder

Automation the KISS way
https://linkdd.github.io/tricorder/
MIT License
53 stars 5 forks source link

:memo: :bug: Module docs don't compile or match function signatures #38

Open cameronelliott opened 2 months ago

cameronelliott commented 2 months ago

The docs example for modules isn't really functional.

The example passes in Json as the 2nd param to module::Tasks::new(), but it doesn't take Json as the 2nd param, it takes a path.

I wrote a functional example like this:

use serde_json::json;
use tricorder::prelude::*;
use tricorder::tasks::module;

const MODULE_FILE: &str = r#"
#!/bin/bash
read -r data
echo echo output: "$data"
"#;

const DATA_FILE: &str = r#"
{
    "data": "data_from_file"
}
"#;

const BINARY_PATH: &str = "/tmp/module.sh";
const DATA_PATH: &str = "/tmp/data_file.json";

fn main() {
    //write the module file

    std::fs::write(BINARY_PATH, MODULE_FILE).unwrap();
    std::fs::write(DATA_PATH, DATA_FILE).unwrap();

    let inventory = Inventory::new()
        .add_host(
            Host::new(Host::id("localhost").unwrap(), "localhost:22".to_string())
                .set_user("root".to_string())
                .add_tag(Host::tag("local").unwrap())
                .set_var("msg".to_string(), json!("hello"))
                .set_var(
                    "module_mod".to_string(),
                    json!({"overwrittendata":"data_from_var1", "vardata":"data_from_var2"}),
                )
                .to_owned(),
        )
        .to_owned();

    let task = module::Task::new(Some(DATA_PATH.to_string()), BINARY_PATH.to_string());

    let result = inventory.hosts.run_task_seq(&task).unwrap();

    println!("{:#?}", result);
}

It's not clear to me how the variable overwritting or passing works.

linkdd commented 2 months ago

Hello,

Thanks for the report, I don't have a lot of free time recently (work + buying a house) to look into it in details.

If @Spiegie (the original author of this feature) can take a look that would be great, otherwise, this will have to wait a few weeks until my super busy schedule clears 🙂

Spiegie commented 1 month ago

sorry I dont think, I can make time for this issue. I hope I can make it faster than you @linkdd but not any time soon. I'll look into it as fast as I can.

Spiegie commented 1 month ago

I reproduced it and thank you very much for reporting this Issue.

Yes the overwriteing of Variables does not work intuitively and the Docs are very bad and not correct. I'm sorry for that.

Right now, you can overwrite the data by naming the variable module_. module_name is the filename (the last bit after the last /) of the module you provide in "BINARY_PATH" in your case the module_name is "module.sh" so the variable holding the data overwriteing the file-data should be named module_module.sh

You can see that in the source-code in src/tasks/module.rs line 98-100. Here the Data gets merged.

Your Code should work like this:

use serde_json::json;
use tricorder::prelude::*;
use tricorder::tasks::module;

const MODULE_FILE: &str = r#"
#!/bin/bash
read -r data
echo echo output: "$data"
"#;

const DATA_FILE: &str = r#"
{
    "data": "data_from_file"
}
"#;

const BINARY_PATH: &str = "/tmp/module.sh";
const DATA_PATH: &str = "/tmp/data_file.json";

fn main() {
    //write the module file

    std::fs::write(BINARY_PATH, MODULE_FILE).unwrap();
    std::fs::write(DATA_PATH, DATA_FILE).unwrap();

    let inventory = Inventory::new()
        .add_host(
            Host::new(Host::id("localhost").unwrap(), "localhost:22".to_string())
                .set_user("root".to_string())
                .add_tag(Host::tag("local").unwrap())
                .set_var("msg".to_string(), json!("hello"))
                .set_var(
                    "module_module.sh".to_string(),
                    json!({"overwrittendata":"data_from_var1", "vardata":"data_from_var2"}),
                )
                .to_owned(),
        )
        .to_owned();

    let task = module::Task::new(Some(DATA_PATH.to_string()), BINARY_PATH.to_string());

    let result = inventory.hosts.run_task_seq(&task).unwrap();

    println!("{:#?}", result);
}

I know this is not very clear. I'll try to refactor the Code or at least the documentation if I dont find a good solution. But im sure, there is a way better solution than the current one.