Skip to content

Commit 6af91ae

Browse files
committed
Provide a restore-only mode, by passing no arguments to the run command
1 parent 34dbd78 commit 6af91ae

File tree

3 files changed

+32
-18
lines changed

3 files changed

+32
-18
lines changed

src/cli/checkpoint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub struct Checkpoint {
7777

7878
/// Amount of CPU at disposal. Possible values are [low, medium, high].
7979
/// Currently, `low` skips compression, `medium` uses lz4, and
80-
/// high uses zstd.
80+
/// `high` uses zstd.
8181
#[structopt(long, default_value="medium")]
8282
cpu_budget: CpuBudget,
8383

src/cli/main.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ use super::{
3535
// subcommand version is not useful, disable it.
3636
global_setting(AppSettings::VersionlessSubcommands),
3737
)]
38+
#[structopt(after_help(" restore-only is achived by using \
39+
the `run` subcommand without passing the application command-line arguments"
40+
))]
3841
pub struct Opts {
3942
#[structopt(subcommand)]
4043
command: Command,

src/cli/run.rs

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ use crate::{
4747
use virt::time::Nanos;
4848

4949

50-
/// Run application. If a checkpoint image exists, the application is restored. Otherwise, the
50+
/// Run application.
51+
/// If a checkpoint image exists, the application is restored. Otherwise, the
5152
/// application is run from scratch.
5253
#[derive(StructOpt, PartialEq, Debug, Serialize)]
5354
#[structopt(after_help("\
@@ -82,8 +83,8 @@ pub struct Run {
8283
#[structopt(short, long, name="url")]
8384
image_url: Option<String>,
8485

85-
/// Application arguments, used when running the app from scratch.
86-
/// Ignored during restore.
86+
/// Application command, used when running the app from scratch.
87+
/// When absent, FastFreeze runs in restore-only mode.
8788
// Note: Type should be OsString, but structopt doesn't like it
8889
// Also, we wish to pass min_values=1, but it's not working.
8990
#[structopt()]
@@ -443,7 +444,7 @@ fn ensure_non_conflicting_pid() -> Result<()> {
443444

444445
fn do_run(
445446
image_url: ImageUrl,
446-
app_args: Vec<String>,
447+
app_args: Option<Vec<String>>,
447448
preserved_paths: HashSet<PathBuf>,
448449
passphrase_file: Option<PathBuf>,
449450
no_restore: bool,
@@ -476,8 +477,8 @@ fn do_run(
476477
.context(ExitCode(EXIT_CODE_RESTORE_FAILURE))?
477478
};
478479

479-
match run_mode {
480-
RunMode::Restore { img_manifest } => {
480+
match (run_mode, app_args) {
481+
(RunMode::Restore { img_manifest }, _) => {
481482
let shard_download_cmds = shard::download_cmds(
482483
&img_manifest, passphrase_file.as_ref(), &*store)?;
483484

@@ -493,7 +494,9 @@ fn do_run(
493494
})
494495
)?;
495496
}
496-
RunMode::FromScratch => {
497+
(RunMode::FromScratch, None) =>
498+
bail!("No application to restore, but running in restore-only mode, aborting"),
499+
(RunMode::FromScratch, Some(app_args)) => {
497500
let app_args = app_args.into_iter().map(|s| s.into()).collect();
498501
with_metrics("run_from_scratch", ||
499502
run_from_scratch(image_url, preserved_paths, passphrase_file, app_args),
@@ -536,23 +539,31 @@ impl super::CLI for Run {
536539
allow_bad_image_version, passphrase_file, preserved_paths,
537540
leave_stopped, verbose: _, app_name, no_container } = self;
538541

539-
ensure!(!app_args.is_empty() && !app_args[0].is_empty(),
540-
"Please provide a command to run");
542+
// We allow app_args to be empty. This indicates a restore-only mode.
543+
let app_args = if app_args.is_empty() {
544+
info!("Running in restore-only mode as no command is given");
545+
None
546+
} else {
547+
ensure!(!app_args[0].is_empty(), "Empty command given");
548+
Some(app_args)
549+
};
541550

542551
let nscaps = container::ns_capabilities()?;
543552

544-
let image_url = match image_url {
545-
Some(image_url) => image_url,
546-
None => {
553+
let image_url = match (image_url, app_args.as_ref()) {
554+
(Some(image_url), _) => image_url,
555+
(None, None) =>
556+
bail!("--image-url is necessary when running in restore-only mode"),
557+
(None, Some(_)) if nscaps.has_restrictions() => {
547558
// We don't want to use a default image-url location when we
548559
// have restrictions creating namespaces. We are most likely in docker/kubernetes,
549560
// and the file system is going to disappear as soon as the container shuts down.
550561
// We cannot assume where the image can be safely saved.
551-
ensure!(!nscaps.has_restrictions(),
552-
"Please provide a checkpoint image location with \
553-
`--image-url file:/persistant_volume/image`");
554-
555-
let image_path = DEFAULT_IMAGE_DIR.join(default_image_name(&app_args));
562+
bail!("Please provide a checkpoint image location with \
563+
`--image-url file:/persistant_volume/image`")
564+
},
565+
(None, Some(app_args)) => {
566+
let image_path = DEFAULT_IMAGE_DIR.join(default_image_name(app_args));
556567
let image_url = format!("file:{}", image_path.display());
557568
info!("image-url is {}", image_url);
558569
image_url

0 commit comments

Comments
 (0)