1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//! The `blob` subcommand: upload a file as a content-addressed blob and print
//! its hash. The general way to provision an artifact — a microVM kernel, a
//! prebuilt rootfs — that another command references by hash.
use clap::Subcommand;
use crate::client;
use crate::config::ProjectConfig;
/// A failure running a `boatramp blob` subcommand.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Resolving the server target from flags/config failed.
#[error(transparent)]
Client(#[from] crate::client::ClientError),
}
/// `blob` module result; `Err` is [`Error`].
type Result<T> = std::result::Result<T, Error>;
/// Arguments for `boatramp blob`.
#[derive(Debug, clap::Args)]
pub struct BlobArgs {
/// boatramp server base URL (overrides [deploy].server).
#[arg(long, env = "BOATRAMP_SERVER", global = true)]
server: Option<String>,
#[command(subcommand)]
command: BlobCommand,
}
#[derive(Debug, Subcommand)]
enum BlobCommand {
/// Upload a file as a content-addressed blob; prints its hash (the key other
/// commands reference, e.g. `compute set --kernel <hash>`).
Put {
/// File to upload.
file: std::path::PathBuf,
},
}
/// Entry point for `boatramp blob`.
pub async fn run(args: BlobArgs, config: &ProjectConfig) -> Result<()> {
let server = client::resolve_server(args.server, config)?;
let cp = client::ControlPlane::new(
server,
client::http_client(client::token(config).as_deref()),
client::resolve_project(config),
);
match args.command {
BlobCommand::Put { file } => {
let hash = cp.put_file_blob(&file).await?;
println!("{hash}");
}
}
Ok(())
}