Skip to content

Commit

Permalink
Merge branch 'main' into dev/changelog
Browse files Browse the repository at this point in the history
  • Loading branch information
ia0 committed Oct 25, 2024
2 parents ec937ac + 4cf9d5a commit 64ef8cb
Show file tree
Hide file tree
Showing 55 changed files with 713 additions and 132 deletions.
2 changes: 1 addition & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[alias]
update-api = "run --manifest-path ./crates/api-desc/crates/update/Cargo.toml"
wasefire = "run --manifest-path ./crates/cli/Cargo.toml --"
wasefire = "run --manifest-path ./crates/cli/Cargo.toml --features=_dev --"
xtask = "run --manifest-path ./crates/xtask/Cargo.toml --"

[build]
Expand Down
3 changes: 2 additions & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
* @ia0
/crates/runner-host/crates/web-client/ @chris-dietz @ia0
/crates/runner-host/crates/web-client/ @chris-dietz @ia0 @ia0-review
/.github/CODEOWNERS @ia0
2 changes: 1 addition & 1 deletion crates/board/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,4 @@

## 0.1.0

<!-- Increment to skip CHANGELOG.md test: 2 -->
<!-- Increment to skip CHANGELOG.md test: 3 -->
26 changes: 26 additions & 0 deletions crates/board/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/board/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ usb-device = { version = "0.3.2", default-features = false, optional = true }
usbd-serial = { version = "0.2.2", default-features = false, optional = true }
wasefire-error = { version = "0.1.2-git", path = "../error" }
wasefire-logger = { version = "0.1.6-git", path = "../logger" }
wasefire-protocol = { version = "0.2.0-git", path = "../protocol" }
wasefire-store = { version = "0.3.0-git", path = "../store", optional = true }

[dependencies.wasefire-applet-api]
Expand Down
10 changes: 10 additions & 0 deletions crates/board/src/applet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

//! Applet interface.

use wasefire_protocol::applet::ExitStatus;

use crate::Error;

/// Applet interface.
Expand Down Expand Up @@ -45,4 +47,12 @@ pub trait Api: Send {
/// Implementations should make sure that if the platform reboots before this call, the
/// persisted applet is empty.
fn finish() -> Result<(), Error>;

/// Notifies an applet start.
fn notify_start() {}

/// Notifies an applet exit.
fn notify_exit(status: ExitStatus) {
let _ = status;
}
}
6 changes: 5 additions & 1 deletion crates/cli-tools/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

### Minor

- Add `action::PlatformInfo` to print platform serial and version
- Add `cmd::spawn()` for more control on command execution
- Add `fs::remove_dir_all()` to remove a directory recursively
- Add `fs::rename()` to rename a file
- Add `cargo` and `changelog` modules and features
- Handle more errors during platform discovery and `action::PlatformReboot`
- Extend `fs::write()` first parameter to set the `OpenOptions` too
Expand All @@ -35,4 +39,4 @@

## 0.1.0

<!-- Increment to skip CHANGELOG.md test: 7 -->
<!-- Increment to skip CHANGELOG.md test: 8 -->
1 change: 1 addition & 0 deletions crates/cli-tools/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 17 additions & 4 deletions crates/cli-tools/src/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,7 @@ pub struct AppletExitStatus {
impl AppletExitStatus {
fn print(status: Option<applet::ExitStatus>) {
match status {
Some(applet::ExitStatus::Exit) => println!("The applet exited."),
Some(applet::ExitStatus::Abort) => println!("The applet aborted."),
Some(applet::ExitStatus::Trap) => println!("The applet trapped."),
Some(applet::ExitStatus::Kill) => println!("The applet was killed."),
Some(status) => println!("{status}."),
None => println!("The applet is still running."),
}
}
Expand Down Expand Up @@ -286,6 +283,22 @@ impl PlatformList {
}
}

/// Prints the informations of a platform.
#[derive(clap::Args)]
pub struct PlatformInfo {}

impl PlatformInfo {
pub async fn run(self, connection: &mut dyn Connection) -> Result<()> {
let PlatformInfo {} = self;
let info = connection.call::<service::PlatformInfo>(()).await?;
let serial = protocol::Hex(info.get().serial.to_vec());
let version = protocol::Hex(info.get().version.to_vec());
println!(" serial: {serial}");
println!("version: {version}");
Ok(())
}
}

/// Updates a platform.
#[derive(clap::Args)]
pub struct PlatformUpdate {
Expand Down
11 changes: 8 additions & 3 deletions crates/cli-tools/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ use std::os::unix::process::CommandExt;
use std::process::Output;

use anyhow::{ensure, Context, Result};
use tokio::process::Command;
use tokio::process::{Child, Command};

/// Spawns a command.
pub fn spawn(command: &mut Command) -> Result<Child> {
debug!("{:?}", command.as_std());
Ok(command.spawn()?)
}

/// Executes a command making sure it's successful.
pub async fn execute(command: &mut Command) -> Result<()> {
debug!("{:?}", command.as_std());
let code = command.spawn()?.wait().await?.code().context("no error code")?;
let code = spawn(command)?.wait().await?.code().context("no error code")?;
ensure!(code == 0, "failed with code {code}");
Ok(())
}
Expand Down
16 changes: 16 additions & 0 deletions crates/cli-tools/src/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,28 @@ pub async fn read_stdin() -> Result<Vec<u8>> {
Ok(data)
}

pub async fn remove_dir_all(path: impl AsRef<Path>) -> Result<()> {
let name = path.as_ref().display();
debug!("rm -r {name:?}");
tokio::fs::remove_dir_all(path.as_ref()).await.with_context(|| format!("removing {name}"))
}

pub async fn remove_file(path: impl AsRef<Path>) -> Result<()> {
let name = path.as_ref().display();
debug!("rm {name:?}");
tokio::fs::remove_file(path.as_ref()).await.with_context(|| format!("removing {name}"))
}

pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> Result<()> {
let src = from.as_ref().display();
let dst = to.as_ref().display();
create_parent(to.as_ref()).await?;
debug!("mv {src:?} {dst:?}");
tokio::fs::rename(from.as_ref(), to.as_ref())
.await
.with_context(|| format!("renaming {src} to {dst}"))
}

pub async fn touch(path: impl AsRef<Path>) -> Result<()> {
if exists(path.as_ref()).await {
return Ok(());
Expand Down
4 changes: 3 additions & 1 deletion crates/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

### Minor

- Add `platform-info` to print platform serial and version
- Add `host` to start a host platform
- Support `RUST_LOG` to control logging
- Add `platform-lock` to lock a platform protocol
- Add `applet-exit-status` to get an applet exit status
Expand Down Expand Up @@ -45,4 +47,4 @@

## 0.1.0

<!-- Increment to skip CHANGELOG.md test: 9 -->
<!-- Increment to skip CHANGELOG.md test: 10 -->
1 change: 1 addition & 0 deletions crates/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions crates/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ include = ["/LICENSE", "/src/"]
keywords = ["cli", "embedded", "framework", "wasm"]
categories = ["command-line-utilities", "embedded", "wasm"]

[package.metadata.docs.rs]
features = ["_dev"]

[[bin]]
name = "wasefire"
path = "src/main.rs"
Expand All @@ -27,6 +30,9 @@ version = "1.40.0"
default-features = false
features = ["macros", "parking_lot", "rt", "rt-multi-thread"]

[features]
_dev = []

[lints]
clippy.unit-arg = "allow"
rust.unreachable-pub = "warn"
Expand Down
73 changes: 71 additions & 2 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(never_type)]

use std::fs::File;
use std::io::Write;
use std::path::{Path, PathBuf};

use anyhow::{bail, Result};
use anyhow::{bail, Context, Result};
use clap::{CommandFactory, Parser, ValueHint};
use clap_complete::Shell;
use wasefire_cli_tools::{action, fs};
use tokio::process::Command;
use wasefire_cli_tools::{action, cmd, fs};

#[derive(Parser)]
#[command(name = "wasefire", version, about)]
Expand Down Expand Up @@ -83,6 +86,17 @@ enum Action {
action: action::AppletRpc,
},

/// Starts a host platform.
Host(Host),

#[group(id = "Action::PlatformInfo")]
PlatformInfo {
#[command(flatten)]
options: action::ConnectionOptions,
#[command(flatten)]
action: action::PlatformInfo,
},

PlatformList(action::PlatformList),

/// Prints the platform update metadata (possibly binary output).
Expand Down Expand Up @@ -140,6 +154,27 @@ enum AppletInstallCommand {
},
}

#[derive(clap::Args)]
struct Host {
/// Path of the directory containing the host platform files.
///
/// Such a directory may contain:
/// - `applet.bin` the persistent applet
/// - `platform.bin` the platform code
/// - `storage.bin` the persistent storage
/// - `uart0` the UNIX socket for the UART
/// - `web` the web interface assets
///
/// If the platform code is missing (including if the directory does not exist), a default
/// platform code is created and started.
#[arg(long, default_value = "wasefire/host", value_hint = ValueHint::DirPath)]
dir: PathBuf,

/// Arguments to forward to the runner.
#[arg(trailing_var_arg = true, allow_hyphen_values = true)]
args: Vec<String>,
}

#[derive(clap::Args)]
struct Completion {
/// Generates a completion file for this shell (tries to guess by default).
Expand All @@ -150,6 +185,38 @@ struct Completion {
output: PathBuf,
}

impl Host {
async fn run(&self) -> Result<!> {
let bin = self.dir.join("platform.bin");
#[cfg(feature = "_dev")]
if !fs::exists(&bin).await {
let bundle = "target/wasefire/platform.bin";
anyhow::ensure!(
fs::exists(&bundle).await,
"Run `cargo xtask runner host bundle` first"
);
fs::copy(bundle, &bin).await?;
}
#[cfg(not(feature = "_dev"))]
if !fs::exists(&bin).await {
fs::create_dir_all(&self.dir).await?;
static HOST_PLATFORM: &[u8] = include_bytes!(env!("WASEFIRE_HOST_PLATFORM"));
let mut params = fs::WriteParams::new(&bin);
params.options().write(true).create_new(true).mode(0o777);
fs::write(params, HOST_PLATFORM).await?;
}
loop {
let mut host = Command::new(&bin);
host.arg(&self.dir);
host.args(&self.args);
let code = cmd::spawn(&mut host)?.wait().await?.code().context("no error code")?;
if code != 0 {
std::process::exit(code);
}
}
}
}

impl Completion {
async fn run(&self) -> Result<()> {
let shell = match self.shell.or_else(Shell::from_env) {
Expand Down Expand Up @@ -195,6 +262,8 @@ async fn main() -> Result<()> {
action.run(&mut options.connect().await?).await
}
Action::AppletRpc { options, action } => action.run(&mut options.connect().await?).await,
Action::Host(x) => x.run().await?,
Action::PlatformInfo { options, action } => action.run(&mut options.connect().await?).await,
Action::PlatformList(x) => x.run().await,
Action::PlatformUpdateMetadata { options } => {
let metadata = action::PlatformUpdate::metadata(&mut options.connect().await?).await?;
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ set -e

test_helper

cargo test --bin=wasefire
cargo test --bin=wasefire --features=_dev
Loading

0 comments on commit 64ef8cb

Please sign in to comment.