pub async fn workload_rollout(mf: &Manifest, kube: &ShipKube) -> Result<bool> {
    use futures_timer::Delay;
    use indicatif::{ProgressBar, ProgressStyle};
    let minimum = mf.min_replicas();
    let waittime = mf.estimate_wait_time();
    let one_sec = std::time::Duration::from_millis(1000);

    match rollout_status(mf, kube, &None).await {
        Ok(rr) => {
            if rr.ok {
                return Ok(true);
            } else {
                debug!("Ignoring rollout failure right after upgrade")
            }
        }
        Err(e) => warn!("Ignoring rollout failure right after upgrade: {}", e),
    };

    Delay::new(one_sec).await;
    // TODO: Don't count until image has been pulled + handle unscheduleble - #96

    info!(
        "Waiting {}s for {:?} {} to rollout (not ready yet)",
        waittime, mf.workload, mf.name
    );
    let mut hash = None;
    match mf.workload {
        PrimaryWorkload::Deployment => {
            // Attempt to find an owning RS hash to track
            if let Some(rs) = kube.get_rs_from_deploy().await? {
                if let Some(meta) = rs.metadata {
                    if let Some(labels) = meta.labels {
                        if let Some(h) = labels.get("pod-template-hash") {
                            debug!("Tracking replicaset {} for {}", h, mf.name);
                            hash = Some(h.clone());
                        }
                    }
                }
            }
        }
        PrimaryWorkload::Statefulset => {
            // Attempt to find an owning revesion hash to track
            let sts = kube.get_statefulset().await?;
            let summary = StatefulSummary::try_from(sts)?;
            if let Some(ur) = summary.update_revision {
                debug!("Tracking statefulset {:?} for {}", ur, mf.name);
                hash = Some(ur);
            }
        }
    }

    // TODO: create progress bar above this fn so we can use MultiProgressBar in cluster.rs
    let pb = ProgressBar::new(minimum.into());
    pb.set_style(
        ProgressStyle::default_bar()
            .template("> {bar:40.green/black} {prefix} {pos}/{len} ({elapsed}) {msg}"),
    );
    pb.set_draw_delta(1);
    if let Some(h) = &hash {
        match mf.workload {
            PrimaryWorkload::Deployment => {
                pb.set_prefix(&format!("{}-{}", mf.name, h));
            }
            PrimaryWorkload::Statefulset => {
                pb.set_prefix(h); // statefulset hash already prefixes name
            }
        }
    } else {
        pb.set_prefix(&mf.name);
    }

    for i in 1..20 {
        trace!("poll iteration {}", i);
        let mut waited = 0;
        // sleep until 1/20th of estimated upgrade time and poll for status
        while waited < waittime / 20 {
            waited += 1;
            trace!("sleep 1s (waited {})", waited);
            Delay::new(one_sec).await;
        }
        let rr = rollout_status(mf, kube, &hash).await?;
        debug!("RR: {:?}", rr);
        if let Some(msg) = rr.message {
            pb.set_message(&msg);
        }
        pb.set_length(rr.expected.into()); // sometimes a replicaset resizes
        pb.set_position(rr.progress.into());
        if rr.ok {
            pb.finish_at_current_pos();
            return Ok(true);
        }
    }
    Ok(false) // timeout
}
/// Track the rollout of the main workload
Track the rollout of the main workload
Track the rollout of the main workload
pub async fn workload_rollout(mf: &Manifest, kube: &ShipKube) -> Result<bool> {
    use futures_timer::Delay;
    use indicatif::{ProgressBar, ProgressStyle};
    let minimum = mf.min_replicas();
    let waittime = mf.estimate_wait_time();
    let one_sec = std::time::Duration::from_millis(1000);
    match rollout_status(mf, kube, &None).await {
        Ok(rr) => {
            if rr.ok {
                return Ok(true);
            } else {
                debug!("Ignoring rollout failure right after upgrade")
            }
        }
        Err(e) => warn!("Ignoring rollout failure right after upgrade: {}", e),
    };
    Delay::new(one_sec).await;
    // TODO: Don't count until image has been pulled + handle unscheduleble - #96
    info!(
        "Waiting {}s for {:?} {} to rollout (not ready yet)",
        waittime, mf.workload, mf.name
    );
    let mut hash = None;
    match mf.workload {
        PrimaryWorkload::Deployment => {
            // Attempt to find an owning RS hash to track
            if let Some(rs) = kube.get_rs_from_deploy().await? {
                if let Some(meta) = rs.metadata {
                    if let Some(labels) = meta.labels {
                        if let Some(h) = labels.get("pod-template-hash") {
                            debug!("Tracking replicaset {} for {}", h, mf.name);
                            hash = Some(h.clone());
                        }
                    }
                }
            }
        }
        PrimaryWorkload::Statefulset => {
            // Attempt to find an owning revesion hash to track
            let sts = kube.get_statefulset().await?;
            let summary = StatefulSummary::try_from(sts)?;
            if let Some(ur) = summary.update_revision {
                debug!("Tracking statefulset {:?} for {}", ur, mf.name);
                hash = Some(ur);
            }
        }
    }
    // TODO: create progress bar above this fn so we can use MultiProgressBar in cluster.rs
    let pb = ProgressBar::new(minimum.into());
    pb.set_style(
        ProgressStyle::default_bar()
            .template("> {bar:40.green/black} {prefix} {pos}/{len} ({elapsed}) {msg}"),
    );
    pb.set_draw_delta(1);
    if let Some(h) = &hash {
        match mf.workload {
            PrimaryWorkload::Deployment => {
                pb.set_prefix(&format!("{}-{}", mf.name, h));
            }
            PrimaryWorkload::Statefulset => {
                pb.set_prefix(h); // statefulset hash already prefixes name
            }
        }
    } else {
        pb.set_prefix(&mf.name);
    }
    for i in 1..20 {
        trace!("poll iteration {}", i);
        let mut waited = 0;
        // sleep until 1/20th of estimated upgrade time and poll for status
        while waited < waittime / 20 {
            waited += 1;
            trace!("sleep 1s (waited {})", waited);
            Delay::new(one_sec).await;
        }
        let rr = rollout_status(mf, kube, &hash).await?;
        debug!("RR: {:?}", rr);
        if let Some(msg) = rr.message {
            pb.set_message(&msg);
        }
        pb.set_length(rr.expected.into()); // sometimes a replicaset resizes
        pb.set_position(rr.progress.into());
        if rr.ok {
            pb.finish_at_current_pos();
            return Ok(true);
        }
    }
    Ok(false) // timeout
}
pub async fn workload_rollout ( mf : & Manifest , kube : & ShipKube ) -> Result < bool > { use futures_timer :: Delay ; use indicatif :: { ProgressBar , ProgressStyle } ; let minimum = mf . min_replicas ( ) ; let waittime = mf . estimate_wait_time ( ) ; let one_sec = std :: time :: Duration :: from_millis ( 1000 ) ; match rollout_status ( mf , kube , & None ) . await { Ok ( rr ) => { if rr . ok { return Ok ( true ) ; } else { debug ! ( " " ) } } Err ( e ) => warn ! ( " " e ) , } ; Delay :: new ( one_sec ) . await ; // TODO: Don't count until image has been pulled + handle unscheduleble - #96 info ! ( " " waittime mf workload mf name ) ; let mut hash = None ; match mf . workload { PrimaryWorkload :: Deployment => { // Attempt to find an owning RS hash to track if let Some ( rs ) = kube . get_rs_from_deploy ( ) . await ? { if let Some ( meta ) = rs . metadata { if let Some ( labels ) = meta . labels { if let Some ( h ) = labels . get ( " " ) { debug ! ( " " h mf name ) ; hash = Some ( h . clone ( ) ) ; } } } } } PrimaryWorkload :: Statefulset => { // Attempt to find an owning revesion hash to track let sts = kube . get_statefulset ( ) . await ? ; let summary = StatefulSummary :: try_from ( sts ) ? ; if let Some ( ur ) = summary . update_revision { debug ! ( " " ur mf name ) ; hash = Some ( ur ) ; } } } // TODO: create progress bar above this fn so we can use MultiProgressBar in cluster.rs let pb = ProgressBar :: new ( minimum . into ( ) ) ; pb . set_style ( ProgressStyle :: default_bar ( ) . template ( " " ) , ) ; pb . set_draw_delta ( 1 ) ; if let Some ( h ) = & hash { match mf . workload { PrimaryWorkload :: Deployment => { pb . set_prefix ( & format ! ( " " mf name h ) ) ; } PrimaryWorkload :: Statefulset => { pb . set_prefix ( h ) ; // statefulset hash already prefixes name } } } else { pb . set_prefix ( & mf . name ) ; } for i in 1 .. 20 { trace ! ( " " i ) ; let mut waited = 0 ; // sleep until 1/20th of estimated upgrade time and poll for status while waited < waittime / 20 { waited += 1 ; trace ! ( " " waited ) ; Delay :: new ( one_sec ) . await ; } let rr = rollout_status ( mf , kube , & hash ) . await ? ; debug ! ( " " rr ) ; if let Some ( msg ) = rr . message { pb . set_message ( & msg ) ; } pb . set_length ( rr . expected . into ( ) ) ; // sometimes a replicaset resizes pb . set_position ( rr . progress . into ( ) ) ; if rr . ok { pb . finish_at_current_pos ( ) ; return Ok ( true ) ; } } Ok ( false ) // timeout }
Track the rollout of the main workload
Track the rollout of the main workload
mf
&Manifest
kube
&ShipKube
mf
&Manifest
kube
&ShipKube