From b146db6519625888775098a47d7a7326fe5c85c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Herbel?= Date: Thu, 21 Nov 2024 16:50:02 +0100 Subject: [PATCH] Migrate setup step that unpacks managed robots This was the last step to migrate. CMK-20352 --- src/bin/scheduler/main.rs | 10 +-- src/bin/scheduler/setup/mod.rs | 1 - src/bin/scheduler/setup/steps/mod.rs | 1 + src/bin/scheduler/setup/steps/run.rs | 7 +- .../setup/{ => steps}/unpack_managed.rs | 75 +++++++++++-------- src/results.rs | 1 - 6 files changed, 48 insertions(+), 47 deletions(-) rename src/bin/scheduler/setup/{ => steps}/unpack_managed.rs (70%) diff --git a/src/bin/scheduler/main.rs b/src/bin/scheduler/main.rs index dc2e9ad1..17ac859a 100644 --- a/src/bin/scheduler/main.rs +++ b/src/bin/scheduler/main.rs @@ -66,17 +66,9 @@ fn run() -> Result<(), Terminate> { write_phase(&SchedulerPhase::Setup, &global_config)?; let (plans, setup_failures) = setup::steps::run::run(&global_config, plans)?; + write_setup_failures(setup_failures.into_iter(), &global_config)?; info!("Setup steps completed"); - write_phase(&SchedulerPhase::ManagedRobots, &global_config)?; - let (plans, unpacking_managed_failures) = setup::unpack_managed::setup(plans); - info!("Managed robot setup completed"); - - write_setup_failures( - setup_failures.into_iter().chain(unpacking_managed_failures), - &global_config, - )?; - if global_config.cancellation_token.is_cancelled() { info!("Terminated"); return Ok(()); diff --git a/src/bin/scheduler/setup/mod.rs b/src/bin/scheduler/setup/mod.rs index 482443e0..9b9474d0 100644 --- a/src/bin/scheduler/setup/mod.rs +++ b/src/bin/scheduler/setup/mod.rs @@ -2,5 +2,4 @@ pub mod base_directories; mod fs_entries; mod ownership; pub mod steps; -pub mod unpack_managed; mod windows_permissions; diff --git a/src/bin/scheduler/setup/steps/mod.rs b/src/bin/scheduler/setup/steps/mod.rs index cb313a99..cefa9ecb 100644 --- a/src/bin/scheduler/setup/steps/mod.rs +++ b/src/bin/scheduler/setup/steps/mod.rs @@ -2,6 +2,7 @@ mod api; mod directories; mod rcc; pub mod run; +mod unpack_managed; use crate::internal_config::Plan; use robotmk::session::Session; diff --git a/src/bin/scheduler/setup/steps/run.rs b/src/bin/scheduler/setup/steps/run.rs index dd8ff1fc..3e29fd39 100644 --- a/src/bin/scheduler/setup/steps/run.rs +++ b/src/bin/scheduler/setup/steps/run.rs @@ -1,5 +1,5 @@ use super::api::{run_steps, SetupStep}; -use super::{directories, rcc}; +use super::{directories, rcc, unpack_managed}; use crate::internal_config::{sort_plans_by_grouping, GlobalConfig, Plan}; use robotmk::results::SetupFailure; use robotmk::termination::Cancelled; @@ -29,9 +29,9 @@ pub fn run( type Gatherer = fn(&GlobalConfig, Vec) -> Vec<(Box, Vec)>; #[cfg(unix)] -type Steps = [Gatherer; 10]; +type Steps = [Gatherer; 11]; #[cfg(windows)] -type Steps = [Gatherer; 16]; +type Steps = [Gatherer; 17]; const STEPS: Steps = [ directories::gather_managed_directories, @@ -56,4 +56,5 @@ const STEPS: Steps = [ #[cfg(windows)] rcc::gather_enable_rcc_long_path_support, rcc::gather_disable_rcc_shared_holotree, + unpack_managed::gather, ]; diff --git a/src/bin/scheduler/setup/unpack_managed.rs b/src/bin/scheduler/setup/steps/unpack_managed.rs similarity index 70% rename from src/bin/scheduler/setup/unpack_managed.rs rename to src/bin/scheduler/setup/steps/unpack_managed.rs index 3fbb5bb0..dda9fd17 100644 --- a/src/bin/scheduler/setup/unpack_managed.rs +++ b/src/bin/scheduler/setup/steps/unpack_managed.rs @@ -1,55 +1,64 @@ -use crate::internal_config::{Plan, Source}; +use super::api::{self, skip, SetupStep, StepWithPlans}; +use crate::internal_config::{GlobalConfig, Plan, Source}; use anyhow::Context; -use camino::Utf8Path; +use camino::{Utf8Path, Utf8PathBuf}; use flate2::read::GzDecoder; -use log::{error, info}; -use robotmk::results::SetupFailure; +use log::info; use std::fs::File; use tar::Archive; const SIZE_LIMIT: u64 = 50 * 1024 * 1024; -pub fn setup(plans: Vec) -> (Vec, Vec) { - let mut surviving_plans = Vec::new(); - let mut failures = vec![]; - for plan in plans.into_iter() { - if let Source::Managed { - tar_gz_path, - target, - .. - } = &plan.source - { - if let Err(error) = unpack_into(tar_gz_path, target, SIZE_LIMIT) { - error!( - "Plan {}: Failed to unpack managed source archive. Plan won't be scheduled. - Error: {error:?}", - plan.id - ); - failures.push(SetupFailure { - plan_id: plan.id.clone(), - summary: "Failed to unpack managed source archive".to_string(), - details: format!("{error:?}"), - }); - continue; +pub fn gather(_config: &GlobalConfig, plans: Vec) -> Vec { + let mut steps: Vec = vec![]; + let mut manual_robots = vec![]; + for plan in plans { + match &plan.source { + Source::Managed { + tar_gz_path, + target, + .. + } => steps.push(( + Box::new(StepUnpackManaged { + tar_gz_path: tar_gz_path.clone(), + target_dir: target.clone(), + size_limit: SIZE_LIMIT, + }), + vec![plan], + )), + Source::Manual => { + manual_robots.push(plan); } - info!("Unpacked {} into `{}`.", tar_gz_path, target); } - surviving_plans.push(plan); } - (surviving_plans, failures) + steps.push(skip(manual_robots)); + steps +} + +struct StepUnpackManaged { + tar_gz_path: Utf8PathBuf, + target_dir: Utf8PathBuf, + size_limit: u64, +} + +impl SetupStep for StepUnpackManaged { + fn setup(&self) -> Result<(), api::Error> { + unpack_into(&self.tar_gz_path, &self.target_dir, &self.size_limit) + .map_err(|err| api::Error::new("Failed to unpack managed robot archive".into(), err)) + } } fn unpack_into( tar_gz_path: &Utf8Path, target_path: &Utf8Path, - size_limit: u64, + size_limit: &u64, ) -> anyhow::Result<()> { info!("Extracting archive \"{tar_gz_path}\""); // We have to open the archive twice. Re-using the already opened archive for extraction does // not work. let archive_size = sum_up_size_of_archive_entries(&mut open_tar_gz_archive(tar_gz_path)?) .context("Failed to compute archive size")?; - if archive_size > size_limit { + if archive_size > *size_limit { anyhow::bail!(format!( "Archive size exceeds limit: {archive_size} B > {size_limit} B" )) @@ -100,7 +109,7 @@ mod tests { let archive_path = temp_dir_path.join("archive.tar.gz"); archive_directory(&dir_to_be_archived, &archive_path, "archived")?; - unpack_into(&archive_path, &temp_dir_path, 1024)?; + unpack_into(&archive_path, &temp_dir_path, &1024)?; assert_eq!( String::from_utf8(fs::read(temp_dir_path.join("archived").join("file.txt"))?)?, @@ -121,7 +130,7 @@ mod tests { let archive_path = temp_dir_path.join("archive.tar.gz"); archive_directory(&dir_to_be_archived, &archive_path, "archived")?; - let error = unpack_into(&archive_path, &temp_dir_path, 1).unwrap_err(); + let error = unpack_into(&archive_path, &temp_dir_path, &1).unwrap_err(); assert!(format!("{error:?}").contains("Archive size exceeds limit: 6 B > 1 B")); Ok(()) diff --git a/src/results.rs b/src/results.rs index 4e8067a2..6f654544 100644 --- a/src/results.rs +++ b/src/results.rs @@ -14,7 +14,6 @@ pub fn plan_results_directory(results_directory: &Utf8Path) -> Utf8PathBuf { #[derive(Serialize)] pub enum SchedulerPhase { - ManagedRobots, GracePeriod(u64), Setup, EnvironmentBuilding,