fn do_pack()

in resctl-bench/src/main.rs [235:333]


    fn do_pack(&mut self) -> Result<()> {
        let args = &self.args_file.data;
        let fname = Path::new(&args.result)
            .file_name()
            .unwrap()
            .to_string_lossy()
            .to_string();
        let stem = fname.trim_end_matches(".gz").trim_end_matches(".json");

        let mut collected = vec![];
        for job in self.jobs.lock().unwrap().vec.iter() {
            let per = job.data.period;
            if per.0 < per.1 {
                collected.push(per);
            }
        }

        collected.sort();
        let mut pers = vec![];
        let mut cur = (0, 0);
        for per in collected.into_iter() {
            if cur.0 == cur.1 {
                cur = per;
            } else if cur.1 < per.0 {
                pers.push(cur);
                cur = per;
            } else {
                cur.1 = cur.1.max(per.1);
            }
        }
        if cur.0 < cur.1 {
            pers.push(cur);
        }

        let tarball = format!("{}.tar.gz", &stem);
        let repdir = format!("{}-report.d", &stem);
        info!(
            "Creating {:?} containing the following report periods",
            &tarball
        );
        for (i, per) in pers.iter().enumerate() {
            info!("[{:02}] {}", i, format_period(*per));
        }

        let f = std::fs::OpenOptions::new()
            .write(true)
            .create(true)
            .truncate(true)
            .open(&tarball)
            .with_context(|| format!("Opening {:?}", &tarball))?;
        let mut tgz =
            tar::Builder::new(libflate::gzip::Encoder::new(f).context("Creating gzip encoder")?);
        let mut base = base::Base::dummy(args);

        let rctx = RunCtx::new(&args, &mut base, self.jobs.clone());

        debug!("Packing {:?} as {:?}", &args.result, &fname);
        tgz.append_path_with_name(&args.result, &fname)
            .with_context(|| format!("Packing {:?}", &args.result))?;

        let pgbar = ProgressBar::new(pers.iter().fold(0, |acc, per| acc + per.1 - per.0));
        pgbar.set_style(ProgressStyle::default_bar()
                        .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>7}/{len:7} ({eta})")
                            .progress_chars("#>-")
        );

        let mut nr_packed = 0;
        let mut nr_skipped = 0;
        for per in pers.iter() {
            for (path, _at) in rctx.report_path_iter(*per) {
                if !path.exists() {
                    nr_skipped += 1;
                    continue;
                }
                nr_packed += 1;
                let target_path = format!(
                    "{}/{}",
                    &repdir,
                    path.file_name().unwrap().to_str().unwrap()
                );
                debug!("Packing {:?} as {:?}", &path, &target_path);
                tgz.append_path_with_name(&path, &target_path)
                    .with_context(|| format!("Packing {:?}", path))?;

                pgbar.set_position(nr_packed + nr_skipped);

                if prog_exiting() {
                    bail!("Program exiting");
                }
            }
        }
        pgbar.finish_and_clear();

        info!("Packed {}/{} reports", nr_packed, nr_packed + nr_skipped);

        let gz = tgz.into_inner().context("Finishing up archive")?;
        gz.finish().into_result().context("Finishing up gzip")?;
        Ok(())
    }