mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-31 04:23:40 +00:00
Feature/lxc container runtime (#2514)
* wip: static-server errors * wip: fix wifi * wip: Fix the service_effects * wip: Fix cors in the middleware * wip(chore): Auth clean up the lint. * wip(fix): Vhost * wip: continue manager refactor Co-authored-by: J H <Blu-J@users.noreply.github.com> * wip: service manager refactor * wip: Some fixes * wip(fix): Fix the lib.rs * wip * wip(fix): Logs * wip: bins * wip(innspect): Add in the inspect * wip: config * wip(fix): Diagnostic * wip(fix): Dependencies * wip: context * wip(fix) Sorta auth * wip: warnings * wip(fix): registry/admin * wip(fix) marketplace * wip(fix) Some more converted and fixed with the linter and config * wip: Working on the static server * wip(fix)static server * wip: Remove some asynnc * wip: Something about the request and regular rpc * wip: gut install Co-authored-by: J H <Blu-J@users.noreply.github.com> * wip: Convert the static server into the new system * wip delete file * test * wip(fix) vhost does not need the with safe defaults * wip: Adding in the wifi * wip: Fix the developer and the verify * wip: new install flow Co-authored-by: J H <Blu-J@users.noreply.github.com> * fix middleware * wip * wip: Fix the auth * wip * continue service refactor * feature: Service get_config * feat: Action * wip: Fighting the great fight against the borrow checker * wip: Remove an error in a file that I just need to deel with later * chore: Add in some more lifetime stuff to the services * wip: Install fix on lifetime * cleanup * wip: Deal with the borrow later * more cleanup * resolve borrowchecker errors * wip(feat): add in the handler for the socket, for now * wip(feat): Update the service_effect_handler::action * chore: Add in the changes to make sure the from_service goes to context * chore: Change the * refactor service map * fix references to service map * fill out restore * wip: Before I work on the store stuff * fix backup module * handle some warnings * feat: add in the ui components on the rust side * feature: Update the procedures * chore: Update the js side of the main and a few of the others * chore: Update the rpc listener to match the persistant container * wip: Working on updating some things to have a better name * wip(feat): Try and get the rpc to return the correct shape? * lxc wip * wip(feat): Try and get the rpc to return the correct shape? * build for container runtime wip * remove container-init * fix build * fix error * chore: Update to work I suppose * lxc wip * remove docker module and feature * download alpine squashfs automatically * overlays effect Co-authored-by: Jade <Blu-J@users.noreply.github.com> * chore: Add the overlay effect * feat: Add the mounter in the main * chore: Convert to use the mounts, still need to work with the sandbox * install fixes * fix ssl * fixes from testing * implement tmpfile for upload * wip * misc fixes * cleanup * cleanup * better progress reporting * progress for sideload * return real guid * add devmode script * fix lxc rootfs path * fix percentage bar * fix progress bar styling * fix build for unstable * tweaks * label progress * tweaks * update progress more often * make symlink in rpc_client * make socket dir * fix parent path * add start-cli to container * add echo and gitInfo commands * wip: Add the init + errors * chore: Add in the exit effect for the system * chore: Change the type to null for failure to parse * move sigterm timeout to stopping status * update order * chore: Update the return type * remove dbg * change the map error * chore: Update the thing to capture id * chore add some life changes * chore: Update the loging * chore: Update the package to run module * us From for RpcError * chore: Update to use import instead * chore: update * chore: Use require for the backup * fix a default * update the type that is wrong * chore: Update the type of the manifest * chore: Update to make null * only symlink if not exists * get rid of double result * better debug info for ErrorCollection * chore: Update effects * chore: fix * mount assets and volumes * add exec instead of spawn * fix mounting in image * fix overlay mounts Co-authored-by: Jade <Blu-J@users.noreply.github.com> * misc fixes * feat: Fix two * fix: systemForEmbassy main * chore: Fix small part of main loop * chore: Modify the bundle * merge * fixMain loop" * move tsc to makefile * chore: Update the return types of the health check * fix client * chore: Convert the todo to use tsmatches * add in the fixes for the seen and create the hack to allow demo * chore: Update to include the systemForStartOs * chore UPdate to the latest types from the expected outout * fixes * fix typo * Don't emit if failure on tsc * wip Co-authored-by: Jade <Blu-J@users.noreply.github.com> * add s9pk api * add inspection * add inspect manifest * newline after display serializable * fix squashfs in image name * edit manifest Co-authored-by: Jade <Blu-J@users.noreply.github.com> * wait for response on repl * ignore sig for now * ignore sig for now * re-enable sig verification * fix * wip * env and chroot * add profiling logs * set uid & gid in squashfs to 100000 * set uid of sqfs to 100000 * fix mksquashfs args * add env to compat * fix * re-add docker feature flag * fix docker output format being stupid * here be dragons * chore: Add in the cross compiling for something * fix npm link * extract logs from container on exit * chore: Update for testing * add log capture to drop trait * chore: add in the modifications that I make * chore: Update small things for no updates * chore: Update the types of something * chore: Make main not complain * idmapped mounts * idmapped volumes * re-enable kiosk * chore: Add in some logging for the new system * bring in start-sdk * remove avahi * chore: Update the deps * switch to musl * chore: Update the version of prettier * chore: Organize' * chore: Update some of the headers back to the standard of fetch * fix musl build * fix idmapped mounts * fix cross build * use cross compiler for correct arch * feat: Add in the faked ssl stuff for the effects * @dr_bonez Did a solution here * chore: Something that DrBonez * chore: up * wip: We have a working server!!! * wip * uninstall * wip * tes --------- Co-authored-by: J H <dragondef@gmail.com> Co-authored-by: J H <Blu-J@users.noreply.github.com> Co-authored-by: J H <2364004+Blu-J@users.noreply.github.com>
This commit is contained in:
@@ -1,163 +0,0 @@
|
||||
use avahi_sys::{
|
||||
self, avahi_client_errno, avahi_entry_group_add_service, avahi_entry_group_commit,
|
||||
avahi_strerror, AvahiClient,
|
||||
};
|
||||
|
||||
fn log_str_error(action: &str, e: i32) {
|
||||
unsafe {
|
||||
let e_str = avahi_strerror(e);
|
||||
eprintln!(
|
||||
"Could not {}: {:?}",
|
||||
action,
|
||||
std::ffi::CStr::from_ptr(e_str)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let aliases: Vec<_> = std::env::args().skip(1).collect();
|
||||
unsafe {
|
||||
let simple_poll = avahi_sys::avahi_simple_poll_new();
|
||||
let poll = avahi_sys::avahi_simple_poll_get(simple_poll);
|
||||
let mut box_err = Box::pin(0 as i32);
|
||||
let err_c: *mut i32 = box_err.as_mut().get_mut();
|
||||
let avahi_client = avahi_sys::avahi_client_new(
|
||||
poll,
|
||||
avahi_sys::AvahiClientFlags::AVAHI_CLIENT_NO_FAIL,
|
||||
Some(client_callback),
|
||||
std::ptr::null_mut(),
|
||||
err_c,
|
||||
);
|
||||
if avahi_client == std::ptr::null_mut::<AvahiClient>() {
|
||||
log_str_error("create Avahi client", *box_err);
|
||||
panic!("Failed to create Avahi Client");
|
||||
}
|
||||
let group = avahi_sys::avahi_entry_group_new(
|
||||
avahi_client,
|
||||
Some(entry_group_callback),
|
||||
std::ptr::null_mut(),
|
||||
);
|
||||
if group == std::ptr::null_mut() {
|
||||
log_str_error("create Avahi entry group", avahi_client_errno(avahi_client));
|
||||
panic!("Failed to create Avahi Entry Group");
|
||||
}
|
||||
let mut hostname_buf = vec![0];
|
||||
let hostname_raw = avahi_sys::avahi_client_get_host_name_fqdn(avahi_client);
|
||||
hostname_buf.extend_from_slice(std::ffi::CStr::from_ptr(hostname_raw).to_bytes_with_nul());
|
||||
let buflen = hostname_buf.len();
|
||||
debug_assert!(hostname_buf.ends_with(b".local\0"));
|
||||
debug_assert!(!hostname_buf[..(buflen - 7)].contains(&b'.'));
|
||||
// assume fixed length prefix on hostname due to local address
|
||||
hostname_buf[0] = (buflen - 8) as u8; // set the prefix length to len - 8 (leading byte, .local, nul) for the main address
|
||||
hostname_buf[buflen - 7] = 5; // set the prefix length to 5 for "local"
|
||||
let mut res;
|
||||
let http_tcp_cstr =
|
||||
std::ffi::CString::new("_http._tcp").expect("Could not cast _http._tcp to c string");
|
||||
res = avahi_entry_group_add_service(
|
||||
group,
|
||||
avahi_sys::AVAHI_IF_UNSPEC,
|
||||
avahi_sys::AVAHI_PROTO_UNSPEC,
|
||||
avahi_sys::AvahiPublishFlags_AVAHI_PUBLISH_USE_MULTICAST,
|
||||
hostname_raw,
|
||||
http_tcp_cstr.as_ptr(),
|
||||
std::ptr::null(),
|
||||
std::ptr::null(),
|
||||
443,
|
||||
// below is a secret final argument that the type signature of this function does not tell you that it
|
||||
// needs. This is because the C lib function takes a variable number of final arguments indicating the
|
||||
// desired TXT records to add to this service entry. The way it decides when to stop taking arguments
|
||||
// from the stack and dereferencing them is when it finds a null pointer...because fuck you, that's why.
|
||||
// The consequence of this is that forgetting this last argument will cause segfaults or other undefined
|
||||
// behavior. Welcome back to the stone age motherfucker.
|
||||
std::ptr::null::<libc::c_char>(),
|
||||
);
|
||||
if res < avahi_sys::AVAHI_OK {
|
||||
log_str_error("add service to Avahi entry group", res);
|
||||
panic!("Failed to load Avahi services");
|
||||
}
|
||||
eprintln!("Published {:?}", std::ffi::CStr::from_ptr(hostname_raw));
|
||||
for alias in aliases {
|
||||
let lan_address = alias + ".local";
|
||||
let lan_address_ptr = std::ffi::CString::new(lan_address)
|
||||
.expect("Could not cast lan address to c string");
|
||||
res = avahi_sys::avahi_entry_group_add_record(
|
||||
group,
|
||||
avahi_sys::AVAHI_IF_UNSPEC,
|
||||
avahi_sys::AVAHI_PROTO_UNSPEC,
|
||||
avahi_sys::AvahiPublishFlags_AVAHI_PUBLISH_USE_MULTICAST
|
||||
| avahi_sys::AvahiPublishFlags_AVAHI_PUBLISH_ALLOW_MULTIPLE,
|
||||
lan_address_ptr.as_ptr(),
|
||||
avahi_sys::AVAHI_DNS_CLASS_IN as u16,
|
||||
avahi_sys::AVAHI_DNS_TYPE_CNAME as u16,
|
||||
avahi_sys::AVAHI_DEFAULT_TTL,
|
||||
hostname_buf.as_ptr().cast(),
|
||||
hostname_buf.len(),
|
||||
);
|
||||
if res < avahi_sys::AVAHI_OK {
|
||||
log_str_error("add CNAME record to Avahi entry group", res);
|
||||
panic!("Failed to load Avahi services");
|
||||
}
|
||||
eprintln!("Published {:?}", lan_address_ptr);
|
||||
}
|
||||
let commit_err = avahi_entry_group_commit(group);
|
||||
if commit_err < avahi_sys::AVAHI_OK {
|
||||
log_str_error("reset Avahi entry group", commit_err);
|
||||
panic!("Failed to load Avahi services: reset");
|
||||
}
|
||||
}
|
||||
std::thread::park()
|
||||
}
|
||||
|
||||
unsafe extern "C" fn entry_group_callback(
|
||||
_group: *mut avahi_sys::AvahiEntryGroup,
|
||||
state: avahi_sys::AvahiEntryGroupState,
|
||||
_userdata: *mut core::ffi::c_void,
|
||||
) {
|
||||
match state {
|
||||
avahi_sys::AvahiEntryGroupState_AVAHI_ENTRY_GROUP_FAILURE => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = AVAHI_ENTRY_GROUP_FAILURE");
|
||||
}
|
||||
avahi_sys::AvahiEntryGroupState_AVAHI_ENTRY_GROUP_COLLISION => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = AVAHI_ENTRY_GROUP_COLLISION");
|
||||
}
|
||||
avahi_sys::AvahiEntryGroupState_AVAHI_ENTRY_GROUP_UNCOMMITED => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = AVAHI_ENTRY_GROUP_UNCOMMITED");
|
||||
}
|
||||
avahi_sys::AvahiEntryGroupState_AVAHI_ENTRY_GROUP_ESTABLISHED => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = AVAHI_ENTRY_GROUP_ESTABLISHED");
|
||||
}
|
||||
avahi_sys::AvahiEntryGroupState_AVAHI_ENTRY_GROUP_REGISTERING => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = AVAHI_ENTRY_GROUP_REGISTERING");
|
||||
}
|
||||
other => {
|
||||
eprintln!("AvahiCallback: EntryGroupState = {}", other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn client_callback(
|
||||
_group: *mut avahi_sys::AvahiClient,
|
||||
state: avahi_sys::AvahiClientState,
|
||||
_userdata: *mut core::ffi::c_void,
|
||||
) {
|
||||
match state {
|
||||
avahi_sys::AvahiClientState_AVAHI_CLIENT_FAILURE => {
|
||||
eprintln!("AvahiCallback: ClientState = AVAHI_CLIENT_FAILURE");
|
||||
}
|
||||
avahi_sys::AvahiClientState_AVAHI_CLIENT_S_RUNNING => {
|
||||
eprintln!("AvahiCallback: ClientState = AVAHI_CLIENT_S_RUNNING");
|
||||
}
|
||||
avahi_sys::AvahiClientState_AVAHI_CLIENT_CONNECTING => {
|
||||
eprintln!("AvahiCallback: ClientState = AVAHI_CLIENT_CONNECTING");
|
||||
}
|
||||
avahi_sys::AvahiClientState_AVAHI_CLIENT_S_COLLISION => {
|
||||
eprintln!("AvahiCallback: ClientState = AVAHI_CLIENT_S_COLLISION");
|
||||
}
|
||||
avahi_sys::AvahiClientState_AVAHI_CLIENT_S_REGISTERING => {
|
||||
eprintln!("AvahiCallback: ClientState = AVAHI_CLIENT_S_REGISTERING");
|
||||
}
|
||||
other => {
|
||||
eprintln!("AvahiCallback: ClientState = {}", other);
|
||||
}
|
||||
}
|
||||
}
|
||||
38
core/startos/src/bins/container_cli.rs
Normal file
38
core/startos/src/bins/container_cli.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
use rpc_toolkit::CliApp;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::service::cli::{ContainerCliContext, ContainerClientConfig};
|
||||
use crate::util::logger::EmbassyLogger;
|
||||
use crate::version::{Current, VersionT};
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref VERSION_STRING: String = Current::new().semver().to_string();
|
||||
}
|
||||
|
||||
pub fn main(args: impl IntoIterator<Item = OsString>) {
|
||||
EmbassyLogger::init();
|
||||
if let Err(e) = CliApp::new(
|
||||
|cfg: ContainerClientConfig| Ok(ContainerCliContext::init(cfg)),
|
||||
crate::service::service_effect_handler::service_effect_handler(),
|
||||
)
|
||||
.run(args)
|
||||
{
|
||||
match e.data {
|
||||
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
|
||||
Some(Value::Object(o)) => {
|
||||
if let Some(Value::String(s)) = o.get("details") {
|
||||
eprintln!("{}: {}", e.message, s);
|
||||
if let Some(Value::String(s)) = o.get("debug") {
|
||||
tracing::debug!("{}", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(a) => eprintln!("{}: {}", e.message, a),
|
||||
None => eprintln!("{}", e.message),
|
||||
}
|
||||
|
||||
std::process::exit(e.code);
|
||||
}
|
||||
}
|
||||
@@ -1,45 +1,54 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::ffi::OsString;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(feature = "avahi-alias")]
|
||||
pub mod avahi_alias;
|
||||
#[cfg(feature = "container-runtime")]
|
||||
pub mod container_cli;
|
||||
pub mod deprecated;
|
||||
#[cfg(feature = "cli")]
|
||||
pub mod start_cli;
|
||||
#[cfg(feature = "daemon")]
|
||||
pub mod start_init;
|
||||
#[cfg(feature = "sdk")]
|
||||
pub mod start_sdk;
|
||||
#[cfg(feature = "daemon")]
|
||||
pub mod startd;
|
||||
|
||||
fn select_executable(name: &str) -> Option<fn()> {
|
||||
fn select_executable(name: &str) -> Option<fn(VecDeque<OsString>)> {
|
||||
match name {
|
||||
#[cfg(feature = "avahi-alias")]
|
||||
"avahi-alias" => Some(avahi_alias::main),
|
||||
#[cfg(feature = "cli")]
|
||||
"start-cli" => Some(start_cli::main),
|
||||
#[cfg(feature = "sdk")]
|
||||
"start-sdk" => Some(start_sdk::main),
|
||||
#[cfg(feature = "container-runtime")]
|
||||
"start-cli" => Some(container_cli::main),
|
||||
#[cfg(feature = "daemon")]
|
||||
"startd" => Some(startd::main),
|
||||
"embassy-cli" => Some(|| deprecated::renamed("embassy-cli", "start-cli")),
|
||||
"embassy-sdk" => Some(|| deprecated::renamed("embassy-sdk", "start-sdk")),
|
||||
"embassyd" => Some(|| deprecated::renamed("embassyd", "startd")),
|
||||
"embassy-init" => Some(|| deprecated::removed("embassy-init")),
|
||||
"embassy-cli" => Some(|_| deprecated::renamed("embassy-cli", "start-cli")),
|
||||
"embassy-sdk" => Some(|_| deprecated::renamed("embassy-sdk", "start-sdk")),
|
||||
"embassyd" => Some(|_| deprecated::renamed("embassyd", "startd")),
|
||||
"embassy-init" => Some(|_| deprecated::removed("embassy-init")),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn startbox() {
|
||||
let args = std::env::args().take(2).collect::<Vec<_>>();
|
||||
let executable = args
|
||||
.get(0)
|
||||
.and_then(|s| Path::new(&*s).file_name())
|
||||
.and_then(|s| s.to_str());
|
||||
if let Some(x) = executable.and_then(|s| select_executable(&s)) {
|
||||
x()
|
||||
} else {
|
||||
eprintln!("unknown executable: {}", executable.unwrap_or("N/A"));
|
||||
std::process::exit(1);
|
||||
let mut args = std::env::args_os().collect::<VecDeque<_>>();
|
||||
for _ in 0..2 {
|
||||
if let Some(s) = args.pop_front() {
|
||||
if let Some(x) = Path::new(&*s)
|
||||
.file_name()
|
||||
.and_then(|s| s.to_str())
|
||||
.and_then(|s| select_executable(&s))
|
||||
{
|
||||
args.push_front(s);
|
||||
return x(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
let args = std::env::args().collect::<VecDeque<_>>();
|
||||
eprintln!(
|
||||
"unknown executable: {}",
|
||||
args.get(1)
|
||||
.or_else(|| args.get(0))
|
||||
.map(|s| s.as_str())
|
||||
.unwrap_or("N/A")
|
||||
);
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
@@ -1,62 +1,39 @@
|
||||
use clap::Arg;
|
||||
use rpc_toolkit::run_cli;
|
||||
use rpc_toolkit::yajrc::RpcError;
|
||||
use std::ffi::OsString;
|
||||
|
||||
use rpc_toolkit::CliApp;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::context::config::ClientConfig;
|
||||
use crate::context::CliContext;
|
||||
use crate::util::logger::EmbassyLogger;
|
||||
use crate::version::{Current, VersionT};
|
||||
use crate::Error;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref VERSION_STRING: String = Current::new().semver().to_string();
|
||||
}
|
||||
|
||||
fn inner_main() -> Result<(), Error> {
|
||||
run_cli!({
|
||||
command: crate::main_api,
|
||||
app: app => app
|
||||
.name("StartOS CLI")
|
||||
.version(&**VERSION_STRING)
|
||||
.arg(
|
||||
clap::Arg::with_name("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.takes_value(true),
|
||||
)
|
||||
.arg(Arg::with_name("host").long("host").short('h').takes_value(true))
|
||||
.arg(Arg::with_name("proxy").long("proxy").short('p').takes_value(true)),
|
||||
context: matches => {
|
||||
EmbassyLogger::init();
|
||||
CliContext::init(matches)?
|
||||
},
|
||||
exit: |e: RpcError| {
|
||||
match e.data {
|
||||
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
|
||||
Some(Value::Object(o)) => if let Some(Value::String(s)) = o.get("details") {
|
||||
pub fn main(args: impl IntoIterator<Item = OsString>) {
|
||||
EmbassyLogger::init();
|
||||
if let Err(e) = CliApp::new(
|
||||
|cfg: ClientConfig| Ok(CliContext::init(cfg.load()?)?),
|
||||
crate::main_api(),
|
||||
)
|
||||
.run(args)
|
||||
{
|
||||
match e.data {
|
||||
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
|
||||
Some(Value::Object(o)) => {
|
||||
if let Some(Value::String(s)) = o.get("details") {
|
||||
eprintln!("{}: {}", e.message, s);
|
||||
if let Some(Value::String(s)) = o.get("debug") {
|
||||
tracing::debug!("{}", s)
|
||||
}
|
||||
}
|
||||
Some(a) => eprintln!("{}: {}", e.message, a),
|
||||
None => eprintln!("{}", e.message),
|
||||
}
|
||||
|
||||
std::process::exit(e.code);
|
||||
Some(a) => eprintln!("{}: {}", e.message, a),
|
||||
None => eprintln!("{}", e.message),
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
match inner_main() {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.source);
|
||||
tracing::debug!("{:?}", e.source);
|
||||
drop(e.source);
|
||||
std::process::exit(e.kind as i32)
|
||||
}
|
||||
std::process::exit(e.code);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
use rpc_toolkit::yajrc::RpcError;
|
||||
use rpc_toolkit::{command, run_cli, Context};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::procedure::js_scripts::ExecuteArgs;
|
||||
use crate::s9pk::manifest::PackageId;
|
||||
use crate::util::serde::{display_serializable, parse_stdin_deserializable, IoFormat};
|
||||
use crate::version::{Current, VersionT};
|
||||
use crate::Error;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref VERSION_STRING: String = Current::new().semver().to_string();
|
||||
}
|
||||
|
||||
struct DenoContext;
|
||||
impl Context for DenoContext {}
|
||||
|
||||
#[command(subcommands(execute, sandbox))]
|
||||
fn deno_api() -> Result<(), Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[command(cli_only, display(display_serializable))]
|
||||
async fn execute(
|
||||
#[arg(stdin, parse(parse_stdin_deserializable))] arg: ExecuteArgs,
|
||||
#[allow(unused_variables)]
|
||||
#[arg(long = "format")]
|
||||
format: Option<IoFormat>,
|
||||
) -> Result<Result<Value, (i32, String)>, Error> {
|
||||
let ExecuteArgs {
|
||||
procedure,
|
||||
directory,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
name,
|
||||
volumes,
|
||||
input,
|
||||
} = arg;
|
||||
PackageLogger::init(&pkg_id);
|
||||
// procedure
|
||||
// .execute_impl(&directory, &pkg_id, &pkg_version, name, &volumes, input)
|
||||
// .await
|
||||
todo!("@DRB Remove")
|
||||
}
|
||||
#[command(cli_only, display(display_serializable))]
|
||||
async fn sandbox(
|
||||
#[arg(stdin, parse(parse_stdin_deserializable))] arg: ExecuteArgs,
|
||||
#[allow(unused_variables)]
|
||||
#[arg(long = "format")]
|
||||
format: Option<IoFormat>,
|
||||
) -> Result<Result<Value, (i32, String)>, Error> {
|
||||
let ExecuteArgs {
|
||||
procedure,
|
||||
directory,
|
||||
pkg_id,
|
||||
pkg_version,
|
||||
name,
|
||||
volumes,
|
||||
input,
|
||||
} = arg;
|
||||
PackageLogger::init(&pkg_id);
|
||||
// procedure
|
||||
// .sandboxed_impl(&directory, &pkg_id, &pkg_version, &volumes, input, name)
|
||||
// .await
|
||||
todo!("@DRB Remove")
|
||||
}
|
||||
|
||||
use tracing::Subscriber;
|
||||
use tracing_subscriber::util::SubscriberInitExt;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct PackageLogger {}
|
||||
|
||||
impl PackageLogger {
|
||||
fn base_subscriber(id: &PackageId) -> impl Subscriber {
|
||||
use tracing_error::ErrorLayer;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::{fmt, EnvFilter};
|
||||
|
||||
let filter_layer = EnvFilter::default().add_directive(
|
||||
format!("{}=warn", std::module_path!().split("::").next().unwrap())
|
||||
.parse()
|
||||
.unwrap(),
|
||||
);
|
||||
let fmt_layer = fmt::layer().with_writer(std::io::stderr).with_target(true);
|
||||
let journald_layer = tracing_journald::layer()
|
||||
.unwrap()
|
||||
.with_syslog_identifier(format!("{id}.embassy"));
|
||||
|
||||
let sub = tracing_subscriber::registry()
|
||||
.with(filter_layer)
|
||||
.with(fmt_layer)
|
||||
.with(journald_layer)
|
||||
.with(ErrorLayer::default());
|
||||
|
||||
sub
|
||||
}
|
||||
pub fn init(id: &PackageId) -> Self {
|
||||
Self::base_subscriber(id).init();
|
||||
color_eyre::install().unwrap_or_else(|_| tracing::warn!("tracing too many times"));
|
||||
|
||||
Self {}
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_main() -> Result<(), Error> {
|
||||
run_cli!({
|
||||
command: deno_api,
|
||||
app: app => app
|
||||
.name("StartOS Deno Executor")
|
||||
.version(&**VERSION_STRING),
|
||||
context: _m => DenoContext,
|
||||
exit: |e: RpcError| {
|
||||
match e.data {
|
||||
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
|
||||
Some(Value::Object(o)) => if let Some(Value::String(s)) = o.get("details") {
|
||||
eprintln!("{}: {}", e.message, s);
|
||||
if let Some(Value::String(s)) = o.get("debug") {
|
||||
tracing::debug!("{}", s)
|
||||
}
|
||||
}
|
||||
Some(a) => eprintln!("{}: {}", e.message, a),
|
||||
None => eprintln!("{}", e.message),
|
||||
}
|
||||
|
||||
std::process::exit(e.code);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
match inner_main() {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.source);
|
||||
tracing::debug!("{:?}", e.source);
|
||||
drop(e.source);
|
||||
std::process::exit(e.kind as i32)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
use std::net::{Ipv6Addr, SocketAddr};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
@@ -7,7 +7,7 @@ use helpers::NonDetachingJoinHandle;
|
||||
use tokio::process::Command;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::context::rpc::RpcContextConfig;
|
||||
use crate::context::config::ServerConfig;
|
||||
use crate::context::{DiagnosticContext, InstallContext, SetupContext};
|
||||
use crate::disk::fsck::{RepairStrategy, RequiresReboot};
|
||||
use crate::disk::main::DEFAULT_PASSWORD;
|
||||
@@ -21,7 +21,7 @@ use crate::util::Invoke;
|
||||
use crate::{Error, ErrorKind, ResultExt, PLATFORM};
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||
async fn setup_or_init(config: &ServerConfig) -> Result<Option<Shutdown>, Error> {
|
||||
let song = NonDetachingJoinHandle::from(tokio::spawn(async {
|
||||
loop {
|
||||
BEP.play().await.unwrap();
|
||||
@@ -82,13 +82,12 @@ async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Er
|
||||
.invoke(crate::ErrorKind::OpenSsh)
|
||||
.await?;
|
||||
|
||||
let ctx = InstallContext::init(cfg_path).await?;
|
||||
let ctx = InstallContext::init().await?;
|
||||
|
||||
let server = WebServer::install(
|
||||
SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80),
|
||||
ctx.clone(),
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
drop(song);
|
||||
tokio::time::sleep(Duration::from_secs(1)).await; // let the record state that I hate this
|
||||
@@ -109,26 +108,24 @@ async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Er
|
||||
.await
|
||||
.is_err()
|
||||
{
|
||||
let ctx = SetupContext::init(cfg_path).await?;
|
||||
let ctx = SetupContext::init(config)?;
|
||||
|
||||
let server = WebServer::setup(
|
||||
SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80),
|
||||
ctx.clone(),
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
drop(song);
|
||||
tokio::time::sleep(Duration::from_secs(1)).await; // let the record state that I hate this
|
||||
CHIME.play().await?;
|
||||
|
||||
ctx.shutdown
|
||||
.subscribe()
|
||||
.recv()
|
||||
.await
|
||||
.expect("context dropped");
|
||||
let mut shutdown = ctx.shutdown.subscribe();
|
||||
shutdown.recv().await.expect("context dropped");
|
||||
|
||||
server.shutdown().await;
|
||||
|
||||
drop(shutdown);
|
||||
|
||||
tokio::task::yield_now().await;
|
||||
if let Err(e) = Command::new("killall")
|
||||
.arg("firefox-esr")
|
||||
@@ -139,13 +136,12 @@ async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Er
|
||||
tracing::debug!("{:?}", e);
|
||||
}
|
||||
} else {
|
||||
let cfg = RpcContextConfig::load(cfg_path).await?;
|
||||
let guid_string = tokio::fs::read_to_string("/media/embassy/config/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
|
||||
.await?;
|
||||
let guid = guid_string.trim();
|
||||
let requires_reboot = crate::disk::main::import(
|
||||
guid,
|
||||
cfg.datadir(),
|
||||
config.datadir(),
|
||||
if tokio::fs::metadata(REPAIR_DISK_PATH).await.is_ok() {
|
||||
RepairStrategy::Aggressive
|
||||
} else {
|
||||
@@ -164,13 +160,13 @@ async fn setup_or_init(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Er
|
||||
.with_ctx(|_| (crate::ErrorKind::Filesystem, REPAIR_DISK_PATH))?;
|
||||
}
|
||||
if requires_reboot.0 {
|
||||
crate::disk::main::export(guid, cfg.datadir()).await?;
|
||||
crate::disk::main::export(guid, config.datadir()).await?;
|
||||
Command::new("reboot")
|
||||
.invoke(crate::ErrorKind::Unknown)
|
||||
.await?;
|
||||
}
|
||||
tracing::info!("Loaded Disk");
|
||||
crate::init::init(&cfg).await?;
|
||||
crate::init::init(config).await?;
|
||||
drop(song);
|
||||
}
|
||||
|
||||
@@ -196,7 +192,7 @@ async fn run_script_if_exists<P: AsRef<Path>>(path: P) {
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||
async fn inner_main(config: &ServerConfig) -> Result<Option<Shutdown>, Error> {
|
||||
if &*PLATFORM == "raspberrypi" && tokio::fs::metadata(STANDBY_MODE_PATH).await.is_ok() {
|
||||
tokio::fs::remove_file(STANDBY_MODE_PATH).await?;
|
||||
Command::new("sync").invoke(ErrorKind::Filesystem).await?;
|
||||
@@ -208,7 +204,7 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
|
||||
run_script_if_exists("/media/embassy/config/preinit.sh").await;
|
||||
|
||||
let res = match setup_or_init(cfg_path.clone()).await {
|
||||
let res = match setup_or_init(config).await {
|
||||
Err(e) => {
|
||||
async move {
|
||||
tracing::error!("{}", e.source);
|
||||
@@ -216,7 +212,7 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
crate::sound::BEETHOVEN.play().await?;
|
||||
|
||||
let ctx = DiagnosticContext::init(
|
||||
cfg_path,
|
||||
config,
|
||||
if tokio::fs::metadata("/media/embassy/config/disk.guid")
|
||||
.await
|
||||
.is_ok()
|
||||
@@ -231,14 +227,12 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
None
|
||||
},
|
||||
e,
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
let server = WebServer::diagnostic(
|
||||
SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80),
|
||||
ctx.clone(),
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
let shutdown = ctx.shutdown.subscribe().recv().await.unwrap();
|
||||
|
||||
@@ -256,23 +250,13 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
res
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let matches = clap::App::new("start-init")
|
||||
.arg(
|
||||
clap::Arg::with_name("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let cfg_path = matches.value_of("config").map(|p| Path::new(p).to_owned());
|
||||
pub fn main(config: &ServerConfig) {
|
||||
let res = {
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("failed to initialize runtime");
|
||||
rt.block_on(inner_main(cfg_path))
|
||||
rt.block_on(inner_main(config))
|
||||
};
|
||||
|
||||
match res {
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
use rpc_toolkit::run_cli;
|
||||
use rpc_toolkit::yajrc::RpcError;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::context::SdkContext;
|
||||
use crate::util::logger::EmbassyLogger;
|
||||
use crate::version::{Current, VersionT};
|
||||
use crate::Error;
|
||||
|
||||
lazy_static::lazy_static! {
|
||||
static ref VERSION_STRING: String = Current::new().semver().to_string();
|
||||
}
|
||||
|
||||
fn inner_main() -> Result<(), Error> {
|
||||
run_cli!({
|
||||
command: crate::portable_api,
|
||||
app: app => app
|
||||
.name("StartOS SDK")
|
||||
.version(&**VERSION_STRING)
|
||||
.arg(
|
||||
clap::Arg::with_name("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.takes_value(true),
|
||||
),
|
||||
context: matches => {
|
||||
if let Err(_) = std::env::var("RUST_LOG") {
|
||||
std::env::set_var("RUST_LOG", "embassy=warn,js_engine=warn");
|
||||
}
|
||||
EmbassyLogger::init();
|
||||
SdkContext::init(matches)?
|
||||
},
|
||||
exit: |e: RpcError| {
|
||||
match e.data {
|
||||
Some(Value::String(s)) => eprintln!("{}: {}", e.message, s),
|
||||
Some(Value::Object(o)) => if let Some(Value::String(s)) = o.get("details") {
|
||||
eprintln!("{}: {}", e.message, s);
|
||||
if let Some(Value::String(s)) = o.get("debug") {
|
||||
tracing::debug!("{}", s)
|
||||
}
|
||||
}
|
||||
Some(a) => eprintln!("{}: {}", e.message, a),
|
||||
None => eprintln!("{}", e.message),
|
||||
}
|
||||
std::process::exit(e.code);
|
||||
}
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
match inner_main() {
|
||||
Ok(_) => (),
|
||||
Err(e) => {
|
||||
eprintln!("{}", e.source);
|
||||
tracing::debug!("{:?}", e.source);
|
||||
drop(e.source);
|
||||
std::process::exit(e.kind as i32)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,15 @@
|
||||
use std::ffi::OsString;
|
||||
use std::net::{Ipv6Addr, SocketAddr};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::eyre;
|
||||
use futures::{FutureExt, TryFutureExt};
|
||||
use tokio::signal::unix::signal;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::context::config::ServerConfig;
|
||||
use crate::context::{DiagnosticContext, RpcContext};
|
||||
use crate::net::web_server::WebServer;
|
||||
use crate::shutdown::Shutdown;
|
||||
@@ -15,10 +18,10 @@ use crate::util::logger::EmbassyLogger;
|
||||
use crate::{Error, ErrorKind, ResultExt};
|
||||
|
||||
#[instrument(skip_all)]
|
||||
async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error> {
|
||||
async fn inner_main(config: &ServerConfig) -> Result<Option<Shutdown>, Error> {
|
||||
let (rpc_ctx, server, shutdown) = async {
|
||||
let rpc_ctx = RpcContext::init(
|
||||
cfg_path,
|
||||
config,
|
||||
Arc::new(
|
||||
tokio::fs::read_to_string("/media/embassy/config/disk.guid") // unique identifier for volume group - keeps track of the disk that goes with your embassy
|
||||
.await?
|
||||
@@ -31,8 +34,7 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
let server = WebServer::main(
|
||||
SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80),
|
||||
rpc_ctx.clone(),
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
let mut shutdown_recv = rpc_ctx.shutdown.subscribe();
|
||||
|
||||
@@ -102,32 +104,23 @@ async fn inner_main(cfg_path: Option<PathBuf>) -> Result<Option<Shutdown>, Error
|
||||
Ok(shutdown)
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
pub fn main(args: impl IntoIterator<Item = OsString>) {
|
||||
EmbassyLogger::init();
|
||||
|
||||
let config = ServerConfig::parse_from(args).load().unwrap();
|
||||
|
||||
if !Path::new("/run/embassy/initialized").exists() {
|
||||
super::start_init::main();
|
||||
super::start_init::main(&config);
|
||||
std::fs::write("/run/embassy/initialized", "").unwrap();
|
||||
}
|
||||
|
||||
let matches = clap::App::new("startd")
|
||||
.arg(
|
||||
clap::Arg::with_name("config")
|
||||
.short('c')
|
||||
.long("config")
|
||||
.takes_value(true),
|
||||
)
|
||||
.get_matches();
|
||||
|
||||
let cfg_path = matches.value_of("config").map(|p| Path::new(p).to_owned());
|
||||
|
||||
let res = {
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()
|
||||
.expect("failed to initialize runtime");
|
||||
rt.block_on(async {
|
||||
match inner_main(cfg_path.clone()).await {
|
||||
match inner_main(&config).await {
|
||||
Ok(a) => Ok(a),
|
||||
Err(e) => {
|
||||
async {
|
||||
@@ -135,7 +128,7 @@ pub fn main() {
|
||||
tracing::debug!("{:?}", e.source);
|
||||
crate::sound::BEETHOVEN.play().await?;
|
||||
let ctx = DiagnosticContext::init(
|
||||
cfg_path,
|
||||
&config,
|
||||
if tokio::fs::metadata("/media/embassy/config/disk.guid")
|
||||
.await
|
||||
.is_ok()
|
||||
@@ -150,14 +143,12 @@ pub fn main() {
|
||||
None
|
||||
},
|
||||
e,
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
let server = WebServer::diagnostic(
|
||||
SocketAddr::new(Ipv6Addr::UNSPECIFIED.into(), 80),
|
||||
ctx.clone(),
|
||||
)
|
||||
.await?;
|
||||
)?;
|
||||
|
||||
let mut shutdown = ctx.shutdown.subscribe();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user