blob: e93e98a486baaa77974e6d3fa524f38b1ce78986 [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
anyhow::Context,
fidl::endpoints::{ControlHandle, Responder},
fidl_fuchsia_dash as fdash, fuchsia_async as fasync,
fuchsia_component::server::ServiceFs,
fuchsia_inspect::{component, health::Reporter},
fuchsia_zircon as zx,
futures::prelude::*,
tracing::*,
};
mod launch;
mod layout;
mod package_resolver;
mod socket;
mod trampoline;
enum IncomingRequest {
Launcher(fdash::LauncherRequestStream),
}
#[fuchsia::main]
async fn main() -> Result<(), anyhow::Error> {
let mut service_fs = ServiceFs::new_local();
// Initialize inspect.
component::health().set_starting_up();
service_fs.dir("svc").add_fidl_service(IncomingRequest::Launcher);
service_fs.take_and_serve_directory_handle().context("failed to serve outgoing namespace")?;
component::health().set_ok();
debug!("Initialized.");
let _inspect_server_task = inspect_runtime::publish(
component::inspector(),
inspect_runtime::PublishOptions::default(),
);
service_fs
.for_each_concurrent(None, |IncomingRequest::Launcher(mut stream)| async move {
while let Some(Ok(request)) = stream.next().await {
match request {
fdash::LauncherRequest::ExploreComponentOverPty {
moniker,
pty,
tool_urls,
command,
ns_layout,
responder,
} => {
let result = crate::launch::component::explore_over_pty(
&moniker, pty, tool_urls, command, ns_layout,
)
.await
.map(|p| {
info!("launched Dash for instance {}", moniker);
notify_on_process_exit(p, responder.control_handle().clone());
});
let _ = responder.send(result);
}
fdash::LauncherRequest::ExploreComponentOverSocket {
moniker,
socket,
tool_urls,
command,
ns_layout,
responder,
} => {
let result = crate::launch::component::explore_over_socket(
&moniker, socket, tool_urls, command, ns_layout,
)
.await
.map(|p| {
info!("launched Dash for instance {}", moniker);
notify_on_process_exit(p, responder.control_handle().clone());
});
let _ = responder.send(result);
}
fdash::LauncherRequest::ExplorePackageOverSocket {
url,
subpackages,
socket,
tool_urls,
command,
responder,
} => {
let result = crate::launch::package::explore_over_socket(
fdash::FuchsiaPkgResolver::Full,
&url,
&subpackages,
socket,
tool_urls,
command,
)
.await
.map(|p| {
info!("launched Dash for package {} {}", url, subpackages.join(" "));
notify_on_process_exit(p, responder.control_handle().clone());
});
let _ = responder.send(result);
}
fdash::LauncherRequest::ExplorePackageOverSocket2 {
fuchsia_pkg_resolver,
url,
subpackages,
socket,
tool_urls,
command,
responder,
} => {
let result = crate::launch::package::explore_over_socket(
fuchsia_pkg_resolver,
&url,
&subpackages,
socket,
tool_urls,
command,
)
.await
.map(|p| {
info!("launched Dash for package {} {}", url, subpackages.join(" "));
notify_on_process_exit(p, responder.control_handle().clone());
});
let _ = responder.send(result);
}
}
}
})
.await;
Ok(())
}
fn notify_on_process_exit(process: zx::Process, control_handle: fdash::LauncherControlHandle) {
fasync::Task::spawn(async move {
let _ = fasync::OnSignals::new(&process, zx::Signals::PROCESS_TERMINATED).await;
match process.info() {
Ok(info) => {
let _ = control_handle
.send_on_terminated(info.return_code.try_into().unwrap())
.context("error sending OnTerminated event");
info!("Dash process has terminated (exit code: {})", info.return_code);
}
Err(s) => {
info!("Dash process has terminated (could not get exit code: {})", s);
control_handle.shutdown();
}
}
})
.detach();
}