mirror of
https://github.com/michael-yuji/xc.git
synced 2026-03-21 16:24:55 +01:00
clippy bits
This commit is contained in:
@@ -486,7 +486,7 @@ mod tests {
|
||||
chdir: Some(dir.to_string()),
|
||||
file: "test-materials/base.tar.zst".to_string(),
|
||||
compression: CompressionType::Auto,
|
||||
print_input_digest: false
|
||||
print_input_digest: false,
|
||||
};
|
||||
do_extract(extract_arg).unwrap();
|
||||
});
|
||||
@@ -500,7 +500,7 @@ mod tests {
|
||||
chdir: Some(dir.to_string()),
|
||||
file: "test-materials/base.tar".to_string(),
|
||||
compression: CompressionType::Auto,
|
||||
print_input_digest: false
|
||||
print_input_digest: false,
|
||||
};
|
||||
do_extract(extract_arg).unwrap();
|
||||
});
|
||||
|
||||
@@ -22,8 +22,8 @@
|
||||
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
// SUCH DAMAGE.
|
||||
|
||||
use crate::jailfile::JailContext;
|
||||
use crate::jailfile::parse::Action;
|
||||
use crate::jailfile::JailContext;
|
||||
|
||||
use anyhow::{bail, Result};
|
||||
use oci_util::image_reference::ImageReference;
|
||||
@@ -31,7 +31,7 @@ use xc::util::gen_id;
|
||||
|
||||
pub(crate) struct FromDirective {
|
||||
image_reference: ImageReference,
|
||||
alias: Option<String>
|
||||
alias: Option<String>,
|
||||
}
|
||||
|
||||
impl FromDirective {
|
||||
@@ -44,9 +44,15 @@ impl FromDirective {
|
||||
if action.args.len() > 1 {
|
||||
let Some("as") = action.args.get(1).map(|s| s.as_str()) else { bail!("unexpected ariable") };
|
||||
let alias = action.args.get(2).expect("expected alias");
|
||||
Ok(FromDirective { image_reference, alias: Some(alias.to_string()) })
|
||||
Ok(FromDirective {
|
||||
image_reference,
|
||||
alias: Some(alias.to_string()),
|
||||
})
|
||||
} else {
|
||||
Ok(FromDirective { image_reference, alias: None })
|
||||
Ok(FromDirective {
|
||||
image_reference,
|
||||
alias: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +66,11 @@ impl FromDirective {
|
||||
let name = format!("build-{}", gen_id());
|
||||
/* create container */
|
||||
if let Some(alias) = &self.alias {
|
||||
context.containers.insert(alias.to_string(), name.to_string());
|
||||
context
|
||||
.containers
|
||||
.insert(alias.to_string(), name.to_string());
|
||||
}
|
||||
context.container_id = Some(name);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
|
||||
@@ -33,5 +33,5 @@ pub(crate) struct JailContext {
|
||||
/// Mapping to different containers for multi-stage build
|
||||
pub(crate) containers: HashMap<String, String>,
|
||||
|
||||
conn: UnixStream
|
||||
conn: UnixStream,
|
||||
}
|
||||
|
||||
@@ -103,38 +103,57 @@ mod tests {
|
||||
"#;
|
||||
|
||||
let parsed = super::parse_jailfile(input).expect("cannot parse input");
|
||||
assert_eq!(parsed[0], Action {
|
||||
directive_name: "FROM".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec!["node:18-alpine".to_string()],
|
||||
heredoc: None
|
||||
});
|
||||
assert_eq!(parsed[1], Action {
|
||||
directive_name: "WORKDIR".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec!["/app".to_string()],
|
||||
heredoc: None
|
||||
});
|
||||
assert_eq!(parsed[2], Action {
|
||||
directive_name: "COPY".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec![".".to_string(), ".".to_string()],
|
||||
heredoc: None
|
||||
});
|
||||
assert_eq!(parsed[3], Action {
|
||||
directive_name: "RUN".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec!["yarn".to_string(), "install".to_string(), "--production".to_string()],
|
||||
heredoc: None
|
||||
});
|
||||
assert_eq!(parsed[4], Action {
|
||||
directive_name: "RUN".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: Vec::new(),
|
||||
heredoc: Some("\n This is some\n funny string\n ".to_string())
|
||||
});
|
||||
assert_eq!(
|
||||
parsed[0],
|
||||
Action {
|
||||
directive_name: "FROM".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec!["node:18-alpine".to_string()],
|
||||
heredoc: None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
parsed[1],
|
||||
Action {
|
||||
directive_name: "WORKDIR".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec!["/app".to_string()],
|
||||
heredoc: None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
parsed[2],
|
||||
Action {
|
||||
directive_name: "COPY".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec![".".to_string(), ".".to_string()],
|
||||
heredoc: None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
parsed[3],
|
||||
Action {
|
||||
directive_name: "RUN".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: vec![
|
||||
"yarn".to_string(),
|
||||
"install".to_string(),
|
||||
"--production".to_string()
|
||||
],
|
||||
heredoc: None
|
||||
}
|
||||
);
|
||||
assert_eq!(
|
||||
parsed[4],
|
||||
Action {
|
||||
directive_name: "RUN".to_string(),
|
||||
directive_args: HashMap::new(),
|
||||
args: Vec::new(),
|
||||
heredoc: Some("\n This is some\n funny string\n ".to_string())
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
/*
|
||||
eprintln!("{parsed:?}");
|
||||
assert!(false);
|
||||
*/
|
||||
|
||||
@@ -143,6 +143,8 @@ enum Action {
|
||||
no_clean: bool,
|
||||
#[clap(long, default_value_t, action)]
|
||||
persist: bool,
|
||||
#[clap(long="create-only", action)]
|
||||
create_only: bool,
|
||||
image_reference: ImageReference,
|
||||
entry_point: Option<String>,
|
||||
entry_point_args: Vec<String>,
|
||||
@@ -192,8 +194,8 @@ enum Action {
|
||||
Exec {
|
||||
name: String,
|
||||
arg0: String,
|
||||
args: Vec<String>
|
||||
}
|
||||
args: Vec<String>,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() -> Result<(), ActionError> {
|
||||
@@ -289,7 +291,7 @@ fn main() -> Result<(), ActionError> {
|
||||
}
|
||||
|
||||
let password = password.unwrap_or_else(|| {
|
||||
print!("Enter password: \n");
|
||||
println!("Enter password: ");
|
||||
rpassword::read_password().unwrap()
|
||||
});
|
||||
|
||||
@@ -444,6 +446,7 @@ fn main() -> Result<(), ActionError> {
|
||||
}
|
||||
Action::Run {
|
||||
image_reference,
|
||||
create_only,
|
||||
detach,
|
||||
entry_point,
|
||||
entry_point_args,
|
||||
@@ -528,7 +531,7 @@ fn main() -> Result<(), ActionError> {
|
||||
Maybe::Some(Fd(fd))
|
||||
};
|
||||
|
||||
let reqt = InstantiateRequest {
|
||||
let mut reqt = InstantiateRequest {
|
||||
alt_root: None,
|
||||
name,
|
||||
hostname,
|
||||
@@ -550,6 +553,12 @@ fn main() -> Result<(), ActionError> {
|
||||
main_started_notify: main_started_notify.clone(),
|
||||
};
|
||||
|
||||
if create_only {
|
||||
reqt.main_norun = true;
|
||||
reqt.init_norun = true;
|
||||
reqt.deinit_norun = true;
|
||||
}
|
||||
|
||||
let res = do_instantiate(&mut conn, reqt)?;
|
||||
(res, main_started_notify)
|
||||
};
|
||||
@@ -615,7 +624,7 @@ fn main() -> Result<(), ActionError> {
|
||||
} else {
|
||||
eprintln!("no such container");
|
||||
}
|
||||
},
|
||||
}
|
||||
Action::Exec { name, arg0, args } => {
|
||||
let n = EventFdNotify::new();
|
||||
let request = ExecCommandRequest {
|
||||
@@ -627,7 +636,7 @@ fn main() -> Result<(), ActionError> {
|
||||
stdout: Maybe::Some(ipc::packet::codec::Fd(1)),
|
||||
stderr: Maybe::Some(ipc::packet::codec::Fd(2)),
|
||||
uid: 0,
|
||||
notify: Maybe::Some(ipc::packet::codec::Fd(n.as_raw_fd()))
|
||||
notify: Maybe::Some(ipc::packet::codec::Fd(n.as_raw_fd())),
|
||||
};
|
||||
if let Ok(response) = do_exec(&mut conn, request)? {
|
||||
n.notified_sync();
|
||||
|
||||
@@ -104,9 +104,8 @@ pub(super) fn spawn_process_forward(
|
||||
cmd: &mut std::process::Command,
|
||||
stdin: Option<RawFd>,
|
||||
stdout: Option<RawFd>,
|
||||
stderr: Option<RawFd>
|
||||
) -> Result<u32, ExecError>
|
||||
{
|
||||
stderr: Option<RawFd>,
|
||||
) -> Result<u32, ExecError> {
|
||||
unsafe {
|
||||
cmd.pre_exec(move || {
|
||||
if let Some(fd) = stdin {
|
||||
|
||||
@@ -32,7 +32,9 @@ use crate::util::exists_exec;
|
||||
|
||||
use anyhow::Context;
|
||||
use freebsd::event::{EventFdNotify, KEventExt};
|
||||
use ipc::packet::codec::json::JsonPacket;
|
||||
use ipc::packet::Packet;
|
||||
use ipc::proto::Request;
|
||||
use jail::process::Jailed;
|
||||
use nix::libc::intptr_t;
|
||||
use nix::sys::event::{kevent_ts, EventFilter, EventFlag, FilterFlag, KEvent};
|
||||
@@ -88,6 +90,26 @@ impl ReadingPacket {
|
||||
}
|
||||
}
|
||||
|
||||
enum Readiness<T> {
|
||||
Pending,
|
||||
Ready(T),
|
||||
}
|
||||
|
||||
impl<T> Readiness<T> {
|
||||
fn map_can_fail<F, A, E>(self, transform: F) -> Result<Readiness<A>, E>
|
||||
where
|
||||
F: FnOnce(T) -> Result<A, E>,
|
||||
{
|
||||
match self {
|
||||
Readiness::Pending => Ok(Readiness::Pending),
|
||||
Readiness::Ready(value) => {
|
||||
let x = transform(value)?;
|
||||
Ok(Readiness::Ready(x))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX: naively pretend writes always successful
|
||||
#[derive(Debug)]
|
||||
pub struct ControlStream {
|
||||
@@ -103,7 +125,26 @@ impl ControlStream {
|
||||
}
|
||||
}
|
||||
|
||||
fn pour_in_bytes(&mut self, known_avail: usize) -> Result<Option<Packet>, anyhow::Error> {
|
||||
fn try_get_request(
|
||||
&mut self,
|
||||
known_avail: usize,
|
||||
) -> Result<Readiness<(String, JsonPacket)>, anyhow::Error> {
|
||||
self.pour_in_bytes(known_avail)
|
||||
.and_then(|readiness| match readiness {
|
||||
Readiness::Pending => Ok(Readiness::Pending),
|
||||
Readiness::Ready(packet) => {
|
||||
let request: ipc::packet::TypedPacket<Request> =
|
||||
packet.map_failable(|vec| serde_json::from_slice(vec))?;
|
||||
|
||||
let method = request.data.method.to_string();
|
||||
let packet = request.map(|req| req.value.clone());
|
||||
|
||||
Ok(Readiness::Ready((method, packet)))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn pour_in_bytes(&mut self, known_avail: usize) -> Result<Readiness<Packet>, anyhow::Error> {
|
||||
if let Some(reading_packet) = &mut self.processing {
|
||||
if reading_packet.ready() {
|
||||
panic!("the client is sending more bytes than expected");
|
||||
@@ -115,13 +156,13 @@ impl ControlStream {
|
||||
}
|
||||
let Some(processing) = self.processing.take() else { panic!() };
|
||||
if processing.ready() {
|
||||
Ok(Some(Packet {
|
||||
Ok(Readiness::Ready(Packet {
|
||||
data: processing.buffer,
|
||||
fds: processing.fds,
|
||||
}))
|
||||
} else {
|
||||
self.processing = Some(processing);
|
||||
Ok(None)
|
||||
Ok(Readiness::Pending)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,10 +392,11 @@ impl ProcessRunner {
|
||||
let err_path = format!("/var/log/xc.{}.{}.err.log", self.container.id, id);
|
||||
spawn_process_files(&mut cmd, &Some(out_path), &Some(err_path))?
|
||||
}
|
||||
StdioMode::Forward { stdin, stdout, stderr } => {
|
||||
spawn_process_forward(
|
||||
&mut cmd, *stdin, *stdout, *stderr)?
|
||||
}
|
||||
StdioMode::Forward {
|
||||
stdin,
|
||||
stdout,
|
||||
stderr,
|
||||
} => spawn_process_forward(&mut cmd, *stdin, *stdout, *stderr)?,
|
||||
};
|
||||
|
||||
tx.send_if_modified(|status| {
|
||||
@@ -421,6 +463,16 @@ impl ProcessRunner {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_control_stream_cmd(&mut self, method: String, request: JsonPacket) {
|
||||
if method == "exec" {
|
||||
let jexec: Jexec = serde_json::from_value(request.data).unwrap();
|
||||
let notify = Arc::new(EventFdNotify::from_fd(jexec.notify.unwrap()));
|
||||
let _result = self.spawn_process(&crate::util::gen_id(), &jexec, Some(notify));
|
||||
} else if method == "run_main" {
|
||||
self.should_run_main = true;
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_pid_event(
|
||||
&mut self,
|
||||
event: KEvent,
|
||||
@@ -474,7 +526,9 @@ impl ProcessRunner {
|
||||
if descentdant_gone {
|
||||
stat.set_tree_exited();
|
||||
if stat.id() == "main" {
|
||||
if self.container.deinit_norun || deinits.is_empty() {
|
||||
if (self.container.deinit_norun || deinits.is_empty())
|
||||
&& !self.container.persist
|
||||
{
|
||||
return true;
|
||||
} else {
|
||||
debug!("activating deinit queue");
|
||||
@@ -566,16 +620,13 @@ impl ProcessRunner {
|
||||
} else if let Some(control_stream) =
|
||||
self.control_streams.get_mut(&(event.ident() as i32))
|
||||
{
|
||||
match control_stream.pour_in_bytes(event.data() as usize) {
|
||||
match control_stream.try_get_request(event.data() as usize) {
|
||||
Err(_) => {
|
||||
self.control_streams.remove(&(event.ident() as i32));
|
||||
}
|
||||
Ok(None) => {
|
||||
}
|
||||
Ok(Some(packet)) => {
|
||||
let jexec: Jexec = serde_json::from_slice(&packet.data).unwrap();
|
||||
let notify = Arc::new(EventFdNotify::from_fd(jexec.notify.unwrap()));
|
||||
let _result = self.spawn_process(&crate::util::gen_id(), &jexec, Some(notify));
|
||||
Ok(Readiness::Pending) => {}
|
||||
Ok(Readiness::Ready((method, request))) => {
|
||||
self.handle_control_stream_cmd(method, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -630,7 +681,7 @@ impl ProcessRunner {
|
||||
}
|
||||
|
||||
pub fn run(
|
||||
container: RunningContainer,
|
||||
container: RunningContainer,
|
||||
control_stream: UnixStream,
|
||||
) -> (i32, Receiver<ContainerManifest>) {
|
||||
let kq = nix::sys::event::kqueue().unwrap();
|
||||
|
||||
@@ -42,8 +42,8 @@ pub enum StdioMode {
|
||||
Forward {
|
||||
stdin: Option<RawFd>,
|
||||
stdout: Option<RawFd>,
|
||||
stderr: Option<RawFd>
|
||||
}
|
||||
stderr: Option<RawFd>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Executable parameters to be executed in container
|
||||
@@ -54,7 +54,7 @@ pub struct Jexec {
|
||||
pub envs: std::collections::HashMap<String, String>,
|
||||
pub uid: u32,
|
||||
pub output_mode: StdioMode,
|
||||
pub notify: Option<RawFd>
|
||||
pub notify: Option<RawFd>,
|
||||
}
|
||||
|
||||
pub struct ResolvedExec {
|
||||
@@ -75,7 +75,7 @@ impl ResolvedExec {
|
||||
stdout: None,
|
||||
stderr: None,
|
||||
},
|
||||
notify: None
|
||||
notify: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ impl InstantiateBlueprint {
|
||||
envs,
|
||||
uid: 0,
|
||||
output_mode: StdioMode::Terminal,
|
||||
notify: None
|
||||
notify: None,
|
||||
}
|
||||
};
|
||||
for assign in request.ips.iter() {
|
||||
|
||||
@@ -469,8 +469,9 @@ impl ServerContext {
|
||||
rename_reference: Option<ImageReference>,
|
||||
) -> anyhow::Result<()> {
|
||||
// XXX: handle pull image error
|
||||
let result = crate::image::pull::pull_image(self.image_manager.clone(), reference, rename_reference)
|
||||
.await;
|
||||
let result =
|
||||
crate::image::pull::pull_image(self.image_manager.clone(), reference, rename_reference)
|
||||
.await;
|
||||
if result.is_err() {
|
||||
error!("result: {result:#?}");
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ use oci_util::digest::OciDigest;
|
||||
use oci_util::distribution::client::{BasicAuth, Registry};
|
||||
use oci_util::image_reference::ImageReference;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use xc::models::exec::{Jexec, StdioMode};
|
||||
use std::collections::HashMap;
|
||||
use std::io::Seek;
|
||||
use std::net::IpAddr;
|
||||
@@ -45,6 +44,7 @@ use tokio::sync::RwLock;
|
||||
use tracing::*;
|
||||
use varutil::string_interpolation::InterpolatedString;
|
||||
use xc::container::request::{MountReq, NetworkAllocRequest};
|
||||
use xc::models::exec::{Jexec, StdioMode};
|
||||
use xc::models::jail_image::JailConfig;
|
||||
use xc::models::network::{DnsSetting, IpAssign, PortRedirection};
|
||||
use xc::res::network::Network;
|
||||
@@ -820,21 +820,20 @@ pub struct ExecCommandRequest {
|
||||
pub stdout: Maybe<Fd>,
|
||||
pub stderr: Maybe<Fd>,
|
||||
pub uid: u32,
|
||||
pub notify: Maybe<Fd>
|
||||
pub notify: Maybe<Fd>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct ExecCommandResponse {
|
||||
pub cid: String
|
||||
pub cid: String,
|
||||
}
|
||||
|
||||
#[ipc_method(method = "exec")]
|
||||
async fn exec(
|
||||
context: Arc<RwLock<ServerContext>>,
|
||||
local_context: &mut ConnectionContext<Variables>,
|
||||
request: ExecCommandRequest
|
||||
) -> GenericResult<ExecCommandResponse>
|
||||
{
|
||||
request: ExecCommandRequest,
|
||||
) -> GenericResult<ExecCommandResponse> {
|
||||
info!("exec!!!");
|
||||
let cid = gen_id();
|
||||
let jexec = Jexec {
|
||||
@@ -845,9 +844,9 @@ async fn exec(
|
||||
output_mode: StdioMode::Forward {
|
||||
stdin: request.stdin.to_option().map(|fd| fd.0),
|
||||
stdout: request.stdout.to_option().map(|fd| fd.0),
|
||||
stderr: request.stderr.to_option().map(|fd| fd.0)
|
||||
stderr: request.stderr.to_option().map(|fd| fd.0),
|
||||
},
|
||||
notify: request.notify.to_option().map(|fd| fd.0)
|
||||
notify: request.notify.to_option().map(|fd| fd.0),
|
||||
};
|
||||
if let Some(arc_site) = context.write().await.get_site(&request.name) {
|
||||
let mut site = arc_site.write().await;
|
||||
@@ -858,6 +857,28 @@ async fn exec(
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct RunMainRequest {
|
||||
pub name: String
|
||||
}
|
||||
|
||||
/// XXX: Temporary
|
||||
#[ipc_method(method = "run_main")]
|
||||
async fn run_main(
|
||||
context: Arc<RwLock<ServerContext>>,
|
||||
local_context: &mut ConnectionContext<Variables>,
|
||||
request: RunMainRequest,
|
||||
) -> GenericResult<()>
|
||||
{
|
||||
if let Some(arc_site) = context.write().await.get_site(&request.name) {
|
||||
let mut site = arc_site.write().await;
|
||||
site.run_main();
|
||||
Ok(())
|
||||
}else {
|
||||
enoent("container not found")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct PushImageRequest {
|
||||
pub image_reference: ImageReference,
|
||||
|
||||
@@ -26,8 +26,8 @@ use anyhow::{anyhow, bail, Context};
|
||||
use freebsd::event::{EventFdNotify, Notify};
|
||||
use freebsd::fs::zfs::ZfsHandle;
|
||||
use ipc::packet::Packet;
|
||||
use ipc::proto::Request;
|
||||
use ipc::transport::PacketTransport;
|
||||
use xc::models::exec::Jexec;
|
||||
use std::ffi::OsString;
|
||||
use std::os::fd::RawFd;
|
||||
use std::os::unix::net::UnixStream;
|
||||
@@ -37,6 +37,7 @@ use tracing::info;
|
||||
use xc::config::XcConfig;
|
||||
use xc::container::effect::UndoStack;
|
||||
use xc::container::{Container, ContainerManifest};
|
||||
use xc::models::exec::Jexec;
|
||||
use xc::models::jail_image::JailImage;
|
||||
|
||||
pub enum SiteState {
|
||||
@@ -113,8 +114,29 @@ impl Site {
|
||||
}
|
||||
|
||||
pub fn exec(&mut self, jexec: Jexec) {
|
||||
let encoded = serde_json::to_vec(&jexec).unwrap();
|
||||
let packet = Packet { data: encoded, fds: Vec::new() };
|
||||
let value = serde_json::to_value(jexec).unwrap();
|
||||
let request = Request { method: "exec".to_string(), value };
|
||||
let encoded = serde_json::to_vec(&request).unwrap();
|
||||
let packet = Packet {
|
||||
data: encoded,
|
||||
fds: Vec::new(),
|
||||
};
|
||||
if let Some(stream) = self.control_stream.as_mut() {
|
||||
let _result = stream.send_packet(&packet);
|
||||
}
|
||||
}
|
||||
|
||||
/// XXX: CHANGE ME
|
||||
pub fn run_main(&mut self) {
|
||||
let request = Request {
|
||||
method: "run_main".to_string(),
|
||||
value: serde_json::json!({})
|
||||
};
|
||||
let encoded = serde_json::to_vec(&request).unwrap();
|
||||
let packet = Packet {
|
||||
data: encoded,
|
||||
fds: Vec::new(),
|
||||
};
|
||||
if let Some(stream) = self.control_stream.as_mut() {
|
||||
let _result = stream.send_packet(&packet);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user