Complete BZZZ functionality port to CHORUS

🎭 CHORUS now contains full BZZZ functionality adapted for containers

Core systems ported:
- P2P networking (libp2p with DHT and PubSub)
- Task coordination (COOEE protocol)
- HMMM collaborative reasoning
- SHHH encryption and security
- SLURP admin election system
- UCXL content addressing
- UCXI server integration
- Hypercore logging system
- Health monitoring and graceful shutdown
- License validation with KACHING

Container adaptations:
- Environment variable configuration (no YAML files)
- Container-optimized logging to stdout/stderr
- Auto-generated agent IDs for container deployments
- Docker-first architecture

All proven BZZZ P2P protocols, AI integration, and collaboration
features are now available in containerized form.

Next: Build and test container deployment.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-02 20:02:37 +10:00
parent 7c6cbd562a
commit 543ab216f9
224 changed files with 86331 additions and 186 deletions

289
pkg/ucxi/storage.go Normal file
View File

@@ -0,0 +1,289 @@
package ucxi
import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
)
// BasicContentStorage provides a basic file-system based implementation of ContentStorage
type BasicContentStorage struct {
basePath string
mutex sync.RWMutex
}
// NewBasicContentStorage creates a new basic content storage
func NewBasicContentStorage(basePath string) (*BasicContentStorage, error) {
// Ensure base directory exists
if err := os.MkdirAll(basePath, 0755); err != nil {
return nil, fmt.Errorf("failed to create storage directory: %w", err)
}
return &BasicContentStorage{
basePath: basePath,
}, nil
}
// Store stores content with the given key
func (s *BasicContentStorage) Store(ctx context.Context, key string, content *Content) error {
if key == "" {
return fmt.Errorf("key cannot be empty")
}
if content == nil {
return fmt.Errorf("content cannot be nil")
}
s.mutex.Lock()
defer s.mutex.Unlock()
// Generate file path
filePath := s.getFilePath(key)
// Ensure directory exists
dir := filepath.Dir(filePath)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed to create directory %s: %w", dir, err)
}
// Calculate checksum if not provided
if content.Checksum == "" {
hash := sha256.Sum256(content.Data)
content.Checksum = hex.EncodeToString(hash[:])
}
// Serialize content to JSON
data, err := json.MarshalIndent(content, "", " ")
if err != nil {
return fmt.Errorf("failed to serialize content: %w", err)
}
// Write to file
if err := ioutil.WriteFile(filePath, data, 0644); err != nil {
return fmt.Errorf("failed to write content file: %w", err)
}
return nil
}
// Retrieve retrieves content by key
func (s *BasicContentStorage) Retrieve(ctx context.Context, key string) (*Content, error) {
if key == "" {
return nil, fmt.Errorf("key cannot be empty")
}
s.mutex.RLock()
defer s.mutex.RUnlock()
filePath := s.getFilePath(key)
// Check if file exists
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return nil, fmt.Errorf("content not found for key: %s", key)
}
// Read file
data, err := ioutil.ReadFile(filePath)
if err != nil {
return nil, fmt.Errorf("failed to read content file: %w", err)
}
// Deserialize content
var content Content
if err := json.Unmarshal(data, &content); err != nil {
return nil, fmt.Errorf("failed to deserialize content: %w", err)
}
// Verify checksum if available
if content.Checksum != "" {
hash := sha256.Sum256(content.Data)
expectedChecksum := hex.EncodeToString(hash[:])
if content.Checksum != expectedChecksum {
return nil, fmt.Errorf("content checksum mismatch")
}
}
return &content, nil
}
// Delete deletes content by key
func (s *BasicContentStorage) Delete(ctx context.Context, key string) error {
if key == "" {
return fmt.Errorf("key cannot be empty")
}
s.mutex.Lock()
defer s.mutex.Unlock()
filePath := s.getFilePath(key)
// Check if file exists
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return fmt.Errorf("content not found for key: %s", key)
}
// Remove file
if err := os.Remove(filePath); err != nil {
return fmt.Errorf("failed to delete content file: %w", err)
}
// Try to remove empty directories
s.cleanupEmptyDirs(filepath.Dir(filePath))
return nil
}
// List lists all keys with the given prefix
func (s *BasicContentStorage) List(ctx context.Context, prefix string) ([]string, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
var keys []string
// Walk through storage directory
err := filepath.Walk(s.basePath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
// Skip directories
if info.IsDir() {
return nil
}
// Skip non-JSON files
if !strings.HasSuffix(path, ".json") {
return nil
}
// Convert file path back to key
relPath, err := filepath.Rel(s.basePath, path)
if err != nil {
return err
}
// Remove .json extension
key := strings.TrimSuffix(relPath, ".json")
// Convert file path separators back to key format
key = strings.ReplaceAll(key, string(filepath.Separator), "/")
// Check prefix match
if prefix == "" || strings.HasPrefix(key, prefix) {
keys = append(keys, key)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to list storage contents: %w", err)
}
return keys, nil
}
// getFilePath converts a storage key to a file path
func (s *BasicContentStorage) getFilePath(key string) string {
// Sanitize key by replacing potentially problematic characters
sanitized := strings.ReplaceAll(key, ":", "_")
sanitized = strings.ReplaceAll(sanitized, "@", "_at_")
sanitized = strings.ReplaceAll(sanitized, "/", string(filepath.Separator))
return filepath.Join(s.basePath, sanitized+".json")
}
// cleanupEmptyDirs removes empty directories up the tree
func (s *BasicContentStorage) cleanupEmptyDirs(dir string) {
// Don't remove the base directory
if dir == s.basePath {
return
}
// Try to remove directory if empty
if err := os.Remove(dir); err == nil {
// Successfully removed, try parent
s.cleanupEmptyDirs(filepath.Dir(dir))
}
}
// GetStorageStats returns statistics about the storage
func (s *BasicContentStorage) GetStorageStats() (map[string]interface{}, error) {
s.mutex.RLock()
defer s.mutex.RUnlock()
var fileCount int
var totalSize int64
err := filepath.Walk(s.basePath, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if !info.IsDir() && strings.HasSuffix(path, ".json") {
fileCount++
totalSize += info.Size()
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to calculate storage stats: %w", err)
}
return map[string]interface{}{
"file_count": fileCount,
"total_size": totalSize,
"base_path": s.basePath,
}, nil
}
// Exists checks if content exists for the given key
func (s *BasicContentStorage) Exists(ctx context.Context, key string) (bool, error) {
if key == "" {
return false, fmt.Errorf("key cannot be empty")
}
filePath := s.getFilePath(key)
s.mutex.RLock()
defer s.mutex.RUnlock()
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
return false, nil
}
if err != nil {
return false, fmt.Errorf("failed to check file existence: %w", err)
}
return true, nil
}
// Clear removes all content from storage
func (s *BasicContentStorage) Clear(ctx context.Context) error {
s.mutex.Lock()
defer s.mutex.Unlock()
// Remove all contents of base directory
entries, err := ioutil.ReadDir(s.basePath)
if err != nil {
return fmt.Errorf("failed to read storage directory: %w", err)
}
for _, entry := range entries {
path := filepath.Join(s.basePath, entry.Name())
if err := os.RemoveAll(path); err != nil {
return fmt.Errorf("failed to remove %s: %w", path, err)
}
}
return nil
}