aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeil Kollack <nkollack@gmail.com>2022-03-20 00:32:28 -0500
committerToby Vincent <tobyv13@gmail.com>2022-03-20 00:32:28 -0500
commit2d377920fd2b624a2a58a051607152ab324a8614 (patch)
treee954aa23274f54f3f37c4e21156bd6ba6c2112fd
parentcc268a453a31b04e9b8ae4b9a8276b7cf78d90d3 (diff)
feat: implement basic terminal
-rw-r--r--Cargo.lock175
-rw-r--r--Cargo.toml2
-rw-r--r--zoned/Cargo.toml2
-rw-r--r--zoned/src/api.rs87
-rw-r--r--zoned/src/main.rs2
5 files changed, 262 insertions, 6 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 911a1fa..c150b6d 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index f38326e..20679e1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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)