mirror of
https://github.com/Astatin3/unshell.git
synced 2026-06-08 14:36:01 -06:00
Work on custom binaries
This commit is contained in:
Generated
+20
-5
@@ -3267,6 +3267,13 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "server2"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"unshell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
@@ -3933,7 +3940,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unshell-crypt"
|
name = "unshell-crypt"
|
||||||
version = "0.0.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"block-padding 0.4.2",
|
"block-padding 0.4.2",
|
||||||
@@ -3947,7 +3954,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unshell-gui"
|
name = "unshell-gui"
|
||||||
version = "0.0.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"eframe",
|
"eframe",
|
||||||
@@ -3967,7 +3974,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unshell-manager"
|
name = "unshell-manager"
|
||||||
version = "0.0.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"libc",
|
"libc",
|
||||||
@@ -3978,7 +3985,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unshell-obfuscate"
|
name = "unshell-obfuscate"
|
||||||
version = "0.0.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -3989,8 +3996,16 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unshell-server"
|
name = "unshell-payload"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"server2",
|
||||||
|
"unshell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unshell-server"
|
||||||
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"axum-extra",
|
"axum-extra",
|
||||||
|
|||||||
+16
-10
@@ -1,4 +1,4 @@
|
|||||||
cargo-features = ["trim-paths"]
|
cargo-features = ["trim-paths", "panic-immediate-abort"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "unshell"
|
name = "unshell"
|
||||||
@@ -14,11 +14,14 @@ include = ["LICENSE-APACHE", "LICENSE-MIT", "**/*.rs", "Cargo.toml"]
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
# Binaries
|
# Binaries
|
||||||
"unshell-gui", "unshell-server",
|
"unshell-gui",
|
||||||
|
|
||||||
|
# UnShell Binaries
|
||||||
|
"unshell-server", "unshell-payload",
|
||||||
|
|
||||||
# Libraries
|
# Libraries
|
||||||
"unshell-manager", "unshell-obfuscate", "unshell-crypt"
|
"unshell-manager", "unshell-obfuscate", "unshell-crypt"
|
||||||
]
|
, "core-modules/server2"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
@@ -51,18 +54,21 @@ toml = "0.9.9"
|
|||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
opt-level = 2
|
opt-level = 2
|
||||||
# strip = true # Strip symbols from the binary
|
|
||||||
# opt-level = "z" # Optimize for size
|
|
||||||
# lto = true # Link tree optimization
|
|
||||||
# codegen-units = 1
|
|
||||||
# panic = "abort"
|
|
||||||
# debug = false # Remove debug
|
|
||||||
# trim-paths="all"
|
|
||||||
|
|
||||||
# Optimize all dependencies even in debug builds:
|
# Optimize all dependencies even in debug builds:
|
||||||
[profile.dev.package."*"]
|
[profile.dev.package."*"]
|
||||||
opt-level = 2
|
opt-level = 2
|
||||||
|
|
||||||
|
[profile.minimize]
|
||||||
|
inherits = "release"
|
||||||
|
strip = true # Strip symbols from the binary
|
||||||
|
opt-level = "z" # Optimize for size
|
||||||
|
lto = true # Link tree optimization
|
||||||
|
codegen-units = 1
|
||||||
|
panic = "immediate-abort"
|
||||||
|
debug = false # Remove debug
|
||||||
|
trim-paths="all"
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------------------
|
||||||
# Lints:
|
# Lints:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
# # -Cpanic=immediate-abort
|
||||||
|
# RUSTFLAGS="-Zunstable-options -Zlocation-detail=none -Zfmt-debug=none" \
|
||||||
|
# cargo +nightly build \
|
||||||
|
# -Z build-std=std,panic_abort \
|
||||||
|
# -Z build-std-features= \
|
||||||
|
# --profile minimize -p unshell-payload -- $@
|
||||||
|
|
||||||
|
cargo build --profile minimize -p unshell-payload
|
||||||
|
|
||||||
|
export BINARY=./target/minimize/unshell-payload
|
||||||
|
|
||||||
|
declare -a headers=(
|
||||||
|
".gnu_debuglink" # - Debug information link
|
||||||
|
".comment" #- Compiler version info
|
||||||
|
".shstrtab" #- Section header string table (only needed by tools like readelf)
|
||||||
|
".note.gnu.bu" ".note.gnu.build-id" # - Build ID note
|
||||||
|
".eh_frame" ".eh_frame_hdr" # Exception handling info (can break C++ exceptions if removed)
|
||||||
|
#".gnu.version" ".gnu.version_r" # Symbol versioning (may be needed for some shared libraries)
|
||||||
|
".gnu.hash" # Hash table for symbol lookup optimization
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# .shstrtab
|
||||||
|
# .interp
|
||||||
|
# .note.ABI-tag
|
||||||
|
# .dynsym
|
||||||
|
# .dynstr
|
||||||
|
# .rela.dyn
|
||||||
|
# .rodata
|
||||||
|
# .text
|
||||||
|
# .init
|
||||||
|
# .fini
|
||||||
|
# .tbss
|
||||||
|
# .fini_array
|
||||||
|
# .init_array
|
||||||
|
# .data.rel.ro
|
||||||
|
# .dynamic
|
||||||
|
# .got
|
||||||
|
# .got.plt
|
||||||
|
# .relro_padding
|
||||||
|
# .tm_clone_table
|
||||||
|
# .data
|
||||||
|
# .bss
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: Implement FAKE section header comments and information
|
||||||
|
# Shuffle order of headers??
|
||||||
|
|
||||||
|
for section in "${headers[@]}"
|
||||||
|
do
|
||||||
|
strip --remove-section="$section" $BINARY
|
||||||
|
echo "Removed section header $section"
|
||||||
|
done
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
name="Client"
|
|
||||||
version="0.1"
|
|
||||||
description="Test Client module"
|
|
||||||
authors=["astatin3"]
|
|
||||||
|
|
||||||
|
|
||||||
[config]
|
|
||||||
header1 = { Header = "Header123" }
|
|
||||||
integer1 = { Integer = {}}
|
|
||||||
|
|
||||||
[build_config]
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
name="Server"
|
|
||||||
version="0.1"
|
|
||||||
description="Test server module for unshell"
|
|
||||||
authors=["astatin3"]
|
|
||||||
|
|
||||||
|
|
||||||
[config]
|
|
||||||
header1 = { Header = "Header123" }
|
|
||||||
integer1 = { Integer = {}}
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "server2"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
log = ["unshell/log"]
|
||||||
|
log_debug = ["unshell/log_debug"]
|
||||||
|
|
||||||
|
# [lib]
|
||||||
|
# crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
unshell.path = "../../"
|
||||||
|
|
||||||
|
[lints]
|
||||||
|
workspace = true
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
use unshell::info;
|
||||||
|
|
||||||
|
pub fn log_test_fn() {
|
||||||
|
info!("Testttttttt");
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
name="UnShell Core"
|
|
||||||
version="0.1"
|
|
||||||
description="Core components for UnShell"
|
|
||||||
authors=["astatin3"]
|
|
||||||
|
|
||||||
child_components = [
|
|
||||||
"client/unshell_component.toml",
|
|
||||||
"server/unshell_component.toml"
|
|
||||||
]
|
|
||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
pub mod config_struct;
|
pub mod config_struct;
|
||||||
pub mod config_struct_list;
|
// pub mod config_struct_list;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
pub use tree::{InterfaceData, InterfaceStruct, Tree, TreeMessage};
|
pub use tree::{InterfaceData, InterfaceStruct, Tree, TreeMessage};
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "unshell-crypt"
|
name = "unshell-crypt"
|
||||||
edition = "2024"
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
include.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes = "0.8.4"
|
aes = "0.8.4"
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "unshell-gui"
|
name = "unshell-gui"
|
||||||
edition = "2024"
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
include.workspace = true
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "unshell-manager"
|
name = "unshell-manager"
|
||||||
edition = "2024"
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
include.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
log = ["unshell/log"]
|
log = ["unshell/log"]
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "unshell-obfuscate"
|
name = "unshell-obfuscate"
|
||||||
edition = "2024"
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
include.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
obfuscate = []
|
obfuscate = []
|
||||||
|
|||||||
+13
-14
@@ -1,8 +1,18 @@
|
|||||||
|
cargo-features = ["trim-paths"]
|
||||||
|
|
||||||
[package]
|
[package]
|
||||||
name = "unshell-payload"
|
name = "unshell-payload"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
# [features]
|
# [lib]
|
||||||
|
# crate-type = ["cdylib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["log"]
|
||||||
|
log = ["unshell/log", "server2/log"]
|
||||||
|
log_debug = ["unshell/log_debug", "server2/log_debug"]
|
||||||
|
|
||||||
|
|
||||||
# obfuscate = ["unshell-obfuscate/obfuscate"]
|
# obfuscate = ["unshell-obfuscate/obfuscate"]
|
||||||
# log = ["unshell-lib/log"]
|
# log = ["unshell-lib/log"]
|
||||||
# log_debug = ["unshell-lib/log_debug"]
|
# log_debug = ["unshell-lib/log_debug"]
|
||||||
@@ -13,17 +23,6 @@ edition = "2024"
|
|||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# lazy_static = "1.5.0"
|
|
||||||
static_init = "1.0.4"
|
|
||||||
|
|
||||||
# unshell-lib = {path = "../unshell-lib", default-features = false}
|
unshell.path = "../"
|
||||||
unshell-obfuscate = {path = "../unshell-obfuscate"}
|
server2.path = "../core-modules/server2"
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
# strip = true # Strip symbols from the binary
|
|
||||||
# opt-level = "z" # Optimize for size
|
|
||||||
# lto = true # Link tree optimization
|
|
||||||
# codegen-units = 1
|
|
||||||
# panic = "abort"
|
|
||||||
# debug = false # Remove debug
|
|
||||||
# trim-paths="all"
|
|
||||||
|
|||||||
+69
-59
@@ -1,76 +1,86 @@
|
|||||||
use std::{any::Any, collections::HashMap, fs::File, io::Read};
|
use unshell::info;
|
||||||
|
|
||||||
use static_init::dynamic;
|
// use std::dyn
|
||||||
use unshell_lib::{
|
|
||||||
ModuleError,
|
|
||||||
config::{PayloadConfig, RuntimeConfig},
|
|
||||||
module::{Manager, Module},
|
|
||||||
};
|
|
||||||
use unshell_obfuscate::{obs, symbol};
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate unshell_lib;
|
|
||||||
|
|
||||||
// The main and initial 'configuration' for a payload
|
|
||||||
|
|
||||||
#[dynamic]
|
|
||||||
static PAYLOAD_CONFIG: PayloadConfig = PayloadConfig {
|
|
||||||
id: symbol!("Test ID"),
|
|
||||||
components: Vec::new(),
|
|
||||||
runtime_config: vec![RuntimeConfig {
|
|
||||||
parent_component: symbol!("client").to_string(),
|
|
||||||
name: symbol!("client runtime").to_string(),
|
|
||||||
config: HashMap::from([
|
|
||||||
(symbol!("host").to_string(), obs!("localhost:1234")),
|
|
||||||
(symbol!("retry").to_string(), obs!("1000")),
|
|
||||||
]),
|
|
||||||
}],
|
|
||||||
};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Init the logger
|
// Init the logger
|
||||||
#[cfg(not(feature = "obfuscate"))]
|
// #[cfg(not(feature = "obfuscate"))]
|
||||||
unshell_lib::logger::PrettyLogger::init();
|
unshell::logger::PrettyLogger::init();
|
||||||
|
|
||||||
debug!("Initialized");
|
server2::log_test_fn();
|
||||||
|
// info!("This is a string!");
|
||||||
match run() {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(e) => {
|
|
||||||
error!("ERROR! '{:?}'", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run() -> Result<(), Box<dyn std::error::Error>> {
|
// use std::{any::Any, collections::HashMap, fs::File, io::Read};
|
||||||
let args = std::env::args();
|
|
||||||
|
|
||||||
// TEMPORARY, load the module paths from command line args.
|
// use static_init::dynamic;
|
||||||
let mut modules = Vec::new();
|
// use unshell_lib::{
|
||||||
for arg in args.skip(1) {
|
// ModuleError,
|
||||||
// debug!("Loading module: {}", arg);
|
// config::{PayloadConfig, RuntimeConfig},
|
||||||
|
// module::{Manager, Module},
|
||||||
|
// };
|
||||||
|
// use unshell_obfuscate::{obs, symbol};
|
||||||
|
|
||||||
// let mut file = File::open(arg).map_err(|e| ModuleError::Error(e.to_string().into()))?;
|
// #[macro_use]
|
||||||
// let mut buffer = Vec::new();
|
// extern crate unshell_lib;
|
||||||
// file.read_to_end(&mut buffer)
|
|
||||||
// .map_err(|e| ModuleError::Error(e.to_string().into()))?;
|
|
||||||
|
|
||||||
debug!("Initializing module: {}", arg);
|
// // The main and initial 'configuration' for a payload
|
||||||
let module = Module::new(&arg)?;
|
|
||||||
|
|
||||||
modules.push(module);
|
// #[dynamic]
|
||||||
|
// static PAYLOAD_CONFIG: PayloadConfig = PayloadConfig {
|
||||||
|
// id: symbol!("Test ID"),
|
||||||
|
// components: Vec::new(),
|
||||||
|
// runtime_config: vec![RuntimeConfig {
|
||||||
|
// parent_component: symbol!("client").to_string(),
|
||||||
|
// name: symbol!("client runtime").to_string(),
|
||||||
|
// config: HashMap::from([
|
||||||
|
// (symbol!("host").to_string(), obs!("localhost:1234")),
|
||||||
|
// (symbol!("retry").to_string(), obs!("1000")),
|
||||||
|
// ]),
|
||||||
|
// }],
|
||||||
|
// };
|
||||||
|
|
||||||
// modules.push(Module::new(&arg)?)
|
// fn main() {
|
||||||
}
|
|
||||||
|
|
||||||
// let modules = vec
|
// debug!("Initialized");
|
||||||
|
|
||||||
debug!("Starting manager...");
|
// match run() {
|
||||||
|
// Ok(_) => {}
|
||||||
|
// Err(e) => {
|
||||||
|
// error!("ERROR! '{:?}'", e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
// Run the manager, this is blocking.
|
// fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let manager = Manager::start(&PAYLOAD_CONFIG, modules);
|
// let args = std::env::args();
|
||||||
|
|
||||||
Manager::join(manager);
|
// // TEMPORARY, load the module paths from command line args.
|
||||||
|
// let mut modules = Vec::new();
|
||||||
|
// for arg in args.skip(1) {
|
||||||
|
// // debug!("Loading module: {}", arg);
|
||||||
|
|
||||||
Ok(())
|
// // let mut file = File::open(arg).map_err(|e| ModuleError::Error(e.to_string().into()))?;
|
||||||
}
|
// // let mut buffer = Vec::new();
|
||||||
|
// // file.read_to_end(&mut buffer)
|
||||||
|
// // .map_err(|e| ModuleError::Error(e.to_string().into()))?;
|
||||||
|
|
||||||
|
// debug!("Initializing module: {}", arg);
|
||||||
|
// let module = Module::new(&arg)?;
|
||||||
|
|
||||||
|
// modules.push(module);
|
||||||
|
|
||||||
|
// // modules.push(Module::new(&arg)?)
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // let modules = vec
|
||||||
|
|
||||||
|
// debug!("Starting manager...");
|
||||||
|
|
||||||
|
// // Run the manager, this is blocking.
|
||||||
|
// let manager = Manager::start(&PAYLOAD_CONFIG, modules);
|
||||||
|
|
||||||
|
// Manager::join(manager);
|
||||||
|
|
||||||
|
// Ok(())
|
||||||
|
// }
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "unshell-server"
|
name = "unshell-server"
|
||||||
edition = "2024"
|
version.workspace = true
|
||||||
|
edition.workspace = true
|
||||||
|
authors.workspace = true
|
||||||
|
include.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["log_debug"]
|
default = ["log_debug"]
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use unshell::config::ConfigStructField;
|
|
||||||
|
|
||||||
// use crate::config::ConfigStructField;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
||||||
pub struct Blob {
|
|
||||||
name: String,
|
|
||||||
|
|
||||||
parent_component: String,
|
|
||||||
// parent_runtime: String,
|
|
||||||
config: HashMap<String, ConfigStructField>,
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
use serde_json::Value;
|
|
||||||
|
|
||||||
use crate::config::ConfigStructField;
|
|
||||||
|
|
||||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
|
||||||
pub enum Interface {
|
|
||||||
Sub(HashMap<String, InterfaceWrapper>),
|
|
||||||
Struct {
|
|
||||||
fields: HashMap<String, ConfigStructField>,
|
|
||||||
value: HashMap<String, Value>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, serde::Deserialize, serde::Serialize)]
|
|
||||||
pub struct InterfaceWrapper {
|
|
||||||
pub name: String,
|
|
||||||
pub interface: Interface,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InterfaceWrapper {
|
|
||||||
pub fn get_path(&self, elements: &Vec<&str>, depth: usize) -> Result<InterfaceWrapper, String> {
|
|
||||||
if depth == elements.len() {
|
|
||||||
return Ok(self.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let element = elements[depth];
|
|
||||||
|
|
||||||
match &self.interface {
|
|
||||||
Interface::Sub(interface_wrappers) => {
|
|
||||||
if let Some(interface) = interface_wrappers.get(element) {
|
|
||||||
interface.get_path(elements, depth)
|
|
||||||
} else {
|
|
||||||
Err("Invalid Path".into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => Err("Invalid Path".into()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_test_interface() -> InterfaceWrapper {
|
|
||||||
InterfaceWrapper {
|
|
||||||
name: "Root Interface".into(),
|
|
||||||
interface: Interface::Sub(HashMap::new()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
mod blob;
|
|
||||||
|
|
||||||
use std::{
|
|
||||||
collections::HashMap,
|
|
||||||
fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use unshell::{ModuleError, Result, debug, info};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
||||||
struct ComponentMetadata {
|
|
||||||
name: String,
|
|
||||||
description: Option<String>,
|
|
||||||
version: Option<String>,
|
|
||||||
authors: Option<Vec<String>>,
|
|
||||||
|
|
||||||
// Struct to contain build information
|
|
||||||
#[serde(default)]
|
|
||||||
build_config: BuildConfig,
|
|
||||||
|
|
||||||
// Other components that can be pointed to by this component
|
|
||||||
#[serde(default)]
|
|
||||||
child_components: Vec<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug, Clone, serde::Deserialize, serde::Serialize)]
|
|
||||||
struct BuildConfig {
|
|
||||||
// Cargo feature list of a component
|
|
||||||
// (Name, Description)
|
|
||||||
#[serde(default)]
|
|
||||||
features: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ComponentState {
|
|
||||||
metadata: ComponentMetadata,
|
|
||||||
path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn load_config(path: &PathBuf) -> Result<Vec<ComponentState>> {
|
|
||||||
let path_absolute =
|
|
||||||
fs::canonicalize(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
|
|
||||||
debug!("Loading data from path: `{:?}`", path_absolute);
|
|
||||||
|
|
||||||
// Read string as path
|
|
||||||
let config_str =
|
|
||||||
fs::read_to_string(path.clone()).map_err(|e| ModuleError::Error(e.to_string()))?;
|
|
||||||
|
|
||||||
// Load config from String
|
|
||||||
let config = toml::from_str::<ComponentMetadata>(&config_str)
|
|
||||||
.map_err(|e| ModuleError::Error(e.to_string()))?;
|
|
||||||
|
|
||||||
info!("Loaded component `{}`", config.name);
|
|
||||||
|
|
||||||
let parent_path = path_absolute.parent().expect("Path must have parent");
|
|
||||||
|
|
||||||
if config.child_components.is_empty() {
|
|
||||||
Ok(vec![ComponentState {
|
|
||||||
metadata: config,
|
|
||||||
path: PathBuf::from(parent_path),
|
|
||||||
}])
|
|
||||||
} else {
|
|
||||||
let mut config_vec = vec![];
|
|
||||||
|
|
||||||
// Load each child component
|
|
||||||
for component_path in &config.child_components {
|
|
||||||
let path = Path::join(parent_path, component_path);
|
|
||||||
let mut config = load_config(&path)?;
|
|
||||||
config_vec.append(&mut config);
|
|
||||||
}
|
|
||||||
|
|
||||||
config_vec.insert(
|
|
||||||
0,
|
|
||||||
ComponentState {
|
|
||||||
metadata: config,
|
|
||||||
path: PathBuf::from(parent_path),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(config_vec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn parse_toml() -> ComponentMetadata {
|
|
||||||
// let data = include_str!("../../test.toml");
|
|
||||||
|
|
||||||
// let config = toml::from_str(data).unwrap();
|
|
||||||
|
|
||||||
// config
|
|
||||||
// }
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
mod api;
|
mod api;
|
||||||
mod auth;
|
mod auth;
|
||||||
mod config;
|
// mod config;
|
||||||
pub mod logger;
|
pub mod logger;
|
||||||
mod server;
|
mod server;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user