apt: query the Launchpad PPA API through the shared HTTP client
This commit is contained in:
+28
-20
@@ -198,7 +198,12 @@ fn validate_keyring_dir(dir_uid: u32, mode: u32, euid: u32) -> Result<(), String
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Download and import a PPA key using Launchpad API
|
/// Download and import a PPA key using the Launchpad API
|
||||||
|
///
|
||||||
|
/// The signing key fingerprint is looked up through the shared HTTP client;
|
||||||
|
/// the key itself is fetched from the keyserver with curl through the
|
||||||
|
/// context, because the key file must land in the context's filesystem
|
||||||
|
/// (which may be remote).
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
/// * `ctx` - Optional context to use
|
/// * `ctx` - Optional context to use
|
||||||
@@ -229,33 +234,36 @@ pub async fn download_trust_ppa_key(
|
|||||||
ppa_name
|
ppa_name
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get PPA information from Launchpad API to get signing key fingerprint
|
// Get PPA information from the Launchpad API to get the signing key
|
||||||
// Use the correct devel API endpoint
|
// fingerprint. The query is context-independent metadata, so it goes
|
||||||
let api_url = format!(
|
// through the shared HTTP client (timeouts, retries) rather than
|
||||||
"https://api.launchpad.net/1.0/~{}/+archive/ubuntu/{}",
|
// shelling out to curl.
|
||||||
ppa_owner, ppa_name
|
let api_url = crate::launchpad::archive_url(ppa_owner, ppa_name);
|
||||||
);
|
|
||||||
log::debug!("Querying Launchpad API: {}", api_url);
|
log::debug!("Querying Launchpad API: {}", api_url);
|
||||||
|
|
||||||
let api_response = ctx
|
let response = distro_info::http_get_retried(&api_url).await.map_err(|e| {
|
||||||
.command("curl")
|
format!(
|
||||||
.arg("-s")
|
"Failed to query Launchpad API for PPA {}/{}: {}",
|
||||||
.arg("-f")
|
ppa_owner, ppa_name, e
|
||||||
.arg("-H")
|
)
|
||||||
.arg("Accept: application/json")
|
})?;
|
||||||
.arg(&api_url)
|
if !response.status().is_success() {
|
||||||
.output()?;
|
|
||||||
|
|
||||||
if !api_response.status.success() {
|
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"Failed to query Launchpad API for PPA {}/{}",
|
"Failed to query Launchpad API for PPA {}/{}: HTTP {}",
|
||||||
ppa_owner, ppa_name
|
ppa_owner,
|
||||||
|
ppa_name,
|
||||||
|
response.status()
|
||||||
)
|
)
|
||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the JSON response to extract the signing key fingerprint
|
// Parse the JSON response to extract the signing key fingerprint
|
||||||
let api_response_str = String::from_utf8_lossy(&api_response.stdout);
|
let api_response_str = response.text().await.map_err(|e| {
|
||||||
|
format!(
|
||||||
|
"Failed to read the Launchpad API response for PPA {}/{}: {}",
|
||||||
|
ppa_owner, ppa_name, e
|
||||||
|
)
|
||||||
|
})?;
|
||||||
let ppa_response: LaunchpadPpaResponse =
|
let ppa_response: LaunchpadPpaResponse =
|
||||||
serde_json::from_str(&api_response_str).map_err(|e| {
|
serde_json::from_str(&api_response_str).map_err(|e| {
|
||||||
format!(
|
format!(
|
||||||
|
|||||||
+3
-2
@@ -92,8 +92,9 @@ fn person_url(user: &str) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// URL of the Launchpad API resource of a PPA (`~user/+archive/ubuntu/name`
|
/// URL of the Launchpad API resource of a PPA (`~user/+archive/ubuntu/name`
|
||||||
/// covers the default `ppa` archive and named archives alike)
|
/// covers the default `ppa` archive and named archives alike); shared by the
|
||||||
fn archive_url(user: &str, ppa: &str) -> String {
|
/// put-side pre-flight checks and the apt keyring's fingerprint lookup
|
||||||
|
pub(crate) fn archive_url(user: &str, ppa: &str) -> String {
|
||||||
format!("{API_BASE}/~{user}/+archive/ubuntu/{ppa}")
|
format!("{API_BASE}/~{user}/+archive/ubuntu/{ppa}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user