From 6de7bf9b564a94b94854640a7ad3aae3e7375c41 Mon Sep 17 00:00:00 2001 From: despiegk Date: Sat, 5 Apr 2025 06:34:16 +0200 Subject: [PATCH] ... --- docs/.gitignore | 34 +++++++++ docs/cfg/footer.json | 72 ++++++++++++++++++ docs/cfg/main.json | 17 +++++ docs/cfg/navbar.json | 25 ++++++ src/docs/{rhai => subdir}/README.md | 0 src/docs/subdir/_category_.json | 8 ++ src/docs/{rhai => subdir}/buildah.md | 0 src/docs/{rhai => subdir}/git.md | 0 src/docs/{rhai => subdir}/os.md | 0 src/docs/{rhai => subdir}/process.md | 0 src/docs/tech.md | 54 +++++++++++++ src/rhai/nerdctl.rs | 96 +++++++++++++++++++++++- src/rhaiexamples/nerdctl_test.rhai | 5 +- src/virt/nerdctl/container_functions.rs | 13 ++++ src/virt/nerdctl/container_operations.rs | 57 ++++++++++---- 15 files changed, 361 insertions(+), 20 deletions(-) create mode 100644 docs/.gitignore create mode 100644 docs/cfg/footer.json create mode 100644 docs/cfg/main.json create mode 100644 docs/cfg/navbar.json rename src/docs/{rhai => subdir}/README.md (100%) create mode 100644 src/docs/subdir/_category_.json rename src/docs/{rhai => subdir}/buildah.md (100%) rename src/docs/{rhai => subdir}/git.md (100%) rename src/docs/{rhai => subdir}/os.md (100%) rename src/docs/{rhai => subdir}/process.md (100%) create mode 100644 src/docs/tech.md diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..77793ac --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,34 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* +bun.lockb +bun.lock + +yarn.lock + +build.sh +build_dev.sh +develop.sh + +docusaurus.config.ts + +sidebars.ts + +tsconfig.json diff --git a/docs/cfg/footer.json b/docs/cfg/footer.json new file mode 100644 index 0000000..0479bf9 --- /dev/null +++ b/docs/cfg/footer.json @@ -0,0 +1,72 @@ +{ + "style": "dark", + "links": [ + { + "title": "Docs", + "items": [ + { + "label": "Introduction", + "to": "/docs/introduction" + }, + { + "label": "Litepaper", + "to": "/docs/litepaper" + }, + { + "label": "Roadmap", + "to": "/docs/roadmap" + }, + { + "label": "Manual", + "href": "https://manual.grid.tf/" + } + ] + }, + { + "title": "Features", + "items": [ + { + "label": "Become a Farmer", + "to": "/docs/category/become-a-farmer" + }, + { + "label": "Components", + "to": "/docs/category/components" + }, + { + "label": "Tokenomics", + "to": "/docs/tokens/tokenomics" + }, + { + "label": "Technology", + "to": "/docs/tech" + } + ] + }, + { + "title": "Web", + "items": [ + { + "label": "ThreeFold.io", + "href": "https://threefold.io" + }, + { + "label": "Dashboard", + "href": "https://dashboard.grid.tf" + }, + { + "label": "GitHub", + "href": "https://github.com/threefoldtech/home" + }, + { + "href": "https://mycelium.threefold.io/", + "label": "Mycelium Network" + }, + { + "href": "https://aibox.threefold.io/", + "label": "AI Box" + } + ] + } + ] +} diff --git a/docs/cfg/main.json b/docs/cfg/main.json new file mode 100644 index 0000000..318cbb3 --- /dev/null +++ b/docs/cfg/main.json @@ -0,0 +1,17 @@ +{ + "title": "ThreeFold DePIN", + "tagline": "ThreeFold DePIN", + "favicon": "img/favicon.png", + "url": "https://docs.threefold.io", + "url_home": "docs/introduction", + "baseUrl": "/", + "image": "img/tf_graph.png", + "metadata": { + "description": "Internet Infrastructur for Everyone by Everyone, Everywhere.", + "image": "https://threefold.info/tfgrid4/img/tf_graph.png", + "title": "ThreeFold DePIN" + }, + "buildDest":["root@info.ourworld.tf:/root/hero/www/info/tfgrid4"], + "buildDestDev":["root@info.ourworld.tf:/root/hero/www/infodev/tfgrid4"], + "copyright": "ThreeFold" +} diff --git a/docs/cfg/navbar.json b/docs/cfg/navbar.json new file mode 100644 index 0000000..a9d11e3 --- /dev/null +++ b/docs/cfg/navbar.json @@ -0,0 +1,25 @@ +{ + "title": "", + "logo": { + "alt": "ThreeFold Logo", + "src": "img/logo.svg", + "srcDark": "img/new_logo_tft.png" + }, + "items": [ + { + "href": "https://threefold.io", + "label": "ThreeFold.io", + "position": "right" + }, + { + "href": "https://mycelium.threefold.io/", + "label": "Mycelium Network", + "position": "right" + }, + { + "href": "https://aibox.threefold.io/", + "label": "AI Box", + "position": "right" + } + ] +} diff --git a/src/docs/rhai/README.md b/src/docs/subdir/README.md similarity index 100% rename from src/docs/rhai/README.md rename to src/docs/subdir/README.md diff --git a/src/docs/subdir/_category_.json b/src/docs/subdir/_category_.json new file mode 100644 index 0000000..17ee60b --- /dev/null +++ b/src/docs/subdir/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "Become a Farmer", + "position": 6, + "link": { + "type": "generated-index", + "description": "Learn how to become a farmer. Let's together build Web4 everywhere for everyone." + } + } \ No newline at end of file diff --git a/src/docs/rhai/buildah.md b/src/docs/subdir/buildah.md similarity index 100% rename from src/docs/rhai/buildah.md rename to src/docs/subdir/buildah.md diff --git a/src/docs/rhai/git.md b/src/docs/subdir/git.md similarity index 100% rename from src/docs/rhai/git.md rename to src/docs/subdir/git.md diff --git a/src/docs/rhai/os.md b/src/docs/subdir/os.md similarity index 100% rename from src/docs/rhai/os.md rename to src/docs/subdir/os.md diff --git a/src/docs/rhai/process.md b/src/docs/subdir/process.md similarity index 100% rename from src/docs/rhai/process.md rename to src/docs/subdir/process.md diff --git a/src/docs/tech.md b/src/docs/tech.md new file mode 100644 index 0000000..91739b4 --- /dev/null +++ b/src/docs/tech.md @@ -0,0 +1,54 @@ +--- +sidebar_position: 10 +--- + +# Technology + +![](img/threefold_parts.png) + + +ThreeFold delivers the plumbing layer for a better Internet which has the potential to achieve Augmented Collective Intelligence[^1]. We call such a system **Web4**. + +> *ThreeFold might be the only platform in the world providing Web4 network, data and cloud capabilities in one system.* + +## 3 Required Levels + +Together with our partners, we have all the required parts to make it happen on 3 major levels: + +### Personal Level + +- **Agent Layer**: Every person owns a Personal Digital Assistant (PDA), managing their digital life. +- **Identity Layer**: Strong reputation management, proof of authenticity, a global name system. +- **Intelligence Layer**: Decentralized, personal AI systems for collaboration & augmented intelligence. +- **Transaction Layer**: Fully integrated with Web3 systems and beyond, e.g. mutual credit, etc. + + +### Infrastructure Level + +- **Network Layer**: Redesign of how communication happens with a private and more scalable network layer. +- **Data Layer**: Redesign of how we share, distribute and store data. +- **Serverless Compute Layer**: Allow code to run close to where participants and data are. +- **Cloud Layer**: Run VMs and containers as part of the ecosystem with Web2 compatibility layer. + +### Physical Level + +- **Routers**: Route between old and new web, and create new secure communication channels. +- **Nodes**: Deliver AI, Data, Compute to the ecosystem. +- **Phones**: Our personal device, capable of building a meshed network, offline support with catchup. +- **Computers**: Any current Linux, Windows, macOS computer seamlessly integrates. + +![](img/zos.png) + +The following are the required components to make all this possible: + +- **Zero-OS**: Custom lightweight operating system for nodes built on the Linux kernel. + - Self-healing and automated resource management via bare metal ThreeFold nodes. +- **Mycelium**: End-to-end encrypted network always using the shortest path. +- **Quantum Safe Storage**: Technology resistant to quantum computer attacks where data can never be lost. +- **Advanced AI Agent**: Creation of apps fully compatibility with Web3. +- **Smart Contract for IT**: Blockchain-based resource allocation with signed contracts. + - Secure, transparent transaction mechanisms for deployment of solutions on the ThreeFold Grid. + +> For more information, read the [ThreeFold Tech ebook](https://threefold.info/tech). + +[^1]: Augmented Collective Intelligence - Supermind [Link](https://www.supermind.design/) diff --git a/src/rhai/nerdctl.rs b/src/rhai/nerdctl.rs index 5ef4f1d..f95ce62 100644 --- a/src/rhai/nerdctl.rs +++ b/src/rhai/nerdctl.rs @@ -25,7 +25,7 @@ fn nerdctl_error_to_rhai_error(result: Result) -> Result { - format!("Nerdctl error: {}. This is an unexpected error.", msg).. + format!("Nerdctl error: {}. This is an unexpected error.", msg) }, }; @@ -101,8 +101,64 @@ pub fn container_with_detach(mut container: Container, detach: bool) -> Containe } /// Build and run the Container +/// +/// This function builds and runs the container using the configured options. +/// It provides detailed error information if the build fails. pub fn container_build(container: Container) -> Result> { - nerdctl_error_to_rhai_error(container.build()) + // Get container details for better error reporting + let container_name = container.name.clone(); + let image = container.image.clone().unwrap_or_else(|| "none".to_string()); + let ports = container.ports.clone(); + let volumes = container.volumes.clone(); + let env_vars = container.env_vars.clone(); + + // Try to build the container + let build_result = container.build(); + + // Handle the result with improved error context + match build_result { + Ok(built_container) => { + // Container built successfully + Ok(built_container) + }, + Err(err) => { + // Add more context to the error + let enhanced_error = match err { + NerdctlError::CommandFailed(msg) => { + // Provide more detailed error information + let mut enhanced_msg = format!("Failed to build container '{}' from image '{}': {}", + container_name, image, msg); + + // Add information about configured options that might be relevant + if !ports.is_empty() { + enhanced_msg.push_str(&format!("\nConfigured ports: {:?}", ports)); + } + + if !volumes.is_empty() { + enhanced_msg.push_str(&format!("\nConfigured volumes: {:?}", volumes)); + } + + if !env_vars.is_empty() { + enhanced_msg.push_str(&format!("\nConfigured environment variables: {:?}", env_vars)); + } + + // Add suggestions for common issues + if msg.contains("not found") || msg.contains("no such image") { + enhanced_msg.push_str("\nSuggestion: The specified image may not exist or may not be pulled yet. Try pulling the image first with nerdctl_image_pull()."); + } else if msg.contains("port is already allocated") { + enhanced_msg.push_str("\nSuggestion: One of the specified ports is already in use. Try using a different port or stopping the container using that port."); + } else if msg.contains("permission denied") { + enhanced_msg.push_str("\nSuggestion: Permission issues detected. Check if you have the necessary permissions to create containers or access the specified volumes."); + } + + NerdctlError::CommandFailed(enhanced_msg) + }, + _ => err + }; + + nerdctl_error_to_rhai_error(Err(enhanced_error)) + } + } } /// Start the Container and verify it's running @@ -139,7 +195,7 @@ pub fn container_start(container: &mut Container) -> Result Result Result> { + // Get container details for better error reporting + let container_name = container.name.clone(); + let container_id = container.container_id.clone().unwrap_or_else(|| "unknown".to_string()); + + // Use the nerdctl::logs function + let logs_result = nerdctl::logs(&container_id); + + match logs_result { + Ok(result) => { + Ok(result) + }, + Err(err) => { + // Add more context to the error + let enhanced_error = NerdctlError::CommandFailed( + format!("Failed to get logs for container '{}' (ID: {}): {}", + container_name, container_id, err) + ); + + nerdctl_error_to_rhai_error(Err(enhanced_error)) + } + } +} + /// Copy files between the Container and local filesystem pub fn container_copy(container: &mut Container, source: &str, dest: &str) -> Result> { nerdctl_error_to_rhai_error(container.copy(source, dest)) @@ -244,6 +325,13 @@ pub fn nerdctl_list(all: bool) -> Result> { nerdctl_error_to_rhai_error(nerdctl::list(all)) } +/// Wrapper for nerdctl::logs +/// +/// Get container logs. +pub fn nerdctl_logs(container: &str) -> Result> { + nerdctl_error_to_rhai_error(nerdctl::logs(container)) +} + // // Image Function Wrappers // @@ -330,6 +418,7 @@ pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box Result<(), Box Result { } execute_nerdctl_command(&args) +} + +/// Get container logs +/// +/// # Arguments +/// +/// * `container` - Container name or ID +/// +/// # Returns +/// +/// * `Result` - Command result or error +pub fn logs(container: &str) -> Result { + execute_nerdctl_command(&["logs", container]) } \ No newline at end of file diff --git a/src/virt/nerdctl/container_operations.rs b/src/virt/nerdctl/container_operations.rs index 1429526..878f3ec 100644 --- a/src/virt/nerdctl/container_operations.rs +++ b/src/virt/nerdctl/container_operations.rs @@ -27,23 +27,37 @@ impl Container { match self.verify_running() { Ok(true) => start_result, Ok(false) => { - // Container started but isn't running - try to get more details + // Container started but isn't running - get detailed information + let mut error_message = format!("Container {} started but is not running.", container_id); + + // Get container status if let Ok(status) = self.status() { - Err(NerdctlError::CommandFailed( - format!("Container {} started but is not running. Status: {}, State: {}, Health: {}", - container_id, - status.status, - status.state, - status.health_status.unwrap_or_else(|| "N/A".to_string()) - ) - )) - } else { - Err(NerdctlError::CommandFailed( - format!("Container {} started but is not running. Unable to get status details.", - container_id - ) - )) + error_message.push_str(&format!("\nStatus: {}, State: {}, Health: {}", + status.status, + status.state, + status.health_status.unwrap_or_else(|| "N/A".to_string()) + )); } + + // Get container logs + if let Ok(logs) = execute_nerdctl_command(&["logs", container_id]) { + if !logs.stdout.trim().is_empty() { + error_message.push_str(&format!("\nContainer logs (stdout):\n{}", logs.stdout.trim())); + } + if !logs.stderr.trim().is_empty() { + error_message.push_str(&format!("\nContainer logs (stderr):\n{}", logs.stderr.trim())); + } + } + + // Get container exit code if available + if let Ok(inspect_result) = execute_nerdctl_command(&["inspect", "--format", "{{.State.ExitCode}}", container_id]) { + let exit_code = inspect_result.stdout.trim(); + if !exit_code.is_empty() && exit_code != "0" { + error_message.push_str(&format!("\nContainer exit code: {}", exit_code)); + } + } + + Err(NerdctlError::CommandFailed(error_message)) }, Err(err) => { // Failed to verify if container is running @@ -274,6 +288,19 @@ impl Container { } else { Err(NerdctlError::Other("No container ID available".to_string())) } + + /// Get container logs + /// + /// # Returns + /// + /// * `Result` - Command result or error + pub fn logs(&self) -> Result { + if let Some(container_id) = &self.container_id { + execute_nerdctl_command(&["logs", container_id]) + } else { + Err(NerdctlError::Other("No container ID available".to_string())) + } + } } /// Get container resource usage