diff --git a/src/deb/local.rs b/src/deb/local.rs index 782a8e7..138f053 100644 --- a/src/deb/local.rs +++ b/src/deb/local.rs @@ -246,12 +246,33 @@ pub async fn build( if let Some(pocket_name) = pocket { let pocket_suite = format!("{series}-{pocket_name}"); log::info!("Enabling pocket '{}' for build dependencies", pocket_suite); - for source in &mut sources { - if crate::deb::is_archive_source_pinned(&source.uri, mirror) - && !source.suite.contains(&pocket_suite) - { - source.suite.push(pocket_suite.clone()); - modified = true; + + // Debian serves security updates from a dedicated archive: appending + // the suite to the main mirror would 404 on 'apt-get update' (ubuntu + // serves every pocket from the same archive, where appending works) + let security_archive = sources.iter().position(|source| { + source.uri.contains("deb.debian.org/debian") + && !source.uri.contains("debian-security") + && source.suite.iter().any(|suite| suite == series) + }); + if pocket_name == "security" + && let Some(index) = security_archive + { + let mut security = sources[index].clone(); + security.uri = sources[index] + .uri + .replace("deb.debian.org/debian", "deb.debian.org/debian-security"); + security.suite = vec![pocket_suite.clone()]; + sources.push(security); + modified = true; + } else { + for source in &mut sources { + if crate::deb::is_archive_source_pinned(&source.uri, mirror) + && !source.suite.contains(&pocket_suite) + { + source.suite.push(pocket_suite.clone()); + modified = true; + } } } diff --git a/src/deb/mod.rs b/src/deb/mod.rs index 7c76889..e34f1dc 100644 --- a/src/deb/mod.rs +++ b/src/deb/mod.rs @@ -319,6 +319,29 @@ async fn build_binary_package_impl( log::info!("Suite '{}' resolved to series {}", series, codename); series = codename; } + // A changelog may also target a pocket suite ('trixie-security') rather + // than the bare series: split the pocket off so the build resolves + // against the base series with that pocket enabled — the same target an + // explicit '-s trixie -p security' names. An explicit --pocket wins. + // The pocket must be one of the base series' distro-info pockets, which + // also guards against series names merely containing a dash. + let mut pocket = pocket.clone(); + if pocket.is_none() + && let Some((base, pocket_name)) = series + .rsplit_once('-') + .map(|(b, p)| (b.to_string(), p.to_string())) + && let Ok(dist) = crate::distro_info::get_dist_from_series(&base).await + && let Ok(pockets) = crate::distro_info::get_dist_pockets(&dist) + && pockets.iter().any(|p| p.as_str() == pocket_name) + { + pocket = Some(pocket_name.clone()); + series = base; + log::info!( + "Pocket suite resolved to series {} (pocket {})", + series, + pocket_name + ); + } let series = series.as_str(); let current_arch = crate::get_current_arch(); let arch = arch.as_deref().unwrap_or(¤t_arch);