style: cargo fmt the workspace (release-gate cargo-fmt was red)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
412251ac9a
commit
db4de0ac96
@@ -64,8 +64,9 @@ impl RpcHandler {
|
||||
.and_then(|p| p.get("trust_level"))
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| {
|
||||
TrustLevel::parse(s)
|
||||
.ok_or_else(|| anyhow::anyhow!("Invalid trust_level: {s} (expected trusted|observer)"))
|
||||
TrustLevel::parse(s).ok_or_else(|| {
|
||||
anyhow::anyhow!("Invalid trust_level: {s} (expected trusted|observer)")
|
||||
})
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or(TrustLevel::Trusted);
|
||||
|
||||
@@ -292,9 +292,7 @@ impl RpcHandler {
|
||||
let r_hash_hex = inv
|
||||
.get("r_hash")
|
||||
.and_then(|v| v.as_str())
|
||||
.and_then(|b64| {
|
||||
base64::engine::general_purpose::STANDARD.decode(b64).ok()
|
||||
})
|
||||
.and_then(|b64| base64::engine::general_purpose::STANDARD.decode(b64).ok())
|
||||
.map(hex::encode)
|
||||
.unwrap_or_default();
|
||||
transactions.push(serde_json::json!({
|
||||
|
||||
@@ -56,9 +56,8 @@ impl RpcHandler {
|
||||
let words =
|
||||
crate::seed::load_lnd_aezeed_encrypted(&self.config.data_dir, &node_secret).await;
|
||||
node_secret.zeroize();
|
||||
let words = words.map_err(|_| {
|
||||
anyhow::anyhow!("Could not decrypt the saved Lightning seed backup")
|
||||
})?;
|
||||
let words = words
|
||||
.map_err(|_| anyhow::anyhow!("Could not decrypt the saved Lightning seed backup"))?;
|
||||
|
||||
let word_count = words.len();
|
||||
Ok(serde_json::json!({ "words": words, "word_count": word_count }))
|
||||
|
||||
@@ -478,7 +478,8 @@ impl RpcHandler {
|
||||
bytes,
|
||||
};
|
||||
let payload = message_types::encode_payload(&content)?;
|
||||
let envelope = TypedEnvelope::new(MeshMessageType::ContentInline, payload).with_seq(seq);
|
||||
let envelope =
|
||||
TypedEnvelope::new(MeshMessageType::ContentInline, payload).with_seq(seq);
|
||||
let wire = envelope.to_wire()?;
|
||||
if use_resource_transfer {
|
||||
svc.send_content_resource(
|
||||
@@ -583,8 +584,7 @@ impl RpcHandler {
|
||||
.map(|d| nodes.iter().any(|n| &n.did == d))
|
||||
.unwrap_or(false);
|
||||
|
||||
let est_seconds =
|
||||
(size.saturating_add(lora_bytes_per_sec - 1) / lora_bytes_per_sec).max(1);
|
||||
let est_seconds = (size.saturating_add(lora_bytes_per_sec - 1) / lora_bytes_per_sec).max(1);
|
||||
|
||||
let is_reticulum = device_type == crate::mesh::types::DeviceType::Reticulum;
|
||||
let (tier, reason) = if size <= MESH_AUTO_MAX {
|
||||
@@ -596,7 +596,10 @@ impl RpcHandler {
|
||||
("auto-mesh", "No Tor path — sending inline over mesh")
|
||||
}
|
||||
} else if is_reticulum && size <= RETICULUM_RESOURCE_MAX {
|
||||
("resource-mesh", "Sending directly over LoRa via a Reticulum resource transfer")
|
||||
(
|
||||
"resource-mesh",
|
||||
"Sending directly over LoRa via a Reticulum resource transfer",
|
||||
)
|
||||
} else if size <= TOR_LARGE_WARN {
|
||||
if has_tor {
|
||||
("tor-only", "Too large for mesh — Tor only")
|
||||
|
||||
@@ -214,8 +214,9 @@ pub(super) fn extract_client_ip(parts: &hyper::http::request::Parts) -> IpAddr {
|
||||
Some(ip) => ip,
|
||||
// No socket info recorded (shouldn't happen in the server path);
|
||||
// fall back to the pre-extension behavior.
|
||||
None => forwarded_client_ip(&parts.headers)
|
||||
.unwrap_or(IpAddr::V4(std::net::Ipv4Addr::LOCALHOST)),
|
||||
None => {
|
||||
forwarded_client_ip(&parts.headers).unwrap_or(IpAddr::V4(std::net::Ipv4Addr::LOCALHOST))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,10 +235,7 @@ mod client_ip_tests {
|
||||
use super::*;
|
||||
use std::net::SocketAddr;
|
||||
|
||||
fn parts_with(
|
||||
peer: Option<&str>,
|
||||
real_ip: Option<&str>,
|
||||
) -> hyper::http::request::Parts {
|
||||
fn parts_with(peer: Option<&str>, real_ip: Option<&str>) -> hyper::http::request::Parts {
|
||||
let mut builder = hyper::Request::builder().uri("/rpc/v1");
|
||||
if let Some(ip) = real_ip {
|
||||
builder = builder.header("x-real-ip", ip);
|
||||
|
||||
@@ -54,11 +54,11 @@ use hyper::{Request, Response, StatusCode};
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, error};
|
||||
|
||||
pub use middleware::PeerAddr;
|
||||
use middleware::{
|
||||
derive_csrf_token, extract_client_ip, extract_cookie, sanitize_error_message,
|
||||
CACHEABLE_METHODS, UNAUTHENTICATED_METHODS,
|
||||
};
|
||||
pub use middleware::PeerAddr;
|
||||
use response::{cookie_header, json_response, ResponseCache, RpcError, RpcRequest, RpcResponse};
|
||||
|
||||
/// Default dev password when no user is set up (matches mock-backend).
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
use super::RpcHandler;
|
||||
use crate::network::router as net_router;
|
||||
use anyhow::Result;
|
||||
use archipelago_openwrt::{
|
||||
detect,
|
||||
router::Router,
|
||||
tollgate::{self, TollGateConfig},
|
||||
wan,
|
||||
wifi_scan,
|
||||
wan, wifi_scan,
|
||||
};
|
||||
use crate::network::router as net_router;
|
||||
|
||||
/// Default port for the local Cashu mint (nutshell / cashu-mint app).
|
||||
const LOCAL_MINT_PORT: u16 = 3338;
|
||||
@@ -23,7 +22,9 @@ impl RpcHandler {
|
||||
) -> Result<serde_json::Value> {
|
||||
let p = params.unwrap_or_default();
|
||||
let subnet: [u8; 4] = parse_ipv4(
|
||||
p.get("subnet").and_then(|v| v.as_str()).unwrap_or("192.168.1.0"),
|
||||
p.get("subnet")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("192.168.1.0"),
|
||||
)?;
|
||||
let prefix = p.get("prefix").and_then(|v| v.as_u64()).unwrap_or(24) as u8;
|
||||
let ssh_user = p
|
||||
@@ -59,8 +60,18 @@ impl RpcHandler {
|
||||
.get("host")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| if saved.configured { Some(saved.address.clone()) } else { None })
|
||||
.ok_or_else(|| anyhow::anyhow!("No router configured — provide host or call router.configure first"))?;
|
||||
.or_else(|| {
|
||||
if saved.configured {
|
||||
Some(saved.address.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"No router configured — provide host or call router.configure first"
|
||||
)
|
||||
})?;
|
||||
|
||||
let ssh_user = p
|
||||
.get("ssh_user")
|
||||
@@ -92,11 +103,14 @@ impl RpcHandler {
|
||||
None,
|
||||
Some(&ssh_user),
|
||||
Some(&ssh_password),
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
}
|
||||
|
||||
// System info
|
||||
let release = router.run_ok("cat /etc/openwrt_release").unwrap_or_default();
|
||||
let release = router
|
||||
.run_ok("cat /etc/openwrt_release")
|
||||
.unwrap_or_default();
|
||||
let hostname = router
|
||||
.uci_get("system.@system[0].hostname")
|
||||
.unwrap_or_else(|_| "unknown".into());
|
||||
@@ -170,8 +184,18 @@ impl RpcHandler {
|
||||
.get("host")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| if saved.configured { Some(saved.address.clone()) } else { None })
|
||||
.ok_or_else(|| anyhow::anyhow!("No router configured — provide host or call router.configure first"))?;
|
||||
.or_else(|| {
|
||||
if saved.configured {
|
||||
Some(saved.address.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"No router configured — provide host or call router.configure first"
|
||||
)
|
||||
})?;
|
||||
let ssh_user = p
|
||||
.get("ssh_user")
|
||||
.and_then(|v| v.as_str())
|
||||
@@ -200,10 +224,7 @@ impl RpcHandler {
|
||||
.get("step_size_ms")
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(60_000),
|
||||
min_steps: p
|
||||
.get("min_steps")
|
||||
.and_then(|v| v.as_u64())
|
||||
.unwrap_or(1) as u32,
|
||||
min_steps: p.get("min_steps").and_then(|v| v.as_u64()).unwrap_or(1) as u32,
|
||||
enabled: p.get("enabled").and_then(|v| v.as_bool()).unwrap_or(true),
|
||||
};
|
||||
|
||||
@@ -229,13 +250,34 @@ impl RpcHandler {
|
||||
let saved = net_router::load_router_config(&self.config.data_dir).await?;
|
||||
let p = params.unwrap_or_default();
|
||||
|
||||
let host = p.get("host").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| if saved.configured { Some(saved.address.clone()) } else { None })
|
||||
.ok_or_else(|| anyhow::anyhow!("No router configured — provide host or call router.configure first"))?;
|
||||
let ssh_user = p.get("ssh_user").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| saved.username.clone()).unwrap_or_else(|| "root".to_string());
|
||||
let ssh_password = p.get("ssh_password").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| saved.password.clone()).unwrap_or_default();
|
||||
let host = p
|
||||
.get("host")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| {
|
||||
if saved.configured {
|
||||
Some(saved.address.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"No router configured — provide host or call router.configure first"
|
||||
)
|
||||
})?;
|
||||
let ssh_user = p
|
||||
.get("ssh_user")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| saved.username.clone())
|
||||
.unwrap_or_else(|| "root".to_string());
|
||||
let ssh_password = p
|
||||
.get("ssh_password")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| saved.password.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
let router = Router::connect_password(&host, 22, &ssh_user, &ssh_password)?;
|
||||
router.verify_openwrt()?;
|
||||
@@ -243,13 +285,15 @@ impl RpcHandler {
|
||||
let networks = wifi_scan::scan_networks(&router)?;
|
||||
let result: Vec<serde_json::Value> = networks
|
||||
.iter()
|
||||
.map(|n| serde_json::json!({
|
||||
"ssid": n.ssid,
|
||||
"bssid": n.bssid,
|
||||
"signal": n.signal,
|
||||
"channel": n.channel,
|
||||
"encryption": n.encryption,
|
||||
}))
|
||||
.map(|n| {
|
||||
serde_json::json!({
|
||||
"ssid": n.ssid,
|
||||
"bssid": n.bssid,
|
||||
"signal": n.signal,
|
||||
"channel": n.channel,
|
||||
"encryption": n.encryption,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(serde_json::json!({ "networks": result }))
|
||||
@@ -265,18 +309,50 @@ impl RpcHandler {
|
||||
let saved = net_router::load_router_config(&self.config.data_dir).await?;
|
||||
let p = params.unwrap_or_default();
|
||||
|
||||
let host = p.get("host").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| if saved.configured { Some(saved.address.clone()) } else { None })
|
||||
.ok_or_else(|| anyhow::anyhow!("No router configured — provide host or call router.configure first"))?;
|
||||
let ssh_user = p.get("ssh_user").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| saved.username.clone()).unwrap_or_else(|| "root".to_string());
|
||||
let ssh_password = p.get("ssh_password").and_then(|v| v.as_str()).map(|s| s.to_string())
|
||||
.or_else(|| saved.password.clone()).unwrap_or_default();
|
||||
let host = p
|
||||
.get("host")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| {
|
||||
if saved.configured {
|
||||
Some(saved.address.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"No router configured — provide host or call router.configure first"
|
||||
)
|
||||
})?;
|
||||
let ssh_user = p
|
||||
.get("ssh_user")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| saved.username.clone())
|
||||
.unwrap_or_else(|| "root".to_string());
|
||||
let ssh_password = p
|
||||
.get("ssh_password")
|
||||
.and_then(|v| v.as_str())
|
||||
.map(|s| s.to_string())
|
||||
.or_else(|| saved.password.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
let ssid = p.get("ssid").and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing required field: ssid"))?.to_string();
|
||||
let password = p.get("password").and_then(|v| v.as_str()).unwrap_or("").to_string();
|
||||
let encryption = p.get("encryption").and_then(|v| v.as_str()).unwrap_or("psk2").to_string();
|
||||
let ssid = p
|
||||
.get("ssid")
|
||||
.and_then(|v| v.as_str())
|
||||
.ok_or_else(|| anyhow::anyhow!("Missing required field: ssid"))?
|
||||
.to_string();
|
||||
let password = p
|
||||
.get("password")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
let encryption = p
|
||||
.get("encryption")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("psk2")
|
||||
.to_string();
|
||||
let dhcp_start = p.get("dhcp_start").and_then(|v| v.as_u64()).unwrap_or(100) as u32;
|
||||
let dhcp_limit = p.get("dhcp_limit").and_then(|v| v.as_u64()).unwrap_or(150) as u32;
|
||||
let masq = p.get("masq").and_then(|v| v.as_bool()).unwrap_or(true);
|
||||
@@ -284,7 +360,14 @@ impl RpcHandler {
|
||||
let router = Router::connect_password(&host, 22, &ssh_user, &ssh_password)?;
|
||||
router.verify_openwrt()?;
|
||||
|
||||
let config = wan::WispConfig { ssid: ssid.clone(), password, encryption, dhcp_start, dhcp_limit, masq };
|
||||
let config = wan::WispConfig {
|
||||
ssid: ssid.clone(),
|
||||
password,
|
||||
encryption,
|
||||
dhcp_start,
|
||||
dhcp_limit,
|
||||
masq,
|
||||
};
|
||||
wan::configure_wisp(&router, &config)?;
|
||||
|
||||
Ok(serde_json::json!({ "ok": true, "host": host, "ssid": ssid }))
|
||||
@@ -325,14 +408,16 @@ fn parse_wifi_interfaces(raw: &str) -> Vec<serde_json::Value> {
|
||||
let mut ifaces: Vec<serde_json::Value> = sections
|
||||
.into_iter()
|
||||
.filter(|(_, f)| f.get("mode").map(|m| m == "ap").unwrap_or(false))
|
||||
.map(|(name, f)| serde_json::json!({
|
||||
"section": name,
|
||||
"ssid": f.get("ssid").cloned().unwrap_or_default(),
|
||||
"device": f.get("device").cloned().unwrap_or_default(),
|
||||
"encryption": f.get("encryption").cloned().unwrap_or_else(|| "none".into()),
|
||||
"network": f.get("network").cloned().unwrap_or_default(),
|
||||
"disabled": f.get("disabled").map(|v| v == "1").unwrap_or(false),
|
||||
}))
|
||||
.map(|(name, f)| {
|
||||
serde_json::json!({
|
||||
"section": name,
|
||||
"ssid": f.get("ssid").cloned().unwrap_or_default(),
|
||||
"device": f.get("device").cloned().unwrap_or_default(),
|
||||
"encryption": f.get("encryption").cloned().unwrap_or_else(|| "none".into()),
|
||||
"network": f.get("network").cloned().unwrap_or_default(),
|
||||
"disabled": f.get("disabled").map(|v| v == "1").unwrap_or(false),
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
ifaces.sort_by_key(|v| v["section"].as_str().unwrap_or("").to_string());
|
||||
|
||||
@@ -378,9 +378,11 @@ where
|
||||
|
||||
// Fail fast if any missing dependency has no installed container
|
||||
// under any name variant — waiting cannot satisfy it.
|
||||
let some_dep_not_installed = missing
|
||||
.iter()
|
||||
.any(|dep| !dep.containers.iter().any(|c| existing.iter().any(|e| e == c)));
|
||||
let some_dep_not_installed = missing.iter().any(|dep| {
|
||||
!dep.containers
|
||||
.iter()
|
||||
.any(|c| existing.iter().any(|e| e == c))
|
||||
});
|
||||
if some_dep_not_installed {
|
||||
let msg = match check_install_deps(package_id, &running) {
|
||||
Err(e) => e.to_string(),
|
||||
@@ -879,8 +881,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Collects "Waiting for X to start…" labels emitted during the wait.
|
||||
fn label_sink() -> (Arc<Mutex<Vec<String>>>, impl FnMut(String) -> std::future::Ready<()>)
|
||||
{
|
||||
fn label_sink() -> (
|
||||
Arc<Mutex<Vec<String>>>,
|
||||
impl FnMut(String) -> std::future::Ready<()>,
|
||||
) {
|
||||
let labels = Arc::new(Mutex::new(Vec::new()));
|
||||
let sink = {
|
||||
let labels = Arc::clone(&labels);
|
||||
@@ -930,7 +934,8 @@ mod tests {
|
||||
// so async_lifecycle removes the optimistic Installing entry.
|
||||
assert!(err.downcast_ref::<DependencyGateError>().is_some());
|
||||
assert!(
|
||||
err.to_string().contains("LND requires a running Bitcoin node"),
|
||||
err.to_string()
|
||||
.contains("LND requires a running Bitcoin node"),
|
||||
"unexpected message: {err}"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,9 @@ impl RpcHandler {
|
||||
|
||||
let to_start = if self.orchestrator.is_some() && uses_single_orchestrator_app(package_id) {
|
||||
vec![orchestrator_app_id(package_id).to_string()]
|
||||
} else if let Some(members) = orchestrator_stack_members(self.orchestrator.is_some(), package_id) {
|
||||
} else if let Some(members) =
|
||||
orchestrator_stack_members(self.orchestrator.is_some(), package_id)
|
||||
{
|
||||
members
|
||||
} else {
|
||||
ordered_containers_for_start(package_id).await?
|
||||
@@ -170,11 +172,12 @@ impl RpcHandler {
|
||||
// fallback to a raw `podman stop` that races systemd over the unit
|
||||
// (immich, gate 2026-07-09).
|
||||
let to_stop_ids = if !single_orchestrator_app {
|
||||
orchestrator_stack_members(self.orchestrator.is_some(), package_id)
|
||||
.map(|mut members| {
|
||||
orchestrator_stack_members(self.orchestrator.is_some(), package_id).map(
|
||||
|mut members| {
|
||||
members.reverse();
|
||||
members
|
||||
})
|
||||
},
|
||||
)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -280,7 +283,9 @@ impl RpcHandler {
|
||||
let companion_app_id = package_id_owned.clone();
|
||||
let to_restart = if single_orchestrator_app {
|
||||
vec![orchestrator_app_id(package_id).to_string()]
|
||||
} else if let Some(members) = orchestrator_stack_members(self.orchestrator.is_some(), package_id) {
|
||||
} else if let Some(members) =
|
||||
orchestrator_stack_members(self.orchestrator.is_some(), package_id)
|
||||
{
|
||||
// Restart stacks via member APP ids: restarting by live container
|
||||
// name podman-stops the quadlet container (systemd --rm removes
|
||||
// it) and the start half then finds no such container — a 5-min
|
||||
@@ -2160,7 +2165,9 @@ mod tests {
|
||||
assert!(is_missing_container_error(
|
||||
"Error: no such object: \"mempool\""
|
||||
));
|
||||
assert!(is_missing_container_error("Error: no such container mempool"));
|
||||
assert!(is_missing_container_error(
|
||||
"Error: no such container mempool"
|
||||
));
|
||||
assert!(is_missing_container_error(
|
||||
"Error: no container with name or id \"x\" found"
|
||||
));
|
||||
|
||||
@@ -100,7 +100,8 @@ impl RpcHandler {
|
||||
}
|
||||
|
||||
let location_file = self.config.data_dir.join("server-location.json");
|
||||
let payload = serde_json::json!({ "lat": lat, "lon": lon, "share_location": share_location });
|
||||
let payload =
|
||||
serde_json::json!({ "lat": lat, "lon": lon, "share_location": share_location });
|
||||
tokio::fs::write(&location_file, serde_json::to_vec(&payload)?)
|
||||
.await
|
||||
.context("Failed to write server location")?;
|
||||
@@ -130,7 +131,9 @@ impl RpcHandler {
|
||||
/// resolves to on the LAN (avahi-daemon advertises `<hostname>.local`).
|
||||
/// Lets Settings show users where to reach this node over HTTPS for
|
||||
/// features (mic/camera access) that require a secure context.
|
||||
pub(in crate::api::rpc) async fn handle_system_get_hostname(&self) -> Result<serde_json::Value> {
|
||||
pub(in crate::api::rpc) async fn handle_system_get_hostname(
|
||||
&self,
|
||||
) -> Result<serde_json::Value> {
|
||||
let hostname = tokio::fs::read_to_string("/etc/hostname")
|
||||
.await
|
||||
.map(|s| s.trim().to_string())
|
||||
@@ -401,7 +404,8 @@ async fn set_system_hostname(hostname: &str) -> Result<()> {
|
||||
/// top once a node has been renamed away from the install-time default.
|
||||
async fn regenerate_tls_cert(hostname: &str) -> Result<()> {
|
||||
let subj = format!("/C=XX/ST=Bitcoin/L=Node/O=Archipelago/CN={hostname}");
|
||||
let san = format!("subjectAltName=DNS:{hostname},DNS:{hostname}.local,DNS:localhost,IP:127.0.0.1");
|
||||
let san =
|
||||
format!("subjectAltName=DNS:{hostname},DNS:{hostname}.local,DNS:localhost,IP:127.0.0.1");
|
||||
let output = tokio::process::Command::new("/usr/bin/sudo")
|
||||
.args([
|
||||
"-n",
|
||||
|
||||
Reference in New Issue
Block a user