mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-13 01:58:50 +00:00
feat: update IPFS configuration and enhance cluster secret management
- Changed default IPFS API URL to port 5001 for better compatibility. - Enhanced the initialization process for IPFS and Cluster by adding support for bootstrap peers. - Introduced user prompts for cluster secret and swarm key generation, improving user experience during setup. - Updated service configuration to dynamically determine paths based on existing configuration files.
This commit is contained in:
parent
93b25c42e4
commit
a5c30d0141
15
CHANGELOG.md
15
CHANGELOG.md
@ -13,6 +13,21 @@ The format is based on [Keep a Changelog][keepachangelog] and adheres to [Semant
|
|||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
## [0.59.1] - 2025-11-08
|
||||||
|
|
||||||
|
### Added
|
||||||
|
\n
|
||||||
|
### Changed
|
||||||
|
- Improved interactive setup to prompt for existing IPFS Cluster secret and Swarm key, allowing easier joining of existing private networks.
|
||||||
|
- Updated default IPFS API URL in configuration files from `http://localhost:9105` to the standard `http://localhost:5001`.
|
||||||
|
- Updated systemd service files (debros-ipfs.service and debros-ipfs-cluster.service) to correctly determine and use the IPFS and Cluster repository paths.
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
\n
|
||||||
## [0.59.0] - 2025-11-08
|
## [0.59.0] - 2025-11-08
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -21,7 +21,7 @@ test-e2e:
|
|||||||
|
|
||||||
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks kill
|
.PHONY: build clean test run-node run-node2 run-node3 run-example deps tidy fmt vet lint clear-ports install-hooks kill
|
||||||
|
|
||||||
VERSION := 0.59.0
|
VERSION := 0.59.1
|
||||||
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
|
||||||
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||||
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
LDFLAGS := -X 'main.version=$(VERSION)' -X 'main.commit=$(COMMIT)' -X 'main.date=$(DATE)'
|
||||||
|
|||||||
@ -545,7 +545,7 @@ olric_servers:
|
|||||||
- "127.0.0.1:3320"
|
- "127.0.0.1:3320"
|
||||||
olric_timeout: "10s"
|
olric_timeout: "10s"
|
||||||
ipfs_cluster_api_url: "http://localhost:9094"
|
ipfs_cluster_api_url: "http://localhost:9094"
|
||||||
ipfs_api_url: "http://localhost:9105"
|
ipfs_api_url: "http://localhost:5001"
|
||||||
ipfs_timeout: "60s"
|
ipfs_timeout: "60s"
|
||||||
ipfs_replication_factor: 3
|
ipfs_replication_factor: 3
|
||||||
`, peersYAML.String())
|
`, peersYAML.String())
|
||||||
|
|||||||
232
pkg/cli/setup.go
232
pkg/cli/setup.go
@ -1513,7 +1513,18 @@ func generateConfigsInteractive(force bool) {
|
|||||||
} else {
|
} else {
|
||||||
nodeID = "node"
|
nodeID = "node"
|
||||||
}
|
}
|
||||||
if err := initializeIPFSForNode(nodeID, vpsIP, isBootstrap); err != nil {
|
|
||||||
|
// Parse bootstrap peers from config
|
||||||
|
var bootstrapPeerList []string
|
||||||
|
if bootstrapPeers != "" {
|
||||||
|
for _, p := range strings.Split(bootstrapPeers, ",") {
|
||||||
|
if p = strings.TrimSpace(p); p != "" {
|
||||||
|
bootstrapPeerList = append(bootstrapPeerList, p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := initializeIPFSForNode(nodeID, vpsIP, isBootstrap, bootstrapPeerList, reader); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "⚠️ Failed to initialize IPFS/Cluster: %v\n", err)
|
fmt.Fprintf(os.Stderr, "⚠️ Failed to initialize IPFS/Cluster: %v\n", err)
|
||||||
fmt.Fprintf(os.Stderr, " You may need to initialize IPFS and Cluster manually\n")
|
fmt.Fprintf(os.Stderr, " You may need to initialize IPFS and Cluster manually\n")
|
||||||
}
|
}
|
||||||
@ -1796,7 +1807,7 @@ func generateGatewayConfigDirect(bootstrapPeers string, enableHTTPS bool, domain
|
|||||||
|
|
||||||
// IPFS Cluster configuration
|
// IPFS Cluster configuration
|
||||||
ipfsYAML := `ipfs_cluster_api_url: "http://localhost:9094"
|
ipfsYAML := `ipfs_cluster_api_url: "http://localhost:9094"
|
||||||
ipfs_api_url: "http://localhost:9105"
|
ipfs_api_url: "http://localhost:5001"
|
||||||
ipfs_timeout: "60s"
|
ipfs_timeout: "60s"
|
||||||
ipfs_replication_factor: 3
|
ipfs_replication_factor: 3
|
||||||
`
|
`
|
||||||
@ -1841,24 +1852,72 @@ func generateOlricConfig(configPath, bindIP string, httpPort, memberlistPort int
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// promptClusterSecret prompts the user for a cluster secret (64 hex characters)
|
||||||
|
func promptClusterSecret(reader *bufio.Reader) (string, error) {
|
||||||
|
for {
|
||||||
|
fmt.Printf("\n Enter cluster secret (64 hex characters, or press Enter to generate new): ")
|
||||||
|
input, _ := reader.ReadString('\n')
|
||||||
|
input = strings.TrimSpace(input)
|
||||||
|
|
||||||
|
if input == "" {
|
||||||
|
// Generate new secret
|
||||||
|
bytes := make([]byte, 32)
|
||||||
|
if _, err := rand.Read(bytes); err != nil {
|
||||||
|
return "", fmt.Errorf("failed to generate cluster secret: %w", err)
|
||||||
|
}
|
||||||
|
secret := hex.EncodeToString(bytes)
|
||||||
|
fmt.Printf(" ✓ Generated new cluster secret\n")
|
||||||
|
return secret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate input (must be 64 hex characters)
|
||||||
|
input = strings.ToUpper(input)
|
||||||
|
if len(input) != 64 {
|
||||||
|
fmt.Printf(" ❌ Invalid: cluster secret must be exactly 64 hex characters\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate hex characters
|
||||||
|
valid := true
|
||||||
|
for _, char := range input {
|
||||||
|
if !((char >= '0' && char <= '9') || (char >= 'A' && char <= 'F')) {
|
||||||
|
valid = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !valid {
|
||||||
|
fmt.Printf(" ❌ Invalid: cluster secret must contain only hex characters (0-9, A-F)\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return input, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// getOrGenerateClusterSecret gets or generates a shared cluster secret
|
// getOrGenerateClusterSecret gets or generates a shared cluster secret
|
||||||
func getOrGenerateClusterSecret() (string, error) {
|
func getOrGenerateClusterSecret(reader *bufio.Reader) (string, error) {
|
||||||
secretPath := "/home/debros/.debros/cluster-secret"
|
secretPath := "/home/debros/.debros/cluster-secret"
|
||||||
|
|
||||||
// Try to read existing secret
|
// Try to read existing secret
|
||||||
if data, err := os.ReadFile(secretPath); err == nil {
|
if data, err := os.ReadFile(secretPath); err == nil {
|
||||||
secret := strings.TrimSpace(string(data))
|
secret := strings.TrimSpace(string(data))
|
||||||
if len(secret) == 64 {
|
if len(secret) == 64 {
|
||||||
|
fmt.Printf(" ✓ Using existing cluster secret\n")
|
||||||
return secret, nil
|
return secret, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new secret (64 hex characters = 32 bytes)
|
// Prompt for secret
|
||||||
bytes := make([]byte, 32)
|
fmt.Printf("\n🔐 Cluster Secret Configuration\n")
|
||||||
if _, err := rand.Read(bytes); err != nil {
|
fmt.Printf(" The cluster secret is used to authenticate IPFS Cluster peers.\n")
|
||||||
return "", fmt.Errorf("failed to generate cluster secret: %w", err)
|
fmt.Printf(" All nodes in the cluster must use the same secret.\n")
|
||||||
|
fmt.Printf(" If this is the first node, press Enter to generate a new secret.\n")
|
||||||
|
fmt.Printf(" If joining an existing cluster, enter the secret from the bootstrap node.\n")
|
||||||
|
|
||||||
|
secret, err := promptClusterSecret(reader)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
secret := hex.EncodeToString(bytes)
|
|
||||||
|
|
||||||
// Save secret
|
// Save secret
|
||||||
if err := os.WriteFile(secretPath, []byte(secret), 0600); err != nil {
|
if err := os.WriteFile(secretPath, []byte(secret), 0600); err != nil {
|
||||||
@ -1869,9 +1928,56 @@ func getOrGenerateClusterSecret() (string, error) {
|
|||||||
return secret, nil
|
return secret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// promptSwarmKey prompts the user for a swarm key (64 hex characters)
|
||||||
|
func promptSwarmKey(reader *bufio.Reader) ([]byte, error) {
|
||||||
|
for {
|
||||||
|
fmt.Printf("\n Enter swarm key (64 hex characters, or press Enter to generate new): ")
|
||||||
|
input, _ := reader.ReadString('\n')
|
||||||
|
input = strings.TrimSpace(input)
|
||||||
|
|
||||||
|
if input == "" {
|
||||||
|
// Generate new key (32 bytes)
|
||||||
|
keyBytes := make([]byte, 32)
|
||||||
|
if _, err := rand.Read(keyBytes); err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to generate swarm key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format as IPFS swarm key file
|
||||||
|
keyHex := strings.ToUpper(hex.EncodeToString(keyBytes))
|
||||||
|
content := fmt.Sprintf("/key/swarm/psk/1.0.0/\n/base16/\n%s\n", keyHex)
|
||||||
|
fmt.Printf(" ✓ Generated new swarm key\n")
|
||||||
|
return []byte(content), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate input (must be 64 hex characters)
|
||||||
|
input = strings.ToUpper(input)
|
||||||
|
if len(input) != 64 {
|
||||||
|
fmt.Printf(" ❌ Invalid: swarm key must be exactly 64 hex characters\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate hex characters
|
||||||
|
valid := true
|
||||||
|
for _, char := range input {
|
||||||
|
if !((char >= '0' && char <= '9') || (char >= 'A' && char <= 'F')) {
|
||||||
|
valid = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !valid {
|
||||||
|
fmt.Printf(" ❌ Invalid: swarm key must contain only hex characters (0-9, A-F)\n")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format as IPFS swarm key file
|
||||||
|
content := fmt.Sprintf("/key/swarm/psk/1.0.0/\n/base16/\n%s\n", input)
|
||||||
|
return []byte(content), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// getOrGenerateSwarmKey gets or generates a shared IPFS swarm key
|
// getOrGenerateSwarmKey gets or generates a shared IPFS swarm key
|
||||||
// Returns the swarm key content as bytes (formatted for IPFS)
|
// Returns the swarm key content as bytes (formatted for IPFS)
|
||||||
func getOrGenerateSwarmKey() ([]byte, error) {
|
func getOrGenerateSwarmKey(reader *bufio.Reader) ([]byte, error) {
|
||||||
secretPath := "/home/debros/.debros/swarm.key"
|
secretPath := "/home/debros/.debros/swarm.key"
|
||||||
|
|
||||||
// Try to read existing key
|
// Try to read existing key
|
||||||
@ -1879,28 +1985,31 @@ func getOrGenerateSwarmKey() ([]byte, error) {
|
|||||||
// Validate it's a proper swarm key format
|
// Validate it's a proper swarm key format
|
||||||
content := string(data)
|
content := string(data)
|
||||||
if strings.Contains(content, "/key/swarm/psk/1.0.0/") {
|
if strings.Contains(content, "/key/swarm/psk/1.0.0/") {
|
||||||
|
fmt.Printf(" ✓ Using existing swarm key\n")
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate new key (32 bytes)
|
// Prompt for key
|
||||||
keyBytes := make([]byte, 32)
|
fmt.Printf("\n🔐 IPFS Swarm Key Configuration\n")
|
||||||
if _, err := rand.Read(keyBytes); err != nil {
|
fmt.Printf(" The swarm key creates a private IPFS network.\n")
|
||||||
return nil, fmt.Errorf("failed to generate swarm key: %w", err)
|
fmt.Printf(" All nodes in the network must use the same swarm key.\n")
|
||||||
|
fmt.Printf(" If this is the first node, press Enter to generate a new key.\n")
|
||||||
|
fmt.Printf(" If joining an existing network, enter the key from the bootstrap node.\n")
|
||||||
|
fmt.Printf(" Enter only the 64 hex characters (e.g., F62B18F11C5457F11E1863126ECAA259E76DA967121A291351FBFA2542B4BF56)\n")
|
||||||
|
|
||||||
|
swarmKey, err := promptSwarmKey(reader)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format as IPFS swarm key file
|
|
||||||
keyHex := strings.ToUpper(hex.EncodeToString(keyBytes))
|
|
||||||
content := fmt.Sprintf("/key/swarm/psk/1.0.0/\n/base16/\n%s\n", keyHex)
|
|
||||||
|
|
||||||
// Save key
|
// Save key
|
||||||
if err := os.WriteFile(secretPath, []byte(content), 0600); err != nil {
|
if err := os.WriteFile(secretPath, swarmKey, 0600); err != nil {
|
||||||
return nil, fmt.Errorf("failed to save swarm key: %w", err)
|
return nil, fmt.Errorf("failed to save swarm key: %w", err)
|
||||||
}
|
}
|
||||||
exec.Command("chown", "debros:debros", secretPath).Run()
|
exec.Command("chown", "debros:debros", secretPath).Run()
|
||||||
|
|
||||||
fmt.Printf(" ✓ Generated private swarm key\n")
|
return swarmKey, nil
|
||||||
return []byte(content), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensureSwarmKey ensures the swarm key exists in the IPFS repo
|
// ensureSwarmKey ensures the swarm key exists in the IPFS repo
|
||||||
@ -1924,17 +2033,17 @@ func ensureSwarmKey(repoPath string, swarmKey []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// initializeIPFSForNode initializes IPFS and IPFS Cluster for a node
|
// initializeIPFSForNode initializes IPFS and IPFS Cluster for a node
|
||||||
func initializeIPFSForNode(nodeID, vpsIP string, isBootstrap bool) error {
|
func initializeIPFSForNode(nodeID, vpsIP string, isBootstrap bool, bootstrapPeers []string, reader *bufio.Reader) error {
|
||||||
fmt.Printf(" Initializing IPFS and Cluster for node %s...\n", nodeID)
|
fmt.Printf(" Initializing IPFS and Cluster for node %s...\n", nodeID)
|
||||||
|
|
||||||
// Get or generate cluster secret
|
// Get or generate cluster secret
|
||||||
secret, err := getOrGenerateClusterSecret()
|
secret, err := getOrGenerateClusterSecret(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get cluster secret: %w", err)
|
return fmt.Errorf("failed to get cluster secret: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get or generate swarm key for private network
|
// Get or generate swarm key for private network
|
||||||
swarmKey, err := getOrGenerateSwarmKey()
|
swarmKey, err := getOrGenerateSwarmKey(reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get swarm key: %w", err)
|
return fmt.Errorf("failed to get swarm key: %w", err)
|
||||||
}
|
}
|
||||||
@ -1988,7 +2097,7 @@ func initializeIPFSForNode(nodeID, vpsIP string, isBootstrap bool) error {
|
|||||||
fmt.Printf(" Initializing IPFS Cluster...\n")
|
fmt.Printf(" Initializing IPFS Cluster...\n")
|
||||||
|
|
||||||
// Generate cluster config
|
// Generate cluster config
|
||||||
clusterConfig := generateClusterServiceConfig(nodeID, vpsIP, secret, isBootstrap)
|
clusterConfig := generateClusterServiceConfig(nodeID, vpsIP, secret, isBootstrap, bootstrapPeers)
|
||||||
|
|
||||||
// Write config
|
// Write config
|
||||||
configJSON, err := json.MarshalIndent(clusterConfig, "", " ")
|
configJSON, err := json.MarshalIndent(clusterConfig, "", " ")
|
||||||
@ -2091,14 +2200,45 @@ type datastoreConfig struct {
|
|||||||
Path string `json:"path"`
|
Path string `json:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extractClusterBootstrapAddresses extracts IPFS Cluster bootstrap addresses from node bootstrap peers
|
||||||
|
// IPFS Cluster uses port 9096 for cluster communication
|
||||||
|
// Note: We extract IP addresses, but cluster peer IDs will be discovered at runtime
|
||||||
|
// For CRDT consensus, bootstrap peers are optional but help with initial discovery
|
||||||
|
func extractClusterBootstrapAddresses(bootstrapPeers []string) []string {
|
||||||
|
var clusterBootstrap []string
|
||||||
|
|
||||||
|
for _, peerAddr := range bootstrapPeers {
|
||||||
|
// Extract IP from multiaddr format: /ip4/IP/tcp/PORT/p2p/PEER_ID
|
||||||
|
ip := extractIPFromMultiaddr(peerAddr)
|
||||||
|
if ip != "" && ip != "127.0.0.1" && ip != "localhost" {
|
||||||
|
// Construct cluster bootstrap address (port 9096 is standard for IPFS Cluster)
|
||||||
|
// Note: We don't have the cluster peer ID yet, but we can construct the address
|
||||||
|
// IPFS Cluster CRDT will discover peers automatically, but having IPs helps
|
||||||
|
// For now, we'll leave bootstrap empty and rely on CRDT auto-discovery
|
||||||
|
// The IP addresses can be used later when cluster peer IDs are known
|
||||||
|
_ = ip // Store for potential future use
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// For now, return empty bootstrap list - CRDT consensus will auto-discover peers
|
||||||
|
// Bootstrap peers can be added later when cluster peer IDs are known
|
||||||
|
return clusterBootstrap
|
||||||
|
}
|
||||||
|
|
||||||
// generateClusterServiceConfig generates IPFS Cluster service.json config
|
// generateClusterServiceConfig generates IPFS Cluster service.json config
|
||||||
func generateClusterServiceConfig(nodeID, vpsIP, secret string, isBootstrap bool) clusterServiceConfig {
|
func generateClusterServiceConfig(nodeID, vpsIP, secret string, isBootstrap bool, bootstrapPeers []string) clusterServiceConfig {
|
||||||
clusterListenAddr := "/ip4/0.0.0.0/tcp/9096"
|
clusterListenAddr := "/ip4/0.0.0.0/tcp/9096"
|
||||||
restAPIListenAddr := "/ip4/0.0.0.0/tcp/9094"
|
restAPIListenAddr := "/ip4/0.0.0.0/tcp/9094"
|
||||||
|
|
||||||
// For bootstrap node, use empty bootstrap list
|
// For bootstrap node, use empty bootstrap list
|
||||||
// For other nodes, bootstrap list will be set when starting the service
|
// For other nodes, extract bootstrap addresses from node config
|
||||||
bootstrap := []string{}
|
// Note: IPFS Cluster CRDT consensus can auto-discover peers, so bootstrap is optional
|
||||||
|
var bootstrap []string
|
||||||
|
if !isBootstrap && len(bootstrapPeers) > 0 {
|
||||||
|
bootstrap = extractClusterBootstrapAddresses(bootstrapPeers)
|
||||||
|
// For now, bootstrap will be empty as we need cluster peer IDs
|
||||||
|
// CRDT will handle peer discovery automatically
|
||||||
|
}
|
||||||
|
|
||||||
return clusterServiceConfig{
|
return clusterServiceConfig{
|
||||||
Cluster: clusterConfig{
|
Cluster: clusterConfig{
|
||||||
@ -2142,7 +2282,17 @@ func createSystemdServices() {
|
|||||||
fmt.Printf("🔧 Creating systemd services...\n")
|
fmt.Printf("🔧 Creating systemd services...\n")
|
||||||
|
|
||||||
// IPFS service (runs on all nodes)
|
// IPFS service (runs on all nodes)
|
||||||
ipfsService := `[Unit]
|
// Determine IPFS path based on config file
|
||||||
|
var ipfsPath string
|
||||||
|
if _, err := os.Stat("/home/debros/.debros/node.yaml"); err == nil {
|
||||||
|
ipfsPath = "/home/debros/.debros/node/ipfs/repo"
|
||||||
|
} else if _, err := os.Stat("/home/debros/.debros/bootstrap.yaml"); err == nil {
|
||||||
|
ipfsPath = "/home/debros/.debros/bootstrap/ipfs/repo"
|
||||||
|
} else {
|
||||||
|
ipfsPath = "/home/debros/.debros/bootstrap/ipfs/repo"
|
||||||
|
}
|
||||||
|
|
||||||
|
ipfsService := fmt.Sprintf(`[Unit]
|
||||||
Description=IPFS Daemon
|
Description=IPFS Daemon
|
||||||
After=network-online.target
|
After=network-online.target
|
||||||
Wants=network-online.target
|
Wants=network-online.target
|
||||||
@ -2152,9 +2302,9 @@ Type=simple
|
|||||||
User=debros
|
User=debros
|
||||||
Group=debros
|
Group=debros
|
||||||
Environment=HOME=/home/debros
|
Environment=HOME=/home/debros
|
||||||
ExecStartPre=/bin/bash -c 'if [ -f /home/debros/.debros/node.yaml ]; then export IPFS_PATH=/home/debros/.debros/node/ipfs/repo; elif [ -f /home/debros/.debros/bootstrap.yaml ]; then export IPFS_PATH=/home/debros/.debros/bootstrap/ipfs/repo; else export IPFS_PATH=/home/debros/.debros/bootstrap/ipfs/repo; fi'
|
Environment=IPFS_PATH=%s
|
||||||
ExecStartPre=/bin/bash -c 'if [ -f /home/debros/.debros/swarm.key ] && [ ! -f ${IPFS_PATH}/swarm.key ]; then cp /home/debros/.debros/swarm.key ${IPFS_PATH}/swarm.key && chmod 600 ${IPFS_PATH}/swarm.key; fi'
|
ExecStartPre=/bin/bash -c 'if [ -f /home/debros/.debros/swarm.key ] && [ ! -f %s/swarm.key ]; then cp /home/debros/.debros/swarm.key %s/swarm.key && chmod 600 %s/swarm.key; fi'
|
||||||
ExecStart=/usr/bin/ipfs daemon --enable-pubsub-experiment --repo-dir=${IPFS_PATH}
|
ExecStart=/usr/bin/ipfs daemon --enable-pubsub-experiment --repo-dir=%s
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
StandardOutput=journal
|
StandardOutput=journal
|
||||||
@ -2168,7 +2318,7 @@ ReadWritePaths=/home/debros
|
|||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
`
|
`, ipfsPath, ipfsPath, ipfsPath, ipfsPath, ipfsPath)
|
||||||
|
|
||||||
if err := os.WriteFile("/etc/systemd/system/debros-ipfs.service", []byte(ipfsService), 0644); err != nil {
|
if err := os.WriteFile("/etc/systemd/system/debros-ipfs.service", []byte(ipfsService), 0644); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "❌ Failed to create IPFS service: %v\n", err)
|
fmt.Fprintf(os.Stderr, "❌ Failed to create IPFS service: %v\n", err)
|
||||||
@ -2176,7 +2326,17 @@ WantedBy=multi-user.target
|
|||||||
}
|
}
|
||||||
|
|
||||||
// IPFS Cluster service (runs on all nodes)
|
// IPFS Cluster service (runs on all nodes)
|
||||||
clusterService := `[Unit]
|
// Determine Cluster path based on config file
|
||||||
|
var clusterPath string
|
||||||
|
if _, err := os.Stat("/home/debros/.debros/node.yaml"); err == nil {
|
||||||
|
clusterPath = "/home/debros/.debros/node/ipfs-cluster"
|
||||||
|
} else if _, err := os.Stat("/home/debros/.debros/bootstrap.yaml"); err == nil {
|
||||||
|
clusterPath = "/home/debros/.debros/bootstrap/ipfs-cluster"
|
||||||
|
} else {
|
||||||
|
clusterPath = "/home/debros/.debros/bootstrap/ipfs-cluster"
|
||||||
|
}
|
||||||
|
|
||||||
|
clusterService := fmt.Sprintf(`[Unit]
|
||||||
Description=IPFS Cluster Service
|
Description=IPFS Cluster Service
|
||||||
After=debros-ipfs.service
|
After=debros-ipfs.service
|
||||||
Wants=debros-ipfs.service
|
Wants=debros-ipfs.service
|
||||||
@ -2188,8 +2348,8 @@ User=debros
|
|||||||
Group=debros
|
Group=debros
|
||||||
WorkingDirectory=/home/debros
|
WorkingDirectory=/home/debros
|
||||||
Environment=HOME=/home/debros
|
Environment=HOME=/home/debros
|
||||||
ExecStartPre=/bin/bash -c 'if [ -f /home/debros/.debros/node.yaml ]; then export CLUSTER_PATH=/home/debros/.debros/node/ipfs-cluster; elif [ -f /home/debros/.debros/bootstrap.yaml ]; then export CLUSTER_PATH=/home/debros/.debros/bootstrap/ipfs-cluster; else export CLUSTER_PATH=/home/debros/.debros/bootstrap/ipfs-cluster; fi'
|
Environment=CLUSTER_PATH=%s
|
||||||
ExecStart=/usr/local/bin/ipfs-cluster-service daemon --config ${CLUSTER_PATH}/service.json
|
ExecStart=/usr/local/bin/ipfs-cluster-service daemon --config %s/service.json
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
StandardOutput=journal
|
StandardOutput=journal
|
||||||
@ -2203,7 +2363,7 @@ ReadWritePaths=/home/debros
|
|||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
`
|
`, clusterPath, clusterPath)
|
||||||
|
|
||||||
if err := os.WriteFile("/etc/systemd/system/debros-ipfs-cluster.service", []byte(clusterService), 0644); err != nil {
|
if err := os.WriteFile("/etc/systemd/system/debros-ipfs-cluster.service", []byte(clusterService), 0644); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "❌ Failed to create IPFS Cluster service: %v\n", err)
|
fmt.Fprintf(os.Stderr, "❌ Failed to create IPFS Cluster service: %v\n", err)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user