/// Acquire the necessary data to perform the update.
///
/// This includes fetching the update package, which contains the list of packages in the
/// target OS and kernel images that need written.
Acquire the necessary data to perform the update.
This includes fetching the update package, which contains the list of packages in the
target OS and kernel images that need written.
Acquire the necessary data to perform the update . This includes fetching the update package which contains the list of packages in the target OS and kernel images that need written .
async fn prepare(
        &mut self,
        target_version: &mut history::Version,
    ) -> Result<(UpdatePackage, UpdateMode, Vec<PkgUrl>, paver::CurrentConfiguration), PrepareError>
    {
        // Ensure that the partition boot metadata is ready for the update to begin. Specifically:
        // - the current configuration must be Healthy and Active, and
        // - the non-current configuration must be Unbootable.
        //
        // If anything goes wrong, abort the update. See the comments in
        // `prepare_partition_metadata` for why this is justified.
        //
        // We do this here rather than just before we write images because this location allows us
        // to "unstage" a previously staged OS in the non-current configuration that would otherwise
        // become active on next reboot. If we moved this to just before writing images, we would be
        // susceptible to a bug of the form:
        // - A is active/current running system version 1.
        // - Stage an OTA of version 2 to B, B is now marked active. Defer reboot.
        // - Start to stage a new OTA (version 3). Fetch packages encounters an error after fetching
        //   half of the updated packages.
        // - Retry the attempt for the new OTA (version 3). This GC may delete packages from the
        //   not-yet-booted system (version 2).
        // - Interrupt the update attempt, reboot.
        // - System attempts to boot to B (version 2), but the packages are not all present anymore
        let current_config = paver::prepare_partition_metadata(&self.env.boot_manager)
            .await
            .map_err(PrepareError::PreparePartitionMetdata)?;
        if let Err(e) = gc(&self.env.space_manager).await {
            fx_log_err!("unable to gc packages (1/2): {:#}", anyhow!(e));
        }
        let update_pkg =
            resolver::resolve_update_package(&self.env.pkg_resolver, &self.config.update_url)
                .await
                .map_err(PrepareError::ResolveUpdate)?;
        *target_version = history::Version::for_update_package(&update_pkg).await;
        let () = update_pkg.verify_name().await.map_err(PrepareError::VerifyName)?;
        if let Err(e) = gc(&self.env.space_manager).await {
            fx_log_err!("unable to gc packages (2/2): {:#}", anyhow!(e));
        }
        let mode = update_mode(&update_pkg).await.map_err(PrepareError::ParseUpdateMode)?;
        match mode {
            UpdateMode::Normal => {}
            UpdateMode::ForceRecovery => {
                if !self.config.should_write_recovery {
                    return Err(PrepareError::VerifyUpdateMode);
                }
            }
        }
        verify_board(&self.env.build_info, &update_pkg).await.map_err(PrepareError::VerifyBoard)?;
        let packages_to_fetch = match mode {
            UpdateMode::Normal => {
                update_pkg.packages().await.map_err(PrepareError::ParsePackages)?
            }
            UpdateMode::ForceRecovery => vec![],
        };
        let () = validate_epoch(SOURCE_EPOCH_RAW, &update_pkg).await?;
        Ok((update_pkg, mode, packages_to_fetch, current_config))
    }
async fn prepare ( & mut self , target_version : & mut history :: Version , ) -> Result < ( UpdatePackage , UpdateMode , Vec < PkgUrl > , paver :: CurrentConfiguration ) , PrepareError > { // Ensure that the partition boot metadata is ready for the update to begin. Specifically: // - the current configuration must be Healthy and Active, and // - the non-current configuration must be Unbootable. // // If anything goes wrong, abort the update. See the comments in // `prepare_partition_metadata` for why this is justified. // // We do this here rather than just before we write images because this location allows us // to "unstage" a previously staged OS in the non-current configuration that would otherwise // become active on next reboot. If we moved this to just before writing images, we would be // susceptible to a bug of the form: // - A is active/current running system version 1. // - Stage an OTA of version 2 to B, B is now marked active. Defer reboot. // - Start to stage a new OTA (version 3). Fetch packages encounters an error after fetching //   half of the updated packages. // - Retry the attempt for the new OTA (version 3). This GC may delete packages from the //   not-yet-booted system (version 2). // - Interrupt the update attempt, reboot. // - System attempts to boot to B (version 2), but the packages are not all present anymore let current_config = paver :: prepare_partition_metadata ( & self . env . boot_manager ) . await . map_err ( PrepareError :: PreparePartitionMetdata ) ? ; if let Err ( e ) = gc ( & self . env . space_manager ) . await { fx_log_err ! ( " " anyhow ( e ) ) ; } let update_pkg = resolver :: resolve_update_package ( & self . env . pkg_resolver , & self . config . update_url ) . await . map_err ( PrepareError :: ResolveUpdate ) ? ; * target_version = history :: Version :: for_update_package ( & update_pkg ) . await ; let ( ) = update_pkg . verify_name ( ) . await . map_err ( PrepareError :: VerifyName ) ? ; if let Err ( e ) = gc ( & self . env . space_manager ) . await { fx_log_err ! ( " " anyhow ( e ) ) ; } let mode = update_mode ( & update_pkg ) . await . map_err ( PrepareError :: ParseUpdateMode ) ? ; match mode { UpdateMode :: Normal => { } UpdateMode :: ForceRecovery => { if ! self . config . should_write_recovery { return Err ( PrepareError :: VerifyUpdateMode ) ; } } } verify_board ( & self . env . build_info , & update_pkg ) . await . map_err ( PrepareError :: VerifyBoard ) ? ; let packages_to_fetch = match mode { UpdateMode :: Normal => { update_pkg . packages ( ) . await . map_err ( PrepareError :: ParsePackages ) ? } UpdateMode :: ForceRecovery => vec ! [ ] , } ; let ( ) = validate_epoch ( SOURCE_EPOCH_RAW , & update_pkg ) . await ? ; Ok ( ( update_pkg , mode , packages_to_fetch , current_config ) ) }
Acquire the necessary data to perform the update.
Acquire the necessary data to perform the update .
&mut self
target_version
&mut history::Version