diff --git a/.github/ISSUE_TEMPLATE/sandbox-limits-increase-request.md b/.github/ISSUE_TEMPLATE/sandbox-limits-increase-request.md index b10c60b0d..53c63d01c 100644 --- a/.github/ISSUE_TEMPLATE/sandbox-limits-increase-request.md +++ b/.github/ISSUE_TEMPLATE/sandbox-limits-increase-request.md @@ -16,5 +16,6 @@ assignees: '' **Requested RAM limit:** **Requested timeout:** +**Requested number of targets:** **Why your crate needs the resource increases:** diff --git a/src/db/migrate.rs b/src/db/migrate.rs index 59e72dbda..a85b6c959 100644 --- a/src/db/migrate.rs +++ b/src/db/migrate.rs @@ -296,6 +296,17 @@ fn migrate_inner(version: Option, conn: &Connection, apply_mode: ApplyM "ALTER TABLE releases ALTER COLUMN default_target DROP NOT NULL; ALTER TABLE releases ALTER COLUMN default_target DROP DEFAULT", ), + migration!( + context, + // version + 9, + // description + "Allow max number of targets to be overriden", + // upgrade query + "ALTER TABLE sandbox_overrides ADD COLUMN max_targets INT;", + // downgrade query + "ALTER TABLE sandbox_overrides DROP COLUMN max_targets;" + ), ]; for migration in migrations { diff --git a/src/docbuilder/limits.rs b/src/docbuilder/limits.rs index 6248f3416..a893e45f6 100644 --- a/src/docbuilder/limits.rs +++ b/src/docbuilder/limits.rs @@ -5,6 +5,7 @@ use std::time::Duration; pub(crate) struct Limits { memory: usize, + targets: usize, timeout: Duration, networking: bool, max_log_size: usize, @@ -15,6 +16,7 @@ impl Default for Limits { Self { memory: 3 * 1024 * 1024 * 1024, // 3 GB timeout: Duration::from_secs(15 * 60), // 15 minutes + targets: 10, networking: false, max_log_size: 100 * 1024, // 100 KB } @@ -37,6 +39,9 @@ impl Limits { if let Some(timeout) = row.get::<_, Option>("timeout_seconds") { limits.timeout = Duration::from_secs(timeout as u64); } + if let Some(targets) = row.get::<_, Option>("max_targets") { + limits.targets = targets as usize; + } } Ok(limits) @@ -58,6 +63,10 @@ impl Limits { self.max_log_size } + pub(crate) fn targets(&self) -> usize { + self.targets + } + pub(crate) fn for_website(&self) -> BTreeMap { let time_scale = |v| scale(v, 60, &["seconds", "minutes", "hours"]); let size_scale = |v| scale(v, 1024, &["bytes", "KB", "MB", "GB"]); @@ -74,6 +83,7 @@ impl Limits { } else { res.insert("Network access".into(), "blocked".into()); } + res.insert("Maximum number of build targets".into(), self.targets.to_string()); res } } diff --git a/src/docbuilder/rustwide_builder.rs b/src/docbuilder/rustwide_builder.rs index 81298edcc..574304a24 100644 --- a/src/docbuilder/rustwide_builder.rs +++ b/src/docbuilder/rustwide_builder.rs @@ -130,6 +130,9 @@ impl RustwideBuilder { // // Removing it beforehand works fine, and prevents rustup from blocking the update later in // the method. + // + // Note that this means that non tier-one targets will be uninstalled on every update, + // and will not be reinstalled until explicitly requested by a crate. for target in installed_targets { if !targets_to_install.remove(&target) { self.toolchain.remove_target(&self.workspace, &target)?; @@ -351,7 +354,8 @@ impl RustwideBuilder { successful_targets.push(res.target.clone()); // Then build the documentation for all the targets - for target in other_targets { + // Limit the number of targets so that no one can try to build all 200000 possible targets + for target in other_targets.into_iter().take(limits.targets()) { debug!("building package {} {} for {}", name, version, target); self.build_target( target, @@ -453,6 +457,11 @@ impl RustwideBuilder { } let mut cargo_args = vec!["doc".to_owned(), "--lib".to_owned(), "--no-deps".to_owned()]; if target != HOST_TARGET { + // If the explicit target is not a tier one target, we need to install it. + if !TARGETS.contains(&target) { + // This is a no-op if the target is already installed. + self.toolchain.add_target(&self.workspace, target)?; + } cargo_args.push("--target".to_owned()); cargo_args.push(target.to_owned()); }; diff --git a/templates/about.hbs b/templates/about.hbs index a6404c0ee..bd52de966 100644 --- a/templates/about.hbs +++ b/templates/about.hbs @@ -153,18 +153,20 @@ no-default-features = true # Target to test build on, used as the default landing page (default: "x86_64-unknown-linux-gnu") # -# Available targets: +# Any target supported by rustup can be used. +default-target = "x86_64-unknown-linux-gnu" + +# Targets to build (default: see below) +# +# Any target supported by rustup can be used. +# +# Default targets: # - x86_64-unknown-linux-gnu # - x86_64-apple-darwin # - x86_64-pc-windows-msvc # - i686-unknown-linux-gnu -# - i686-apple-darwin # - i686-pc-windows-msvc -default-target = "x86_64-unknown-linux-gnu" - -# Targets to build (default: all tier 1 targets) # -# Same available targets as `default-target`. # Set this to `[]` to only build the default target. # # If `default-target` is unset, the first element of `targets` is treated as the default target.