...
This commit is contained in:
parent
49c879359b
commit
dee38eb6c2
@ -49,13 +49,17 @@ sha2 = "0.10.7" # SHA-2 hash functions
|
||||
tempfile = "3.5" # For temporary file operations
|
||||
tera = "1.19.0" # Template engine for text rendering
|
||||
thiserror = "2.0.12" # For error handling
|
||||
tokio = "1.45.0"
|
||||
tokio = { version = "1.45.0", features = ["full"] }
|
||||
tokio-postgres = "0.7.8" # Async PostgreSQL client
|
||||
tokio-test = "0.4.4"
|
||||
uuid = { version = "1.16.0", features = ["v4"] }
|
||||
reqwest = { version = "0.12.15", features = ["json"] }
|
||||
urlencoding = "2.1.3"
|
||||
zinit-client = "0.3.0"
|
||||
russh = "0.42.0"
|
||||
russh-keys = "0.42.0"
|
||||
async-trait = "0.1.81"
|
||||
futures = "0.3.30"
|
||||
|
||||
# Optional features for specific OS functionality
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
|
@ -9,7 +9,7 @@ println(`Using local image: ${local_image_name}`);
|
||||
|
||||
// Import the image from buildah to nerdctl
|
||||
println("Importing image from buildah to nerdctl...");
|
||||
process_run("buildah", ["push", "custom-golang-nginx:latest", "docker-daemon:custom-golang-nginx:latest"]);
|
||||
process_run("buildah", ["push", "custom-golang-nginx:latest", "docker-daemon:localhost/custom-golang-nginx:latest"]);
|
||||
|
||||
let tag_result = nerdctl_image_tag("custom-golang-nginx:latest", local_image_name);
|
||||
|
||||
|
@ -2,7 +2,7 @@ print("Running a command using run().log().do()...");
|
||||
|
||||
// The .log() method will print the command string to the console before execution.
|
||||
// This is useful for debugging or tracing which commands are being run.
|
||||
let result = run("echo This command is logged").log().do();
|
||||
let result = run("echo This command is logged").log().execute();
|
||||
|
||||
print(`Command finished.`);
|
||||
print(`Success: ${result.success}`);
|
||||
|
@ -8,14 +8,23 @@ fn nerdctl_download(){
|
||||
copy_bin(`/tmp/${name}/*`);
|
||||
delete(`/tmp/${name}`);
|
||||
|
||||
screen_kill("containerd");
|
||||
let name="containerd";
|
||||
let url="https://github.com/containerd/containerd/releases/download/v2.1.2/containerd-2.1.2-linux-amd64.tar.gz";
|
||||
download(url,`/tmp/${name}`,20000);
|
||||
copy_bin(`/tmp/${name}/bin/*`);
|
||||
// copy_bin(`/tmp/${name}/bin/*`);
|
||||
delete(`/tmp/${name}`);
|
||||
|
||||
screen_kill("containerd");
|
||||
let cfg = `
|
||||
[[registry]]
|
||||
location = "localhost:5000"
|
||||
insecure = true
|
||||
`;
|
||||
file_write("/etc/containers/registries.conf", dedent(cfg));
|
||||
screen_new("containerd", "containerd");
|
||||
sleep(1);
|
||||
nerdctl_remove_all();
|
||||
run("nerdctl run -d -p 5000:5000 --name registry registry:2").log().execute();
|
||||
|
||||
package_install("buildah");
|
||||
package_install("runc");
|
||||
|
@ -49,6 +49,7 @@ pub mod virt;
|
||||
pub mod vault;
|
||||
pub mod zinit_client;
|
||||
pub mod mycelium;
|
||||
pub mod net;
|
||||
|
||||
// Version information
|
||||
/// Returns the version of the SAL library
|
||||
|
51
src/net/http.rs
Normal file
51
src/net/http.rs
Normal file
@ -0,0 +1,51 @@
|
||||
use reqwest::Client;
|
||||
use std::time::Duration;
|
||||
|
||||
// HTTP Checker
|
||||
pub struct HttpChecker {
|
||||
client: Client,
|
||||
url: String,
|
||||
}
|
||||
|
||||
impl HttpChecker {
|
||||
pub async fn check_url(&self) -> Result<bool, reqwest::Error> {
|
||||
let res = self.client.get(&self.url).send().await?;
|
||||
Ok(res.status().is_success())
|
||||
}
|
||||
}
|
||||
|
||||
// HTTP Checker Builder
|
||||
pub struct HttpCheckerBuilder {
|
||||
url: String,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl HttpCheckerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
url: "http://localhost".to_string(),
|
||||
timeout: Duration::from_secs(30),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url<S: Into<String>>(mut self, url: S) -> Self {
|
||||
self.url = url.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> HttpChecker {
|
||||
let client = Client::builder()
|
||||
.timeout(self.timeout)
|
||||
.build()
|
||||
.expect("Failed to build HTTP client");
|
||||
HttpChecker {
|
||||
client,
|
||||
url: self.url,
|
||||
}
|
||||
}
|
||||
}
|
3
src/net/mod.rs
Normal file
3
src/net/mod.rs
Normal file
@ -0,0 +1,3 @@
|
||||
pub mod ssh;
|
||||
pub mod tcp;
|
||||
pub mod http;
|
133
src/net/ssh.rs
Normal file
133
src/net/ssh.rs
Normal file
@ -0,0 +1,133 @@
|
||||
use russh::client;
|
||||
use russh_keys::key;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
// SSH Connection
|
||||
#[derive(Clone)]
|
||||
pub struct SshConnection {
|
||||
session: Arc<client::Handle<Client>>,
|
||||
}
|
||||
|
||||
impl SshConnection {
|
||||
pub async fn ping(&self) -> Result<(), anyhow::Error> {
|
||||
let mut channel = self.session.channel_open_session().await?;
|
||||
channel.exec(true, "ping -c 1 127.0.0.1").await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
// SSH Connection Builder
|
||||
pub struct SshConnectionBuilder {
|
||||
host: String,
|
||||
port: u16,
|
||||
user: String,
|
||||
password: Option<String>,
|
||||
key_path: Option<PathBuf>,
|
||||
use_agent: bool,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl SshConnectionBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
host: "localhost".to_string(),
|
||||
port: 22,
|
||||
user: "root".to_string(),
|
||||
password: None,
|
||||
key_path: None,
|
||||
use_agent: true,
|
||||
timeout: Duration::from_secs(30),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
self.host = host.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn port(mut self, port: u16) -> Self {
|
||||
self.port = port;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn user<S: Into<String>>(mut self, user: S) -> Self {
|
||||
self.user = user.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn password<S: Into<String>>(mut self, password: S) -> Self {
|
||||
self.password = Some(password.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn key_path(mut self, key_path: PathBuf) -> Self {
|
||||
self.key_path = Some(key_path);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn use_agent(mut self, use_agent: bool) -> Self {
|
||||
self.use_agent = use_agent;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn build(self) -> Result<SshConnection, anyhow::Error> {
|
||||
let config = Arc::new(client::Config::default());
|
||||
let sh = Client;
|
||||
|
||||
let mut session = client::connect(config, (self.host.as_str(), self.port), sh).await?;
|
||||
|
||||
let auth_res = if self.use_agent {
|
||||
let mut agent = russh_keys::agent::client::AgentClient::connect_env().await?;
|
||||
let mut keys = agent.request_identities().await?;
|
||||
if keys.is_empty() {
|
||||
return Err(anyhow::anyhow!("No identities found in ssh-agent"));
|
||||
}
|
||||
let key = keys.remove(0);
|
||||
let (_agent, authed) = session
|
||||
.authenticate_future(self.user.as_str(), Arc::new(key), agent)
|
||||
.await;
|
||||
authed?
|
||||
} else if let Some(password) = self.password {
|
||||
session
|
||||
.authenticate_password(self.user.as_str(), &password)
|
||||
.await?
|
||||
} else if let Some(key_path) = self.key_path {
|
||||
let key_pair = russh_keys::load_secret_key(key_path, None)?;
|
||||
session
|
||||
.authenticate_publickey(self.user.as_str(), Arc::new(key_pair))
|
||||
.await?
|
||||
} else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"No authentication method specified"
|
||||
));
|
||||
};
|
||||
|
||||
if !auth_res {
|
||||
return Err(anyhow::anyhow!("Authentication failed"));
|
||||
}
|
||||
|
||||
Ok(SshConnection {
|
||||
session: Arc::new(session),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Client;
|
||||
|
||||
impl client::Handler for Client {
|
||||
type Error = russh::Error;
|
||||
|
||||
fn check_server_key(
|
||||
&mut self,
|
||||
_server_public_key: &key::PublicKey,
|
||||
) -> std::future::Ready<Result<bool, Self::Error>> {
|
||||
std::future::ready(Ok(true))
|
||||
}
|
||||
}
|
64
src/net/tcp.rs
Normal file
64
src/net/tcp.rs
Normal file
@ -0,0 +1,64 @@
|
||||
use std::net::{SocketAddr, TcpStream};
|
||||
use std::time::Duration;
|
||||
|
||||
// TCP Checker
|
||||
pub struct TcpChecker {
|
||||
host: String,
|
||||
port: u16,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl TcpChecker {
|
||||
pub fn ping(&self) -> Result<(), std::io::Error> {
|
||||
let addr = format!("{}:{}", self.host, self.port);
|
||||
let socket_addr: SocketAddr = addr.parse().expect("Failed to parse socket address");
|
||||
TcpStream::connect_timeout(&socket_addr, self.timeout)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_port(&self) -> bool {
|
||||
let addr = format!("{}:{}", self.host, self.port);
|
||||
let socket_addr: SocketAddr = addr.parse().expect("Failed to parse socket address");
|
||||
TcpStream::connect_timeout(&socket_addr, self.timeout).is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
// TCP Checker Builder
|
||||
pub struct TcpCheckerBuilder {
|
||||
host: String,
|
||||
port: u16,
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl TcpCheckerBuilder {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
host: "localhost".to_string(),
|
||||
port: 80,
|
||||
timeout: Duration::from_secs(1),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn host<S: Into<String>>(mut self, host: S) -> Self {
|
||||
self.host = host.into();
|
||||
self
|
||||
}
|
||||
|
||||
pub fn port(mut self, port: u16) -> Self {
|
||||
self.port = port;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> TcpChecker {
|
||||
TcpChecker {
|
||||
host: self.host,
|
||||
port: self.port,
|
||||
timeout: self.timeout,
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user