diff options
author | Neil Kollack <nkollack@gmail.com> | 2022-03-20 00:32:28 -0500 |
---|---|---|
committer | Toby Vincent <tobyv13@gmail.com> | 2022-03-20 00:32:28 -0500 |
commit | 2d377920fd2b624a2a58a051607152ab324a8614 (patch) | |
tree | e954aa23274f54f3f37c4e21156bd6ba6c2112fd | |
parent | cc268a453a31b04e9b8ae4b9a8276b7cf78d90d3 (diff) |
feat: implement basic terminal
-rw-r--r-- | Cargo.lock | 175 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | zoned/Cargo.toml | 2 | ||||
-rw-r--r-- | zoned/src/api.rs | 87 | ||||
-rw-r--r-- | zoned/src/main.rs | 2 |
5 files changed, 262 insertions, 6 deletions
@@ -62,9 +62,11 @@ checksum = "c9f346c92c1e9a71d14fe4aaf7c2a5d9932cc4e5e48d8fb6641524416eb79ddd" dependencies = [ "async-trait", "axum-core", + "base64", "bitflags", "bytes", "futures-util", + "headers", "http", "http-body", "hyper", @@ -76,8 +78,10 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sha-1 0.10.0", "sync_wrapper", "tokio", + "tokio-tungstenite", "tower", "tower-http", "tower-layer", @@ -111,6 +115,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] name = "bumpalo" version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -127,6 +149,12 @@ dependencies = [ ] [[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -213,6 +241,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" [[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] name = "darling" version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -279,6 +326,25 @@ dependencies = [ ] [[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer 0.10.2", + "crypto-common", +] + +[[package]] name = "either" version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -381,6 +447,7 @@ checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ "futures-core", "futures-io", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -389,6 +456,16 @@ dependencies = [ ] [[package]] +name = "generic-array" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] name = "getrandom" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -425,6 +502,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] +name = "headers" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +dependencies = [ + "base64", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha-1 0.10.0", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] name = "heck" version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -733,6 +835,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] name = "openssl" version = "0.10.38" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1165,6 +1273,30 @@ dependencies = [ ] [[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.3", +] + +[[package]] name = "sharded-slab" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1403,6 +1535,18 @@ dependencies = [ ] [[package]] +name = "tokio-tungstenite" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e80b39df6afcc12cdf752398ade96a6b9e99c903dfdc36e53ad10b9c366bca72" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite", +] + +[[package]] name = "tokio-util" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1553,6 +1697,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] +name = "tungstenite" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" +dependencies = [ + "base64", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand", + "sha-1 0.9.8", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] name = "uncased" version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1607,6 +1776,12 @@ dependencies = [ ] [[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] name = "utf8-width" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1,3 +1,3 @@ [workspace] members = ["zone", "zone_core", "zone_nspawn", "zone_zfs", "zoned"] -default-members = ["zone"] +default-members = ["zone", "zoned"] diff --git a/zoned/Cargo.toml b/zoned/Cargo.toml index 201dd3f..faeee3f 100644 --- a/zoned/Cargo.toml +++ b/zoned/Cargo.toml @@ -14,7 +14,7 @@ workspace = ".." [dependencies] anyhow = "1.0.53" -axum = { version = "0.4.8", features = ["json"] } +axum = { version = "0.4.8", features = ["json", "ws", "headers", "http2"] } figment = { version = "0.10.6", features = ["toml", "env", "test"] } serde = "1.0.136" serde_json = "1.0.79" diff --git a/zoned/src/api.rs b/zoned/src/api.rs index 8dc2c39..3e5c85e 100644 --- a/zoned/src/api.rs +++ b/zoned/src/api.rs @@ -1,9 +1,14 @@ use axum::{ - extract::{Extension, Query}, + extract::{ + Extension, + Query, + ws::{Message, WebSocket, WebSocketUpgrade}, + TypedHeader, + }, routing::{get, post}, - Json, Router, + Json, Router, response::IntoResponse, headers, }; -use std::sync::Arc; +use std::{sync::Arc, process::Command}; use tracing::warn; use zone_core::{Container, ContainerOptions, FilterContainer}; use zone_nspawn::NSpawn; @@ -15,6 +20,7 @@ pub fn build_routes() -> Router { .route("/test", get(test_endpoint)) .route("/container", post(clone_container)) .route("/container/list?<container..>", get(container_list)) + .route("/ws", get(ws_handler)) } /// # Test endpoint @@ -59,3 +65,78 @@ async fn clone_container( .map_err(Error::from) .map(Container::into) } + +async fn ws_handler( + ws: WebSocketUpgrade, + user_agent: Option<TypedHeader<headers::UserAgent>>, +) -> impl IntoResponse { + if let Some(TypedHeader(user_agent)) = user_agent { + println!("`{}` connected", user_agent.as_str()); + } + + ws.on_upgrade(handle_socket) +} + +async fn handle_socket(mut socket: WebSocket) { + let mut term_input: Vec<String> = Vec::new(); + + loop { + if let Some(msg) = socket.recv().await { + if let Ok(msg) = msg { + match msg { + Message::Text(t) => { + println!("client send str: {:?}", t); + // Enter + if t.eq("\r") { + let response = parse_command(term_input.to_owned()).await; + if socket.send(Message::Text(response)).await.is_err() { + println!("send failed"); + return; + } + term_input = Vec::new(); + // Backspace + } else if t.eq("\u{7f}") { + term_input.pop(); + } else { + term_input.push(t.to_owned()); + } + } + Message::Close(_) => { + println!("client disconnected"); + return; + } + _ => {return;} + } + } else { + println!("client disconnected"); + return; + } + } + } +} + +async fn parse_command(input: Vec<String>) -> String { + let temp = input.concat(); + let cmd: Vec<&str> = temp.split(' ').collect(); + + let output = if cmd.len() <= 1 { + Command::new(cmd[0]) + .output().ok() + } else { + let mut args = cmd.to_owned(); + args.remove(0); + + Command::new(cmd[0]) + .args(args) + .output().ok() + }; + + match output { + Some(x) => if x.status.success() { + String::from_utf8(x.stdout).unwrap() + } else { + String::from_utf8(x.stderr).unwrap() + } + _ => String::from("") + } +}
\ No newline at end of file diff --git a/zoned/src/main.rs b/zoned/src/main.rs index 11180f3..019c9e0 100644 --- a/zoned/src/main.rs +++ b/zoned/src/main.rs @@ -32,7 +32,7 @@ async fn main() { }; let routes = build_routes().layer(Extension(shared_state)); - let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); + let addr = SocketAddr::from(([172, 21, 110, 173], 3001)); debug!("listening on {}", addr); axum::Server::bind(&addr) |