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:
Mahmoud-Emad
2025-11-19 15:17:39 +02:00
parent 1452d65f48
commit df462174e5
6 changed files with 113 additions and 175 deletions

View File

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

View File

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

View File

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

View File

@@ -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()!

View File

@@ -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()!
} }

View File

@@ -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)!
} }