mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-15 22:27:26 +08:00
support ohos (#974)
* support ohos --------- Co-authored-by: FrankHan <2777926911@qq.com>
This commit is contained in:
148
easytier-contrib/easytier-ohrs/src/lib.rs
Normal file
148
easytier-contrib/easytier-ohrs/src/lib.rs
Normal file
@@ -0,0 +1,148 @@
|
||||
mod native_log;
|
||||
|
||||
use easytier::common::config::{ConfigLoader, TomlConfigLoader};
|
||||
use easytier::instance_manager::NetworkInstanceManager;
|
||||
use easytier::launcher::ConfigSource;
|
||||
use napi_derive_ohos::napi;
|
||||
use ohos_hilog_binding::{hilog_debug, hilog_error};
|
||||
use std::format;
|
||||
use uuid::Uuid;
|
||||
|
||||
static INSTANCE_MANAGER: once_cell::sync::Lazy<NetworkInstanceManager> =
|
||||
once_cell::sync::Lazy::new(NetworkInstanceManager::new);
|
||||
|
||||
#[napi(object)]
|
||||
pub struct KeyValuePair {
|
||||
pub key: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn set_tun_fd(
|
||||
inst_id: String,
|
||||
fd: i32,
|
||||
) -> bool {
|
||||
match Uuid::try_parse(&inst_id) {
|
||||
Ok(uuid) => {
|
||||
match INSTANCE_MANAGER.set_tun_fd(&uuid, fd) {
|
||||
Ok(_) => {
|
||||
hilog_debug!("[Rust] set tun fd {} to {}.", fd, inst_id);
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] cant set tun fd {} to {}. {}", fd, inst_id, e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] cant covert {} to uuid. {}", inst_id, e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn parse_config(cfg_str: String) -> bool {
|
||||
match TomlConfigLoader::new_from_str(&cfg_str) {
|
||||
Ok(_) => {
|
||||
true
|
||||
}
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] parse config failed {}", e);
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn run_network_instance(cfg_str: String) -> bool {
|
||||
let cfg = match TomlConfigLoader::new_from_str(&cfg_str) {
|
||||
Ok(cfg) => cfg,
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] parse config failed {}", e);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
if INSTANCE_MANAGER.list_network_instance_ids().len() > 0 {
|
||||
hilog_error!("[Rust] there is a running instance!");
|
||||
return false;
|
||||
}
|
||||
|
||||
let inst_id = cfg.get_id();
|
||||
if INSTANCE_MANAGER
|
||||
.list_network_instance_ids()
|
||||
.contains(&inst_id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
INSTANCE_MANAGER
|
||||
.run_network_instance(cfg, ConfigSource::FFI)
|
||||
.unwrap();
|
||||
true
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn stop_network_instance(inst_names: Vec<String>) {
|
||||
INSTANCE_MANAGER
|
||||
.delete_network_instance(
|
||||
inst_names
|
||||
.into_iter()
|
||||
.filter_map(|s| Uuid::parse_str(&s).ok())
|
||||
.collect(),
|
||||
)
|
||||
.unwrap();
|
||||
hilog_debug!("[Rust] stop_network_instance");
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn collect_network_infos() -> Vec<KeyValuePair> {
|
||||
let mut result = Vec::new();
|
||||
match INSTANCE_MANAGER.collect_network_infos() {
|
||||
Ok(map) => {
|
||||
for (uuid, info) in map.iter() {
|
||||
// convert value to json string
|
||||
let value = match serde_json::to_string(&info) {
|
||||
Ok(value) => value,
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] failed to serialize instance {} info: {}", uuid, e);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
result.push(KeyValuePair {
|
||||
key: uuid.clone().to_string(),
|
||||
value: value.clone(),
|
||||
});
|
||||
}
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn collect_running_network() -> Vec<String> {
|
||||
INSTANCE_MANAGER
|
||||
.list_network_instance_ids()
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|id| id.to_string())
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn is_running_network(inst_id: String) -> bool {
|
||||
match Uuid::try_parse(&inst_id) {
|
||||
Ok(uuid) => {
|
||||
INSTANCE_MANAGER
|
||||
.list_network_instance_ids()
|
||||
.contains(&uuid)
|
||||
}
|
||||
Err(e) => {
|
||||
hilog_error!("[Rust] cant covert {} to uuid. {}", inst_id, e);
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
98
easytier-contrib/easytier-ohrs/src/native_log.rs
Normal file
98
easytier-contrib/easytier-ohrs/src/native_log.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use std::collections::HashMap;
|
||||
use std::panic;
|
||||
use napi_derive_ohos::napi;
|
||||
use ohos_hilog_binding::{hilog_debug, hilog_error, hilog_info, hilog_warn, set_global_options, LogOptions};
|
||||
use tracing::{Event, Subscriber};
|
||||
use tracing_core::Level;
|
||||
use tracing_subscriber::layer::{Context, Layer};
|
||||
use tracing_subscriber::prelude::*;
|
||||
|
||||
static INITIALIZED: std::sync::Once = std::sync::Once::new();
|
||||
fn panic_hook(info: &panic::PanicHookInfo) {
|
||||
hilog_error!("RUST PANIC: {}", info);
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn init_panic_hook() {
|
||||
INITIALIZED.call_once(|| {
|
||||
panic::set_hook(Box::new(panic_hook));
|
||||
});
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn hilog_global_options(
|
||||
domain: u32,
|
||||
tag: String,
|
||||
) {
|
||||
ohos_hilog_binding::forward_stdio_to_hilog();
|
||||
set_global_options(LogOptions{
|
||||
domain,
|
||||
tag: Box::leak(tag.clone().into_boxed_str()),
|
||||
})
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub fn init_tracing_subscriber() {
|
||||
tracing_subscriber::registry()
|
||||
.with(
|
||||
CallbackLayer {
|
||||
callback: Box::new(tracing_callback),
|
||||
}
|
||||
)
|
||||
.init();
|
||||
}
|
||||
|
||||
fn tracing_callback(event: &Event, fields: HashMap<String, String>) {
|
||||
let metadata = event.metadata();
|
||||
#[cfg(target_env = "ohos")]
|
||||
{
|
||||
let loc = metadata.target().split("::").last().unwrap();
|
||||
match *metadata.level() {
|
||||
Level::TRACE => {
|
||||
hilog_debug!("[{}] {:?}", loc, fields.values().collect::<Vec<_>>());
|
||||
}
|
||||
Level::DEBUG => {
|
||||
hilog_debug!("[{}] {:?}", loc, fields.values().collect::<Vec<_>>());
|
||||
}
|
||||
Level::INFO => {
|
||||
hilog_info!("[{}] {:?}", loc, fields.values().collect::<Vec<_>>());
|
||||
}
|
||||
Level::WARN => {
|
||||
hilog_warn!("[{}] {:?}", loc, fields.values().collect::<Vec<_>>());
|
||||
}
|
||||
Level::ERROR => {
|
||||
hilog_error!("[{}] {:?}", loc, fields.values().collect::<Vec<_>>());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CallbackLayer {
|
||||
callback: Box<dyn Fn(&Event, HashMap<String, String>) + Send + Sync>,
|
||||
}
|
||||
|
||||
impl<S: Subscriber> Layer<S> for CallbackLayer {
|
||||
fn on_event(&self, event: &Event, _ctx: Context<S>) {
|
||||
// 使用 fmt::format::FmtSpan 提取字段值
|
||||
let mut fields = HashMap::new();
|
||||
let mut visitor = FieldCollector(&mut fields);
|
||||
event.record(&mut visitor);
|
||||
(self.callback)(event, fields);
|
||||
}
|
||||
}
|
||||
|
||||
struct FieldCollector<'a>(&'a mut HashMap<String, String>);
|
||||
|
||||
impl<'a> tracing::field::Visit for FieldCollector<'a> {
|
||||
fn record_i64(&mut self, field: &tracing::field::Field, value: i64) {
|
||||
self.0.insert(field.name().to_string(), value.to_string());
|
||||
}
|
||||
|
||||
fn record_str(&mut self, field: &tracing::field::Field, value: &str) {
|
||||
self.0.insert(field.name().to_string(), value.to_string());
|
||||
}
|
||||
|
||||
fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) {
|
||||
self.0.insert(field.name().to_string(), format!("{:?}", value));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user