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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
use tokio::io::AsyncWriteExt;
use ya_runtime_api::server::proto::{output::Type, request::RunProcess, Output};
use crate::cli::{Command, CommandCli};
use crate::env::{DefaultEnv, Env};
use crate::runtime::{Context, Runtime, RuntimeMode};
use crate::server::Server;
pub async fn run<R: Runtime + 'static>() -> anyhow::Result<()> {
run_with::<R, _>(DefaultEnv::default()).await
}
pub async fn run_with<R: Runtime + 'static, E: Env>(env: E) -> anyhow::Result<()> {
let mut runtime = R::default();
let mut ctx = Context::<R>::try_with(env)?;
match ctx.cli.command() {
Command::Deploy { .. } => {
let deployment = match runtime.deploy(&mut ctx).await? {
Some(deployment) => deployment,
None => {
crate::serialize::json::json!({
"startMode": match R::MODE {
RuntimeMode::Server => "blocking",
RuntimeMode::Command => "empty",
},
"valid": {"Ok": ""},
"vols": []
})
}
};
output(deployment).await?;
}
Command::Start { .. } => match R::MODE {
RuntimeMode::Command => {
if let Some(started) = runtime.start(&mut ctx).await? {
output(started).await?;
}
}
RuntimeMode::Server => {
ya_runtime_api::server::run_async(|emitter| async move {
let start = {
ctx.set_emitter(emitter);
runtime.start(&mut ctx)
};
let mut cmd_ctx = crate::runtime::RunCommandContext {
id: ctx.next_pid(),
emitter: ctx.emitter.clone(),
};
if let Some(out) = start.await.expect("Failed to start the runtime") {
cmd_ctx.stdout(out.to_string()).await;
}
Server::new(runtime, ctx)
})
.await;
}
},
Command::Run { args } => {
if args.is_empty() {
anyhow::bail!("not enough arguments");
}
let mut args = args.clone();
let bin = args.remove(0);
let capture = Some(Output {
r#type: Some(Type::AtEnd(40960)),
});
let command = RunProcess {
bin,
args,
work_dir: ctx.cli.workdir().unwrap().display().to_string(),
stdout: capture.clone(),
stderr: capture,
};
let pid = runtime
.run_command(command, RuntimeMode::Command, &mut ctx)
.await?;
output(serde_json::json!(pid)).await?;
}
Command::OfferTemplate { .. } => {
if let Some(template) = runtime.offer(&mut ctx).await? {
output(template).await?;
}
}
Command::Test { .. } => runtime.test(&mut ctx).await?,
}
Ok(())
}
async fn output(json: serde_json::Value) -> anyhow::Result<()> {
let string = json.to_string();
let mut stdout = tokio::io::stdout();
stdout.write_all(string.as_bytes()).await?;
stdout.flush().await?;
Ok(())
}