fix(agent): import JRE from offline bundle

This commit is contained in:
zipg
2026-07-13 22:20:58 +08:00
committed by GitHub
parent c81eda22b0
commit c02b3967df
2 changed files with 86 additions and 1 deletions
+8 -1
View File
@@ -1239,6 +1239,7 @@ pub fn import_offline_zip(
let registry = read_registry_from_zip(&mut archive)?;
let platform = AgentManager::current_platform();
std::fs::create_dir_all(am.base_dir()).map_err(|e| format!("Failed to create agent directory: {e}"))?;
let mut local_state = am.load_state();
let mut result =
OfflineImportResult { jre_installed: Vec::new(), drivers_installed: Vec::new(), drivers_skipped: Vec::new() };
@@ -1375,7 +1376,7 @@ fn read_registry_from_zip(archive: &mut zip::ZipArchive<std::fs::File>) -> Resul
fn extract_jre_key_from_filename(name: &str) -> Option<String> {
let filename = name.rsplit('/').next()?;
let rest = filename.strip_prefix("jre-")?;
let rest = filename.strip_prefix("dbx-jre-").or_else(|| filename.strip_prefix("jre-"))?;
let key = rest.split('-').next()?;
if key.is_empty() {
return None;
@@ -1442,6 +1443,12 @@ mod agent_download_url_tests {
"agents/drivers/dbx-agent-h2.jar?mirror=r2&v=0.5.33"
);
}
#[test]
fn offline_jre_filename_parser_accepts_release_and_legacy_names() {
assert_eq!(extract_jre_key_from_filename("jre/dbx-jre-21-macos-aarch64.tar.gz").as_deref(), Some("21"));
assert_eq!(extract_jre_key_from_filename("jre/jre-21-macos-aarch64.tar.gz").as_deref(), Some("21"));
}
}
#[cfg(test)]
+78
View File
@@ -491,6 +491,26 @@ fn offline_zip_import_emits_progress_and_updates_state() {
assert!(events.iter().any(|event| event.step == "driver" && event.db_type.as_deref() == Some("H2")));
}
#[test]
fn offline_zip_import_installs_release_named_jre() {
let manager = test_manager("offline-release-jre");
let zip_path = test_path("offline-release-jre-zip").join("agents.zip");
std::fs::create_dir_all(zip_path.parent().unwrap()).unwrap();
write_offline_driver_zip_with_jre(&zip_path, "h2", "0.2.0", "21.0.12");
let events = std::sync::Mutex::new(Vec::new());
let result = import_agents_from_zip(&manager, &zip_path, |event| {
events.lock().unwrap().push(event);
})
.unwrap();
assert_eq!(result.jre_installed, vec![DEFAULT_JRE_KEY]);
assert_eq!(result.drivers_installed, vec!["h2"]);
assert!(manager.is_jre_installed(DEFAULT_JRE_KEY));
assert_eq!(manager.load_state().jre_versions.get(DEFAULT_JRE_KEY).map(String::as_str), Some("21.0.12"));
assert!(events.lock().unwrap().iter().any(|event| event.step == "jre-extract"));
}
#[test]
fn offline_zip_import_rejects_corrupt_jar() {
let manager = test_manager("offline-corrupt-driver");
@@ -509,6 +529,64 @@ fn write_offline_driver_zip(path: &std::path::Path, db_type: &str, version: &str
write_offline_driver_zip_with_jar(path, db_type, version, test_agent_jar_bytes());
}
fn write_offline_driver_zip_with_jre(path: &std::path::Path, db_type: &str, version: &str, jre_version: &str) {
let file = std::fs::File::create(path).unwrap();
let mut zip = zip::ZipWriter::new(file);
let options = zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored);
let jar = test_agent_jar_bytes();
let jre_archive = test_jre_archive_bytes();
let registry = serde_json::json!({
"jres": {
DEFAULT_JRE_KEY: {
"version": jre_version,
"platforms": {}
}
},
"drivers": {
db_type: {
"version": version,
"label": db_type,
"min_app_version": "0.1.0",
"jre": DEFAULT_JRE_KEY,
"jar": { "url": format!("https://example.com/dbx-agent-{db_type}.jar"), "size": jar.len() }
}
}
});
zip.start_file("agent-registry.json", options).unwrap();
std::io::Write::write_all(&mut zip, registry.to_string().as_bytes()).unwrap();
zip.start_file(format!("jre/dbx-jre-{DEFAULT_JRE_KEY}-{}.tar.gz", AgentManager::current_platform()), options)
.unwrap();
std::io::Write::write_all(&mut zip, &jre_archive).unwrap();
zip.start_file(format!("drivers/dbx-agent-{db_type}.jar"), options).unwrap();
std::io::Write::write_all(&mut zip, &jar).unwrap();
zip.finish().unwrap();
}
fn test_jre_archive_bytes() -> Vec<u8> {
let root = test_path("jre-archive");
let runtime_root = root.join("dbx-jre");
let bin_dir = runtime_root.join("bin");
let archive = root.join("jre.tar.gz");
std::fs::create_dir_all(&bin_dir).unwrap();
std::fs::write(bin_dir.join("java"), b"java").unwrap();
std::fs::write(bin_dir.join("java.exe"), b"java").unwrap();
let status = std::process::Command::new("tar")
.arg("czf")
.arg(&archive)
.arg("-C")
.arg(&root)
.arg("dbx-jre")
.status()
.unwrap();
assert!(status.success());
let bytes = std::fs::read(&archive).unwrap();
std::fs::remove_dir_all(root).ok();
bytes
}
fn write_offline_driver_zip_with_jar(path: &std::path::Path, db_type: &str, version: &str, jar: Vec<u8>) {
let file = std::fs::File::create(path).unwrap();
let mut zip = zip::ZipWriter::new(file);