Alioth Code Coverage

main.rs0.00%

1// Copyright 2024 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#[path = "boot/boot.rs"]
16mod boot;
17mod img;
18mod objects;
19#[cfg(target_os = "linux")]
20mod vu;
21
22use std::path::Path;
23
24use clap::{Parser, Subcommand};
25use flexi_logger::{FileSpec, Logger};
26
27#[derive(Subcommand, Debug)]
28enum Command {
29 /// Create and boot a virtual machine.
30 Boot(Box<boot::BootArgs>),
31 #[cfg(target_os = "linux")]
32 /// Start a vhost-user backend device.
33 Vu(Box<vu::VuArgs>),
34 /// Manipulate disk images.
35 Img(Box<img::ImgArgs>),
36}
37
38#[derive(Parser, Debug)]
39#[command(author, version, about)]
40struct Cli {
41 #[arg(short, long, value_name = "SPEC")]
42 /// Loglevel specification, see
43 /// https://docs.rs/flexi_logger/latest/flexi_logger/struct.LogSpecification.html.
44 /// If not set, environment variable $RUST_LOG is used.
45 pub log_spec: Option<String>,
46
47 /// Log to file instead of STDERR.
48 #[arg(long)]
49 pub log_to_file: bool,
50
51 /// Path to a directory where the log file is stored.
52 #[arg(long, value_name = "PATH")]
53 pub log_dir: Option<Box<Path>>,
54
55 #[command(subcommand)]
56 pub cmd: Command,
57}
58
59fn main() -> Result<(), Box<dyn std::error::Error>> {
60 let cli = Cli::parse();
61 let logger = if let Some(ref spec) = cli.log_spec {
62 Logger::try_with_str(spec)
63 } else {
64 Logger::try_with_env_or_str("warn")
65 }?;
66 let logger = if cli.log_to_file {
67 logger.log_to_file(
68 FileSpec::default()
69 .suppress_timestamp()
70 .o_directory(cli.log_dir),
71 )
72 } else {
73 logger
74 };
75 let _handle = logger.start()?;
76 log::debug!(
77 "{} {} started...",
78 env!("CARGO_PKG_NAME"),
79 env!("CARGO_PKG_VERSION"),
80 );
81
82 match cli.cmd {
83 Command::Boot(args) => boot::boot(*args)?,
84 #[cfg(target_os = "linux")]
85 Command::Vu(args) => vu::start(*args)?,
86 Command::Img(args) => img::exec(*args)?,
87 }
88 Ok(())
89}
90
91#[cfg(test)]
92#[ctor::ctor]
93fn global_setup() {
94 flexi_logger::init();
95}
96