refactor: Refactor Mycelium configuration and dependencies
- Flatten MyceliumConfig struct into HeroPods - Remove Mycelium installer and service management logic - Update Mycelium initialization to check for prerequisites only - Adjust peers configuration to be comma-separated string
This commit is contained in:
@@ -28,18 +28,7 @@
|
|||||||
version:'v0.5.6'
|
version:'v0.5.6'
|
||||||
ipv6_range:'400::/7'
|
ipv6_range:'400::/7'
|
||||||
key_path:'~/hero/cfg/priv_key.bin'
|
key_path:'~/hero/cfg/priv_key.bin'
|
||||||
peers:[
|
peers:'tcp://185.69.166.8:9651,quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651,tcp://65.109.18.113:9651,quic://[2a01:4f9:5a:1042::2]:9651,tcp://5.78.122.16:9651,quic://[2a01:4ff:1f0:8859::1]:9651,tcp://5.223.43.251:9651,quic://[2a01:4ff:2f0:3621::1]:9651,tcp://142.93.217.194:9651,quic://[2400:6180:100:d0::841:2001]:9651'
|
||||||
'tcp://185.69.166.8:9651',
|
|
||||||
'quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651',
|
|
||||||
'tcp://65.109.18.113:9651',
|
|
||||||
'quic://[2a01:4f9:5a:1042::2]:9651',
|
|
||||||
'tcp://5.78.122.16:9651',
|
|
||||||
'quic://[2a01:4ff:1f0:8859::1]:9651',
|
|
||||||
'tcp://5.223.43.251:9651',
|
|
||||||
'quic://[2a01:4ff:2f0:3621::1]:9651',
|
|
||||||
'tcp://142.93.217.194:9651',
|
|
||||||
'quic://[2400:6180:100:d0::841:2001]:9651'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Step 3: Create a new Alpine Linux container
|
// Step 3: Create a new Alpine Linux container
|
||||||
// Alpine includes basic IPv6 networking tools
|
// Alpine includes basic IPv6 networking tools
|
||||||
@@ -87,7 +76,7 @@
|
|||||||
// This doesn't require special capabilities
|
// This doesn't require special capabilities
|
||||||
!!heropods.container_exec
|
!!heropods.container_exec
|
||||||
name:'mycelium_container'
|
name:'mycelium_container'
|
||||||
cmd:'nc -6 -zv -w 3 400:8f3a:8d0e:3503:db8e:6a02:2e9:83dd 80 2>&1 || echo "nc test completed"'
|
cmd:'nc -6 -zv -w 3 400:8f3a:8d0e:3503:db8e:6a02:2e9:83dd 80 2>&1 || echo nc test completed'
|
||||||
stdout:true
|
stdout:true
|
||||||
|
|
||||||
// Step 7: Show Mycelium-specific information
|
// Step 7: Show Mycelium-specific information
|
||||||
@@ -95,7 +84,7 @@
|
|||||||
// Display the container's Mycelium IPv6 address
|
// Display the container's Mycelium IPv6 address
|
||||||
!!heropods.container_exec
|
!!heropods.container_exec
|
||||||
name:'mycelium_container'
|
name:'mycelium_container'
|
||||||
cmd:'ip -6 addr show | grep "400:" || echo "No Mycelium IPv6 address found"'
|
cmd:'ip -6 addr show | grep 400: || echo No Mycelium IPv6 address found'
|
||||||
stdout:true
|
stdout:true
|
||||||
|
|
||||||
// Show IPv6 neighbors (if any)
|
// Show IPv6 neighbors (if any)
|
||||||
|
|||||||
@@ -1,5 +1,24 @@
|
|||||||
# Mycelium IPv6 Overlay Network Integration for HeroPods
|
# Mycelium IPv6 Overlay Network Integration for HeroPods
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
**Mycelium must be installed on your system before using this feature.** HeroPods does not install Mycelium automatically.
|
||||||
|
|
||||||
|
### Installing Mycelium
|
||||||
|
|
||||||
|
Download and install Mycelium from the official repository:
|
||||||
|
|
||||||
|
- **GitHub**: <https://github.com/threefoldtech/mycelium>
|
||||||
|
- **Releases**: <https://github.com/threefoldtech/mycelium/releases>
|
||||||
|
|
||||||
|
For detailed installation instructions, see the [Mycelium documentation](https://github.com/threefoldtech/mycelium/tree/master/docs).
|
||||||
|
|
||||||
|
After installation, verify that the `mycelium` command is available:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mycelium -V
|
||||||
|
```
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
HeroPods now supports Mycelium IPv6 overlay networking, providing end-to-end encrypted IPv6 connectivity for containers across the internet.
|
HeroPods now supports Mycelium IPv6 overlay networking, providing end-to-end encrypted IPv6 connectivity for containers across the internet.
|
||||||
@@ -18,7 +37,7 @@ Mycelium is an IPv6 overlay network that provides:
|
|||||||
### Components
|
### Components
|
||||||
|
|
||||||
1. **mycelium.v** - Core Mycelium integration logic
|
1. **mycelium.v** - Core Mycelium integration logic
|
||||||
- Installation and service management
|
- Service management (start/stop)
|
||||||
- Container IPv6 configuration
|
- Container IPv6 configuration
|
||||||
- veth pair creation for IPv6 routing
|
- veth pair creation for IPv6 routing
|
||||||
|
|
||||||
@@ -61,11 +80,7 @@ All parameters are **required** when enabling Mycelium:
|
|||||||
version:'v0.5.6'
|
version:'v0.5.6'
|
||||||
ipv6_range:'400::/7'
|
ipv6_range:'400::/7'
|
||||||
key_path:'~/hero/cfg/priv_key.bin'
|
key_path:'~/hero/cfg/priv_key.bin'
|
||||||
peers:[
|
peers:'tcp://185.69.166.8:9651,quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651,tcp://65.109.18.113:9651'
|
||||||
'tcp://185.69.166.8:9651',
|
|
||||||
'quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651',
|
|
||||||
'tcp://65.109.18.113:9651'
|
|
||||||
]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Configuration Parameters
|
### Configuration Parameters
|
||||||
@@ -75,7 +90,7 @@ All parameters are **required**:
|
|||||||
- `version` (string): Mycelium version to install (e.g., 'v0.5.6')
|
- `version` (string): Mycelium version to install (e.g., 'v0.5.6')
|
||||||
- `ipv6_range` (string): Mycelium IPv6 address range (e.g., '400::/7')
|
- `ipv6_range` (string): Mycelium IPv6 address range (e.g., '400::/7')
|
||||||
- `key_path` (string): Path to Mycelium private key (e.g., '~/hero/cfg/priv_key.bin')
|
- `key_path` (string): Path to Mycelium private key (e.g., '~/hero/cfg/priv_key.bin')
|
||||||
- `peers` (array of strings): Array of Mycelium peer addresses
|
- `peers` (string): Comma-separated list of Mycelium peer addresses (e.g., 'tcp://185.69.166.8:9651,quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651')
|
||||||
|
|
||||||
### Default Public Peers
|
### Default Public Peers
|
||||||
|
|
||||||
@@ -111,10 +126,7 @@ See `examples/virt/heropods/container_mycelium.heroscript` for a complete exampl
|
|||||||
version:'v0.5.6'
|
version:'v0.5.6'
|
||||||
ipv6_range:'400::/7'
|
ipv6_range:'400::/7'
|
||||||
key_path:'~/hero/cfg/priv_key.bin'
|
key_path:'~/hero/cfg/priv_key.bin'
|
||||||
peers:[
|
peers:'tcp://185.69.166.8:9651,quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651'
|
||||||
'tcp://185.69.166.8:9651',
|
|
||||||
'quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651'
|
|
||||||
]
|
|
||||||
|
|
||||||
// Create and start container
|
// Create and start container
|
||||||
!!heropods.container_new
|
!!heropods.container_new
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ pub fn (mut self Container) start() ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup Mycelium IPv6 overlay network if enabled
|
// Setup Mycelium IPv6 overlay network if enabled
|
||||||
if self.factory.mycelium_config.enabled {
|
if self.factory.mycelium_enabled {
|
||||||
container_pid := self.pid()!
|
container_pid := self.pid()!
|
||||||
self.factory.mycelium_setup_container(self.name, container_pid) or {
|
self.factory.mycelium_setup_container(self.name, container_pid) or {
|
||||||
self.factory.logger.log(
|
self.factory.logger.log(
|
||||||
@@ -442,7 +442,7 @@ fn (mut self Container) cleanup_network() ! {
|
|||||||
factory.network_cleanup_container(self.name)!
|
factory.network_cleanup_container(self.name)!
|
||||||
|
|
||||||
// Cleanup Mycelium IPv6 overlay network if enabled
|
// Cleanup Mycelium IPv6 overlay network if enabled
|
||||||
if factory.mycelium_config.enabled {
|
if factory.mycelium_enabled {
|
||||||
factory.mycelium_cleanup_container(self.name) or {
|
factory.mycelium_cleanup_container(self.name) or {
|
||||||
factory.logger.log(
|
factory.logger.log(
|
||||||
cat: 'container'
|
cat: 'container'
|
||||||
|
|||||||
@@ -42,22 +42,20 @@ pub mut:
|
|||||||
|
|
||||||
pub fn new(args ArgsGet) !&HeroPods {
|
pub fn new(args ArgsGet) !&HeroPods {
|
||||||
mut obj := HeroPods{
|
mut obj := HeroPods{
|
||||||
name: args.name
|
name: args.name
|
||||||
reset: args.reset
|
reset: args.reset
|
||||||
use_podman: args.use_podman
|
use_podman: args.use_podman
|
||||||
network_config: NetworkConfig{
|
network_config: NetworkConfig{
|
||||||
bridge_name: args.bridge_name
|
bridge_name: args.bridge_name
|
||||||
subnet: args.subnet
|
subnet: args.subnet
|
||||||
gateway_ip: args.gateway_ip
|
gateway_ip: args.gateway_ip
|
||||||
dns_servers: args.dns_servers
|
dns_servers: args.dns_servers
|
||||||
}
|
}
|
||||||
mycelium_config: MyceliumConfig{
|
mycelium_enabled: args.enable_mycelium
|
||||||
enabled: args.enable_mycelium
|
mycelium_version: args.mycelium_version
|
||||||
version: args.mycelium_version
|
mycelium_ipv6_range: args.mycelium_ipv6_range
|
||||||
ipv6_range: args.mycelium_ipv6_range
|
mycelium_peers: args.mycelium_peers
|
||||||
peers: args.mycelium_peers
|
mycelium_key_path: args.mycelium_key_path
|
||||||
key_path: args.mycelium_key_path
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
set(obj)!
|
set(obj)!
|
||||||
return get(name: args.name)!
|
return get(name: args.name)!
|
||||||
@@ -192,21 +190,22 @@ pub fn play(mut plbook PlayBook) ! {
|
|||||||
mycelium_key_path := p.get('key_path') or {
|
mycelium_key_path := p.get('key_path') or {
|
||||||
return error('heropods.enable_mycelium: "key_path" is required (e.g., key_path:\'~/hero/cfg/priv_key.bin\')')
|
return error('heropods.enable_mycelium: "key_path" is required (e.g., key_path:\'~/hero/cfg/priv_key.bin\')')
|
||||||
}
|
}
|
||||||
peers_array := p.get_list('peers') or {
|
mycelium_peers_str := p.get('peers') or {
|
||||||
return error('heropods.enable_mycelium: "peers" is required. Provide array of peer addresses (e.g., peers:[\'tcp://185.69.166.8:9651\', \'quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651\'])')
|
return error('heropods.enable_mycelium: "peers" is required. Provide comma-separated list of peer addresses (e.g., peers:\'tcp://185.69.166.8:9651,quic://[2a02:1802:5e:0:ec4:7aff:fe51:e36b]:9651\')')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate peers list is not empty
|
// Parse and validate peers list
|
||||||
|
peers_array := mycelium_peers_str.split(',').map(it.trim_space()).filter(it.len > 0)
|
||||||
if peers_array.len == 0 {
|
if peers_array.len == 0 {
|
||||||
return error('heropods.enable_mycelium: "peers" cannot be empty. Provide at least one peer address.')
|
return error('heropods.enable_mycelium: "peers" cannot be empty. Provide at least one peer address.')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Mycelium configuration
|
// Update Mycelium configuration
|
||||||
hp.mycelium_config.enabled = true
|
hp.mycelium_enabled = true
|
||||||
hp.mycelium_config.version = mycelium_version
|
hp.mycelium_version = mycelium_version
|
||||||
hp.mycelium_config.ipv6_range = mycelium_ipv6_range
|
hp.mycelium_ipv6_range = mycelium_ipv6_range
|
||||||
hp.mycelium_config.key_path = mycelium_key_path
|
hp.mycelium_key_path = mycelium_key_path
|
||||||
hp.mycelium_config.peers = peers_array
|
hp.mycelium_peers = peers_array
|
||||||
|
|
||||||
// Initialize Mycelium if not already done
|
// Initialize Mycelium if not already done
|
||||||
hp.mycelium_init()!
|
hp.mycelium_init()!
|
||||||
|
|||||||
@@ -12,17 +12,8 @@ pub const version = '0.0.0'
|
|||||||
const singleton = false
|
const singleton = false
|
||||||
const default = true
|
const default = true
|
||||||
|
|
||||||
// MyceliumConfig holds Mycelium IPv6 overlay network configuration
|
// MyceliumConfig holds Mycelium IPv6 overlay network configuration (flattened into HeroPods struct)
|
||||||
struct MyceliumConfig {
|
// Note: These fields are flattened to avoid nested struct serialization issues with encoderhero
|
||||||
pub mut:
|
|
||||||
enabled bool // Whether Mycelium is enabled
|
|
||||||
version string // Mycelium version to install (e.g., 'v0.5.6')
|
|
||||||
ipv6_range string // Mycelium IPv6 address range (e.g., '400::/7')
|
|
||||||
peers []string // Mycelium peer addresses
|
|
||||||
key_path string // Path to Mycelium private key
|
|
||||||
mycelium_ip6 string // Host's Mycelium IPv6 address (cached)
|
|
||||||
interface_name string // Mycelium TUN interface name (e.g., "mycelium0")
|
|
||||||
}
|
|
||||||
|
|
||||||
// HeroPods factory for managing containers
|
// HeroPods factory for managing containers
|
||||||
//
|
//
|
||||||
@@ -33,18 +24,25 @@ pub mut:
|
|||||||
@[heap]
|
@[heap]
|
||||||
pub struct HeroPods {
|
pub struct HeroPods {
|
||||||
pub mut:
|
pub mut:
|
||||||
tmux_session string // tmux session name
|
tmux_session string // tmux session name
|
||||||
containers map[string]&Container // name -> container mapping
|
containers map[string]&Container // name -> container mapping
|
||||||
images map[string]&ContainerImage // name -> image mapping
|
images map[string]&ContainerImage // name -> image mapping
|
||||||
crun_configs map[string]&crun.CrunConfig // name -> crun config mapping
|
crun_configs map[string]&crun.CrunConfig // name -> crun config mapping
|
||||||
base_dir string // base directory for all container data
|
base_dir string // base directory for all container data
|
||||||
reset bool // will reset the heropods
|
reset bool // will reset the heropods
|
||||||
use_podman bool = true // will use podman for image management
|
use_podman bool = true // will use podman for image management
|
||||||
name string // name of the heropods
|
name string // name of the heropods
|
||||||
network_config NetworkConfig @[skip; str: skip] // network configuration (automatically initialized, not serialized)
|
network_config NetworkConfig @[skip; str: skip] // network configuration (automatically initialized, not serialized)
|
||||||
network_mutex sync.Mutex @[skip; str: skip] // protects network_config for thread-safe concurrent access
|
network_mutex sync.Mutex @[skip; str: skip] // protects network_config for thread-safe concurrent access
|
||||||
mycelium_config MyceliumConfig // mycelium IPv6 overlay network configuration
|
// Mycelium IPv6 overlay network configuration (flattened fields)
|
||||||
logger logger.Logger @[skip; str: skip] // logger instance for debugging (not serialized)
|
mycelium_enabled bool // Whether Mycelium is enabled
|
||||||
|
mycelium_version string // Mycelium version to install (e.g., 'v0.5.6')
|
||||||
|
mycelium_ipv6_range string // Mycelium IPv6 address range (e.g., '400::/7')
|
||||||
|
mycelium_peers []string // Mycelium peer addresses
|
||||||
|
mycelium_key_path string // Path to Mycelium private key
|
||||||
|
mycelium_ip6 string // Host's Mycelium IPv6 address (cached)
|
||||||
|
mycelium_interface_name string // Mycelium TUN interface name (e.g., "mycelium0")
|
||||||
|
logger logger.Logger @[skip; str: skip] // logger instance for debugging (not serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
// obj_init performs lightweight validation and field normalization only
|
// obj_init performs lightweight validation and field normalization only
|
||||||
@@ -83,8 +81,8 @@ fn obj_init(mycfg_ HeroPods) !HeroPods {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize Mycelium configuration defaults (only for non-required fields)
|
// Initialize Mycelium configuration defaults (only for non-required fields)
|
||||||
if mycfg.mycelium_config.interface_name == '' {
|
if mycfg.mycelium_interface_name == '' {
|
||||||
mycfg.mycelium_config.interface_name = 'mycelium0'
|
mycfg.mycelium_interface_name = 'mycelium0'
|
||||||
}
|
}
|
||||||
|
|
||||||
return mycfg
|
return mycfg
|
||||||
@@ -123,7 +121,7 @@ fn (mut self HeroPods) initialize() ! {
|
|||||||
self.network_init()!
|
self.network_init()!
|
||||||
|
|
||||||
// Initialize Mycelium IPv6 overlay network if enabled
|
// Initialize Mycelium IPv6 overlay network if enabled
|
||||||
if self.mycelium_config.enabled {
|
if self.mycelium_enabled {
|
||||||
self.mycelium_init()!
|
self.mycelium_init()!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,36 +2,38 @@ module heropods
|
|||||||
|
|
||||||
import incubaid.herolib.osal.core as osal
|
import incubaid.herolib.osal.core as osal
|
||||||
import incubaid.herolib.clients.mycelium
|
import incubaid.herolib.clients.mycelium
|
||||||
import incubaid.herolib.installers.net.mycelium_installer
|
|
||||||
import time
|
|
||||||
import crypto.sha256
|
import crypto.sha256
|
||||||
|
|
||||||
// Initialize Mycelium for HeroPods
|
// Initialize Mycelium for HeroPods
|
||||||
//
|
//
|
||||||
// This method:
|
// This method:
|
||||||
// 1. Validates required configuration
|
// 1. Validates required configuration
|
||||||
// 2. Installs Mycelium binary if not present
|
// 2. Checks that Mycelium binary is installed
|
||||||
// 3. Starts Mycelium service with configured peers
|
// 3. Checks that Mycelium service is running
|
||||||
// 4. Retrieves the host's Mycelium IPv6 address
|
// 4. Retrieves the host's Mycelium IPv6 address
|
||||||
//
|
//
|
||||||
|
// Prerequisites:
|
||||||
|
// - Mycelium must be installed on the system
|
||||||
|
// - Mycelium service must be running
|
||||||
|
//
|
||||||
// Thread Safety:
|
// Thread Safety:
|
||||||
// This is called during HeroPods initialization, before any concurrent operations.
|
// This is called during HeroPods initialization, before any concurrent operations.
|
||||||
fn (mut self HeroPods) mycelium_init() ! {
|
fn (mut self HeroPods) mycelium_init() ! {
|
||||||
if !self.mycelium_config.enabled {
|
if !self.mycelium_enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate required configuration
|
// Validate required configuration
|
||||||
if self.mycelium_config.version == '' {
|
if self.mycelium_version == '' {
|
||||||
return error('Mycelium configuration error: "version" is required. Use heropods.enable_mycelium to configure.')
|
return error('Mycelium configuration error: "version" is required. Use heropods.enable_mycelium to configure.')
|
||||||
}
|
}
|
||||||
if self.mycelium_config.ipv6_range == '' {
|
if self.mycelium_ipv6_range == '' {
|
||||||
return error('Mycelium configuration error: "ipv6_range" is required. Use heropods.enable_mycelium to configure.')
|
return error('Mycelium configuration error: "ipv6_range" is required. Use heropods.enable_mycelium to configure.')
|
||||||
}
|
}
|
||||||
if self.mycelium_config.key_path == '' {
|
if self.mycelium_key_path == '' {
|
||||||
return error('Mycelium configuration error: "key_path" is required. Use heropods.enable_mycelium to configure.')
|
return error('Mycelium configuration error: "key_path" is required. Use heropods.enable_mycelium to configure.')
|
||||||
}
|
}
|
||||||
if self.mycelium_config.peers.len == 0 {
|
if self.mycelium_peers.len == 0 {
|
||||||
return error('Mycelium configuration error: "peers" is required. Use heropods.enable_mycelium to configure.')
|
return error('Mycelium configuration error: "peers" is required. Use heropods.enable_mycelium to configure.')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,39 +42,34 @@ fn (mut self HeroPods) mycelium_init() ! {
|
|||||||
log: 'START mycelium_init() - Initializing Mycelium IPv6 overlay network'
|
log: 'START mycelium_init() - Initializing Mycelium IPv6 overlay network'
|
||||||
) or {}
|
) or {}
|
||||||
|
|
||||||
// Check if Mycelium is already installed and running
|
// Check if Mycelium is installed - it's a prerequisite
|
||||||
if mycelium_installed := self.mycelium_check_installed() {
|
if !self.mycelium_check_installed()! {
|
||||||
if mycelium_installed {
|
return error('Mycelium is not installed. Please install Mycelium first. See: https://github.com/threefoldtech/mycelium')
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Mycelium is already installed'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
} else {
|
|
||||||
// Install Mycelium
|
|
||||||
self.mycelium_install()!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start Mycelium service if not running
|
self.logger.log(
|
||||||
if mycelium_running := self.mycelium_check_running() {
|
cat: 'mycelium'
|
||||||
if mycelium_running {
|
log: 'Mycelium binary found'
|
||||||
self.logger.log(
|
logtype: .stdout
|
||||||
cat: 'mycelium'
|
) or {}
|
||||||
log: 'Mycelium service is already running'
|
|
||||||
logtype: .stdout
|
// Check if Mycelium service is running - it's a prerequisite
|
||||||
) or {}
|
if !self.mycelium_check_running()! {
|
||||||
} else {
|
return error('Mycelium service is not running. Please start Mycelium service first (e.g., mycelium --key-file ${self.mycelium_key_path} --peers <peers>)')
|
||||||
self.mycelium_start_service()!
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.logger.log(
|
||||||
|
cat: 'mycelium'
|
||||||
|
log: 'Mycelium service is running'
|
||||||
|
logtype: .stdout
|
||||||
|
) or {}
|
||||||
|
|
||||||
// Get and cache the host's Mycelium IPv6 address
|
// Get and cache the host's Mycelium IPv6 address
|
||||||
self.mycelium_get_host_address()!
|
self.mycelium_get_host_address()!
|
||||||
|
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
cat: 'mycelium'
|
cat: 'mycelium'
|
||||||
log: 'END mycelium_init() - Mycelium initialized successfully with address ${self.mycelium_config.mycelium_ip6}'
|
log: 'END mycelium_init() - Mycelium initialized successfully with address ${self.mycelium_ip6}'
|
||||||
logtype: .stdout
|
logtype: .stdout
|
||||||
) or {}
|
) or {}
|
||||||
}
|
}
|
||||||
@@ -85,67 +82,10 @@ fn (mut self HeroPods) mycelium_check_installed() !bool {
|
|||||||
// Check if Mycelium service is running
|
// Check if Mycelium service is running
|
||||||
fn (mut self HeroPods) mycelium_check_running() !bool {
|
fn (mut self HeroPods) mycelium_check_running() !bool {
|
||||||
// Try to inspect Mycelium - if it succeeds, it's running
|
// Try to inspect Mycelium - if it succeeds, it's running
|
||||||
mycelium.inspect(key_file_path: self.mycelium_config.key_path) or { return false }
|
mycelium.inspect(key_file_path: self.mycelium_key_path) or { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install Mycelium binary
|
|
||||||
fn (mut self HeroPods) mycelium_install() ! {
|
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Installing Mycelium ${self.mycelium_config.version}...'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
|
|
||||||
// Use the mycelium_installer to install
|
|
||||||
mut installer := mycelium_installer.get(create: true)!
|
|
||||||
installer.peers = self.mycelium_config.peers
|
|
||||||
|
|
||||||
// Install Mycelium using the instance method
|
|
||||||
installer.install(reset: false)!
|
|
||||||
|
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Mycelium installed successfully'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start Mycelium service
|
|
||||||
fn (mut self HeroPods) mycelium_start_service() ! {
|
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Starting Mycelium service...'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
|
|
||||||
// Use the mycelium_installer to start the service
|
|
||||||
mut installer := mycelium_installer.get()!
|
|
||||||
installer.start()!
|
|
||||||
|
|
||||||
// Wait for Mycelium to be ready
|
|
||||||
for i in 0 .. 50 {
|
|
||||||
if self.mycelium_check_running()! {
|
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Mycelium service started successfully'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if i % 10 == 0 {
|
|
||||||
self.logger.log(
|
|
||||||
cat: 'mycelium'
|
|
||||||
log: 'Waiting for Mycelium service to start... (${i}/50)'
|
|
||||||
logtype: .stdout
|
|
||||||
) or {}
|
|
||||||
}
|
|
||||||
time.sleep(100 * time.millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
return error('Mycelium service failed to start after 5 seconds')
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the host's Mycelium IPv6 address
|
// Get the host's Mycelium IPv6 address
|
||||||
fn (mut self HeroPods) mycelium_get_host_address() ! {
|
fn (mut self HeroPods) mycelium_get_host_address() ! {
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
@@ -155,17 +95,17 @@ fn (mut self HeroPods) mycelium_get_host_address() ! {
|
|||||||
) or {}
|
) or {}
|
||||||
|
|
||||||
// Use mycelium inspect to get the address
|
// Use mycelium inspect to get the address
|
||||||
inspect_result := mycelium.inspect(key_file_path: self.mycelium_config.key_path)!
|
inspect_result := mycelium.inspect(key_file_path: self.mycelium_key_path)!
|
||||||
|
|
||||||
if inspect_result.address == '' {
|
if inspect_result.address == '' {
|
||||||
return error('Failed to get Mycelium IPv6 address from inspect')
|
return error('Failed to get Mycelium IPv6 address from inspect')
|
||||||
}
|
}
|
||||||
|
|
||||||
self.mycelium_config.mycelium_ip6 = inspect_result.address
|
self.mycelium_ip6 = inspect_result.address
|
||||||
|
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
cat: 'mycelium'
|
cat: 'mycelium'
|
||||||
log: 'Host Mycelium IPv6 address: ${self.mycelium_config.mycelium_ip6}'
|
log: 'Host Mycelium IPv6 address: ${self.mycelium_ip6}'
|
||||||
logtype: .stdout
|
logtype: .stdout
|
||||||
) or {}
|
) or {}
|
||||||
}
|
}
|
||||||
@@ -182,7 +122,7 @@ fn (mut self HeroPods) mycelium_get_host_address() ! {
|
|||||||
// This is called from container.start() which is already serialized per container.
|
// This is called from container.start() which is already serialized per container.
|
||||||
// Multiple containers can be started concurrently, each with their own veth pair.
|
// Multiple containers can be started concurrently, each with their own veth pair.
|
||||||
fn (mut self HeroPods) mycelium_setup_container(container_name string, container_pid int) ! {
|
fn (mut self HeroPods) mycelium_setup_container(container_name string, container_pid int) ! {
|
||||||
if !self.mycelium_config.enabled {
|
if !self.mycelium_enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,12 +220,12 @@ fn (mut self HeroPods) mycelium_setup_container(container_name string, container
|
|||||||
// Add route in container for Mycelium traffic (400::/7 via link-local)
|
// Add route in container for Mycelium traffic (400::/7 via link-local)
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
cat: 'mycelium'
|
cat: 'mycelium'
|
||||||
log: 'Adding route for ${self.mycelium_config.ipv6_range} via ${veth_host_ll}'
|
log: 'Adding route for ${self.mycelium_ipv6_range} via ${veth_host_ll}'
|
||||||
logtype: .stdout
|
logtype: .stdout
|
||||||
) or {}
|
) or {}
|
||||||
|
|
||||||
osal.exec(
|
osal.exec(
|
||||||
cmd: 'nsenter -t ${container_pid} -n ip route add ${self.mycelium_config.ipv6_range} via ${veth_host_ll} dev ${veth_container}'
|
cmd: 'nsenter -t ${container_pid} -n ip route add ${self.mycelium_ipv6_range} via ${veth_host_ll} dev ${veth_container}'
|
||||||
stdout: false
|
stdout: false
|
||||||
)!
|
)!
|
||||||
|
|
||||||
@@ -313,14 +253,14 @@ fn (mut self HeroPods) mycelium_setup_container(container_name string, container
|
|||||||
// Extracts the /64 prefix from the full IPv6 address
|
// Extracts the /64 prefix from the full IPv6 address
|
||||||
// Example: "400:1234:5678::1" -> "400:1234:5678:"
|
// Example: "400:1234:5678::1" -> "400:1234:5678:"
|
||||||
fn (mut self HeroPods) mycelium_get_ipv6_prefix() !string {
|
fn (mut self HeroPods) mycelium_get_ipv6_prefix() !string {
|
||||||
if self.mycelium_config.mycelium_ip6 == '' {
|
if self.mycelium_ip6 == '' {
|
||||||
return error('Mycelium IPv6 address not set')
|
return error('Mycelium IPv6 address not set')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split the address by ':' and take the first 3 parts for /64 prefix
|
// Split the address by ':' and take the first 3 parts for /64 prefix
|
||||||
parts := self.mycelium_config.mycelium_ip6.split(':')
|
parts := self.mycelium_ip6.split(':')
|
||||||
if parts.len < 3 {
|
if parts.len < 3 {
|
||||||
return error('Invalid Mycelium IPv6 address format: ${self.mycelium_config.mycelium_ip6}')
|
return error('Invalid Mycelium IPv6 address format: ${self.mycelium_ip6}')
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconstruct the prefix (first 3 parts)
|
// Reconstruct the prefix (first 3 parts)
|
||||||
@@ -369,7 +309,7 @@ fn (mut self HeroPods) mycelium_get_link_local_address(interface_name string) !s
|
|||||||
// Thread Safety:
|
// Thread Safety:
|
||||||
// This is called from container.stop() and container.delete() which are serialized per container.
|
// This is called from container.stop() and container.delete() which are serialized per container.
|
||||||
fn (mut self HeroPods) mycelium_cleanup_container(container_name string) ! {
|
fn (mut self HeroPods) mycelium_cleanup_container(container_name string) ! {
|
||||||
if !self.mycelium_config.enabled {
|
if !self.mycelium_enabled {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,9 +354,9 @@ fn (mut self HeroPods) mycelium_cleanup_container(container_name string) ! {
|
|||||||
//
|
//
|
||||||
// Returns the public key and IPv6 address of the Mycelium node
|
// Returns the public key and IPv6 address of the Mycelium node
|
||||||
pub fn (mut self HeroPods) mycelium_inspect() !mycelium.MyceliumInspectResult {
|
pub fn (mut self HeroPods) mycelium_inspect() !mycelium.MyceliumInspectResult {
|
||||||
if !self.mycelium_config.enabled {
|
if !self.mycelium_enabled {
|
||||||
return error('Mycelium is not enabled')
|
return error('Mycelium is not enabled')
|
||||||
}
|
}
|
||||||
|
|
||||||
return mycelium.inspect(key_file_path: self.mycelium_config.key_path)!
|
return mycelium.inspect(key_file_path: self.mycelium_key_path)!
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user