Skip to content

Commit

Permalink
wip: add macros crate
Browse files Browse the repository at this point in the history
  • Loading branch information
cilki committed Jan 1, 2025
1 parent d0c0a8e commit ac970a4
Show file tree
Hide file tree
Showing 11 changed files with 177 additions and 83 deletions.
155 changes: 91 additions & 64 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ members = [
"sandpolis",
"sandpolis-bootagent",
"sandpolis-client-mobile",
"sandpolis-macros",
]
12 changes: 12 additions & 0 deletions sandpolis-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "sandpolis-macros"
version = "0.1.0"
edition = "2021"

[lib]
proc-macro = true

[dependencies]
proc-macro2 = "1.0.92"
quote = "1.0.38"
syn = "2.0.93"
19 changes: 19 additions & 0 deletions sandpolis-macros/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{self, parse_macro_input, DeriveInput};

#[proc_macro_derive(Event)]
pub fn derive_event(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let name = input.ident;

let expanded = quote! {
impl Into<axum::extract::ws::Message> for #name {
fn into(self) -> axum::extract::ws::Message {
axum::extract::ws::Message::Binary(axum::body::Bytes::from(serde_cbor::to_vec(&self).unwrap()))
}
}
};

TokenStream::from(expanded)
}
2 changes: 2 additions & 0 deletions sandpolis/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ os_info = "3.8.2"
rand = "0.8.5"
reqwest = { version = "0.12.5", default-features = false, features = ["stream", "cookies", "json", "rustls-tls", "charset"] }
serde_bytes = "0.11.15"
serde_cbor = "0.11.2"
serde_json = "1.0.134"
serde = { version = "1.0.203", features = ["derive"] }
strum = { version = "0.26.3", features = ["derive"] }
Expand All @@ -29,6 +30,7 @@ tokio = { version = "1.42.0", features = ["full"] }
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
uuid = { version = "1.10.0", features = ["v7", "serde"] }
sandpolis-macros = { path = "../sandpolis-macros" }

# Server dependencies
axum-macros = { version = "0.4.1", optional = true }
Expand Down
5 changes: 5 additions & 0 deletions sandpolis/src/agent/layer/desktop/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
use axum::Router;

pub fn router() -> Router {
todo!()
}
5 changes: 5 additions & 0 deletions sandpolis/src/agent/layer/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
#[cfg(feature = "layer-desktop")]
pub mod desktop;
#[cfg(feature = "layer-package")]
pub mod package;
#[cfg(feature = "layer-shell")]
pub mod shell;
4 changes: 4 additions & 0 deletions sandpolis/src/agent/layer/package/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,7 @@ pub trait PackageManager {
bail!("Not implemented");
}
}

pub fn router() -> Router {
todo!()
}
45 changes: 28 additions & 17 deletions sandpolis/src/agent/layer/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use axum::{
self,
ws::{Message, WebSocket, WebSocketUpgrade},
},
http::StatusCode,
response::IntoResponse,
routing::{any, post},
Json, Router,
Expand All @@ -19,12 +20,9 @@ use tokio::{
};
use tracing::debug;

use crate::core::layer::{
network::stream::{StreamSink, StreamSource},
shell::{
ShellExecuteRequest, ShellExecuteResponse, ShellSessionData, ShellSessionInputEvent,
ShellSessionOutputEvent, ShellSessionRequest,
},
use crate::core::layer::shell::{
ShellExecuteRequest, ShellExecuteResponse, ShellSessionData, ShellSessionInputEvent,
ShellSessionOutputEvent, ShellSessionRequest,
};

pub struct ShellSession {
Expand All @@ -34,13 +32,20 @@ pub struct ShellSession {
}

impl ShellSession {
pub fn new() -> Self {}
pub fn new(request: ShellSessionRequest) -> Result<Self> {
Ok(Self {
process: Command::new(&request.path)
.envs(request.environment)
.spawn()?,
data: todo!(),
})
}

pub async fn run(&mut self, socket: WebSocket) {
pub async fn run(mut self, socket: WebSocket) {
let (mut sender, mut receiver) = socket.split();

let mut stdin = self.process.stdin.take().unwrap();
let mut stdin_task = tokio::spawn(async move {
let stdin = self.process.stdin.take().unwrap();
while let Some(Ok(msg)) = receiver.next().await {
match msg {
Message::Binary(data) => match stdin.write_all(&data).await {
Expand All @@ -53,8 +58,8 @@ impl ShellSession {
}
});

let mut stdout = self.process.stdout.take().unwrap();
let mut stdout_task = tokio::spawn(async move {
let stdout = self.process.stdout.take().unwrap();
loop {
let mut event = ShellSessionOutputEvent::default();
match stdout.read_buf(&mut event.stdout).await {
Expand Down Expand Up @@ -100,19 +105,22 @@ async fn shell_session(
// state: State<AppState>,
ws: WebSocketUpgrade,
extract::Json(request): extract::Json<ShellSessionRequest>,
) -> impl IntoResponse {
let mut session = ShellSession::new();
ws.on_upgrade(move |socket| session.run(socket))
) -> Result<(), StatusCode> {
let session = ShellSession::new(request).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

ws.on_upgrade(move |socket| session.run(socket));

Ok(())
}

#[debug_handler]
async fn shell_execute(
// state: State<AppState>,
extract::Json(request): extract::Json<ShellExecuteRequest>,
) -> Result<Json<ShellExecuteResponse>, axum::http::StatusCode> {
let cmd = Command::new(request.shell)
) -> Result<Json<ShellExecuteResponse>, StatusCode> {
let mut cmd = Command::new(request.shell)
.spawn()
.map_err(|_| axum::http::StatusCode::NOT_FOUND)?;
.map_err(|_| StatusCode::NOT_FOUND)?;

Ok(Json(if request.capture_output {
match timeout(Duration::from_secs(request.timeout), cmd.wait_with_output()).await {
Expand All @@ -122,7 +130,10 @@ async fn shell_execute(
} else {
match timeout(Duration::from_secs(request.timeout), cmd.wait()).await {
Ok(exit_status) => ShellExecuteResponse::Ok {
exit_code: exit_status,
exit_code: exit_status
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
.code()
.unwrap_or(-1),
duration: todo!(),
output: todo!(),
},
Expand Down
9 changes: 8 additions & 1 deletion sandpolis/src/agent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,8 @@ pub struct AgentCommandLine {
pub poll: Option<String>,

/// Agent socket
#[clap(long, value_parser = parse_storage_dir, default_value = default_storage_dir().into_os_string())]
#[clap(long)]
//, value_parser = parse_storage_dir, default_value = default_storage_dir().into_os_string())]
pub agent_socket: PathBuf,
}

Expand All @@ -220,6 +221,12 @@ pub async fn main(args: CommandLine) -> Result<()> {
#[cfg(feature = "layer-shell")]
let app = app.nest("/layer/shell", crate::agent::layer::shell::router());

#[cfg(feature = "layer-package")]
let app = app.nest("/layer/package", crate::agent::layer::package::router());

#[cfg(feature = "layer-desktop")]
let app = app.nest("/layer/desktop", crate::agent::layer::desktop::router());

axum::serve(uds, app.into_make_service()).await.unwrap();
});

Expand Down
3 changes: 2 additions & 1 deletion sandpolis/src/core/layer/shell.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::{collections::HashMap, path::PathBuf};

use sandpolis_macros::Event;
use serde::{Deserialize, Serialize};

pub struct ShellLayer {
Expand Down Expand Up @@ -168,7 +169,7 @@ pub struct ShellSessionInputEvent {
}

/// Event containing standard-output and standard-error
#[derive(Serialize, Deserialize, Default)]
#[derive(Serialize, Deserialize, Default, Event)]
pub struct ShellSessionOutputEvent {
pub stdout: Vec<u8>,
pub stderr: Vec<u8>,
Expand Down

0 comments on commit ac970a4

Please sign in to comment.