Compare commits
7 Commits
developmen
...
network_se
Author | SHA1 | Date | |
---|---|---|---|
|
da3da0ae30 | ||
|
784f87db97 | ||
|
773db2238d | ||
|
e8a369e3a2 | ||
|
4b4f3371b0 | ||
|
1bb731711b | ||
|
af89ef0149 |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -63,7 +63,4 @@ sidebars.ts
|
|||||||
|
|
||||||
tsconfig.json
|
tsconfig.json
|
||||||
Cargo.toml.bak
|
Cargo.toml.bak
|
||||||
for_augment
|
for_augment
|
||||||
|
|
||||||
myenv.sh
|
|
||||||
|
|
@@ -16,7 +16,6 @@ members = [
|
|||||||
"packages/clients/postgresclient",
|
"packages/clients/postgresclient",
|
||||||
"packages/clients/redisclient",
|
"packages/clients/redisclient",
|
||||||
"packages/clients/zinitclient",
|
"packages/clients/zinitclient",
|
||||||
"packages/clients/rfsclient",
|
|
||||||
"packages/core/net",
|
"packages/core/net",
|
||||||
"packages/core/text",
|
"packages/core/text",
|
||||||
"packages/crypt/vault",
|
"packages/crypt/vault",
|
||||||
@@ -32,7 +31,6 @@ members = [
|
|||||||
"rhailib",
|
"rhailib",
|
||||||
"herodo",
|
"herodo",
|
||||||
"packages/clients/hetznerclient",
|
"packages/clients/hetznerclient",
|
||||||
"packages/ai/codemonkey",
|
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|
||||||
@@ -44,7 +42,6 @@ rust-version = "1.70.0"
|
|||||||
# Core shared dependencies with consistent versions
|
# Core shared dependencies with consistent versions
|
||||||
anyhow = "1.0.98"
|
anyhow = "1.0.98"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
bytes = "1.7.1"
|
|
||||||
dirs = "6.0.0"
|
dirs = "6.0.0"
|
||||||
env_logger = "0.11.8"
|
env_logger = "0.11.8"
|
||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
@@ -111,7 +108,6 @@ sal-kubernetes = { path = "packages/system/kubernetes" }
|
|||||||
sal-redisclient = { path = "packages/clients/redisclient" }
|
sal-redisclient = { path = "packages/clients/redisclient" }
|
||||||
sal-mycelium = { path = "packages/clients/myceliumclient" }
|
sal-mycelium = { path = "packages/clients/myceliumclient" }
|
||||||
sal-hetzner = { path = "packages/clients/hetznerclient" }
|
sal-hetzner = { path = "packages/clients/hetznerclient" }
|
||||||
sal-rfs-client = { path = "packages/clients/rfsclient" }
|
|
||||||
sal-text = { path = "packages/core/text" }
|
sal-text = { path = "packages/core/text" }
|
||||||
sal-os = { path = "packages/system/os" }
|
sal-os = { path = "packages/system/os" }
|
||||||
sal-net = { path = "packages/core/net" }
|
sal-net = { path = "packages/core/net" }
|
||||||
@@ -133,7 +129,6 @@ sal-kubernetes = { workspace = true, optional = true }
|
|||||||
sal-redisclient = { workspace = true, optional = true }
|
sal-redisclient = { workspace = true, optional = true }
|
||||||
sal-mycelium = { workspace = true, optional = true }
|
sal-mycelium = { workspace = true, optional = true }
|
||||||
sal-hetzner = { workspace = true, optional = true }
|
sal-hetzner = { workspace = true, optional = true }
|
||||||
sal-rfs-client = { workspace = true, optional = true }
|
|
||||||
sal-text = { workspace = true, optional = true }
|
sal-text = { workspace = true, optional = true }
|
||||||
sal-os = { workspace = true, optional = true }
|
sal-os = { workspace = true, optional = true }
|
||||||
sal-net = { workspace = true, optional = true }
|
sal-net = { workspace = true, optional = true }
|
||||||
@@ -154,7 +149,6 @@ kubernetes = ["dep:sal-kubernetes"]
|
|||||||
redisclient = ["dep:sal-redisclient"]
|
redisclient = ["dep:sal-redisclient"]
|
||||||
mycelium = ["dep:sal-mycelium"]
|
mycelium = ["dep:sal-mycelium"]
|
||||||
hetzner = ["dep:sal-hetzner"]
|
hetzner = ["dep:sal-hetzner"]
|
||||||
rfsclient = ["dep:sal-rfs-client"]
|
|
||||||
text = ["dep:sal-text"]
|
text = ["dep:sal-text"]
|
||||||
os = ["dep:sal-os"]
|
os = ["dep:sal-os"]
|
||||||
net = ["dep:sal-net"]
|
net = ["dep:sal-net"]
|
||||||
@@ -168,7 +162,7 @@ rhai = ["dep:sal-rhai"]
|
|||||||
|
|
||||||
# Convenience feature groups
|
# Convenience feature groups
|
||||||
core = ["os", "process", "text", "net"]
|
core = ["os", "process", "text", "net"]
|
||||||
clients = ["redisclient", "postgresclient", "zinit_client", "mycelium", "hetzner", "rfsclient"]
|
clients = ["redisclient", "postgresclient", "zinit_client", "mycelium", "hetzner"]
|
||||||
infrastructure = ["git", "vault", "kubernetes", "virt"]
|
infrastructure = ["git", "vault", "kubernetes", "virt"]
|
||||||
scripting = ["rhai"]
|
scripting = ["rhai"]
|
||||||
all = [
|
all = [
|
||||||
@@ -177,7 +171,6 @@ all = [
|
|||||||
"redisclient",
|
"redisclient",
|
||||||
"mycelium",
|
"mycelium",
|
||||||
"hetzner",
|
"hetzner",
|
||||||
"rfsclient",
|
|
||||||
"text",
|
"text",
|
||||||
"os",
|
"os",
|
||||||
"net",
|
"net",
|
||||||
|
@@ -10,7 +10,7 @@ license = "Apache-2.0"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
# Use workspace dependencies for consistency
|
# Use workspace dependencies for consistency
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
tokio = { workspace = true, features = ["process", "time", "sync"] }
|
tokio = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
@@ -20,9 +20,6 @@ once_cell = { workspace = true }
|
|||||||
zinit-client = { version = "0.4.0" }
|
zinit-client = { version = "0.4.0" }
|
||||||
# Optional Rhai integration
|
# Optional Rhai integration
|
||||||
rhai = { workspace = true, optional = true }
|
rhai = { workspace = true, optional = true }
|
||||||
# Process manager dependencies
|
|
||||||
async-trait = "0.1"
|
|
||||||
chrono = "0.4"
|
|
||||||
|
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
@@ -83,34 +83,20 @@ pub trait ServiceManager: Send + Sync {
|
|||||||
fn remove(&self, service_name: &str) -> Result<(), ServiceManagerError>;
|
fn remove(&self, service_name: &str) -> Result<(), ServiceManagerError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform-specific implementations (commented out for now to simplify)
|
// Platform-specific implementations
|
||||||
// #[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
// mod launchctl;
|
mod launchctl;
|
||||||
// #[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
// pub use launchctl::LaunchctlServiceManager;
|
pub use launchctl::LaunchctlServiceManager;
|
||||||
|
|
||||||
// #[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
// mod systemd;
|
mod systemd;
|
||||||
// #[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
// pub use systemd::SystemdServiceManager;
|
pub use systemd::SystemdServiceManager;
|
||||||
|
|
||||||
mod zinit;
|
mod zinit;
|
||||||
pub use zinit::ZinitServiceManager;
|
pub use zinit::ZinitServiceManager;
|
||||||
|
|
||||||
// Process manager module for actor lifecycle management
|
|
||||||
pub mod process_manager;
|
|
||||||
pub use process_manager::{
|
|
||||||
ProcessManager, ProcessConfig, ProcessStatus, ProcessManagerError, ProcessManagerResult,
|
|
||||||
SimpleProcessManager, LogInfo,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod tmux_manager;
|
|
||||||
pub use tmux_manager::TmuxProcessManager;
|
|
||||||
|
|
||||||
// Re-export process managers for easier access
|
|
||||||
pub use process_manager::SimpleProcessManager as SimpleManager;
|
|
||||||
pub use tmux_manager::TmuxProcessManager as TmuxManager;
|
|
||||||
|
|
||||||
#[cfg(feature = "rhai")]
|
#[cfg(feature = "rhai")]
|
||||||
pub mod rhai;
|
pub mod rhai;
|
||||||
|
|
||||||
@@ -220,11 +206,7 @@ fn test_zinit_socket(socket_path: &str) -> bool {
|
|||||||
pub fn create_service_manager() -> Result<Box<dyn ServiceManager>, ServiceManagerError> {
|
pub fn create_service_manager() -> Result<Box<dyn ServiceManager>, ServiceManagerError> {
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
{
|
{
|
||||||
// LaunchctlServiceManager is commented out for now
|
Ok(Box::new(LaunchctlServiceManager::new()))
|
||||||
// For now, return an error on macOS since launchctl is disabled
|
|
||||||
Err(ServiceManagerError::Other(
|
|
||||||
"Service manager not available on macOS (launchctl disabled for simplification)".to_string(),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
{
|
{
|
||||||
|
@@ -1,371 +0,0 @@
|
|||||||
//! # Process Manager
|
|
||||||
//!
|
|
||||||
//! This module provides process management abstractions specifically designed for
|
|
||||||
//! actor lifecycle management. It bridges the gap between the service manager
|
|
||||||
//! and actor-specific process requirements.
|
|
||||||
//!
|
|
||||||
//! The ProcessManager trait provides a unified interface for managing actor processes
|
|
||||||
//! across different process management systems (tmux, zinit, simple spawning, etc.).
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::process::Stdio;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::time::Duration;
|
|
||||||
use thiserror::Error;
|
|
||||||
use tokio::process::{Child, Command};
|
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
/// Errors that can occur during process management operations
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum ProcessManagerError {
|
|
||||||
#[error("Process '{0}' not found")]
|
|
||||||
ProcessNotFound(String),
|
|
||||||
#[error("Process '{0}' already running")]
|
|
||||||
ProcessAlreadyRunning(String),
|
|
||||||
#[error("Failed to start process '{0}': {1}")]
|
|
||||||
StartupFailed(String, String),
|
|
||||||
#[error("Failed to stop process '{0}': {1}")]
|
|
||||||
StopFailed(String, String),
|
|
||||||
#[error("Failed to get process status '{0}': {1}")]
|
|
||||||
StatusFailed(String, String),
|
|
||||||
#[error("Failed to get logs for process '{0}': {1}")]
|
|
||||||
LogsFailed(String, String),
|
|
||||||
#[error("Process manager error: {0}")]
|
|
||||||
Other(String),
|
|
||||||
#[error("IO error: {0}")]
|
|
||||||
IoError(#[from] std::io::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result type for process manager operations
|
|
||||||
pub type ProcessManagerResult<T> = Result<T, ProcessManagerError>;
|
|
||||||
|
|
||||||
/// Represents the current status of a process
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
|
||||||
pub enum ProcessStatus {
|
|
||||||
/// Process is not running
|
|
||||||
Stopped,
|
|
||||||
/// Process is currently starting up
|
|
||||||
Starting,
|
|
||||||
/// Process is running and ready
|
|
||||||
Running,
|
|
||||||
/// Process is in the process of stopping
|
|
||||||
Stopping,
|
|
||||||
/// Process has encountered an error
|
|
||||||
Error(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configuration for a process
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct ProcessConfig {
|
|
||||||
/// Unique identifier for the process
|
|
||||||
pub process_id: String,
|
|
||||||
/// Path to the binary to execute
|
|
||||||
pub binary_path: PathBuf,
|
|
||||||
/// Command line arguments
|
|
||||||
pub args: Vec<String>,
|
|
||||||
/// Working directory (optional)
|
|
||||||
pub working_dir: Option<PathBuf>,
|
|
||||||
/// Environment variables
|
|
||||||
pub env_vars: HashMap<String, String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProcessConfig {
|
|
||||||
/// Create a new process configuration
|
|
||||||
pub fn new(process_id: String, binary_path: PathBuf) -> Self {
|
|
||||||
Self {
|
|
||||||
process_id,
|
|
||||||
binary_path,
|
|
||||||
args: Vec::new(),
|
|
||||||
working_dir: None,
|
|
||||||
env_vars: HashMap::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a command line argument
|
|
||||||
pub fn with_arg(mut self, arg: String) -> Self {
|
|
||||||
self.args.push(arg);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add multiple command line arguments
|
|
||||||
pub fn with_args(mut self, args: Vec<String>) -> Self {
|
|
||||||
self.args.extend(args);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the working directory
|
|
||||||
pub fn with_working_dir(mut self, working_dir: PathBuf) -> Self {
|
|
||||||
self.working_dir = Some(working_dir);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an environment variable
|
|
||||||
pub fn with_env_var(mut self, key: String, value: String) -> Self {
|
|
||||||
self.env_vars.insert(key, value);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Log information for a process
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct LogInfo {
|
|
||||||
/// Timestamp of the log entry
|
|
||||||
pub timestamp: String,
|
|
||||||
/// Log level (info, warn, error, etc.)
|
|
||||||
pub level: String,
|
|
||||||
/// Log message content
|
|
||||||
pub message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Process manager abstraction for different process management systems
|
|
||||||
#[async_trait]
|
|
||||||
pub trait ProcessManager: Send + Sync {
|
|
||||||
/// Start a process with the given configuration
|
|
||||||
async fn start_process(&mut self, config: &ProcessConfig) -> ProcessManagerResult<()>;
|
|
||||||
|
|
||||||
/// Stop a process by process ID
|
|
||||||
async fn stop_process(&mut self, process_id: &str, force: bool) -> ProcessManagerResult<()>;
|
|
||||||
|
|
||||||
/// Get the status of a process
|
|
||||||
async fn process_status(&self, process_id: &str) -> ProcessManagerResult<ProcessStatus>;
|
|
||||||
|
|
||||||
/// Get logs for a process
|
|
||||||
async fn process_logs(&self, process_id: &str, lines: Option<usize>, follow: bool) -> ProcessManagerResult<Vec<LogInfo>>;
|
|
||||||
|
|
||||||
/// Check if the process manager is available and working
|
|
||||||
async fn health_check(&self) -> ProcessManagerResult<()>;
|
|
||||||
|
|
||||||
/// List all managed processes
|
|
||||||
async fn list_processes(&self) -> ProcessManagerResult<Vec<String>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Simple process manager implementation using direct process spawning
|
|
||||||
/// This is useful for development and testing, but production should use
|
|
||||||
/// more robust process managers like tmux or zinit.
|
|
||||||
pub struct SimpleProcessManager {
|
|
||||||
processes: Arc<Mutex<HashMap<String, Child>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SimpleProcessManager {
|
|
||||||
/// Create a new simple process manager
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
processes: Arc::new(Mutex::new(HashMap::new())),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn build_command(&self, config: &ProcessConfig) -> Command {
|
|
||||||
let mut cmd = Command::new(&config.binary_path);
|
|
||||||
|
|
||||||
// Add arguments
|
|
||||||
for arg in &config.args {
|
|
||||||
cmd.arg(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set working directory
|
|
||||||
if let Some(working_dir) = &config.working_dir {
|
|
||||||
cmd.current_dir(working_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set environment variables
|
|
||||||
for (key, value) in &config.env_vars {
|
|
||||||
cmd.env(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure stdio
|
|
||||||
cmd.stdout(Stdio::piped())
|
|
||||||
.stderr(Stdio::piped())
|
|
||||||
.stdin(Stdio::null());
|
|
||||||
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for SimpleProcessManager {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl ProcessManager for SimpleProcessManager {
|
|
||||||
async fn start_process(&mut self, config: &ProcessConfig) -> ProcessManagerResult<()> {
|
|
||||||
let mut processes = self.processes.lock().await;
|
|
||||||
|
|
||||||
if processes.contains_key(&config.process_id) {
|
|
||||||
return Err(ProcessManagerError::ProcessAlreadyRunning(config.process_id.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut cmd = self.build_command(config);
|
|
||||||
|
|
||||||
log::debug!("Starting process for {}: {:?}", config.process_id, cmd);
|
|
||||||
|
|
||||||
let child = cmd.spawn().map_err(|e| ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
format!("Failed to spawn process: {}", e),
|
|
||||||
))?;
|
|
||||||
|
|
||||||
processes.insert(config.process_id.clone(), child);
|
|
||||||
|
|
||||||
// Wait a moment to ensure the process started successfully
|
|
||||||
drop(processes);
|
|
||||||
tokio::time::sleep(Duration::from_millis(100)).await;
|
|
||||||
let mut processes = self.processes.lock().await;
|
|
||||||
|
|
||||||
// Check if the process is still running
|
|
||||||
if let Some(child) = processes.get_mut(&config.process_id) {
|
|
||||||
match child.try_wait() {
|
|
||||||
Ok(Some(status)) => {
|
|
||||||
processes.remove(&config.process_id);
|
|
||||||
return Err(ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
format!("Process exited immediately with status: {}", status),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Ok(None) => {
|
|
||||||
// Process is still running
|
|
||||||
log::info!("Successfully started process {}", config.process_id);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
processes.remove(&config.process_id);
|
|
||||||
return Err(ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
format!("Failed to check process status: {}", e),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn stop_process(&mut self, process_id: &str, force: bool) -> ProcessManagerResult<()> {
|
|
||||||
let mut processes = self.processes.lock().await;
|
|
||||||
|
|
||||||
let mut child = processes.remove(process_id)
|
|
||||||
.ok_or_else(|| ProcessManagerError::ProcessNotFound(process_id.to_string()))?;
|
|
||||||
|
|
||||||
if force {
|
|
||||||
child.kill().await.map_err(|e| ProcessManagerError::StopFailed(
|
|
||||||
process_id.to_string(),
|
|
||||||
format!("Failed to kill process: {}", e),
|
|
||||||
))?;
|
|
||||||
} else {
|
|
||||||
// Try graceful shutdown first
|
|
||||||
if let Some(id) = child.id() {
|
|
||||||
#[cfg(unix)]
|
|
||||||
{
|
|
||||||
use std::process::Command as StdCommand;
|
|
||||||
let _ = StdCommand::new("kill")
|
|
||||||
.arg("-TERM")
|
|
||||||
.arg(id.to_string())
|
|
||||||
.output();
|
|
||||||
|
|
||||||
// Wait a bit for graceful shutdown
|
|
||||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force kill if still running
|
|
||||||
let _ = child.kill().await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the process to exit
|
|
||||||
let _ = child.wait().await;
|
|
||||||
|
|
||||||
log::info!("Successfully stopped process {}", process_id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn process_status(&self, process_id: &str) -> ProcessManagerResult<ProcessStatus> {
|
|
||||||
let mut processes = self.processes.lock().await;
|
|
||||||
|
|
||||||
if let Some(child) = processes.get_mut(process_id) {
|
|
||||||
match child.try_wait() {
|
|
||||||
Ok(Some(_)) => {
|
|
||||||
// Process has exited
|
|
||||||
processes.remove(process_id);
|
|
||||||
Ok(ProcessStatus::Stopped)
|
|
||||||
}
|
|
||||||
Ok(None) => {
|
|
||||||
// Process is still running
|
|
||||||
Ok(ProcessStatus::Running)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
Ok(ProcessStatus::Error(format!("Failed to check status: {}", e)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(ProcessStatus::Stopped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn process_logs(&self, process_id: &str, _lines: Option<usize>, _follow: bool) -> ProcessManagerResult<Vec<LogInfo>> {
|
|
||||||
// Simple process manager doesn't capture logs by default
|
|
||||||
// This would require more sophisticated process management
|
|
||||||
log::warn!("Log retrieval not implemented for SimpleProcessManager");
|
|
||||||
Ok(vec![LogInfo {
|
|
||||||
timestamp: chrono::Utc::now().to_rfc3339(),
|
|
||||||
level: "info".to_string(),
|
|
||||||
message: format!("Log retrieval not available for process {}", process_id),
|
|
||||||
}])
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn health_check(&self) -> ProcessManagerResult<()> {
|
|
||||||
// Simple process manager is always healthy if we can lock the processes
|
|
||||||
let _processes = self.processes.lock().await;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn list_processes(&self) -> ProcessManagerResult<Vec<String>> {
|
|
||||||
let processes = self.processes.lock().await;
|
|
||||||
Ok(processes.keys().cloned().collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_process_config_creation() {
|
|
||||||
let config = ProcessConfig::new(
|
|
||||||
"test_process".to_string(),
|
|
||||||
PathBuf::from("/usr/bin/echo"),
|
|
||||||
)
|
|
||||||
.with_arg("hello".to_string())
|
|
||||||
.with_arg("world".to_string())
|
|
||||||
.with_env_var("TEST_VAR".to_string(), "test_value".to_string());
|
|
||||||
|
|
||||||
assert_eq!(config.process_id, "test_process");
|
|
||||||
assert_eq!(config.binary_path, PathBuf::from("/usr/bin/echo"));
|
|
||||||
assert_eq!(config.args, vec!["hello", "world"]);
|
|
||||||
assert_eq!(config.env_vars.get("TEST_VAR"), Some(&"test_value".to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_simple_process_manager_creation() {
|
|
||||||
let pm = SimpleProcessManager::new();
|
|
||||||
assert!(pm.health_check().await.is_ok());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_process_status_types() {
|
|
||||||
let status1 = ProcessStatus::Running;
|
|
||||||
let status2 = ProcessStatus::Stopped;
|
|
||||||
let status3 = ProcessStatus::Error("test error".to_string());
|
|
||||||
|
|
||||||
assert_eq!(status1, ProcessStatus::Running);
|
|
||||||
assert_eq!(status2, ProcessStatus::Stopped);
|
|
||||||
assert_ne!(status1, status2);
|
|
||||||
|
|
||||||
if let ProcessStatus::Error(msg) = status3 {
|
|
||||||
assert_eq!(msg, "test error");
|
|
||||||
} else {
|
|
||||||
panic!("Expected Error status");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,404 +0,0 @@
|
|||||||
//! # Tmux Process Manager
|
|
||||||
//!
|
|
||||||
//! This module provides a tmux-based process manager implementation that manages
|
|
||||||
//! processes within tmux sessions and windows. This is useful for production
|
|
||||||
//! environments where you need persistent, manageable processes.
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
use chrono::Utc;
|
|
||||||
use std::process::Output;
|
|
||||||
use tokio::process::Command;
|
|
||||||
|
|
||||||
use crate::process_manager::{
|
|
||||||
LogInfo, ProcessConfig, ProcessManager, ProcessManagerError, ProcessManagerResult,
|
|
||||||
ProcessStatus,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Tmux-based process manager implementation
|
|
||||||
///
|
|
||||||
/// This manager creates and manages processes within tmux sessions, providing
|
|
||||||
/// better process isolation and management capabilities compared to simple spawning.
|
|
||||||
pub struct TmuxProcessManager {
|
|
||||||
/// Name of the tmux session to use
|
|
||||||
session_name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TmuxProcessManager {
|
|
||||||
/// Create a new tmux process manager with the specified session name
|
|
||||||
pub fn new(session_name: String) -> Self {
|
|
||||||
Self { session_name }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Execute a tmux command and return the output
|
|
||||||
async fn tmux_command(&self, args: &[&str]) -> ProcessManagerResult<Output> {
|
|
||||||
let output = Command::new("tmux")
|
|
||||||
.args(args)
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.map_err(|e| ProcessManagerError::Other(format!("Failed to execute tmux command: {}", e)))?;
|
|
||||||
|
|
||||||
log::debug!("Tmux command: tmux {}", args.join(" "));
|
|
||||||
log::debug!("Tmux output: {}", String::from_utf8_lossy(&output.stdout));
|
|
||||||
|
|
||||||
if !output.stderr.is_empty() {
|
|
||||||
log::debug!("Tmux stderr: {}", String::from_utf8_lossy(&output.stderr));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create the tmux session if it doesn't exist
|
|
||||||
async fn create_session_if_needed(&self) -> ProcessManagerResult<()> {
|
|
||||||
// Check if session exists
|
|
||||||
let output = self
|
|
||||||
.tmux_command(&["has-session", "-t", &self.session_name])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
// Session doesn't exist, create it
|
|
||||||
log::info!("Creating tmux session: {}", self.session_name);
|
|
||||||
let output = self
|
|
||||||
.tmux_command(&["new-session", "-d", "-s", &self.session_name])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return Err(ProcessManagerError::Other(format!(
|
|
||||||
"Failed to create tmux session '{}': {}",
|
|
||||||
self.session_name,
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build the command string for running a process
|
|
||||||
fn build_process_command(&self, config: &ProcessConfig) -> String {
|
|
||||||
let mut cmd_parts = vec![config.binary_path.to_string_lossy().to_string()];
|
|
||||||
cmd_parts.extend(config.args.clone());
|
|
||||||
cmd_parts.join(" ")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the window name for a process
|
|
||||||
fn get_window_name(&self, process_id: &str) -> String {
|
|
||||||
format!("proc-{}", process_id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl ProcessManager for TmuxProcessManager {
|
|
||||||
async fn start_process(&mut self, config: &ProcessConfig) -> ProcessManagerResult<()> {
|
|
||||||
self.create_session_if_needed().await?;
|
|
||||||
|
|
||||||
let window_name = self.get_window_name(&config.process_id);
|
|
||||||
let command = self.build_process_command(config);
|
|
||||||
|
|
||||||
// Check if window already exists
|
|
||||||
let check_output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"list-windows",
|
|
||||||
"-t",
|
|
||||||
&self.session_name,
|
|
||||||
"-F",
|
|
||||||
"#{window_name}",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let existing_windows = String::from_utf8_lossy(&check_output.stdout);
|
|
||||||
if existing_windows.lines().any(|line| line.trim() == window_name) {
|
|
||||||
return Err(ProcessManagerError::ProcessAlreadyRunning(config.process_id.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new window and run the process
|
|
||||||
let mut tmux_args = vec![
|
|
||||||
"new-window",
|
|
||||||
"-t",
|
|
||||||
&self.session_name,
|
|
||||||
"-n",
|
|
||||||
&window_name,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Set working directory if specified
|
|
||||||
let working_dir_arg;
|
|
||||||
if let Some(working_dir) = &config.working_dir {
|
|
||||||
working_dir_arg = working_dir.to_string_lossy().to_string();
|
|
||||||
tmux_args.extend(&["-c", &working_dir_arg]);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmux_args.push(&command);
|
|
||||||
|
|
||||||
let output = self.tmux_command(&tmux_args).await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return Err(ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
format!(
|
|
||||||
"Failed to create tmux window: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a moment and check if the process is still running
|
|
||||||
tokio::time::sleep(std::time::Duration::from_millis(500)).await;
|
|
||||||
|
|
||||||
match self.process_status(&config.process_id).await? {
|
|
||||||
ProcessStatus::Running => {
|
|
||||||
log::info!("Successfully started process {} in tmux window {}", config.process_id, window_name);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
ProcessStatus::Stopped => {
|
|
||||||
Err(ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
"Process exited immediately after startup".to_string(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
ProcessStatus::Error(msg) => {
|
|
||||||
Err(ProcessManagerError::StartupFailed(
|
|
||||||
config.process_id.clone(),
|
|
||||||
format!("Process failed to start: {}", msg),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
_ => Ok(()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn stop_process(&mut self, process_id: &str, force: bool) -> ProcessManagerResult<()> {
|
|
||||||
let window_name = self.get_window_name(process_id);
|
|
||||||
|
|
||||||
// Check if window exists
|
|
||||||
let check_output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"list-windows",
|
|
||||||
"-t",
|
|
||||||
&self.session_name,
|
|
||||||
"-F",
|
|
||||||
"#{window_name}",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let existing_windows = String::from_utf8_lossy(&check_output.stdout);
|
|
||||||
if !existing_windows.lines().any(|line| line.trim() == window_name) {
|
|
||||||
return Err(ProcessManagerError::ProcessNotFound(process_id.to_string()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if force {
|
|
||||||
// Kill the window immediately
|
|
||||||
let output = self
|
|
||||||
.tmux_command(&["kill-window", "-t", &format!("{}:{}", self.session_name, window_name)])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return Err(ProcessManagerError::StopFailed(
|
|
||||||
process_id.to_string(),
|
|
||||||
format!(
|
|
||||||
"Failed to kill tmux window: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Send SIGTERM to the process in the window
|
|
||||||
let output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"send-keys",
|
|
||||||
"-t",
|
|
||||||
&format!("{}:{}", self.session_name, window_name),
|
|
||||||
"C-c",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
log::warn!("Failed to send SIGTERM, trying force kill");
|
|
||||||
// Fallback to force kill
|
|
||||||
return self.stop_process(process_id, true).await;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait a bit for graceful shutdown
|
|
||||||
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
|
|
||||||
|
|
||||||
// Check if process is still running, force kill if needed
|
|
||||||
if let Ok(ProcessStatus::Running) = self.process_status(process_id).await {
|
|
||||||
log::info!("Process {} didn't stop gracefully, force killing", process_id);
|
|
||||||
return self.stop_process(process_id, true).await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log::info!("Successfully stopped process {}", process_id);
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn process_status(&self, process_id: &str) -> ProcessManagerResult<ProcessStatus> {
|
|
||||||
let window_name = self.get_window_name(process_id);
|
|
||||||
|
|
||||||
// Check if window exists
|
|
||||||
let check_output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"list-windows",
|
|
||||||
"-t",
|
|
||||||
&self.session_name,
|
|
||||||
"-F",
|
|
||||||
"#{window_name}",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
let existing_windows = String::from_utf8_lossy(&check_output.stdout);
|
|
||||||
if !existing_windows.lines().any(|line| line.trim() == window_name) {
|
|
||||||
return Ok(ProcessStatus::Stopped);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if there are any panes in the window (process running)
|
|
||||||
let pane_output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"list-panes",
|
|
||||||
"-t",
|
|
||||||
&format!("{}:{}", self.session_name, window_name),
|
|
||||||
"-F",
|
|
||||||
"#{pane_pid}",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if pane_output.status.success() && !pane_output.stdout.is_empty() {
|
|
||||||
Ok(ProcessStatus::Running)
|
|
||||||
} else {
|
|
||||||
Ok(ProcessStatus::Stopped)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn process_logs(&self, process_id: &str, lines: Option<usize>, _follow: bool) -> ProcessManagerResult<Vec<LogInfo>> {
|
|
||||||
let window_name = self.get_window_name(process_id);
|
|
||||||
|
|
||||||
// Capture the pane content (this is the best we can do with tmux)
|
|
||||||
let target_window = format!("{}:{}", self.session_name, window_name);
|
|
||||||
let mut tmux_args = vec![
|
|
||||||
"capture-pane",
|
|
||||||
"-t",
|
|
||||||
&target_window,
|
|
||||||
"-p",
|
|
||||||
];
|
|
||||||
|
|
||||||
// Add line limit if specified
|
|
||||||
let lines_arg;
|
|
||||||
if let Some(line_count) = lines {
|
|
||||||
lines_arg = format!("-S -{}", line_count);
|
|
||||||
tmux_args.push(&lines_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
let output = self.tmux_command(&tmux_args).await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
return Err(ProcessManagerError::LogsFailed(
|
|
||||||
process_id.to_string(),
|
|
||||||
format!(
|
|
||||||
"Failed to capture tmux pane: {}",
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let content = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let timestamp = Utc::now().to_rfc3339();
|
|
||||||
|
|
||||||
let logs = content
|
|
||||||
.lines()
|
|
||||||
.filter(|line| !line.trim().is_empty())
|
|
||||||
.map(|line| LogInfo {
|
|
||||||
timestamp: timestamp.clone(),
|
|
||||||
level: "info".to_string(),
|
|
||||||
message: line.to_string(),
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(logs)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn health_check(&self) -> ProcessManagerResult<()> {
|
|
||||||
// Check if tmux is available
|
|
||||||
let output = Command::new("tmux")
|
|
||||||
.arg("list-sessions")
|
|
||||||
.output()
|
|
||||||
.await
|
|
||||||
.map_err(|e| ProcessManagerError::Other(format!("Tmux not available: {}", e)))?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
let error_msg = String::from_utf8_lossy(&output.stderr);
|
|
||||||
if error_msg.contains("no server running") {
|
|
||||||
// This is fine, tmux server will start when needed
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ProcessManagerError::Other(format!("Tmux health check failed: {}", error_msg)))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn list_processes(&self) -> ProcessManagerResult<Vec<String>> {
|
|
||||||
// List all windows in our session that match our process naming pattern
|
|
||||||
let output = self
|
|
||||||
.tmux_command(&[
|
|
||||||
"list-windows",
|
|
||||||
"-t",
|
|
||||||
&self.session_name,
|
|
||||||
"-F",
|
|
||||||
"#{window_name}",
|
|
||||||
])
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
if !output.status.success() {
|
|
||||||
// Session might not exist
|
|
||||||
return Ok(Vec::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let windows = String::from_utf8_lossy(&output.stdout);
|
|
||||||
let processes = windows
|
|
||||||
.lines()
|
|
||||||
.filter_map(|line| {
|
|
||||||
let window_name = line.trim();
|
|
||||||
if window_name.starts_with("proc-") {
|
|
||||||
Some(window_name.strip_prefix("proc-").unwrap().to_string())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(processes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_tmux_manager_creation() {
|
|
||||||
let manager = TmuxProcessManager::new("test_session".to_string());
|
|
||||||
assert_eq!(manager.session_name, "test_session");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_window_name_generation() {
|
|
||||||
let manager = TmuxProcessManager::new("test_session".to_string());
|
|
||||||
let window_name = manager.get_window_name("test_process");
|
|
||||||
assert_eq!(window_name, "proc-test_process");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn test_command_building() {
|
|
||||||
let manager = TmuxProcessManager::new("test_session".to_string());
|
|
||||||
let config = ProcessConfig::new(
|
|
||||||
"test_process".to_string(),
|
|
||||||
PathBuf::from("/usr/bin/echo"),
|
|
||||||
)
|
|
||||||
.with_arg("hello".to_string())
|
|
||||||
.with_arg("world".to_string());
|
|
||||||
|
|
||||||
let command = manager.build_process_command(&config);
|
|
||||||
assert!(command.contains("/usr/bin/echo"));
|
|
||||||
assert!(command.contains("hello"));
|
|
||||||
assert!(command.contains("world"));
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,14 +0,0 @@
|
|||||||
# Environment Configuration
|
|
||||||
|
|
||||||
To set up your environment variables:
|
|
||||||
|
|
||||||
1. Copy the template file to `env.sh`:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cp config/myenv_templ.sh config/env.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Edit `config/env.sh` and fill in your specific values for the variables.
|
|
||||||
|
|
||||||
3. This file (`config/env.sh`) is excluded from version control by the project's `.gitignore` configuration, ensuring your sensitive information remains local and is never committed to the repository.
|
|
||||||
|
|
@@ -1,6 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
export OPENROUTER_API_KEY=""
|
|
||||||
export GROQ_API_KEY=""
|
|
||||||
export CEREBRAS_API_KEY=""
|
|
||||||
export OPENAI_API_KEY="sk-xxxxxxx"
|
|
@@ -1,43 +0,0 @@
|
|||||||
# RFS Client Rhai Examples
|
|
||||||
|
|
||||||
This folder contains Rhai examples that use the SAL RFS client wrappers registered by `sal::rhai::register(&mut engine)` and executed by the `herodo` binary.
|
|
||||||
|
|
||||||
## Quick start
|
|
||||||
|
|
||||||
Run the auth + upload + download example (uses hardcoded credentials and `/etc/hosts` as input):
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run -p herodo -- examples/rfsclient/auth_and_upload.rhai
|
|
||||||
```
|
|
||||||
|
|
||||||
By default, the script:
|
|
||||||
|
|
||||||
- Uses base URL `http://127.0.0.1:8080`
|
|
||||||
- Uses credentials `user` / `password`
|
|
||||||
- Uploads the file `/etc/hosts`
|
|
||||||
- Downloads to `/tmp/rfs_example_out.txt`
|
|
||||||
|
|
||||||
To customize, edit `examples/rfsclient/auth_and_upload.rhai` near the top and change `BASE_URL`, `USER`, `PASS`, and file paths.
|
|
||||||
|
|
||||||
## What the example does
|
|
||||||
|
|
||||||
- Creates the RFS client: `rfs_create_client(BASE_URL, USER, PASS, TIMEOUT)`
|
|
||||||
- Health check: `rfs_health_check()`
|
|
||||||
- Authenticates: `rfs_authenticate()`
|
|
||||||
- Uploads a file: `rfs_upload_file(local_path, chunk_size, verify)` → returns file hash
|
|
||||||
- Downloads it back: `rfs_download_file(file_id_or_hash, dest_path, verify)` → returns unit (throws on error)
|
|
||||||
|
|
||||||
See `examples/rfsclient/auth_and_upload.rhai` for details.
|
|
||||||
|
|
||||||
## Using the Rust client directly (optional)
|
|
||||||
|
|
||||||
If you want to use the Rust API (without Rhai), depend on `sal-rfs-client` and see:
|
|
||||||
|
|
||||||
- `packages/clients/rfsclient/src/client.rs` (`RfsClient`)
|
|
||||||
- `packages/clients/rfsclient/src/types.rs` (config and option types)
|
|
||||||
- `packages/clients/rfsclient/examples/` (example usage)
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
- Auth failures: verify credentials and that the server requires/authenticates them.
|
|
||||||
- Connection errors: verify the base URL is reachable from your machine.
|
|
@@ -1,41 +0,0 @@
|
|||||||
// RFS Client: Auth + Upload + Download example
|
|
||||||
// Prereqs:
|
|
||||||
// - RFS server reachable at RFS_BASE_URL
|
|
||||||
// - Valid credentials in env: RFS_USER, RFS_PASS
|
|
||||||
// - Run with herodo so the SAL Rhai modules are registered
|
|
||||||
|
|
||||||
// NOTE: env_get not available in this runtime; hardcode or replace with your env loader
|
|
||||||
let BASE_URL = "http://127.0.0.1:8080";
|
|
||||||
let USER = "user";
|
|
||||||
let PASS = "password";
|
|
||||||
let TIMEOUT = 30; // seconds
|
|
||||||
|
|
||||||
if BASE_URL == "" { throw "Set BASE_URL in the script"; }
|
|
||||||
|
|
||||||
// Create client
|
|
||||||
let ok = rfs_create_client(BASE_URL, USER, PASS, TIMEOUT);
|
|
||||||
if !ok { throw "Failed to create RFS client"; }
|
|
||||||
|
|
||||||
// Optional health check
|
|
||||||
let health = rfs_health_check();
|
|
||||||
print(`RFS health: ${health}`);
|
|
||||||
|
|
||||||
// Authenticate (required for some operations)
|
|
||||||
let auth_ok = rfs_authenticate();
|
|
||||||
if !auth_ok { throw "Authentication failed"; }
|
|
||||||
|
|
||||||
// Upload a local file
|
|
||||||
// Use an existing readable file to avoid needing os_write_file module
|
|
||||||
let local_file = "/etc/hosts";
|
|
||||||
// rfs_upload_file(file_path, chunk_size, verify)
|
|
||||||
let hash = rfs_upload_file(local_file, 0, false);
|
|
||||||
print(`Uploaded file hash: ${hash}`);
|
|
||||||
|
|
||||||
// Download it back
|
|
||||||
let out_path = "/tmp/rfs_example_out.txt";
|
|
||||||
// rfs_download_file(file_id, output_path, verify) returns unit and throws on error
|
|
||||||
rfs_download_file(hash, out_path, false);
|
|
||||||
|
|
||||||
print(`Downloaded to: ${out_path}`);
|
|
||||||
|
|
||||||
true
|
|
@@ -1,15 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "openrouter_example"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[workspace]
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "openrouter_example"
|
|
||||||
path = "openrouter_example.rs"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
codemonkey = { path = "../../packages/ai/codemonkey" }
|
|
||||||
openai-api-rs = "6.0.8"
|
|
||||||
tokio = { version = "1.0", features = ["full"] }
|
|
@@ -1,47 +0,0 @@
|
|||||||
use codemonkey::{create_ai_provider, AIProviderType, CompletionRequestBuilder, Message, MessageRole, Content};
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn Error>> {
|
|
||||||
|
|
||||||
let (mut provider, provider_type) = create_ai_provider(AIProviderType::OpenRouter)?;
|
|
||||||
|
|
||||||
let messages = vec![Message {
|
|
||||||
role: MessageRole::user,
|
|
||||||
content: Content::Text("Explain the concept of a factory design pattern in Rust.".to_string()),
|
|
||||||
name: None,
|
|
||||||
tool_calls: None,
|
|
||||||
tool_call_id: None,
|
|
||||||
}];
|
|
||||||
|
|
||||||
println!("Sending request to OpenRouter...");
|
|
||||||
let response = CompletionRequestBuilder::new(
|
|
||||||
&mut *provider,
|
|
||||||
"openai/gpt-oss-120b".to_string(), // Model name as specified by the user
|
|
||||||
messages,
|
|
||||||
provider_type, // Pass the provider_type
|
|
||||||
)
|
|
||||||
.temperature(1.0)
|
|
||||||
.max_tokens(8192)
|
|
||||||
.top_p(1.0)
|
|
||||||
.reasoning_effort("medium")
|
|
||||||
.stream(false)
|
|
||||||
.openrouter_options(|builder| {
|
|
||||||
builder.provider(
|
|
||||||
codemonkey::OpenRouterProviderOptionsBuilder::new()
|
|
||||||
.order(vec!["cerebras"])
|
|
||||||
.build(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.completion()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
for choice in response.choices {
|
|
||||||
if let Some(content) = choice.message.content {
|
|
||||||
print!("{}", content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
println!();
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@@ -1,13 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Change to directory where this script is located
|
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")"
|
|
||||||
|
|
||||||
source ../../config/myenv.sh
|
|
||||||
|
|
||||||
# Build the example
|
|
||||||
cargo build
|
|
||||||
|
|
||||||
# Run the example
|
|
||||||
cargo run --bin openrouter_example
|
|
@@ -1,10 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "codemonkey"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tokio = { version = "1", features = ["full"] }
|
|
||||||
async-trait = "0.1.80"
|
|
||||||
openrouter-rs = "0.4.5"
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
@@ -1,216 +0,0 @@
|
|||||||
use async_trait::async_trait;
|
|
||||||
use openrouter_rs::{OpenRouterClient, api::chat::{ChatCompletionRequest, Message}, types::completion::CompletionsResponse};
|
|
||||||
use std::env;
|
|
||||||
use std::error::Error;
|
|
||||||
|
|
||||||
// Re-export MessageRole for easier use in client code
|
|
||||||
pub use openrouter_rs::types::Role as MessageRole;
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
pub trait AIProvider {
|
|
||||||
async fn completion(
|
|
||||||
&mut self,
|
|
||||||
request: CompletionRequest,
|
|
||||||
) -> Result<CompletionsResponse, Box<dyn Error>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CompletionRequest {
|
|
||||||
pub model: String,
|
|
||||||
pub messages: Vec<Message>,
|
|
||||||
pub temperature: Option<f64>,
|
|
||||||
pub max_tokens: Option<i64>,
|
|
||||||
pub top_p: Option<f64>,
|
|
||||||
pub stream: Option<bool>,
|
|
||||||
pub stop: Option<Vec<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CompletionRequestBuilder<'a> {
|
|
||||||
provider: &'a mut dyn AIProvider,
|
|
||||||
model: String,
|
|
||||||
messages: Vec<Message>,
|
|
||||||
temperature: Option<f64>,
|
|
||||||
max_tokens: Option<i64>,
|
|
||||||
top_p: Option<f64>,
|
|
||||||
stream: Option<bool>,
|
|
||||||
stop: Option<Vec<String>>,
|
|
||||||
provider_type: AIProviderType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> CompletionRequestBuilder<'a> {
|
|
||||||
pub fn new(provider: &'a mut dyn AIProvider, model: String, messages: Vec<Message>, provider_type: AIProviderType) -> Self {
|
|
||||||
Self {
|
|
||||||
provider,
|
|
||||||
model,
|
|
||||||
messages,
|
|
||||||
temperature: None,
|
|
||||||
max_tokens: None,
|
|
||||||
top_p: None,
|
|
||||||
stream: None,
|
|
||||||
stop: None,
|
|
||||||
provider_type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn temperature(mut self, temperature: f64) -> Self {
|
|
||||||
self.temperature = Some(temperature);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn max_tokens(mut self, max_tokens: i64) -> Self {
|
|
||||||
self.max_tokens = Some(max_tokens);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn top_p(mut self, top_p: f64) -> Self {
|
|
||||||
self.top_p = Some(top_p);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stream(mut self, stream: bool) -> Self {
|
|
||||||
self.stream = Some(stream);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn stop(mut self, stop: Vec<String>) -> Self {
|
|
||||||
self.stop = Some(stop);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn completion(self) -> Result<CompletionsResponse, Box<dyn Error>> {
|
|
||||||
let request = CompletionRequest {
|
|
||||||
model: self.model,
|
|
||||||
messages: self.messages,
|
|
||||||
temperature: self.temperature,
|
|
||||||
max_tokens: self.max_tokens,
|
|
||||||
top_p: self.top_p,
|
|
||||||
stream: self.stream,
|
|
||||||
stop: self.stop,
|
|
||||||
};
|
|
||||||
self.provider.completion(request).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GroqAIProvider {
|
|
||||||
client: OpenRouterClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl AIProvider for GroqAIProvider {
|
|
||||||
async fn completion(
|
|
||||||
&mut self,
|
|
||||||
request: CompletionRequest,
|
|
||||||
) -> Result<CompletionsResponse, Box<dyn Error>> {
|
|
||||||
let chat_request = ChatCompletionRequest::builder()
|
|
||||||
.model(request.model)
|
|
||||||
.messages(request.messages)
|
|
||||||
.temperature(request.temperature.unwrap_or(1.0))
|
|
||||||
.max_tokens(request.max_tokens.map(|x| x as u32).unwrap_or(2048))
|
|
||||||
.top_p(request.top_p.unwrap_or(1.0))
|
|
||||||
.build()?;
|
|
||||||
|
|
||||||
let result = self.client.send_chat_completion(&chat_request).await?;
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OpenAIProvider {
|
|
||||||
client: OpenRouterClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl AIProvider for OpenAIProvider {
|
|
||||||
async fn completion(
|
|
||||||
&mut self,
|
|
||||||
request: CompletionRequest,
|
|
||||||
) -> Result<CompletionsResponse, Box<dyn Error>> {
|
|
||||||
let chat_request = ChatCompletionRequest::builder()
|
|
||||||
.model(request.model)
|
|
||||||
.messages(request.messages)
|
|
||||||
.temperature(request.temperature.unwrap_or(1.0))
|
|
||||||
.max_tokens(request.max_tokens.map(|x| x as u32).unwrap_or(2048))
|
|
||||||
.top_p(request.top_p.unwrap_or(1.0))
|
|
||||||
.build()?;
|
|
||||||
|
|
||||||
let result = self.client.send_chat_completion(&chat_request).await?;
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OpenRouterAIProvider {
|
|
||||||
client: OpenRouterClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl AIProvider for OpenRouterAIProvider {
|
|
||||||
async fn completion(
|
|
||||||
&mut self,
|
|
||||||
request: CompletionRequest,
|
|
||||||
) -> Result<CompletionsResponse, Box<dyn Error>> {
|
|
||||||
let chat_request = ChatCompletionRequest::builder()
|
|
||||||
.model(request.model)
|
|
||||||
.messages(request.messages)
|
|
||||||
.temperature(request.temperature.unwrap_or(1.0))
|
|
||||||
.max_tokens(request.max_tokens.map(|x| x as u32).unwrap_or(2048))
|
|
||||||
.top_p(request.top_p.unwrap_or(1.0))
|
|
||||||
.build()?;
|
|
||||||
|
|
||||||
let result = self.client.send_chat_completion(&chat_request).await?;
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct CerebrasAIProvider {
|
|
||||||
client: OpenRouterClient,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl AIProvider for CerebrasAIProvider {
|
|
||||||
async fn completion(
|
|
||||||
&mut self,
|
|
||||||
request: CompletionRequest,
|
|
||||||
) -> Result<CompletionsResponse, Box<dyn Error>> {
|
|
||||||
let chat_request = ChatCompletionRequest::builder()
|
|
||||||
.model(request.model)
|
|
||||||
.messages(request.messages)
|
|
||||||
.temperature(request.temperature.unwrap_or(1.0))
|
|
||||||
.max_tokens(request.max_tokens.map(|x| x as u32).unwrap_or(2048))
|
|
||||||
.top_p(request.top_p.unwrap_or(1.0))
|
|
||||||
.build()?;
|
|
||||||
|
|
||||||
let result = self.client.send_chat_completion(&chat_request).await?;
|
|
||||||
Ok(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
|
||||||
pub enum AIProviderType {
|
|
||||||
Groq,
|
|
||||||
OpenAI,
|
|
||||||
OpenRouter,
|
|
||||||
Cerebras,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_ai_provider(provider_type: AIProviderType) -> Result<(Box<dyn AIProvider>, AIProviderType), Box<dyn Error>> {
|
|
||||||
match provider_type {
|
|
||||||
AIProviderType::Groq => {
|
|
||||||
let api_key = env::var("GROQ_API_KEY")?;
|
|
||||||
let client = OpenRouterClient::builder().api_key(api_key).build()?;
|
|
||||||
Ok((Box::new(GroqAIProvider { client }), AIProviderType::Groq))
|
|
||||||
}
|
|
||||||
AIProviderType::OpenAI => {
|
|
||||||
let api_key = env::var("OPENAI_API_KEY")?;
|
|
||||||
let client = OpenRouterClient::builder().api_key(api_key).build()?;
|
|
||||||
Ok((Box::new(OpenAIProvider { client }), AIProviderType::OpenAI))
|
|
||||||
}
|
|
||||||
AIProviderType::OpenRouter => {
|
|
||||||
let api_key = env::var("OPENROUTER_API_KEY")?;
|
|
||||||
let client = OpenRouterClient::builder().api_key(api_key).build()?;
|
|
||||||
Ok((Box::new(OpenRouterAIProvider { client }), AIProviderType::OpenRouter))
|
|
||||||
}
|
|
||||||
AIProviderType::Cerebras => {
|
|
||||||
let api_key = env::var("CEREBRAS_API_KEY")?;
|
|
||||||
let client = OpenRouterClient::builder().api_key(api_key).build()?;
|
|
||||||
Ok((Box::new(CerebrasAIProvider { client }), AIProviderType::Cerebras))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1004,7 +1004,7 @@ impl OrderServerProduct {
|
|||||||
})
|
})
|
||||||
.with_get("traffic", |o: &mut OrderServerProduct| o.traffic.clone())
|
.with_get("traffic", |o: &mut OrderServerProduct| o.traffic.clone())
|
||||||
.with_get("dist", |o: &mut OrderServerProduct| o.dist.clone())
|
.with_get("dist", |o: &mut OrderServerProduct| o.dist.clone())
|
||||||
.with_get("arch", |o: &mut OrderServerProduct| o.dist.clone())
|
.with_get("arch", |o: &mut OrderServerProduct| o.arch.clone())
|
||||||
.with_get("lang", |o: &mut OrderServerProduct| o.lang.clone())
|
.with_get("lang", |o: &mut OrderServerProduct| o.lang.clone())
|
||||||
.with_get("location", |o: &mut OrderServerProduct| o.location.clone())
|
.with_get("location", |o: &mut OrderServerProduct| o.location.clone())
|
||||||
.with_get("prices", |o: &mut OrderServerProduct| o.prices.clone())
|
.with_get("prices", |o: &mut OrderServerProduct| o.prices.clone())
|
||||||
@@ -1027,7 +1027,7 @@ impl fmt::Display for OrderServerProduct {
|
|||||||
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
||||||
table.add_row(row![
|
table.add_row(row![
|
||||||
"Architectures",
|
"Architectures",
|
||||||
self.dist.join(", ")
|
self.arch.as_deref().unwrap_or_default().join(", ")
|
||||||
]);
|
]);
|
||||||
table.add_row(row!["Languages", self.lang.join(", ")]);
|
table.add_row(row!["Languages", self.lang.join(", ")]);
|
||||||
table.add_row(row!["Locations", self.location.join(", ")]);
|
table.add_row(row!["Locations", self.location.join(", ")]);
|
||||||
@@ -1270,7 +1270,7 @@ impl AuctionServerProduct {
|
|||||||
})
|
})
|
||||||
.with_get("traffic", |p: &mut AuctionServerProduct| p.traffic.clone())
|
.with_get("traffic", |p: &mut AuctionServerProduct| p.traffic.clone())
|
||||||
.with_get("dist", |p: &mut AuctionServerProduct| p.dist.clone())
|
.with_get("dist", |p: &mut AuctionServerProduct| p.dist.clone())
|
||||||
.with_get("arch", |p: &mut AuctionServerProduct| p.dist.clone())
|
.with_get("arch", |p: &mut AuctionServerProduct| p.arch.clone())
|
||||||
.with_get("lang", |p: &mut AuctionServerProduct| p.lang.clone())
|
.with_get("lang", |p: &mut AuctionServerProduct| p.lang.clone())
|
||||||
.with_get("cpu", |p: &mut AuctionServerProduct| p.cpu.clone())
|
.with_get("cpu", |p: &mut AuctionServerProduct| p.cpu.clone())
|
||||||
.with_get("cpu_benchmark", |p: &mut AuctionServerProduct| {
|
.with_get("cpu_benchmark", |p: &mut AuctionServerProduct| {
|
||||||
@@ -1328,7 +1328,7 @@ impl fmt::Display for AuctionServerProduct {
|
|||||||
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
table.add_row(row!["Distributions", self.dist.join(", ")]);
|
||||||
table.add_row(row![
|
table.add_row(row![
|
||||||
"Architectures",
|
"Architectures",
|
||||||
self.dist.join(", ")
|
self.arch.as_deref().unwrap_or_default().join(", ")
|
||||||
]);
|
]);
|
||||||
table.add_row(row!["Languages", self.lang.join(", ")]);
|
table.add_row(row!["Languages", self.lang.join(", ")]);
|
||||||
table.add_row(row!["CPU", self.cpu.clone()]);
|
table.add_row(row!["CPU", self.cpu.clone()]);
|
||||||
@@ -1486,7 +1486,7 @@ impl fmt::Display for AuctionTransaction {
|
|||||||
table.add_row(row!["Product Distributions", self.product.dist.clone()]);
|
table.add_row(row!["Product Distributions", self.product.dist.clone()]);
|
||||||
table.add_row(row![
|
table.add_row(row![
|
||||||
"Product Architectures",
|
"Product Architectures",
|
||||||
&self.product.dist
|
self.product.arch.as_deref().unwrap_or("N/A")
|
||||||
]);
|
]);
|
||||||
table.add_row(row!["Product Languages", self.product.lang.clone()]);
|
table.add_row(row!["Product Languages", self.product.lang.clone()]);
|
||||||
table.add_row(row!["Product CPU", self.product.cpu.clone()]);
|
table.add_row(row!["Product CPU", self.product.cpu.clone()]);
|
||||||
@@ -1569,7 +1569,7 @@ impl AuctionTransactionProduct {
|
|||||||
})
|
})
|
||||||
.with_get("dist", |p: &mut AuctionTransactionProduct| p.dist.clone())
|
.with_get("dist", |p: &mut AuctionTransactionProduct| p.dist.clone())
|
||||||
.with_get("arch", |p: &mut AuctionTransactionProduct| {
|
.with_get("arch", |p: &mut AuctionTransactionProduct| {
|
||||||
p.dist.clone()
|
p.arch.clone().unwrap_or_default()
|
||||||
})
|
})
|
||||||
.with_get("lang", |p: &mut AuctionTransactionProduct| p.lang.clone())
|
.with_get("lang", |p: &mut AuctionTransactionProduct| p.lang.clone())
|
||||||
.with_get("cpu", |p: &mut AuctionTransactionProduct| p.cpu.clone())
|
.with_get("cpu", |p: &mut AuctionTransactionProduct| p.cpu.clone())
|
||||||
|
@@ -100,7 +100,7 @@ pub fn pretty_print_auction_server_products(products: rhai::Array) {
|
|||||||
product.description.join(", "),
|
product.description.join(", "),
|
||||||
product.traffic,
|
product.traffic,
|
||||||
product.dist.join(", "),
|
product.dist.join(", "),
|
||||||
product.dist.join(", "),
|
product.arch.as_deref().unwrap_or_default().join(", "),
|
||||||
product.lang.join(", "),
|
product.lang.join(", "),
|
||||||
product.cpu,
|
product.cpu,
|
||||||
product.cpu_benchmark,
|
product.cpu_benchmark,
|
||||||
|
@@ -1,26 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "sal-rfs-client"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
description = "SAL RFS Client - Client library for Remote File System server"
|
|
||||||
repository = "https://git.threefold.info/herocode/sal"
|
|
||||||
license = "Apache-2.0"
|
|
||||||
keywords = ["rfs", "client", "filesystem", "remote"]
|
|
||||||
categories = ["filesystem", "api-bindings"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
openapi = { path = "./openapi" }
|
|
||||||
thiserror.workspace = true
|
|
||||||
url.workspace = true
|
|
||||||
reqwest = { workspace = true, features = ["json", "multipart"] }
|
|
||||||
tokio = { workspace = true, features = ["full"] }
|
|
||||||
serde = { workspace = true, features = ["derive"] }
|
|
||||||
serde_json.workspace = true
|
|
||||||
log.workspace = true
|
|
||||||
bytes.workspace = true
|
|
||||||
futures.workspace = true
|
|
||||||
rhai.workspace = true
|
|
||||||
lazy_static.workspace = true
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tempfile = "3.0"
|
|
@@ -1,195 +0,0 @@
|
|||||||
# RFS Client
|
|
||||||
|
|
||||||
A Rust client library for interacting with the Remote File System (RFS) server.
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This client library provides a user-friendly wrapper around the OpenAPI-generated client code. It offers high-level abstractions for common operations such as:
|
|
||||||
|
|
||||||
- Authentication and session management
|
|
||||||
- File uploads and downloads with progress tracking
|
|
||||||
- Block-level operations and verification
|
|
||||||
- FList creation, monitoring, and management
|
|
||||||
- Timeout configuration and error handling
|
|
||||||
|
|
||||||
## Structure
|
|
||||||
|
|
||||||
The library is organized as follows:
|
|
||||||
|
|
||||||
- `client.rs`: Main client implementation with methods for interacting with the RFS server
|
|
||||||
- `error.rs`: Error types and handling
|
|
||||||
- `types.rs`: Type definitions and utilities
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use rfs_client::RfsClient;
|
|
||||||
use rfs_client::types::{ClientConfig, Credentials};
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Create a client with custom configuration
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate
|
|
||||||
client.authenticate().await?;
|
|
||||||
println!("Authentication successful");
|
|
||||||
|
|
||||||
// Upload a file
|
|
||||||
let file_path = "/path/to/file.txt";
|
|
||||||
let file_hash = client.upload_file(file_path, None).await?;
|
|
||||||
println!("File uploaded with hash: {}", file_hash);
|
|
||||||
|
|
||||||
// Download the file
|
|
||||||
let output_path = "/path/to/output.txt";
|
|
||||||
client.download_file(&file_hash, output_path, None).await?;
|
|
||||||
println!("File downloaded to {}", output_path);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Feature Examples
|
|
||||||
|
|
||||||
### Authentication
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Create a client with authentication
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 30,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
if client.is_authenticated() {
|
|
||||||
println!("Authentication successful");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### File Management
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Upload a file with options
|
|
||||||
let upload_options = UploadOptions {
|
|
||||||
chunk_size: Some(1024 * 1024), // 1MB chunks
|
|
||||||
verify: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_hash = client.upload_file("/path/to/file.txt", Some(upload_options)).await?;
|
|
||||||
|
|
||||||
// Download the file
|
|
||||||
let download_options = DownloadOptions {
|
|
||||||
verify: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
client.download_file(&file_hash, "/path/to/output.txt", Some(download_options)).await?;
|
|
||||||
```
|
|
||||||
|
|
||||||
### FList Operations
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// Create an FList from a Docker image
|
|
||||||
let options = FlistOptions {
|
|
||||||
auth: None,
|
|
||||||
username: None,
|
|
||||||
password: None,
|
|
||||||
email: None,
|
|
||||||
server_address: Some("docker.io".to_string()),
|
|
||||||
identity_token: None,
|
|
||||||
registry_token: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let job_id = client.create_flist("alpine:latest", Some(options)).await?;
|
|
||||||
|
|
||||||
// Wait for FList creation with progress tracking
|
|
||||||
let wait_options = WaitOptions {
|
|
||||||
timeout_seconds: 60,
|
|
||||||
poll_interval_ms: 1000,
|
|
||||||
progress_callback: Some(Box::new(|state| {
|
|
||||||
println!("Progress: FList state is now {:?}", state);
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
let final_state = client.wait_for_flist_creation(&job_id, Some(wait_options)).await?;
|
|
||||||
|
|
||||||
// List available FLists
|
|
||||||
let flists = client.list_flists().await?;
|
|
||||||
|
|
||||||
// Preview an FList
|
|
||||||
let preview = client.preview_flist("flists/user/alpine-latest.fl").await?;
|
|
||||||
|
|
||||||
// Download an FList
|
|
||||||
client.download_flist("flists/user/alpine-latest.fl", "/tmp/downloaded_flist.fl").await?;
|
|
||||||
```
|
|
||||||
|
|
||||||
### Block Management
|
|
||||||
|
|
||||||
```rust
|
|
||||||
// List blocks
|
|
||||||
let blocks_list = client.list_blocks(None).await?;
|
|
||||||
|
|
||||||
// Check if a block exists
|
|
||||||
let exists = client.check_block("block_hash").await?;
|
|
||||||
|
|
||||||
// Get block content
|
|
||||||
let block_content = client.get_block("block_hash").await?;
|
|
||||||
|
|
||||||
// Upload a block
|
|
||||||
let block_hash = client.upload_block("file_hash", 0, data).await?;
|
|
||||||
|
|
||||||
// Verify blocks
|
|
||||||
let request = VerifyBlocksRequest { blocks: verify_blocks };
|
|
||||||
let verify_result = client.verify_blocks(request).await?;
|
|
||||||
```
|
|
||||||
|
|
||||||
## Complete Examples
|
|
||||||
|
|
||||||
For more detailed examples, check the `examples` directory:
|
|
||||||
|
|
||||||
- `authentication.rs`: Authentication and health check examples
|
|
||||||
- `file_management.rs`: File upload and download with verification
|
|
||||||
- `flist_operations.rs`: Complete FList creation, monitoring, listing, preview, and download
|
|
||||||
- `block_management.rs`: Block-level operations including listing, verification, and upload
|
|
||||||
- `wait_for_flist.rs`: Advanced FList creation with progress monitoring
|
|
||||||
|
|
||||||
Run an example with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo run --example flist_operations
|
|
||||||
```
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
This library wraps the OpenAPI-generated client located in the `openapi` directory. The OpenAPI client was generated using the OpenAPI Generator CLI.
|
|
||||||
|
|
||||||
To build the library:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo build
|
|
||||||
```
|
|
||||||
|
|
||||||
To run tests:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo test -- --test-threads=1
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
MIT
|
|
@@ -1,42 +0,0 @@
|
|||||||
use sal_rfs_client::types::{ClientConfig, Credentials};
|
|
||||||
use sal_rfs_client::RfsClient;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Create a client with authentication credentials
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 30,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
println!("Client created with authentication credentials");
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
if client.is_authenticated() {
|
|
||||||
println!("Authentication successful");
|
|
||||||
} else {
|
|
||||||
println!("Authentication failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a client without authentication
|
|
||||||
let config_no_auth = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: None,
|
|
||||||
timeout_seconds: 30,
|
|
||||||
};
|
|
||||||
|
|
||||||
let client_no_auth = RfsClient::new(config_no_auth);
|
|
||||||
println!("Client created without authentication credentials");
|
|
||||||
|
|
||||||
// Check health endpoint (doesn't require authentication)
|
|
||||||
let health = client_no_auth.health_check().await?;
|
|
||||||
println!("Server health: {:?}", health);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@@ -1,153 +0,0 @@
|
|||||||
use openapi::models::{VerifyBlock, VerifyBlocksRequest};
|
|
||||||
use sal_rfs_client::types::{ClientConfig, Credentials};
|
|
||||||
use sal_rfs_client::RfsClient;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Create a client with authentication
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
println!("Authentication successful");
|
|
||||||
|
|
||||||
// Create a test file to upload for block testing
|
|
||||||
let test_file_path = "/tmp/block_test.txt";
|
|
||||||
let test_content = "This is a test file for RFS client block management";
|
|
||||||
std::fs::write(test_file_path, test_content)?;
|
|
||||||
println!("Created test file at {}", test_file_path);
|
|
||||||
|
|
||||||
// Upload the file to get blocks
|
|
||||||
println!("Uploading file to get blocks...");
|
|
||||||
let file_hash = client.upload_file(test_file_path, None).await?;
|
|
||||||
println!("File uploaded with hash: {}", file_hash);
|
|
||||||
|
|
||||||
// Get blocks by file hash
|
|
||||||
println!("Getting blocks for file hash: {}", file_hash);
|
|
||||||
let blocks = client.get_blocks_by_hash(&file_hash).await?;
|
|
||||||
println!("Found {} blocks for the file", blocks.blocks.len());
|
|
||||||
|
|
||||||
// Print block information
|
|
||||||
for (i, block_data) in blocks.blocks.iter().enumerate() {
|
|
||||||
println!(
|
|
||||||
"Block {}: Hash={}, Index={}",
|
|
||||||
i, block_data.hash, block_data.index
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verify blocks with complete information
|
|
||||||
println!("Verifying blocks...");
|
|
||||||
|
|
||||||
// Create a list of VerifyBlock objects with complete information
|
|
||||||
let verify_blocks = blocks
|
|
||||||
.blocks
|
|
||||||
.iter()
|
|
||||||
.map(|block| {
|
|
||||||
VerifyBlock {
|
|
||||||
block_hash: block.hash.clone(),
|
|
||||||
block_index: block.index,
|
|
||||||
file_hash: file_hash.clone(), // Using the actual file hash
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
// Create the request with the complete block information
|
|
||||||
for block in verify_blocks.iter() {
|
|
||||||
println!("Block: {}", block.block_hash);
|
|
||||||
println!("Block index: {}", block.block_index);
|
|
||||||
println!("File hash: {}", block.file_hash);
|
|
||||||
}
|
|
||||||
let request = VerifyBlocksRequest {
|
|
||||||
blocks: verify_blocks,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send the verification request
|
|
||||||
let verify_result = client.verify_blocks(request).await?;
|
|
||||||
println!(
|
|
||||||
"Verification result: {} missing blocks",
|
|
||||||
verify_result.missing.len()
|
|
||||||
);
|
|
||||||
for block in verify_result.missing.iter() {
|
|
||||||
println!("Missing block: {}", block);
|
|
||||||
}
|
|
||||||
|
|
||||||
// List blocks (list_blocks_handler)
|
|
||||||
println!("\n1. Listing all blocks with pagination...");
|
|
||||||
let blocks_list = client.list_blocks(None).await?;
|
|
||||||
println!("Server has {} blocks in total", blocks_list.len());
|
|
||||||
if !blocks_list.is_empty() {
|
|
||||||
let first_few = blocks_list
|
|
||||||
.iter()
|
|
||||||
.take(3)
|
|
||||||
.map(|s| s.as_str())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ");
|
|
||||||
println!("First few blocks: {}", first_few);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if a block exists (check_block_handler)
|
|
||||||
if !blocks.blocks.is_empty() {
|
|
||||||
let block_to_check = &blocks.blocks[0].hash;
|
|
||||||
println!("\n2. Checking if block exists: {}", block_to_check);
|
|
||||||
let exists = client.check_block(block_to_check).await?;
|
|
||||||
println!("Block exists: {}", exists);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get block downloads statistics (get_block_downloads_handler)
|
|
||||||
if !blocks.blocks.is_empty() {
|
|
||||||
let block_to_check = &blocks.blocks[0].hash;
|
|
||||||
println!(
|
|
||||||
"\n3. Getting download statistics for block: {}",
|
|
||||||
block_to_check
|
|
||||||
);
|
|
||||||
let downloads = client.get_block_downloads(block_to_check).await?;
|
|
||||||
println!(
|
|
||||||
"Block has been downloaded {} times",
|
|
||||||
downloads.downloads_count
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get a specific block content (get_block_handler)
|
|
||||||
if !blocks.blocks.is_empty() {
|
|
||||||
let block_to_get = &blocks.blocks[0].hash;
|
|
||||||
println!("\n4. Getting content for block: {}", block_to_get);
|
|
||||||
let block_content = client.get_block(block_to_get).await?;
|
|
||||||
println!("Retrieved block with {} bytes", block_content.len());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get user blocks (get_user_blocks_handler)
|
|
||||||
println!("\n6. Listing user blocks...");
|
|
||||||
let user_blocks = client.get_user_blocks(Some(1), Some(10)).await?;
|
|
||||||
println!(
|
|
||||||
"User has {} blocks (showing page 1 with 10 per page)",
|
|
||||||
user_blocks.total
|
|
||||||
);
|
|
||||||
for block in user_blocks.blocks.iter().take(3) {
|
|
||||||
println!(" - Block: {}, Size: {}", block.hash, block.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Upload a block (upload_block_handler)
|
|
||||||
println!("\n7. Uploading a new test block...");
|
|
||||||
let test_block_data = b"This is test block data for direct block upload";
|
|
||||||
let new_file_hash = "test_file_hash_for_block_upload";
|
|
||||||
let block_index = 0;
|
|
||||||
let block_hash = client
|
|
||||||
.upload_block(new_file_hash, block_index, test_block_data.to_vec())
|
|
||||||
.await?;
|
|
||||||
println!("Uploaded block with hash: {}", block_hash);
|
|
||||||
|
|
||||||
// Clean up
|
|
||||||
std::fs::remove_file(test_file_path)?;
|
|
||||||
println!("Test file cleaned up");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@@ -1,66 +0,0 @@
|
|||||||
use sal_rfs_client::types::{ClientConfig, Credentials, DownloadOptions, UploadOptions};
|
|
||||||
use sal_rfs_client::RfsClient;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Create a client with authentication
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
println!("Authentication successful");
|
|
||||||
|
|
||||||
// Create a test file to upload
|
|
||||||
let test_file_path = "/tmp/test_upload.txt";
|
|
||||||
std::fs::write(test_file_path, "This is a test file for RFS client upload")?;
|
|
||||||
println!("Created test file at {}", test_file_path);
|
|
||||||
|
|
||||||
// Upload the file with options
|
|
||||||
println!("Uploading file...");
|
|
||||||
let upload_options = UploadOptions {
|
|
||||||
chunk_size: Some(1024 * 1024), // 1MB chunks
|
|
||||||
verify: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let file_hash = client
|
|
||||||
.upload_file(test_file_path, Some(upload_options))
|
|
||||||
.await?;
|
|
||||||
println!("File uploaded with hash: {}", file_hash);
|
|
||||||
|
|
||||||
// Download the file
|
|
||||||
let download_path = "/tmp/test_download.txt";
|
|
||||||
println!("Downloading file to {}...", download_path);
|
|
||||||
|
|
||||||
let download_options = DownloadOptions { verify: true };
|
|
||||||
|
|
||||||
client
|
|
||||||
.download_file(&file_hash, download_path, Some(download_options))
|
|
||||||
.await?;
|
|
||||||
println!("File downloaded to {}", download_path);
|
|
||||||
|
|
||||||
// Verify the downloaded file matches the original
|
|
||||||
let original_content = std::fs::read_to_string(test_file_path)?;
|
|
||||||
let downloaded_content = std::fs::read_to_string(download_path)?;
|
|
||||||
|
|
||||||
if original_content == downloaded_content {
|
|
||||||
println!("File contents match! Download successful.");
|
|
||||||
} else {
|
|
||||||
println!("ERROR: File contents do not match!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up test files
|
|
||||||
std::fs::remove_file(test_file_path)?;
|
|
||||||
std::fs::remove_file(download_path)?;
|
|
||||||
println!("Test files cleaned up");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@@ -1,176 +0,0 @@
|
|||||||
use sal_rfs_client::types::{ClientConfig, Credentials, FlistOptions, WaitOptions};
|
|
||||||
use sal_rfs_client::RfsClient;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
let parent_dir = "flists";
|
|
||||||
// Create a client with authentication
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
println!("Authentication successful");
|
|
||||||
|
|
||||||
println!("\n1. CREATE FLIST - Creating an FList from a Docker image");
|
|
||||||
let image_name = "alpine:latest";
|
|
||||||
println!("Creating FList for image: {}", image_name);
|
|
||||||
|
|
||||||
// Use FlistOptions to specify additional parameters
|
|
||||||
let options = FlistOptions {
|
|
||||||
auth: None,
|
|
||||||
username: None,
|
|
||||||
password: None,
|
|
||||||
email: None,
|
|
||||||
server_address: Some("docker.io".to_string()),
|
|
||||||
identity_token: None,
|
|
||||||
registry_token: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create the FList and handle potential conflict error
|
|
||||||
let job_id = match client.create_flist(&image_name, Some(options)).await {
|
|
||||||
Ok(id) => {
|
|
||||||
println!("FList creation started with job ID: {}", id);
|
|
||||||
Some(id)
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
if e.to_string().contains("Conflict") {
|
|
||||||
println!("FList already exists");
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
return Err(e.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 2. Check FList state if we have a job ID
|
|
||||||
if let Some(job_id) = &job_id {
|
|
||||||
println!("\n2. GET FLIST STATE - Checking FList creation state");
|
|
||||||
let state = client.get_flist_state(job_id).await?;
|
|
||||||
println!("Current FList state: {:?}", state.flist_state);
|
|
||||||
|
|
||||||
// 3. Wait for FList creation with progress reporting
|
|
||||||
println!("\n3. WAIT FOR FLIST CREATION - Waiting for FList to be created with progress reporting");
|
|
||||||
let wait_options = WaitOptions {
|
|
||||||
timeout_seconds: 60, // Shorter timeout for the example
|
|
||||||
poll_interval_ms: 1000,
|
|
||||||
progress_callback: Some(Box::new(|state| {
|
|
||||||
println!("Progress: FList state is now {:?}", state);
|
|
||||||
// No return value needed (returns unit type)
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wait for the FList to be created (with a timeout)
|
|
||||||
match client
|
|
||||||
.wait_for_flist_creation(job_id, Some(wait_options))
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(final_state) => {
|
|
||||||
println!("FList creation completed with state: {:?}", final_state);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
println!("Error waiting for FList creation: {}", e);
|
|
||||||
// Continue with the example even if waiting fails
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. List all available FLists
|
|
||||||
println!("\n4. LIST FLISTS - Listing all available FLists");
|
|
||||||
|
|
||||||
// Variable to store the FList path for preview and download
|
|
||||||
let mut flist_path_for_preview: Option<String> = None;
|
|
||||||
|
|
||||||
match client.list_flists().await {
|
|
||||||
Ok(flists) => {
|
|
||||||
println!("Found {} FList categories", flists.len());
|
|
||||||
|
|
||||||
for (category, files) in &flists {
|
|
||||||
println!("Category: {}", category);
|
|
||||||
for file in files.iter().take(2) {
|
|
||||||
// Show only first 2 files per category
|
|
||||||
println!(" - {} (size: {} bytes)", file.name, file.size);
|
|
||||||
|
|
||||||
// Save the first FList path for preview
|
|
||||||
if flist_path_for_preview.is_none() {
|
|
||||||
let path = format!("{}/{}/{}", parent_dir, category, file.name);
|
|
||||||
flist_path_for_preview = Some(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if files.len() > 2 {
|
|
||||||
println!(" - ... and {} more files", files.len() - 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Preview an FList if we found one
|
|
||||||
if let Some(ref flist_path) = flist_path_for_preview {
|
|
||||||
println!("\n5. PREVIEW FLIST - Previewing FList: {}", flist_path);
|
|
||||||
match client.preview_flist(flist_path).await {
|
|
||||||
Ok(preview) => {
|
|
||||||
println!("FList preview for {}:", flist_path);
|
|
||||||
println!(" - Checksum: {}", preview.checksum);
|
|
||||||
println!(" - Metadata: {}", preview.metadata);
|
|
||||||
|
|
||||||
// Display content (list of strings)
|
|
||||||
if !preview.content.is_empty() {
|
|
||||||
println!(" - Content entries:");
|
|
||||||
for (i, entry) in preview.content.iter().enumerate().take(5) {
|
|
||||||
println!(" {}. {}", i + 1, entry);
|
|
||||||
}
|
|
||||||
if preview.content.len() > 5 {
|
|
||||||
println!(" ... and {} more entries", preview.content.len() - 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => println!("Error previewing FList: {}", e),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!("No FLists available for preview");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => println!("Error listing FLists: {}", e),
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. DOWNLOAD FLIST - Downloading an FList to a local file
|
|
||||||
if let Some(ref flist_path) = flist_path_for_preview {
|
|
||||||
println!("\n6. DOWNLOAD FLIST - Downloading FList: {}", flist_path);
|
|
||||||
|
|
||||||
// Create a temporary output path for the downloaded FList
|
|
||||||
let output_path = "/tmp/downloaded_flist.fl";
|
|
||||||
|
|
||||||
match client.download_flist(flist_path, output_path).await {
|
|
||||||
Ok(_) => {
|
|
||||||
println!("FList successfully downloaded to {}", output_path);
|
|
||||||
|
|
||||||
// Get file size
|
|
||||||
match std::fs::metadata(output_path) {
|
|
||||||
Ok(metadata) => println!("Downloaded file size: {} bytes", metadata.len()),
|
|
||||||
Err(e) => println!("Error getting file metadata: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => println!("Error downloading FList: {}", e),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
println!("\n6. DOWNLOAD FLIST - No FList available for download");
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("\nAll FList operations demonstrated:");
|
|
||||||
println!("1. create_flist - Create a new FList from a Docker image");
|
|
||||||
println!("2. get_flist_state - Check the state of an FList creation job");
|
|
||||||
println!(
|
|
||||||
"3. wait_for_flist_creation - Wait for an FList to be created with progress reporting"
|
|
||||||
);
|
|
||||||
println!("4. list_flists - List all available FLists");
|
|
||||||
println!("5. preview_flist - Preview the content of an FList");
|
|
||||||
println!("6. download_flist - Download an FList to a local file");
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
@@ -1,64 +0,0 @@
|
|||||||
use openapi::models::FlistState;
|
|
||||||
use sal_rfs_client::types::{ClientConfig, Credentials, WaitOptions};
|
|
||||||
use sal_rfs_client::RfsClient;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Create a client with authentication
|
|
||||||
let config = ClientConfig {
|
|
||||||
base_url: "http://localhost:8080".to_string(),
|
|
||||||
credentials: Some(Credentials {
|
|
||||||
username: "user".to_string(),
|
|
||||||
password: "password".to_string(),
|
|
||||||
}),
|
|
||||||
timeout_seconds: 60,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut client = RfsClient::new(config);
|
|
||||||
|
|
||||||
// Authenticate with the server
|
|
||||||
client.authenticate().await?;
|
|
||||||
println!("Authentication successful");
|
|
||||||
|
|
||||||
// Create an FList from a Docker image
|
|
||||||
let image_name = "redis:latest";
|
|
||||||
println!("Creating FList for image: {}", image_name);
|
|
||||||
|
|
||||||
let job_id = client.create_flist(&image_name, None).await?;
|
|
||||||
println!("FList creation started with job ID: {}", job_id);
|
|
||||||
|
|
||||||
// Set up options for waiting with progress reporting
|
|
||||||
let options = WaitOptions {
|
|
||||||
timeout_seconds: 600, // 10 minutes timeout
|
|
||||||
poll_interval_ms: 2000, // Check every 2 seconds
|
|
||||||
progress_callback: Some(Box::new(|state| match state {
|
|
||||||
FlistState::FlistStateInProgress(info) => {
|
|
||||||
println!(
|
|
||||||
"Progress: {:.1}% - {}",
|
|
||||||
info.in_progress.progress, info.in_progress.msg
|
|
||||||
);
|
|
||||||
}
|
|
||||||
FlistState::FlistStateStarted(_) => {
|
|
||||||
println!("FList creation started...");
|
|
||||||
}
|
|
||||||
FlistState::FlistStateAccepted(_) => {
|
|
||||||
println!("FList creation request accepted...");
|
|
||||||
}
|
|
||||||
_ => println!("State: {:?}", state),
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Wait for the FList to be created
|
|
||||||
println!("Waiting for FList creation to complete...");
|
|
||||||
|
|
||||||
// Use ? operator to propagate errors properly
|
|
||||||
let state = client
|
|
||||||
.wait_for_flist_creation(&job_id, Some(options))
|
|
||||||
.await
|
|
||||||
.map_err(|e| -> Box<dyn std::error::Error> { Box::new(e) })?;
|
|
||||||
|
|
||||||
println!("FList created successfully!");
|
|
||||||
println!("Final state: {:?}", state);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
@@ -1,3 +0,0 @@
|
|||||||
/target/
|
|
||||||
**/*.rs.bk
|
|
||||||
Cargo.lock
|
|
@@ -1,23 +0,0 @@
|
|||||||
# OpenAPI Generator Ignore
|
|
||||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
|
||||||
|
|
||||||
# Use this file to prevent files from being overwritten by the generator.
|
|
||||||
# The patterns follow closely to .gitignore or .dockerignore.
|
|
||||||
|
|
||||||
# As an example, the C# client generator defines ApiClient.cs.
|
|
||||||
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
|
|
||||||
#ApiClient.cs
|
|
||||||
|
|
||||||
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
|
||||||
#foo/*/qux
|
|
||||||
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
|
||||||
|
|
||||||
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
|
||||||
#foo/**/qux
|
|
||||||
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
|
||||||
|
|
||||||
# You can also negate patterns with an exclamation (!).
|
|
||||||
# For example, you can ignore all files in a docs folder with the file extension .md:
|
|
||||||
#docs/*.md
|
|
||||||
# Then explicitly reverse the ignore rule for a single file:
|
|
||||||
#!docs/README.md
|
|
@@ -1,125 +0,0 @@
|
|||||||
.gitignore
|
|
||||||
.travis.yml
|
|
||||||
Cargo.toml
|
|
||||||
README.md
|
|
||||||
docs/AuthenticationApi.md
|
|
||||||
docs/BlockDownloadsResponse.md
|
|
||||||
docs/BlockInfo.md
|
|
||||||
docs/BlockManagementApi.md
|
|
||||||
docs/BlockUploadedResponse.md
|
|
||||||
docs/BlocksResponse.md
|
|
||||||
docs/DirListTemplate.md
|
|
||||||
docs/DirLister.md
|
|
||||||
docs/ErrorTemplate.md
|
|
||||||
docs/FileDownloadRequest.md
|
|
||||||
docs/FileInfo.md
|
|
||||||
docs/FileManagementApi.md
|
|
||||||
docs/FileUploadResponse.md
|
|
||||||
docs/FlistBody.md
|
|
||||||
docs/FlistManagementApi.md
|
|
||||||
docs/FlistState.md
|
|
||||||
docs/FlistStateAccepted.md
|
|
||||||
docs/FlistStateCreated.md
|
|
||||||
docs/FlistStateInProgress.md
|
|
||||||
docs/FlistStateInfo.md
|
|
||||||
docs/FlistStateResponse.md
|
|
||||||
docs/FlistStateStarted.md
|
|
||||||
docs/HealthResponse.md
|
|
||||||
docs/Job.md
|
|
||||||
docs/ListBlocksParams.md
|
|
||||||
docs/ListBlocksResponse.md
|
|
||||||
docs/PreviewResponse.md
|
|
||||||
docs/ResponseError.md
|
|
||||||
docs/ResponseErrorBadRequest.md
|
|
||||||
docs/ResponseErrorConflict.md
|
|
||||||
docs/ResponseErrorForbidden.md
|
|
||||||
docs/ResponseErrorNotFound.md
|
|
||||||
docs/ResponseErrorTemplateError.md
|
|
||||||
docs/ResponseErrorUnauthorized.md
|
|
||||||
docs/ResponseResult.md
|
|
||||||
docs/ResponseResultBlockUploaded.md
|
|
||||||
docs/ResponseResultDirTemplate.md
|
|
||||||
docs/ResponseResultFileUploaded.md
|
|
||||||
docs/ResponseResultFlistCreated.md
|
|
||||||
docs/ResponseResultFlistState.md
|
|
||||||
docs/ResponseResultFlists.md
|
|
||||||
docs/ResponseResultPreviewFlist.md
|
|
||||||
docs/ResponseResultRes.md
|
|
||||||
docs/ResponseResultSignedIn.md
|
|
||||||
docs/SignInBody.md
|
|
||||||
docs/SignInResponse.md
|
|
||||||
docs/SystemApi.md
|
|
||||||
docs/TemplateErr.md
|
|
||||||
docs/TemplateErrBadRequest.md
|
|
||||||
docs/TemplateErrInternalServerError.md
|
|
||||||
docs/TemplateErrNotFound.md
|
|
||||||
docs/UploadBlockParams.md
|
|
||||||
docs/UserBlockInfo.md
|
|
||||||
docs/UserBlocksResponse.md
|
|
||||||
docs/VerifyBlock.md
|
|
||||||
docs/VerifyBlocksRequest.md
|
|
||||||
docs/VerifyBlocksResponse.md
|
|
||||||
docs/WebsiteServingApi.md
|
|
||||||
git_push.sh
|
|
||||||
src/apis/authentication_api.rs
|
|
||||||
src/apis/block_management_api.rs
|
|
||||||
src/apis/configuration.rs
|
|
||||||
src/apis/file_management_api.rs
|
|
||||||
src/apis/flist_management_api.rs
|
|
||||||
src/apis/mod.rs
|
|
||||||
src/apis/system_api.rs
|
|
||||||
src/apis/website_serving_api.rs
|
|
||||||
src/lib.rs
|
|
||||||
src/models/block_downloads_response.rs
|
|
||||||
src/models/block_info.rs
|
|
||||||
src/models/block_uploaded_response.rs
|
|
||||||
src/models/blocks_response.rs
|
|
||||||
src/models/dir_list_template.rs
|
|
||||||
src/models/dir_lister.rs
|
|
||||||
src/models/error_template.rs
|
|
||||||
src/models/file_download_request.rs
|
|
||||||
src/models/file_info.rs
|
|
||||||
src/models/file_upload_response.rs
|
|
||||||
src/models/flist_body.rs
|
|
||||||
src/models/flist_state.rs
|
|
||||||
src/models/flist_state_accepted.rs
|
|
||||||
src/models/flist_state_created.rs
|
|
||||||
src/models/flist_state_in_progress.rs
|
|
||||||
src/models/flist_state_info.rs
|
|
||||||
src/models/flist_state_response.rs
|
|
||||||
src/models/flist_state_started.rs
|
|
||||||
src/models/health_response.rs
|
|
||||||
src/models/job.rs
|
|
||||||
src/models/list_blocks_params.rs
|
|
||||||
src/models/list_blocks_response.rs
|
|
||||||
src/models/mod.rs
|
|
||||||
src/models/preview_response.rs
|
|
||||||
src/models/response_error.rs
|
|
||||||
src/models/response_error_bad_request.rs
|
|
||||||
src/models/response_error_conflict.rs
|
|
||||||
src/models/response_error_forbidden.rs
|
|
||||||
src/models/response_error_not_found.rs
|
|
||||||
src/models/response_error_template_error.rs
|
|
||||||
src/models/response_error_unauthorized.rs
|
|
||||||
src/models/response_result.rs
|
|
||||||
src/models/response_result_block_uploaded.rs
|
|
||||||
src/models/response_result_dir_template.rs
|
|
||||||
src/models/response_result_file_uploaded.rs
|
|
||||||
src/models/response_result_flist_created.rs
|
|
||||||
src/models/response_result_flist_state.rs
|
|
||||||
src/models/response_result_flists.rs
|
|
||||||
src/models/response_result_preview_flist.rs
|
|
||||||
src/models/response_result_res.rs
|
|
||||||
src/models/response_result_signed_in.rs
|
|
||||||
src/models/sign_in_body.rs
|
|
||||||
src/models/sign_in_response.rs
|
|
||||||
src/models/template_err.rs
|
|
||||||
src/models/template_err_bad_request.rs
|
|
||||||
src/models/template_err_internal_server_error.rs
|
|
||||||
src/models/template_err_not_found.rs
|
|
||||||
src/models/upload_block_params.rs
|
|
||||||
src/models/user_block_info.rs
|
|
||||||
src/models/user_blocks_response.rs
|
|
||||||
src/models/verify_block.rs
|
|
||||||
src/models/verify_blocks_request.rs
|
|
||||||
src/models/verify_blocks_response.rs
|
|
@@ -1 +0,0 @@
|
|||||||
7.13.0
|
|
@@ -1 +0,0 @@
|
|||||||
language: rust
|
|
@@ -1,15 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "openapi"
|
|
||||||
version = "0.2.0"
|
|
||||||
authors = ["OpenAPI Generator team and contributors"]
|
|
||||||
description = "No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)"
|
|
||||||
license = ""
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
serde = { version = "^1.0", features = ["derive"] }
|
|
||||||
serde_with = { version = "^3.8", default-features = false, features = ["base64", "std", "macros"] }
|
|
||||||
serde_json = "^1.0"
|
|
||||||
serde_repr = "^0.1"
|
|
||||||
url = "^2.5"
|
|
||||||
reqwest = { version = "^0.12", default-features = false, features = ["json", "multipart"] }
|
|
@@ -1,114 +0,0 @@
|
|||||||
# Rust API client for openapi
|
|
||||||
|
|
||||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://openapis.org) from a remote server, you can easily generate an API client.
|
|
||||||
|
|
||||||
- API version: 0.2.0
|
|
||||||
- Package version: 0.2.0
|
|
||||||
- Generator version: 7.13.0
|
|
||||||
- Build package: `org.openapitools.codegen.languages.RustClientCodegen`
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
Put the package under your project folder in a directory named `openapi` and add the following to `Cargo.toml` under `[dependencies]`:
|
|
||||||
|
|
||||||
```
|
|
||||||
openapi = { path = "./openapi" }
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation for API Endpoints
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Class | Method | HTTP request | Description
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
*AuthenticationApi* | [**sign_in_handler**](docs/AuthenticationApi.md#sign_in_handler) | **POST** /api/v1/signin |
|
|
||||||
*BlockManagementApi* | [**check_block_handler**](docs/BlockManagementApi.md#check_block_handler) | **HEAD** /api/v1/block/{hash} | Checks a block by its hash.
|
|
||||||
*BlockManagementApi* | [**get_block_downloads_handler**](docs/BlockManagementApi.md#get_block_downloads_handler) | **GET** /api/v1/block/{hash}/downloads | Retrieve the number of times a block has been downloaded.
|
|
||||||
*BlockManagementApi* | [**get_block_handler**](docs/BlockManagementApi.md#get_block_handler) | **GET** /api/v1/block/{hash} | Retrieve a block by its hash.
|
|
||||||
*BlockManagementApi* | [**get_blocks_by_hash_handler**](docs/BlockManagementApi.md#get_blocks_by_hash_handler) | **GET** /api/v1/blocks/{hash} | Retrieve blocks by hash (file hash or block hash).
|
|
||||||
*BlockManagementApi* | [**get_user_blocks_handler**](docs/BlockManagementApi.md#get_user_blocks_handler) | **GET** /api/v1/user/blocks | Retrieve all blocks uploaded by a specific user.
|
|
||||||
*BlockManagementApi* | [**list_blocks_handler**](docs/BlockManagementApi.md#list_blocks_handler) | **GET** /api/v1/blocks | List all block hashes in the server with pagination
|
|
||||||
*BlockManagementApi* | [**upload_block_handler**](docs/BlockManagementApi.md#upload_block_handler) | **POST** /api/v1/block | Upload a block to the server.
|
|
||||||
*BlockManagementApi* | [**verify_blocks_handler**](docs/BlockManagementApi.md#verify_blocks_handler) | **POST** /api/v1/block/verify | Verify if multiple blocks exist on the server.
|
|
||||||
*FileManagementApi* | [**get_file_handler**](docs/FileManagementApi.md#get_file_handler) | **GET** /api/v1/file/{hash} | Retrieve a file by its hash from path, with optional custom filename in request body.
|
|
||||||
*FileManagementApi* | [**upload_file_handler**](docs/FileManagementApi.md#upload_file_handler) | **POST** /api/v1/file | Upload a file to the server.
|
|
||||||
*FlistManagementApi* | [**create_flist_handler**](docs/FlistManagementApi.md#create_flist_handler) | **POST** /api/v1/fl |
|
|
||||||
*FlistManagementApi* | [**get_flist_state_handler**](docs/FlistManagementApi.md#get_flist_state_handler) | **GET** /api/v1/fl/{job_id} |
|
|
||||||
*FlistManagementApi* | [**list_flists_handler**](docs/FlistManagementApi.md#list_flists_handler) | **GET** /api/v1/fl |
|
|
||||||
*FlistManagementApi* | [**preview_flist_handler**](docs/FlistManagementApi.md#preview_flist_handler) | **GET** /api/v1/fl/preview/{flist_path} |
|
|
||||||
*FlistManagementApi* | [**serve_flists**](docs/FlistManagementApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem
|
|
||||||
*SystemApi* | [**health_check_handler**](docs/SystemApi.md#health_check_handler) | **GET** /api/v1 |
|
|
||||||
*WebsiteServingApi* | [**serve_website_handler**](docs/WebsiteServingApi.md#serve_website_handler) | **GET** /api/v1/website/{website_hash}/{path} |
|
|
||||||
|
|
||||||
|
|
||||||
## Documentation For Models
|
|
||||||
|
|
||||||
- [BlockDownloadsResponse](docs/BlockDownloadsResponse.md)
|
|
||||||
- [BlockInfo](docs/BlockInfo.md)
|
|
||||||
- [BlockUploadedResponse](docs/BlockUploadedResponse.md)
|
|
||||||
- [BlocksResponse](docs/BlocksResponse.md)
|
|
||||||
- [DirListTemplate](docs/DirListTemplate.md)
|
|
||||||
- [DirLister](docs/DirLister.md)
|
|
||||||
- [ErrorTemplate](docs/ErrorTemplate.md)
|
|
||||||
- [FileDownloadRequest](docs/FileDownloadRequest.md)
|
|
||||||
- [FileInfo](docs/FileInfo.md)
|
|
||||||
- [FileUploadResponse](docs/FileUploadResponse.md)
|
|
||||||
- [FlistBody](docs/FlistBody.md)
|
|
||||||
- [FlistState](docs/FlistState.md)
|
|
||||||
- [FlistStateAccepted](docs/FlistStateAccepted.md)
|
|
||||||
- [FlistStateCreated](docs/FlistStateCreated.md)
|
|
||||||
- [FlistStateInProgress](docs/FlistStateInProgress.md)
|
|
||||||
- [FlistStateInfo](docs/FlistStateInfo.md)
|
|
||||||
- [FlistStateResponse](docs/FlistStateResponse.md)
|
|
||||||
- [FlistStateStarted](docs/FlistStateStarted.md)
|
|
||||||
- [HealthResponse](docs/HealthResponse.md)
|
|
||||||
- [Job](docs/Job.md)
|
|
||||||
- [ListBlocksParams](docs/ListBlocksParams.md)
|
|
||||||
- [ListBlocksResponse](docs/ListBlocksResponse.md)
|
|
||||||
- [PreviewResponse](docs/PreviewResponse.md)
|
|
||||||
- [ResponseError](docs/ResponseError.md)
|
|
||||||
- [ResponseErrorBadRequest](docs/ResponseErrorBadRequest.md)
|
|
||||||
- [ResponseErrorConflict](docs/ResponseErrorConflict.md)
|
|
||||||
- [ResponseErrorForbidden](docs/ResponseErrorForbidden.md)
|
|
||||||
- [ResponseErrorNotFound](docs/ResponseErrorNotFound.md)
|
|
||||||
- [ResponseErrorTemplateError](docs/ResponseErrorTemplateError.md)
|
|
||||||
- [ResponseErrorUnauthorized](docs/ResponseErrorUnauthorized.md)
|
|
||||||
- [ResponseResult](docs/ResponseResult.md)
|
|
||||||
- [ResponseResultBlockUploaded](docs/ResponseResultBlockUploaded.md)
|
|
||||||
- [ResponseResultDirTemplate](docs/ResponseResultDirTemplate.md)
|
|
||||||
- [ResponseResultFileUploaded](docs/ResponseResultFileUploaded.md)
|
|
||||||
- [ResponseResultFlistCreated](docs/ResponseResultFlistCreated.md)
|
|
||||||
- [ResponseResultFlistState](docs/ResponseResultFlistState.md)
|
|
||||||
- [ResponseResultFlists](docs/ResponseResultFlists.md)
|
|
||||||
- [ResponseResultPreviewFlist](docs/ResponseResultPreviewFlist.md)
|
|
||||||
- [ResponseResultRes](docs/ResponseResultRes.md)
|
|
||||||
- [ResponseResultSignedIn](docs/ResponseResultSignedIn.md)
|
|
||||||
- [SignInBody](docs/SignInBody.md)
|
|
||||||
- [SignInResponse](docs/SignInResponse.md)
|
|
||||||
- [TemplateErr](docs/TemplateErr.md)
|
|
||||||
- [TemplateErrBadRequest](docs/TemplateErrBadRequest.md)
|
|
||||||
- [TemplateErrInternalServerError](docs/TemplateErrInternalServerError.md)
|
|
||||||
- [TemplateErrNotFound](docs/TemplateErrNotFound.md)
|
|
||||||
- [UploadBlockParams](docs/UploadBlockParams.md)
|
|
||||||
- [UserBlockInfo](docs/UserBlockInfo.md)
|
|
||||||
- [UserBlocksResponse](docs/UserBlocksResponse.md)
|
|
||||||
- [VerifyBlock](docs/VerifyBlock.md)
|
|
||||||
- [VerifyBlocksRequest](docs/VerifyBlocksRequest.md)
|
|
||||||
- [VerifyBlocksResponse](docs/VerifyBlocksResponse.md)
|
|
||||||
|
|
||||||
|
|
||||||
To get access to the crate's generated documentation, use:
|
|
||||||
|
|
||||||
```
|
|
||||||
cargo doc --open
|
|
||||||
```
|
|
||||||
|
|
||||||
## Author
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,37 +0,0 @@
|
|||||||
# \AuthenticationApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**sign_in_handler**](AuthenticationApi.md#sign_in_handler) | **POST** /api/v1/signin |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## sign_in_handler
|
|
||||||
|
|
||||||
> models::SignInResponse sign_in_handler(sign_in_body)
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**sign_in_body** | [**SignInBody**](SignInBody.md) | | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::SignInResponse**](SignInResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,14 +0,0 @@
|
|||||||
# Block
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**data** | [**std::path::PathBuf**](std::path::PathBuf.md) | |
|
|
||||||
**hash** | **String** | |
|
|
||||||
**index** | **i64** | |
|
|
||||||
**size** | **i32** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# BlockDownloadsResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**block_hash** | **String** | Block hash |
|
|
||||||
**block_size** | **i64** | Size of the block in bytes |
|
|
||||||
**downloads_count** | **i64** | Number of times the block has been downloaded |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# BlockInfo
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | Block hash |
|
|
||||||
**index** | **i64** | Block index within the file |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,250 +0,0 @@
|
|||||||
# \BlockManagementApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**check_block_handler**](BlockManagementApi.md#check_block_handler) | **HEAD** /api/v1/block/{hash} | Checks a block by its hash.
|
|
||||||
[**get_block_downloads_handler**](BlockManagementApi.md#get_block_downloads_handler) | **GET** /api/v1/block/{hash}/downloads | Retrieve the number of times a block has been downloaded.
|
|
||||||
[**get_block_handler**](BlockManagementApi.md#get_block_handler) | **GET** /api/v1/block/{hash} | Retrieve a block by its hash.
|
|
||||||
[**get_blocks_by_hash_handler**](BlockManagementApi.md#get_blocks_by_hash_handler) | **GET** /api/v1/blocks/{hash} | Retrieve blocks by hash (file hash or block hash).
|
|
||||||
[**get_user_blocks_handler**](BlockManagementApi.md#get_user_blocks_handler) | **GET** /api/v1/user/blocks | Retrieve all blocks uploaded by a specific user.
|
|
||||||
[**list_blocks_handler**](BlockManagementApi.md#list_blocks_handler) | **GET** /api/v1/blocks | List all block hashes in the server with pagination
|
|
||||||
[**upload_block_handler**](BlockManagementApi.md#upload_block_handler) | **POST** /api/v1/block | Upload a block to the server.
|
|
||||||
[**verify_blocks_handler**](BlockManagementApi.md#verify_blocks_handler) | **POST** /api/v1/block/verify | Verify if multiple blocks exist on the server.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## check_block_handler
|
|
||||||
|
|
||||||
> check_block_handler(hash)
|
|
||||||
Checks a block by its hash.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | Block hash | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
(empty response body)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## get_block_downloads_handler
|
|
||||||
|
|
||||||
> models::BlockDownloadsResponse get_block_downloads_handler(hash)
|
|
||||||
Retrieve the number of times a block has been downloaded.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | Block hash | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::BlockDownloadsResponse**](BlockDownloadsResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## get_block_handler
|
|
||||||
|
|
||||||
> std::path::PathBuf get_block_handler(hash)
|
|
||||||
Retrieve a block by its hash.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | Block hash | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**std::path::PathBuf**](std::path::PathBuf.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/octet-stream, application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## get_blocks_by_hash_handler
|
|
||||||
|
|
||||||
> models::BlocksResponse get_blocks_by_hash_handler(hash)
|
|
||||||
Retrieve blocks by hash (file hash or block hash).
|
|
||||||
|
|
||||||
If the hash is a file hash, returns all blocks with their block index related to that file. If the hash is a block hash, returns the block itself.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | File hash or block hash | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::BlocksResponse**](BlocksResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## get_user_blocks_handler
|
|
||||||
|
|
||||||
> models::UserBlocksResponse get_user_blocks_handler(page, per_page)
|
|
||||||
Retrieve all blocks uploaded by a specific user.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**page** | Option<**i32**> | Page number (1-indexed) | |
|
|
||||||
**per_page** | Option<**i32**> | Number of items per page | |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::UserBlocksResponse**](UserBlocksResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[bearerAuth](../README.md#bearerAuth)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## list_blocks_handler
|
|
||||||
|
|
||||||
> models::ListBlocksResponse list_blocks_handler(page, per_page)
|
|
||||||
List all block hashes in the server with pagination
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**page** | Option<**i32**> | Page number (1-indexed) | |
|
|
||||||
**per_page** | Option<**i32**> | Number of items per page | |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::ListBlocksResponse**](ListBlocksResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## upload_block_handler
|
|
||||||
|
|
||||||
> models::BlockUploadedResponse upload_block_handler(file_hash, idx, body)
|
|
||||||
Upload a block to the server.
|
|
||||||
|
|
||||||
If the block already exists, the server will return a 200 OK response. If the block is new, the server will return a 201 Created response.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**file_hash** | **String** | File hash associated with the block | [required] |
|
|
||||||
**idx** | **i64** | Block index within the file | [required] |
|
|
||||||
**body** | **std::path::PathBuf** | Block data to upload | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::BlockUploadedResponse**](BlockUploadedResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[bearerAuth](../README.md#bearerAuth)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/octet-stream
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## verify_blocks_handler
|
|
||||||
|
|
||||||
> models::VerifyBlocksResponse verify_blocks_handler(verify_blocks_request)
|
|
||||||
Verify if multiple blocks exist on the server.
|
|
||||||
|
|
||||||
Returns a list of missing blocks.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**verify_blocks_request** | [**VerifyBlocksRequest**](VerifyBlocksRequest.md) | List of block hashes to verify | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::VerifyBlocksResponse**](VerifyBlocksResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# BlockUploadedResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | |
|
|
||||||
**message** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# BlocksResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**blocks** | [**Vec<models::BlockInfo>**](BlockInfo.md) | List of blocks with their indices |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# DirListTemplate
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**cur_path** | **String** | |
|
|
||||||
**lister** | [**models::DirLister**](DirLister.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# DirLister
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**files** | [**Vec<models::FileInfo>**](FileInfo.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# ErrorTemplate
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**cur_path** | **String** | |
|
|
||||||
**err** | [**models::TemplateErr**](TemplateErr.md) | |
|
|
||||||
**message** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# File
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**file_content** | [**std::path::PathBuf**](std::path::PathBuf.md) | |
|
|
||||||
**file_hash** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FileDownloadRequest
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**file_name** | **String** | The custom filename to use for download |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,16 +0,0 @@
|
|||||||
# FileInfo
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**is_file** | **bool** | |
|
|
||||||
**last_modified** | **i64** | |
|
|
||||||
**name** | **String** | |
|
|
||||||
**path_uri** | **String** | |
|
|
||||||
**progress** | **f32** | |
|
|
||||||
**size** | **i64** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,71 +0,0 @@
|
|||||||
# \FileManagementApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**get_file_handler**](FileManagementApi.md#get_file_handler) | **GET** /api/v1/file/{hash} | Retrieve a file by its hash from path, with optional custom filename in request body.
|
|
||||||
[**upload_file_handler**](FileManagementApi.md#upload_file_handler) | **POST** /api/v1/file | Upload a file to the server.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## get_file_handler
|
|
||||||
|
|
||||||
> std::path::PathBuf get_file_handler(hash, file_download_request)
|
|
||||||
Retrieve a file by its hash from path, with optional custom filename in request body.
|
|
||||||
|
|
||||||
The file will be reconstructed from its blocks.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | File hash | [required] |
|
|
||||||
**file_download_request** | [**FileDownloadRequest**](FileDownloadRequest.md) | Optional custom filename for download | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**std::path::PathBuf**](std::path::PathBuf.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: application/octet-stream, application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## upload_file_handler
|
|
||||||
|
|
||||||
> models::FileUploadResponse upload_file_handler(body)
|
|
||||||
Upload a file to the server.
|
|
||||||
|
|
||||||
The file will be split into blocks and stored in the database.
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**body** | **std::path::PathBuf** | File data to upload | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::FileUploadResponse**](FileUploadResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[bearerAuth](../README.md#bearerAuth)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/octet-stream
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# FileUploadResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**file_hash** | **String** | The file hash |
|
|
||||||
**message** | **String** | Message indicating success |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,18 +0,0 @@
|
|||||||
# FlistBody
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**auth** | Option<**String**> | | [optional]
|
|
||||||
**email** | Option<**String**> | | [optional]
|
|
||||||
**identity_token** | Option<**String**> | | [optional]
|
|
||||||
**image_name** | **String** | |
|
|
||||||
**password** | Option<**String**> | | [optional]
|
|
||||||
**registry_token** | Option<**String**> | | [optional]
|
|
||||||
**server_address** | Option<**String**> | | [optional]
|
|
||||||
**username** | Option<**String**> | | [optional]
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,150 +0,0 @@
|
|||||||
# \FlistManagementApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**create_flist_handler**](FlistManagementApi.md#create_flist_handler) | **POST** /api/v1/fl |
|
|
||||||
[**get_flist_state_handler**](FlistManagementApi.md#get_flist_state_handler) | **GET** /api/v1/fl/{job_id} |
|
|
||||||
[**list_flists_handler**](FlistManagementApi.md#list_flists_handler) | **GET** /api/v1/fl |
|
|
||||||
[**preview_flist_handler**](FlistManagementApi.md#preview_flist_handler) | **GET** /api/v1/fl/preview/{flist_path} |
|
|
||||||
[**serve_flists**](FlistManagementApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## create_flist_handler
|
|
||||||
|
|
||||||
> models::Job create_flist_handler(flist_body)
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**flist_body** | [**FlistBody**](FlistBody.md) | | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::Job**](Job.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[bearerAuth](../README.md#bearerAuth)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: application/json
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## get_flist_state_handler
|
|
||||||
|
|
||||||
> models::FlistStateResponse get_flist_state_handler(job_id)
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**job_id** | **String** | flist job id | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::FlistStateResponse**](FlistStateResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
[bearerAuth](../README.md#bearerAuth)
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## list_flists_handler
|
|
||||||
|
|
||||||
> std::collections::HashMap<String, Vec<models::FileInfo>> list_flists_handler()
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
This endpoint does not need any parameter.
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**std::collections::HashMap<String, Vec<models::FileInfo>>**](Vec.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## preview_flist_handler
|
|
||||||
|
|
||||||
> models::PreviewResponse preview_flist_handler(flist_path)
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**flist_path** | **String** | flist file path | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::PreviewResponse**](PreviewResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
||||||
## serve_flists
|
|
||||||
|
|
||||||
> std::path::PathBuf serve_flists(path)
|
|
||||||
Serve flist files from the server's filesystem
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**path** | **String** | Path to the flist file or directory to serve | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**std::path::PathBuf**](std::path::PathBuf.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/octet-stream, application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,37 +0,0 @@
|
|||||||
# \FlistServingApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**serve_flists**](FlistServingApi.md#serve_flists) | **GET** /{path} | Serve flist files from the server's filesystem
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## serve_flists
|
|
||||||
|
|
||||||
> models::ResponseResult serve_flists(path)
|
|
||||||
Serve flist files from the server's filesystem
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**path** | **String** | Path to the flist file or directory to serve | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::ResponseResult**](ResponseResult.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,15 +0,0 @@
|
|||||||
# FlistState
|
|
||||||
|
|
||||||
## Enum Variants
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
|---- | -----|
|
|
||||||
| FlistStateAccepted | |
|
|
||||||
| FlistStateCreated | |
|
|
||||||
| FlistStateInProgress | |
|
|
||||||
| FlistStateStarted | |
|
|
||||||
| String | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FlistStateAccepted
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**accepted** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FlistStateCreated
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**created** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FlistStateInProgress
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**in_progress** | [**models::FlistStateInfo**](FlistStateInfo.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# FlistStateInfo
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**msg** | **String** | |
|
|
||||||
**progress** | **f32** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FlistStateResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**flist_state** | [**models::FlistState**](FlistState.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# FlistStateStarted
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**started** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# HealthResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**msg** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# Job
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**id** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# ListBlocksParams
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**page** | Option<**i32**> | Page number (1-indexed) | [optional][default to 1]
|
|
||||||
**per_page** | Option<**i32**> | Number of items per page | [optional][default to 50]
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,14 +0,0 @@
|
|||||||
# ListBlocksResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**blocks** | **Vec<String>** | List of block hashes |
|
|
||||||
**page** | **i32** | Current page number |
|
|
||||||
**per_page** | **i32** | Number of items per page |
|
|
||||||
**total** | **i64** | Total number of blocks |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# PreviewResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**checksum** | **String** | |
|
|
||||||
**content** | **Vec<String>** | |
|
|
||||||
**metadata** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,17 +0,0 @@
|
|||||||
# ResponseError
|
|
||||||
|
|
||||||
## Enum Variants
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
|---- | -----|
|
|
||||||
| ResponseErrorBadRequest | |
|
|
||||||
| ResponseErrorConflict | |
|
|
||||||
| ResponseErrorForbidden | |
|
|
||||||
| ResponseErrorNotFound | |
|
|
||||||
| ResponseErrorTemplateError | |
|
|
||||||
| ResponseErrorUnauthorized | |
|
|
||||||
| String | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorBadRequest
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**bad_request** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorConflict
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**conflict** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorForbidden
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**forbidden** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorNotFound
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**not_found** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorTemplateError
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**template_error** | [**models::ErrorTemplate**](ErrorTemplate.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseErrorUnauthorized
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**unauthorized** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,20 +0,0 @@
|
|||||||
# ResponseResult
|
|
||||||
|
|
||||||
## Enum Variants
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
|---- | -----|
|
|
||||||
| ResponseResultBlockUploaded | |
|
|
||||||
| ResponseResultDirTemplate | |
|
|
||||||
| ResponseResultFileUploaded | |
|
|
||||||
| ResponseResultFlistCreated | |
|
|
||||||
| ResponseResultFlistState | |
|
|
||||||
| ResponseResultFlists | |
|
|
||||||
| ResponseResultPreviewFlist | |
|
|
||||||
| ResponseResultRes | |
|
|
||||||
| ResponseResultSignedIn | |
|
|
||||||
| String | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultBlockUploaded
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**block_uploaded** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultDirTemplate
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**dir_template** | [**models::DirListTemplate**](DirListTemplate.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultFileUploaded
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**file_uploaded** | [**models::FileUploadResponse**](FileUploadResponse.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultFlistCreated
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**flist_created** | [**models::Job**](Job.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultFlistState
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**flist_state** | [**models::FlistState**](FlistState.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultFlists
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**flists** | [**std::collections::HashMap<String, Vec<models::FileInfo>>**](Vec.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultPreviewFlist
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**preview_flist** | [**models::PreviewResponse**](PreviewResponse.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultRes
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**res** | [**std::path::PathBuf**](std::path::PathBuf.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# ResponseResultSignedIn
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**signed_in** | [**models::SignInResponse**](SignInResponse.md) | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# SignInBody
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**password** | **String** | |
|
|
||||||
**username** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# SignInResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**access_token** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,34 +0,0 @@
|
|||||||
# \SystemApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**health_check_handler**](SystemApi.md#health_check_handler) | **GET** /api/v1 |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## health_check_handler
|
|
||||||
|
|
||||||
> models::HealthResponse health_check_handler()
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
This endpoint does not need any parameter.
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**models::HealthResponse**](HealthResponse.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# TemplateErr
|
|
||||||
|
|
||||||
## Enum Variants
|
|
||||||
|
|
||||||
| Name | Description |
|
|
||||||
|---- | -----|
|
|
||||||
| TemplateErrBadRequest | |
|
|
||||||
| TemplateErrInternalServerError | |
|
|
||||||
| TemplateErrNotFound | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# TemplateErrBadRequest
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**bad_request** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# TemplateErrInternalServerError
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**internal_server_error** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# TemplateErrNotFound
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**not_found** | **String** | |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# UploadBlockParams
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**file_hash** | **String** | File hash associated with the block |
|
|
||||||
**idx** | **i64** | Block index within the file |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,12 +0,0 @@
|
|||||||
# UserBlockInfo
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**hash** | **String** | Block hash |
|
|
||||||
**size** | **i64** | Block size in bytes |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# UserBlocksResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**all_blocks** | **i64** | Total number of all blocks |
|
|
||||||
**blocks** | [**Vec<models::UserBlockInfo>**](UserBlockInfo.md) | List of blocks with their sizes |
|
|
||||||
**total** | **i64** | Total number of blocks |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,13 +0,0 @@
|
|||||||
# VerifyBlock
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**block_hash** | **String** | Block hash to verify |
|
|
||||||
**block_index** | **i64** | Block index within the file |
|
|
||||||
**file_hash** | **String** | File hash associated with the block |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# VerifyBlocksRequest
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**blocks** | [**Vec<models::VerifyBlock>**](VerifyBlock.md) | List of blocks to verify |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,11 +0,0 @@
|
|||||||
# VerifyBlocksResponse
|
|
||||||
|
|
||||||
## Properties
|
|
||||||
|
|
||||||
Name | Type | Description | Notes
|
|
||||||
------------ | ------------- | ------------- | -------------
|
|
||||||
**missing** | **Vec<String>** | List of block hashes that are missing on the server |
|
|
||||||
|
|
||||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
|
||||||
|
|
||||||
|
|
@@ -1,38 +0,0 @@
|
|||||||
# \WebsiteServingApi
|
|
||||||
|
|
||||||
All URIs are relative to *http://localhost*
|
|
||||||
|
|
||||||
Method | HTTP request | Description
|
|
||||||
------------- | ------------- | -------------
|
|
||||||
[**serve_website_handler**](WebsiteServingApi.md#serve_website_handler) | **GET** /api/v1/website/{website_hash}/{path} |
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## serve_website_handler
|
|
||||||
|
|
||||||
> std::path::PathBuf serve_website_handler(website_hash, path)
|
|
||||||
|
|
||||||
|
|
||||||
### Parameters
|
|
||||||
|
|
||||||
|
|
||||||
Name | Type | Description | Required | Notes
|
|
||||||
------------- | ------------- | ------------- | ------------- | -------------
|
|
||||||
**website_hash** | **String** | flist hash of the website directory | [required] |
|
|
||||||
**path** | **String** | Path to the file within the website directory, defaults to index.html if empty | [required] |
|
|
||||||
|
|
||||||
### Return type
|
|
||||||
|
|
||||||
[**std::path::PathBuf**](std::path::PathBuf.md)
|
|
||||||
|
|
||||||
### Authorization
|
|
||||||
|
|
||||||
No authorization required
|
|
||||||
|
|
||||||
### HTTP request headers
|
|
||||||
|
|
||||||
- **Content-Type**: Not defined
|
|
||||||
- **Accept**: application/octet-stream, application/json
|
|
||||||
|
|
||||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
|
||||||
|
|
@@ -1,57 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
|
||||||
#
|
|
||||||
# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com"
|
|
||||||
|
|
||||||
git_user_id=$1
|
|
||||||
git_repo_id=$2
|
|
||||||
release_note=$3
|
|
||||||
git_host=$4
|
|
||||||
|
|
||||||
if [ "$git_host" = "" ]; then
|
|
||||||
git_host="github.com"
|
|
||||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$git_user_id" = "" ]; then
|
|
||||||
git_user_id="GIT_USER_ID"
|
|
||||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$git_repo_id" = "" ]; then
|
|
||||||
git_repo_id="GIT_REPO_ID"
|
|
||||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "$release_note" = "" ]; then
|
|
||||||
release_note="Minor update"
|
|
||||||
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Initialize the local directory as a Git repository
|
|
||||||
git init
|
|
||||||
|
|
||||||
# Adds the files in the local repository and stages them for commit.
|
|
||||||
git add .
|
|
||||||
|
|
||||||
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
|
||||||
git commit -m "$release_note"
|
|
||||||
|
|
||||||
# Sets the new remote
|
|
||||||
git_remote=$(git remote)
|
|
||||||
if [ "$git_remote" = "" ]; then # git remote not defined
|
|
||||||
|
|
||||||
if [ "$GIT_TOKEN" = "" ]; then
|
|
||||||
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
|
|
||||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
|
||||||
else
|
|
||||||
git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
git pull origin master
|
|
||||||
|
|
||||||
# Pushes (Forces) the changes in the local repository up to the remote repository
|
|
||||||
echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git"
|
|
||||||
git push origin master 2>&1 | grep -v 'To https'
|
|
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
use reqwest;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error as _};
|
|
||||||
use crate::{apis::ResponseContent, models};
|
|
||||||
use super::{Error, configuration, ContentType};
|
|
||||||
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`sign_in_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum SignInHandlerError {
|
|
||||||
Status401(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn sign_in_handler(configuration: &configuration::Configuration, sign_in_body: models::SignInBody) -> Result<models::SignInResponse, Error<SignInHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_sign_in_body = sign_in_body;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/signin", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
req_builder = req_builder.json(&p_sign_in_body);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::SignInResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::SignInResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<SignInHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,385 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
use reqwest;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error as _};
|
|
||||||
use crate::{apis::ResponseContent, models};
|
|
||||||
use super::{Error, configuration, ContentType};
|
|
||||||
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`check_block_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum CheckBlockHandlerError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_block_downloads_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetBlockDownloadsHandlerError {
|
|
||||||
Status404(),
|
|
||||||
Status500(),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_block_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetBlockHandlerError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_blocks_by_hash_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetBlocksByHashHandlerError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_user_blocks_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetUserBlocksHandlerError {
|
|
||||||
Status401(),
|
|
||||||
Status500(),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`list_blocks_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ListBlocksHandlerError {
|
|
||||||
Status400(),
|
|
||||||
Status500(),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`upload_block_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum UploadBlockHandlerError {
|
|
||||||
Status400(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`verify_blocks_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum VerifyBlocksHandlerError {
|
|
||||||
Status400(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn check_block_handler(configuration: &configuration::Configuration, hash: &str) -> Result<(), Error<CheckBlockHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_hash = hash;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/block/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::HEAD, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<CheckBlockHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_block_downloads_handler(configuration: &configuration::Configuration, hash: &str) -> Result<models::BlockDownloadsResponse, Error<GetBlockDownloadsHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_hash = hash;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/block/{hash}/downloads", configuration.base_path, hash=crate::apis::urlencode(p_hash));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlockDownloadsResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlockDownloadsResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetBlockDownloadsHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_block_handler(configuration: &configuration::Configuration, hash: &str) -> Result<reqwest::Response, Error<GetBlockHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_hash = hash;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/block/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
Ok(resp)
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetBlockHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the hash is a file hash, returns all blocks with their block index related to that file. If the hash is a block hash, returns the block itself.
|
|
||||||
pub async fn get_blocks_by_hash_handler(configuration: &configuration::Configuration, hash: &str) -> Result<models::BlocksResponse, Error<GetBlocksByHashHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_hash = hash;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/blocks/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlocksResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlocksResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetBlocksByHashHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_user_blocks_handler(configuration: &configuration::Configuration, page: Option<i32>, per_page: Option<i32>) -> Result<models::UserBlocksResponse, Error<GetUserBlocksHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_page = page;
|
|
||||||
let p_per_page = per_page;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/user/blocks", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref param_value) = p_page {
|
|
||||||
req_builder = req_builder.query(&[("page", ¶m_value.to_string())]);
|
|
||||||
}
|
|
||||||
if let Some(ref param_value) = p_per_page {
|
|
||||||
req_builder = req_builder.query(&[("per_page", ¶m_value.to_string())]);
|
|
||||||
}
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
if let Some(ref token) = configuration.bearer_access_token {
|
|
||||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
|
||||||
};
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::UserBlocksResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::UserBlocksResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetUserBlocksHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn list_blocks_handler(configuration: &configuration::Configuration, page: Option<i32>, per_page: Option<i32>) -> Result<models::ListBlocksResponse, Error<ListBlocksHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_page = page;
|
|
||||||
let p_per_page = per_page;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/blocks", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref param_value) = p_page {
|
|
||||||
req_builder = req_builder.query(&[("page", ¶m_value.to_string())]);
|
|
||||||
}
|
|
||||||
if let Some(ref param_value) = p_per_page {
|
|
||||||
req_builder = req_builder.query(&[("per_page", ¶m_value.to_string())]);
|
|
||||||
}
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ListBlocksResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ListBlocksResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<ListBlocksHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the block already exists, the server will return a 200 OK response. If the block is new, the server will return a 201 Created response.
|
|
||||||
pub async fn upload_block_handler(configuration: &configuration::Configuration, file_hash: &str, idx: i64, body: std::path::PathBuf) -> Result<models::BlockUploadedResponse, Error<UploadBlockHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_file_hash = file_hash;
|
|
||||||
let p_idx = idx;
|
|
||||||
let p_body = body;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/block", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
|
|
||||||
|
|
||||||
req_builder = req_builder.query(&[("file_hash", &p_file_hash.to_string())]);
|
|
||||||
req_builder = req_builder.query(&[("idx", &p_idx.to_string())]);
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
if let Some(ref token) = configuration.bearer_access_token {
|
|
||||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
|
||||||
};
|
|
||||||
let file_content = std::fs::read(&p_body).map_err(|e| Error::Io(e))?;
|
|
||||||
req_builder = req_builder.body(file_content);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::BlockUploadedResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::BlockUploadedResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<UploadBlockHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of missing blocks.
|
|
||||||
pub async fn verify_blocks_handler(configuration: &configuration::Configuration, verify_blocks_request: models::VerifyBlocksRequest) -> Result<models::VerifyBlocksResponse, Error<VerifyBlocksHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_verify_blocks_request = verify_blocks_request;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/block/verify", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
req_builder = req_builder.json(&p_verify_blocks_request);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::VerifyBlocksResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::VerifyBlocksResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<VerifyBlocksHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,51 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct Configuration {
|
|
||||||
pub base_path: String,
|
|
||||||
pub user_agent: Option<String>,
|
|
||||||
pub client: reqwest::Client,
|
|
||||||
pub basic_auth: Option<BasicAuth>,
|
|
||||||
pub oauth_access_token: Option<String>,
|
|
||||||
pub bearer_access_token: Option<String>,
|
|
||||||
pub api_key: Option<ApiKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type BasicAuth = (String, Option<String>);
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct ApiKey {
|
|
||||||
pub prefix: Option<String>,
|
|
||||||
pub key: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl Configuration {
|
|
||||||
pub fn new() -> Configuration {
|
|
||||||
Configuration::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Configuration {
|
|
||||||
fn default() -> Self {
|
|
||||||
Configuration {
|
|
||||||
base_path: "http://localhost".to_owned(),
|
|
||||||
user_agent: Some("OpenAPI-Generator/0.2.0/rust".to_owned()),
|
|
||||||
client: reqwest::Client::new(),
|
|
||||||
basic_auth: None,
|
|
||||||
oauth_access_token: None,
|
|
||||||
bearer_access_token: None,
|
|
||||||
api_key: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,106 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
use reqwest;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error as _};
|
|
||||||
use crate::{apis::ResponseContent, models};
|
|
||||||
use super::{Error, configuration, ContentType};
|
|
||||||
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_file_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetFileHandlerError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`upload_file_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum UploadFileHandlerError {
|
|
||||||
Status400(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// The file will be reconstructed from its blocks.
|
|
||||||
pub async fn get_file_handler(configuration: &configuration::Configuration, hash: &str, file_download_request: models::FileDownloadRequest) -> Result<reqwest::Response, Error<GetFileHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_hash = hash;
|
|
||||||
let p_file_download_request = file_download_request;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/file/{hash}", configuration.base_path, hash=crate::apis::urlencode(p_hash));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
req_builder = req_builder.json(&p_file_download_request);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
Ok(resp)
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetFileHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The file will be split into blocks and stored in the database.
|
|
||||||
pub async fn upload_file_handler(configuration: &configuration::Configuration, body: std::path::PathBuf) -> Result<models::FileUploadResponse, Error<UploadFileHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_body = body;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/file", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
if let Some(ref token) = configuration.bearer_access_token {
|
|
||||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
|
||||||
};
|
|
||||||
let file_content = std::fs::read(&p_body).map_err(|e| Error::Io(e))?;
|
|
||||||
req_builder = req_builder.body(file_content);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FileUploadResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FileUploadResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<UploadFileHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,244 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
use reqwest;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error as _};
|
|
||||||
use crate::{apis::ResponseContent, models};
|
|
||||||
use super::{Error, configuration, ContentType};
|
|
||||||
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`create_flist_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum CreateFlistHandlerError {
|
|
||||||
Status401(models::ResponseError),
|
|
||||||
Status403(models::ResponseError),
|
|
||||||
Status409(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`get_flist_state_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum GetFlistStateHandlerError {
|
|
||||||
Status401(models::ResponseError),
|
|
||||||
Status403(models::ResponseError),
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`list_flists_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ListFlistsHandlerError {
|
|
||||||
Status401(models::ResponseError),
|
|
||||||
Status403(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`preview_flist_handler`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum PreviewFlistHandlerError {
|
|
||||||
Status400(models::ResponseError),
|
|
||||||
Status401(models::ResponseError),
|
|
||||||
Status403(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`serve_flists`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ServeFlistsError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn create_flist_handler(configuration: &configuration::Configuration, flist_body: models::FlistBody) -> Result<models::Job, Error<CreateFlistHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_flist_body = flist_body;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/fl", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::POST, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
if let Some(ref token) = configuration.bearer_access_token {
|
|
||||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
|
||||||
};
|
|
||||||
req_builder = req_builder.json(&p_flist_body);
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::Job`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::Job`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<CreateFlistHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn get_flist_state_handler(configuration: &configuration::Configuration, job_id: &str) -> Result<models::FlistStateResponse, Error<GetFlistStateHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_job_id = job_id;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/fl/{job_id}", configuration.base_path, job_id=crate::apis::urlencode(p_job_id));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
if let Some(ref token) = configuration.bearer_access_token {
|
|
||||||
req_builder = req_builder.bearer_auth(token.to_owned());
|
|
||||||
};
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::FlistStateResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::FlistStateResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<GetFlistStateHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn list_flists_handler(configuration: &configuration::Configuration, ) -> Result<std::collections::HashMap<String, Vec<models::FileInfo>>, Error<ListFlistsHandlerError>> {
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/fl", configuration.base_path);
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `std::collections::HashMap<String, Vec<models::FileInfo>>`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `std::collections::HashMap<String, Vec<models::FileInfo>>`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<ListFlistsHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn preview_flist_handler(configuration: &configuration::Configuration, flist_path: &str) -> Result<models::PreviewResponse, Error<PreviewFlistHandlerError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_flist_path = flist_path;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/api/v1/fl/preview/{flist_path}", configuration.base_path, flist_path=crate::apis::urlencode(p_flist_path));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::PreviewResponse`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::PreviewResponse`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<PreviewFlistHandlerError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn serve_flists(configuration: &configuration::Configuration, path: &str) -> Result<reqwest::Response, Error<ServeFlistsError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_path = path;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/{path}", configuration.base_path, path=crate::apis::urlencode(p_path));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
Ok(resp)
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<ServeFlistsError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@@ -1,63 +0,0 @@
|
|||||||
/*
|
|
||||||
* rfs
|
|
||||||
*
|
|
||||||
* No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
|
||||||
*
|
|
||||||
* The version of the OpenAPI document: 0.2.0
|
|
||||||
*
|
|
||||||
* Generated by: https://openapi-generator.tech
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
use reqwest;
|
|
||||||
use serde::{Deserialize, Serialize, de::Error as _};
|
|
||||||
use crate::{apis::ResponseContent, models};
|
|
||||||
use super::{Error, configuration, ContentType};
|
|
||||||
|
|
||||||
|
|
||||||
/// struct for typed errors of method [`serve_flists`]
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
||||||
#[serde(untagged)]
|
|
||||||
pub enum ServeFlistsError {
|
|
||||||
Status404(models::ResponseError),
|
|
||||||
Status500(models::ResponseError),
|
|
||||||
UnknownValue(serde_json::Value),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub async fn serve_flists(configuration: &configuration::Configuration, path: &str) -> Result<models::ResponseResult, Error<ServeFlistsError>> {
|
|
||||||
// add a prefix to parameters to efficiently prevent name collisions
|
|
||||||
let p_path = path;
|
|
||||||
|
|
||||||
let uri_str = format!("{}/{path}", configuration.base_path, path=crate::apis::urlencode(p_path));
|
|
||||||
let mut req_builder = configuration.client.request(reqwest::Method::GET, &uri_str);
|
|
||||||
|
|
||||||
if let Some(ref user_agent) = configuration.user_agent {
|
|
||||||
req_builder = req_builder.header(reqwest::header::USER_AGENT, user_agent.clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
let req = req_builder.build()?;
|
|
||||||
let resp = configuration.client.execute(req).await?;
|
|
||||||
|
|
||||||
let status = resp.status();
|
|
||||||
let content_type = resp
|
|
||||||
.headers()
|
|
||||||
.get("content-type")
|
|
||||||
.and_then(|v| v.to_str().ok())
|
|
||||||
.unwrap_or("application/octet-stream");
|
|
||||||
let content_type = super::ContentType::from(content_type);
|
|
||||||
|
|
||||||
if !status.is_client_error() && !status.is_server_error() {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
match content_type {
|
|
||||||
ContentType::Json => serde_json::from_str(&content).map_err(Error::from),
|
|
||||||
ContentType::Text => return Err(Error::from(serde_json::Error::custom("Received `text/plain` content type response that cannot be converted to `models::ResponseResult`"))),
|
|
||||||
ContentType::Unsupported(unknown_type) => return Err(Error::from(serde_json::Error::custom(format!("Received `{unknown_type}` content type response that cannot be converted to `models::ResponseResult`")))),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let content = resp.text().await?;
|
|
||||||
let entity: Option<ServeFlistsError> = serde_json::from_str(&content).ok();
|
|
||||||
Err(Error::ResponseError(ResponseContent { status, content, entity }))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user