This commit is contained in:
despiegk 2025-04-05 06:34:16 +02:00
parent 245aee12bf
commit 6de7bf9b56
15 changed files with 361 additions and 20 deletions

34
docs/.gitignore vendored Normal file
View File

@ -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

72
docs/cfg/footer.json Normal file
View File

@ -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"
}
]
}
]
}

17
docs/cfg/main.json Normal file
View File

@ -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"
}

25
docs/cfg/navbar.json Normal file
View File

@ -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"
}
]
}

View File

@ -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."
}
}

54
src/docs/tech.md Normal file
View File

@ -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/)

View File

@ -25,7 +25,7 @@ fn nerdctl_error_to_rhai_error<T>(result: Result<T, NerdctlError>) -> Result<T,
format!("Data conversion error: {}. This may indicate unexpected output format from nerdctl.", msg) format!("Data conversion error: {}. This may indicate unexpected output format from nerdctl.", msg)
}, },
NerdctlError::Other(msg) => { NerdctlError::Other(msg) => {
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 /// 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<Container, Box<EvalAltResult>> { pub fn container_build(container: Container) -> Result<Container, Box<EvalAltResult>> {
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 /// Start the Container and verify it's running
@ -172,6 +228,31 @@ pub fn container_exec(container: &mut Container, command: &str) -> Result<Comman
nerdctl_error_to_rhai_error(container.exec(command)) nerdctl_error_to_rhai_error(container.exec(command))
} }
/// Get container logs
pub fn container_logs(container: &mut Container) -> Result<CommandResult, Box<EvalAltResult>> {
// 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 /// Copy files between the Container and local filesystem
pub fn container_copy(container: &mut Container, source: &str, dest: &str) -> Result<CommandResult, Box<EvalAltResult>> { pub fn container_copy(container: &mut Container, source: &str, dest: &str) -> Result<CommandResult, Box<EvalAltResult>> {
nerdctl_error_to_rhai_error(container.copy(source, dest)) nerdctl_error_to_rhai_error(container.copy(source, dest))
@ -244,6 +325,13 @@ pub fn nerdctl_list(all: bool) -> Result<CommandResult, Box<EvalAltResult>> {
nerdctl_error_to_rhai_error(nerdctl::list(all)) nerdctl_error_to_rhai_error(nerdctl::list(all))
} }
/// Wrapper for nerdctl::logs
///
/// Get container logs.
pub fn nerdctl_logs(container: &str) -> Result<CommandResult, Box<EvalAltResult>> {
nerdctl_error_to_rhai_error(nerdctl::logs(container))
}
// //
// Image Function Wrappers // Image Function Wrappers
// //
@ -330,6 +418,7 @@ pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box<EvalAltRes
engine.register_fn("stop", container_stop); engine.register_fn("stop", container_stop);
engine.register_fn("remove", container_remove); engine.register_fn("remove", container_remove);
engine.register_fn("exec", container_exec); engine.register_fn("exec", container_exec);
engine.register_fn("logs", container_logs);
engine.register_fn("copy", container_copy); engine.register_fn("copy", container_copy);
// Register legacy container functions (for backward compatibility) // Register legacy container functions (for backward compatibility)
@ -342,6 +431,7 @@ pub fn register_nerdctl_module(engine: &mut Engine) -> Result<(), Box<EvalAltRes
engine.register_fn("nerdctl_stop", nerdctl_stop); engine.register_fn("nerdctl_stop", nerdctl_stop);
engine.register_fn("nerdctl_remove", nerdctl_remove); engine.register_fn("nerdctl_remove", nerdctl_remove);
engine.register_fn("nerdctl_list", nerdctl_list); engine.register_fn("nerdctl_list", nerdctl_list);
engine.register_fn("nerdctl_logs", nerdctl_logs);
// Register image functions // Register image functions
engine.register_fn("nerdctl_images", nerdctl_images); engine.register_fn("nerdctl_images", nerdctl_images);

View File

@ -126,8 +126,6 @@ try {
// Build the container // Build the container
println("\nBuilding the container..."); println("\nBuilding the container...");
container = container.build(); container = container.build();
// Print container ID after building
println(`Container built successfully with ID: ${container.container_id}`); println(`Container built successfully with ID: ${container.container_id}`);
// Start the container // Start the container
@ -137,6 +135,9 @@ try {
// Execute a command in the running container // Execute a command in the running container
println("\nExecuting command in the container..."); println("\nExecuting command in the container...");
let exec_result = container.exec("echo 'Hello from Alpine container!'");
println(`Command output: ${exec_result.stdout}`);
println("\nExecuting command in the container...");
let run_cmd = container.exec("echo 'Hello from Alpine container'"); let run_cmd = container.exec("echo 'Hello from Alpine container'");
println(`Command output: ${run_cmd.stdout}`); println(`Command output: ${run_cmd.stdout}`);

View File

@ -126,3 +126,16 @@ pub fn list(all: bool) -> Result<CommandResult, NerdctlError> {
execute_nerdctl_command(&args) execute_nerdctl_command(&args)
} }
/// Get container logs
///
/// # Arguments
///
/// * `container` - Container name or ID
///
/// # Returns
///
/// * `Result<CommandResult, NerdctlError>` - Command result or error
pub fn logs(container: &str) -> Result<CommandResult, NerdctlError> {
execute_nerdctl_command(&["logs", container])
}

View File

@ -27,23 +27,37 @@ impl Container {
match self.verify_running() { match self.verify_running() {
Ok(true) => start_result, Ok(true) => start_result,
Ok(false) => { 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() { if let Ok(status) = self.status() {
Err(NerdctlError::CommandFailed( error_message.push_str(&format!("\nStatus: {}, State: {}, Health: {}",
format!("Container {} started but is not running. Status: {}, State: {}, Health: {}", status.status,
container_id, status.state,
status.status, status.health_status.unwrap_or_else(|| "N/A".to_string())
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
)
))
} }
// 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) => { Err(err) => {
// Failed to verify if container is running // Failed to verify if container is running
@ -274,6 +288,19 @@ impl Container {
} else { } else {
Err(NerdctlError::Other("No container ID available".to_string())) Err(NerdctlError::Other("No container ID available".to_string()))
} }
/// Get container logs
///
/// # Returns
///
/// * `Result<CommandResult, NerdctlError>` - Command result or error
pub fn logs(&self) -> Result<CommandResult, NerdctlError> {
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 /// Get container resource usage