Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #23585: Port the index and database parsing of rudder-package in rust #5102

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 133 additions & 0 deletions relay/sources/rudder-pkg/rust/rudder-package/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions relay/sources/rudder-pkg/rust/rudder-package/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
amousset marked this conversation as resolved.
Show resolved Hide resolved
name = "rudder-package"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.75"
ar = "0.9.0"
pretty_assertions = "1.4.0"
serde = { version = "1.0.189", features = ["derive"] }
serde_json = "1.0.107"
serde_toml = "0.0.1"
149 changes: 149 additions & 0 deletions relay/sources/rudder-pkg/rust/rudder-package/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
use std::{
collections::HashMap,
fs::File,
io::{Read},
str,
};
use ar::Archive;
use anyhow::{Result, Context};

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct PluginMetadata {
#[serde(rename(serialize = "type", deserialize = "type"))]
Fdall marked this conversation as resolved.
Show resolved Hide resolved
plugin_type: String,
name: String,
version: String,
#[serde(rename(serialize = "build-date", deserialize = "build-date"))]
build_date: String,
depends: Option<InstalledPluginDependency>,
#[serde(rename(serialize = "build-commit", deserialize = "build-commit"))]
build_commit: String,
content: HashMap<String, String>,
#[serde(rename(serialize = "jar-files", deserialize = "jar-files"))]
jar_files: Option<Vec<String>>,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct RepoIndex(Vec<PluginInRepoIndex>);

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct PluginInRepoIndex {
path: String,

#[serde(flatten)]
metadata: PluginMetadata,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct InstalledPluginDatabase {
plugins: HashMap<String, InstalledPlugin>,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct InstalledPlugin {
files: Vec<String>,

#[serde(flatten)]
metadata: PluginMetadata,
}

#[derive(Serialize, Deserialize, PartialEq, Eq, Debug)]
struct InstalledPluginDependency {
python: Option<Vec<String>>,
amousset marked this conversation as resolved.
Show resolved Hide resolved
binary: Option<Vec<String>>,
apt: Option<Vec<String>>,
rpm: Option<Vec<String>>,
}

fn read_rpkg_metadata(path: String) -> Result<PluginMetadata>{
let p = &path;
let mut archive = Archive::new(File::open(p).unwrap());
while let Some(entry_result) = archive.next_entry() {
let mut entry = entry_result.unwrap();
let mut buffer = String::new();
let entry_title = str::from_utf8(entry.header().identifier()).unwrap();
if entry_title == "metadata" {
let _ = entry.read_to_string(&mut buffer)?;
let m: PluginMetadata = serde_json::from_str(&buffer)
.with_context(|| format!("Failed to parse {} metadata", p))?;
return Ok(m)
};
};
return Err(anyhow::anyhow!("No metadata found in {}", p));
amousset marked this conversation as resolved.
Show resolved Hide resolved
}

fn main() {
let m = read_rpkg_metadata(String::from("/home/fdallidet/Downloads/rudder-plugin-aix-8.0.0~rc1-2.1.rpkg"));
println!("{:?}", m.unwrap());
}

#[cfg(test)]
mod tests {
use super::*;
use pretty_assertions::assert_eq;

#[test]
fn test_plugin_database_parsing() {
let data = fs::read_to_string("./tests/plugin_database_parsing.json").expect("Unable to parse file './tests/pluginèdatabase_parsing.json'");
let db: InstalledPluginDatabase = serde_json::from_str(&data).unwrap();
assert_eq!(db.plugins["rudder-plugin-aix"].metadata.plugin_type, "plugin");
}

#[test]
fn test_plugin_index_parsing() {
let data = fs::read_to_string("./tests/repo_index.json").expect("Unable to parse file './tests/repo_index.json'");
let index: RepoIndex = serde_json::from_str(&data).unwrap();
let expected = RepoIndex {
0: vec!(
PluginInRepoIndex {
metadata: PluginMetadata {
plugin_type: String::from("plugin"),
name: String::from("rudder-plugin-aix"),
version: String::from("8.0.0~beta2-2.1"),
build_date: String::from("2023-09-14T14:31:35+00:00"),
build_commit: String::from("2198ca7c0aa0a4e19f04e0ace099520371641f92"),
content: HashMap::from([
(String::from("files.txz"), String::from("/opt/rudder/share/plugins")),
]),
depends: None,
jar_files: Some(vec![String::from("/opt/rudder/share/plugins/aix/aix.jar")]),
},
path: String::from("./8.0/aix/release/rudder-plugin-aix-8.0.0~beta2-2.1.rpkg"),
},
PluginInRepoIndex {
metadata: PluginMetadata {
plugin_type: String::from("plugin"),
name: String::from("rudder-plugin-aix"),
version: String::from("8.0.0~rc1-2.1"),
build_date: String::from("2023-10-13T09:44:54+00:00"),
build_commit: String::from("cdcf8a4b01124b9b309903cafd95b3a161a9c35c"),
content: HashMap::from([
(String::from("files.txz"), String::from("/opt/rudder/share/plugins")),
]),
depends: None,
jar_files: Some(vec![String::from("/opt/rudder/share/plugins/aix/aix.jar")]),
},
path: String::from("./8.0/aix/rudder-plugin-aix-8.0.0~rc1-2.1.rpkg/release/rudder-plugin-aix-8.0.0~rc1-2.1.rpkg"),
},
PluginInRepoIndex {
metadata: PluginMetadata {
plugin_type: String::from("plugin"),
name: String::from("rudder-plugin-vault"),
version: String::from("8.0.0~rc1-2.1-nightly"),
build_date: String::from("2023-10-07T20:38:18+00:00"),
build_commit: String::from("747126d505b3cac0403014cf35a4caf3a3ec886f"),
content: HashMap::from([
(String::from("files.txz"), String::from("/opt/rudder/")),
]),
depends: None,
jar_files: None,
},
path: String::from("./8.0/rudder-plugin-vault-8.0.0~rc1-2.1-nightly.rpkg/nightly/rudder-plugin-vault-8.0.0~rc1-2.1-nightly.rpkg"),
},
)
};
assert_eq!(expected, index);
}
}
Loading