claude-flow-novice 2.14.14 → 2.14.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/cfn-loop-cli.md +21 -27
- package/claude-assets/commands/cfn-loop-cli.md +21 -27
- package/claude-assets/skills/cfn-multi-coordinator-planning/map-dependencies-conflicts.sh +375 -375
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-coordinator-resources.sh +257 -257
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-multi-coordinator-work.sh +266 -266
- package/claude-assets/skills/cfn-multi-coordinator-planning/plan-risk-rollout.sh +349 -349
- package/claude-assets/skills/cfn-multi-coordinator-planning/test-multi-coordinator-planning.sh +337 -337
- package/claude-assets/skills/cfn-multi-coordinator-planning/validate-task-planning.sh +188 -188
- package/dist/agent/skill-mcp-selector.js +459 -0
- package/dist/agent/skill-mcp-selector.js.map +1 -0
- package/dist/cli/agent-token-manager.js +382 -0
- package/dist/cli/agent-token-manager.js.map +1 -0
- package/dist/cli/config-manager.js +91 -109
- package/dist/cli/config-manager.js.map +1 -1
- package/dist/mcp/auth-middleware.js +367 -0
- package/dist/mcp/auth-middleware.js.map +1 -0
- package/dist/mcp/playwright-mcp-server-auth.js +515 -0
- package/dist/mcp/playwright-mcp-server-auth.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,258 +1,258 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
-
source "$SCRIPT_DIR/../cfn-redis-coordination/redis-utils.sh"
|
|
7
|
-
|
|
8
|
-
# Configuration
|
|
9
|
-
DEFAULT_MEMORY_PER_COORDINATOR=2048 # MB
|
|
10
|
-
DEFAULT_CPU_PER_COORDINATOR=2
|
|
11
|
-
DEFAULT_REDIS_DB_START=1
|
|
12
|
-
DEFAULT_REDIS_DB_END=15
|
|
13
|
-
CLEANUP_OVERHEAD=0.15 # 15%
|
|
14
|
-
MONITORING_OVERHEAD=0.05 # 5%
|
|
15
|
-
|
|
16
|
-
# Colors
|
|
17
|
-
RED='\033[0;31m'
|
|
18
|
-
GREEN='\033[0;32m'
|
|
19
|
-
YELLOW='\033[1;33m'
|
|
20
|
-
BLUE='\033[0;34m'
|
|
21
|
-
NC='\033[0m'
|
|
22
|
-
|
|
23
|
-
log() {
|
|
24
|
-
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
warn() {
|
|
28
|
-
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
error() {
|
|
32
|
-
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
|
33
|
-
exit 1
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
info() {
|
|
37
|
-
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get_system_resources() {
|
|
41
|
-
local memory_kb cpu_cores
|
|
42
|
-
memory_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
|
43
|
-
cpu_cores=$(nproc)
|
|
44
|
-
|
|
45
|
-
local memory_mb=$((memory_kb / 1024))
|
|
46
|
-
|
|
47
|
-
echo "{\"memory_mb\": $memory_mb, \"cpu_cores\": $cpu_cores}"
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
calculate_max_coordinators() {
|
|
51
|
-
local system_resources="$1"
|
|
52
|
-
local memory_mb cpu_cores
|
|
53
|
-
|
|
54
|
-
memory_mb=$(echo "$system_resources" | jq -r '.memory_mb')
|
|
55
|
-
cpu_cores=$(echo "$system_resources" | jq -r '.cpu_cores')
|
|
56
|
-
|
|
57
|
-
# Calculate with overhead
|
|
58
|
-
local effective_memory=$((memory_mb - (memory_mb * CLEANUP_OVERHEAD + memory_mb * MONITORING_OVERHEAD)))
|
|
59
|
-
local effective_cpu=$((cpu_cores - (cpu_cores * CLEANUP_OVERHEAD + cpu_cores * MONITORING_OVERHEAD)))
|
|
60
|
-
|
|
61
|
-
local max_by_memory=$((effective_memory / DEFAULT_MEMORY_PER_COORDINATOR))
|
|
62
|
-
local max_by_cpu=$((effective_cpu / DEFAULT_CPU_PER_COORDINATOR))
|
|
63
|
-
|
|
64
|
-
# Return the smaller of the two limits
|
|
65
|
-
if [[ $max_by_memory -lt $max_by_cpu ]]; then
|
|
66
|
-
echo $max_by_memory
|
|
67
|
-
else
|
|
68
|
-
echo $max_by_cpu
|
|
69
|
-
fi
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
reserve_redis_namespace() {
|
|
73
|
-
local zone_name="$1"
|
|
74
|
-
local task_id="$2"
|
|
75
|
-
local redis_db="$3"
|
|
76
|
-
|
|
77
|
-
local namespace_pattern="swarm:zone-${zone_name}:${task_id}"
|
|
78
|
-
|
|
79
|
-
# Test Redis connectivity
|
|
80
|
-
if ! redis-cli ping >/dev/null 2>&1; then
|
|
81
|
-
error "Redis connection failed"
|
|
82
|
-
fi
|
|
83
|
-
|
|
84
|
-
# Reserve namespace with SETNX and TTL
|
|
85
|
-
local reservation_key="${namespace_pattern}:reservation"
|
|
86
|
-
local reservation_result
|
|
87
|
-
reservation_result=$(redis-cli setnx "$reservation_key" "$(date '+%s')" 2>/dev/null || echo "0")
|
|
88
|
-
|
|
89
|
-
if [[ "$reservation_result" != "1" ]]; then
|
|
90
|
-
error "Namespace already reserved: $namespace_pattern"
|
|
91
|
-
fi
|
|
92
|
-
|
|
93
|
-
# Set TTL for reservation (1 hour)
|
|
94
|
-
redis-cli expire "$reservation_key" 3600 >/dev/null
|
|
95
|
-
|
|
96
|
-
log "✓ Redis namespace reserved: $namespace_pattern (DB: $redis_db)"
|
|
97
|
-
echo "$namespace_pattern"
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
allocate_redis_databases() {
|
|
101
|
-
local zone_count="$1"
|
|
102
|
-
local start_db="$2"
|
|
103
|
-
local end_db="$3"
|
|
104
|
-
|
|
105
|
-
local available_dbs=$((end_db - start_db + 1))
|
|
106
|
-
|
|
107
|
-
if [[ $zone_count -gt $available_dbs ]]; then
|
|
108
|
-
error "Too many zones: $zone_count (available DBs: $available_dbs)"
|
|
109
|
-
fi
|
|
110
|
-
|
|
111
|
-
local db_allocation=()
|
|
112
|
-
for ((i=0; i<zone_count; i++)); do
|
|
113
|
-
db_allocation+=($((start_db + i)))
|
|
114
|
-
done
|
|
115
|
-
|
|
116
|
-
printf '%s\n' "${db_allocation[@]}"
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
generate_task_id() {
|
|
120
|
-
local zone_name="$1"
|
|
121
|
-
local timestamp
|
|
122
|
-
timestamp=$(date '+%s')
|
|
123
|
-
|
|
124
|
-
echo "zone-${zone_name}-${timestamp}"
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
plan_zone_resources() {
|
|
128
|
-
local zone_name="$1"
|
|
129
|
-
local redis_db="$2"
|
|
130
|
-
local task_data="$3"
|
|
131
|
-
|
|
132
|
-
local task_id
|
|
133
|
-
task_id=$(generate_task_id "$zone_name")
|
|
134
|
-
|
|
135
|
-
# Reserve Redis namespace
|
|
136
|
-
local namespace_pattern
|
|
137
|
-
namespace_pattern=$(reserve_redis_namespace "$zone_name" "$task_id" "$redis_db")
|
|
138
|
-
|
|
139
|
-
# Generate resource plan
|
|
140
|
-
local resource_plan="{
|
|
141
|
-
\"zone_name\": \"$zone_name\",
|
|
142
|
-
\"task_id\": \"$task_id\",
|
|
143
|
-
\"namespace_pattern\": \"$namespace_pattern\",
|
|
144
|
-
\"redis_db\": $redis_db,
|
|
145
|
-
\"memory_mb\": $DEFAULT_MEMORY_PER_COORDINATOR,
|
|
146
|
-
\"cpu_cores\": $DEFAULT_CPU_PER_COORDINATOR,
|
|
147
|
-
\"working_directory\": \"/tmp/zone-${zone_name}-${task_id}\",
|
|
148
|
-
\"monitoring_port\": $((8080 + redis_db)),
|
|
149
|
-
\"timestamp\": $(date '+%s')
|
|
150
|
-
}"
|
|
151
|
-
|
|
152
|
-
log "✓ Resource plan generated for zone: $zone_name"
|
|
153
|
-
echo "$resource_plan"
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
validate_resource_availability() {
|
|
157
|
-
local zone_count="$1"
|
|
158
|
-
local system_resources="$2"
|
|
159
|
-
|
|
160
|
-
local max_coordinators
|
|
161
|
-
max_coordinators=$(calculate_max_coordinators "$system_resources")
|
|
162
|
-
|
|
163
|
-
if [[ $zone_count -gt $max_coordinators ]]; then
|
|
164
|
-
error "Insufficient resources for $zone_count coordinators (maximum: $max_coordinators)"
|
|
165
|
-
fi
|
|
166
|
-
|
|
167
|
-
log "✓ Resource availability validated: $zone_count zones (capacity: $max_coordinators)"
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
main() {
|
|
171
|
-
local config_file="$1"
|
|
172
|
-
|
|
173
|
-
if [[ -z "$config_file" ]]; then
|
|
174
|
-
error "Usage: $0 <zone-config-file>"
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
if [[ ! -f "$config_file" ]]; then
|
|
178
|
-
error "Configuration file not found: $config_file"
|
|
179
|
-
fi
|
|
180
|
-
|
|
181
|
-
log "Starting coordinator resource planning for: $config_file"
|
|
182
|
-
|
|
183
|
-
# Read configuration
|
|
184
|
-
local zone_config
|
|
185
|
-
if ! zone_config=$(jq . "$config_file" 2>/dev/null); then
|
|
186
|
-
error "Invalid JSON in configuration file: $config_file"
|
|
187
|
-
fi
|
|
188
|
-
|
|
189
|
-
local zone_count
|
|
190
|
-
zone_count=$(echo "$zone_config" | jq '.zones | length')
|
|
191
|
-
|
|
192
|
-
if [[ $zone_count -eq 0 ]]; then
|
|
193
|
-
error "No zones found in configuration"
|
|
194
|
-
fi
|
|
195
|
-
|
|
196
|
-
info "Planning resources for $zone_count zones"
|
|
197
|
-
|
|
198
|
-
# Get system resources
|
|
199
|
-
local system_resources
|
|
200
|
-
system_resources=$(get_system_resources)
|
|
201
|
-
|
|
202
|
-
# Validate resource availability
|
|
203
|
-
validate_resource_availability "$zone_count" "$system_resources"
|
|
204
|
-
|
|
205
|
-
# Allocate Redis databases
|
|
206
|
-
local redis_dbs
|
|
207
|
-
mapfile -t redis_dbs < <(allocate_redis_databases "$zone_count" "$DEFAULT_REDIS_DB_START" "$DEFAULT_REDIS_DB_END")
|
|
208
|
-
|
|
209
|
-
# Generate resource plan for each zone
|
|
210
|
-
local resource_plans="[]"
|
|
211
|
-
local i=0
|
|
212
|
-
|
|
213
|
-
while IFS= read -r zone_name; do
|
|
214
|
-
local zone_data
|
|
215
|
-
zone_data=$(echo "$zone_config" | jq -r ".zones[$i]")
|
|
216
|
-
|
|
217
|
-
local resource_plan
|
|
218
|
-
resource_plan=$(plan_zone_resources "$zone_name" "${redis_dbs[$i]}" "$zone_data")
|
|
219
|
-
|
|
220
|
-
resource_plans=$(echo "$resource_plans" | jq ". + [$resource_plan]")
|
|
221
|
-
|
|
222
|
-
((i++))
|
|
223
|
-
done < <(echo "$zone_config" | jq -r '.zones[].name')
|
|
224
|
-
|
|
225
|
-
# Generate complete resource allocation plan
|
|
226
|
-
local allocation_plan="{
|
|
227
|
-
\"timestamp\": $(date '+%s'),
|
|
228
|
-
\"zone_count\": $zone_count,
|
|
229
|
-
\"system_resources\": $system_resources,
|
|
230
|
-
\"max_coordinators\": $(calculate_max_coordinators "$system_resources"),
|
|
231
|
-
\"resource_plans\": $resource_plans,
|
|
232
|
-
\"redis_allocation\": {
|
|
233
|
-
\"databases_used\": $(printf '%s,' "${redis_dbs[@]}" | sed 's/,$//'),
|
|
234
|
-
\"total_allocated\": $zone_count
|
|
235
|
-
}
|
|
236
|
-
}"
|
|
237
|
-
|
|
238
|
-
# Save allocation plan
|
|
239
|
-
local output_file="/tmp/coordinator-resource-plan-$(date '+%s').json"
|
|
240
|
-
echo "$allocation_plan" > "$output_file"
|
|
241
|
-
|
|
242
|
-
log "✅ Coordinator resource planning completed"
|
|
243
|
-
log "Resource allocation plan saved to: $output_file"
|
|
244
|
-
|
|
245
|
-
# Display summary
|
|
246
|
-
echo
|
|
247
|
-
info "=== Resource Allocation Summary ==="
|
|
248
|
-
echo "Zones to execute: $zone_count"
|
|
249
|
-
echo "System memory: $(echo "$system_resources" | jq -r '.memory_mb') MB"
|
|
250
|
-
echo "System CPUs: $(echo "$system_resources" | jq -r '.cpu_cores')"
|
|
251
|
-
echo "Memory per coordinator: ${DEFAULT_MEMORY_PER_COORDINATOR} MB"
|
|
252
|
-
echo "CPUs per coordinator: ${DEFAULT_CPU_PER_COORDINATOR}"
|
|
253
|
-
echo "Redis databases allocated: ${redis_dbs[*]}"
|
|
254
|
-
echo
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
# Execute main function with all arguments
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
source "$SCRIPT_DIR/../cfn-redis-coordination/redis-utils.sh"
|
|
7
|
+
|
|
8
|
+
# Configuration
|
|
9
|
+
DEFAULT_MEMORY_PER_COORDINATOR=2048 # MB
|
|
10
|
+
DEFAULT_CPU_PER_COORDINATOR=2
|
|
11
|
+
DEFAULT_REDIS_DB_START=1
|
|
12
|
+
DEFAULT_REDIS_DB_END=15
|
|
13
|
+
CLEANUP_OVERHEAD=0.15 # 15%
|
|
14
|
+
MONITORING_OVERHEAD=0.05 # 5%
|
|
15
|
+
|
|
16
|
+
# Colors
|
|
17
|
+
RED='\033[0;31m'
|
|
18
|
+
GREEN='\033[0;32m'
|
|
19
|
+
YELLOW='\033[1;33m'
|
|
20
|
+
BLUE='\033[0;34m'
|
|
21
|
+
NC='\033[0m'
|
|
22
|
+
|
|
23
|
+
log() {
|
|
24
|
+
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
warn() {
|
|
28
|
+
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
error() {
|
|
32
|
+
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
|
|
33
|
+
exit 1
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
info() {
|
|
37
|
+
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1${NC}"
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get_system_resources() {
|
|
41
|
+
local memory_kb cpu_cores
|
|
42
|
+
memory_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}')
|
|
43
|
+
cpu_cores=$(nproc)
|
|
44
|
+
|
|
45
|
+
local memory_mb=$((memory_kb / 1024))
|
|
46
|
+
|
|
47
|
+
echo "{\"memory_mb\": $memory_mb, \"cpu_cores\": $cpu_cores}"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
calculate_max_coordinators() {
|
|
51
|
+
local system_resources="$1"
|
|
52
|
+
local memory_mb cpu_cores
|
|
53
|
+
|
|
54
|
+
memory_mb=$(echo "$system_resources" | jq -r '.memory_mb')
|
|
55
|
+
cpu_cores=$(echo "$system_resources" | jq -r '.cpu_cores')
|
|
56
|
+
|
|
57
|
+
# Calculate with overhead
|
|
58
|
+
local effective_memory=$((memory_mb - (memory_mb * CLEANUP_OVERHEAD + memory_mb * MONITORING_OVERHEAD)))
|
|
59
|
+
local effective_cpu=$((cpu_cores - (cpu_cores * CLEANUP_OVERHEAD + cpu_cores * MONITORING_OVERHEAD)))
|
|
60
|
+
|
|
61
|
+
local max_by_memory=$((effective_memory / DEFAULT_MEMORY_PER_COORDINATOR))
|
|
62
|
+
local max_by_cpu=$((effective_cpu / DEFAULT_CPU_PER_COORDINATOR))
|
|
63
|
+
|
|
64
|
+
# Return the smaller of the two limits
|
|
65
|
+
if [[ $max_by_memory -lt $max_by_cpu ]]; then
|
|
66
|
+
echo $max_by_memory
|
|
67
|
+
else
|
|
68
|
+
echo $max_by_cpu
|
|
69
|
+
fi
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
reserve_redis_namespace() {
|
|
73
|
+
local zone_name="$1"
|
|
74
|
+
local task_id="$2"
|
|
75
|
+
local redis_db="$3"
|
|
76
|
+
|
|
77
|
+
local namespace_pattern="swarm:zone-${zone_name}:${task_id}"
|
|
78
|
+
|
|
79
|
+
# Test Redis connectivity
|
|
80
|
+
if ! redis-cli ping >/dev/null 2>&1; then
|
|
81
|
+
error "Redis connection failed"
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
# Reserve namespace with SETNX and TTL
|
|
85
|
+
local reservation_key="${namespace_pattern}:reservation"
|
|
86
|
+
local reservation_result
|
|
87
|
+
reservation_result=$(redis-cli setnx "$reservation_key" "$(date '+%s')" 2>/dev/null || echo "0")
|
|
88
|
+
|
|
89
|
+
if [[ "$reservation_result" != "1" ]]; then
|
|
90
|
+
error "Namespace already reserved: $namespace_pattern"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Set TTL for reservation (1 hour)
|
|
94
|
+
redis-cli expire "$reservation_key" 3600 >/dev/null
|
|
95
|
+
|
|
96
|
+
log "✓ Redis namespace reserved: $namespace_pattern (DB: $redis_db)"
|
|
97
|
+
echo "$namespace_pattern"
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
allocate_redis_databases() {
|
|
101
|
+
local zone_count="$1"
|
|
102
|
+
local start_db="$2"
|
|
103
|
+
local end_db="$3"
|
|
104
|
+
|
|
105
|
+
local available_dbs=$((end_db - start_db + 1))
|
|
106
|
+
|
|
107
|
+
if [[ $zone_count -gt $available_dbs ]]; then
|
|
108
|
+
error "Too many zones: $zone_count (available DBs: $available_dbs)"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
local db_allocation=()
|
|
112
|
+
for ((i=0; i<zone_count; i++)); do
|
|
113
|
+
db_allocation+=($((start_db + i)))
|
|
114
|
+
done
|
|
115
|
+
|
|
116
|
+
printf '%s\n' "${db_allocation[@]}"
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
generate_task_id() {
|
|
120
|
+
local zone_name="$1"
|
|
121
|
+
local timestamp
|
|
122
|
+
timestamp=$(date '+%s')
|
|
123
|
+
|
|
124
|
+
echo "zone-${zone_name}-${timestamp}"
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
plan_zone_resources() {
|
|
128
|
+
local zone_name="$1"
|
|
129
|
+
local redis_db="$2"
|
|
130
|
+
local task_data="$3"
|
|
131
|
+
|
|
132
|
+
local task_id
|
|
133
|
+
task_id=$(generate_task_id "$zone_name")
|
|
134
|
+
|
|
135
|
+
# Reserve Redis namespace
|
|
136
|
+
local namespace_pattern
|
|
137
|
+
namespace_pattern=$(reserve_redis_namespace "$zone_name" "$task_id" "$redis_db")
|
|
138
|
+
|
|
139
|
+
# Generate resource plan
|
|
140
|
+
local resource_plan="{
|
|
141
|
+
\"zone_name\": \"$zone_name\",
|
|
142
|
+
\"task_id\": \"$task_id\",
|
|
143
|
+
\"namespace_pattern\": \"$namespace_pattern\",
|
|
144
|
+
\"redis_db\": $redis_db,
|
|
145
|
+
\"memory_mb\": $DEFAULT_MEMORY_PER_COORDINATOR,
|
|
146
|
+
\"cpu_cores\": $DEFAULT_CPU_PER_COORDINATOR,
|
|
147
|
+
\"working_directory\": \"/tmp/zone-${zone_name}-${task_id}\",
|
|
148
|
+
\"monitoring_port\": $((8080 + redis_db)),
|
|
149
|
+
\"timestamp\": $(date '+%s')
|
|
150
|
+
}"
|
|
151
|
+
|
|
152
|
+
log "✓ Resource plan generated for zone: $zone_name"
|
|
153
|
+
echo "$resource_plan"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
validate_resource_availability() {
|
|
157
|
+
local zone_count="$1"
|
|
158
|
+
local system_resources="$2"
|
|
159
|
+
|
|
160
|
+
local max_coordinators
|
|
161
|
+
max_coordinators=$(calculate_max_coordinators "$system_resources")
|
|
162
|
+
|
|
163
|
+
if [[ $zone_count -gt $max_coordinators ]]; then
|
|
164
|
+
error "Insufficient resources for $zone_count coordinators (maximum: $max_coordinators)"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
log "✓ Resource availability validated: $zone_count zones (capacity: $max_coordinators)"
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
main() {
|
|
171
|
+
local config_file="$1"
|
|
172
|
+
|
|
173
|
+
if [[ -z "$config_file" ]]; then
|
|
174
|
+
error "Usage: $0 <zone-config-file>"
|
|
175
|
+
fi
|
|
176
|
+
|
|
177
|
+
if [[ ! -f "$config_file" ]]; then
|
|
178
|
+
error "Configuration file not found: $config_file"
|
|
179
|
+
fi
|
|
180
|
+
|
|
181
|
+
log "Starting coordinator resource planning for: $config_file"
|
|
182
|
+
|
|
183
|
+
# Read configuration
|
|
184
|
+
local zone_config
|
|
185
|
+
if ! zone_config=$(jq . "$config_file" 2>/dev/null); then
|
|
186
|
+
error "Invalid JSON in configuration file: $config_file"
|
|
187
|
+
fi
|
|
188
|
+
|
|
189
|
+
local zone_count
|
|
190
|
+
zone_count=$(echo "$zone_config" | jq '.zones | length')
|
|
191
|
+
|
|
192
|
+
if [[ $zone_count -eq 0 ]]; then
|
|
193
|
+
error "No zones found in configuration"
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
info "Planning resources for $zone_count zones"
|
|
197
|
+
|
|
198
|
+
# Get system resources
|
|
199
|
+
local system_resources
|
|
200
|
+
system_resources=$(get_system_resources)
|
|
201
|
+
|
|
202
|
+
# Validate resource availability
|
|
203
|
+
validate_resource_availability "$zone_count" "$system_resources"
|
|
204
|
+
|
|
205
|
+
# Allocate Redis databases
|
|
206
|
+
local redis_dbs
|
|
207
|
+
mapfile -t redis_dbs < <(allocate_redis_databases "$zone_count" "$DEFAULT_REDIS_DB_START" "$DEFAULT_REDIS_DB_END")
|
|
208
|
+
|
|
209
|
+
# Generate resource plan for each zone
|
|
210
|
+
local resource_plans="[]"
|
|
211
|
+
local i=0
|
|
212
|
+
|
|
213
|
+
while IFS= read -r zone_name; do
|
|
214
|
+
local zone_data
|
|
215
|
+
zone_data=$(echo "$zone_config" | jq -r ".zones[$i]")
|
|
216
|
+
|
|
217
|
+
local resource_plan
|
|
218
|
+
resource_plan=$(plan_zone_resources "$zone_name" "${redis_dbs[$i]}" "$zone_data")
|
|
219
|
+
|
|
220
|
+
resource_plans=$(echo "$resource_plans" | jq ". + [$resource_plan]")
|
|
221
|
+
|
|
222
|
+
((i++))
|
|
223
|
+
done < <(echo "$zone_config" | jq -r '.zones[].name')
|
|
224
|
+
|
|
225
|
+
# Generate complete resource allocation plan
|
|
226
|
+
local allocation_plan="{
|
|
227
|
+
\"timestamp\": $(date '+%s'),
|
|
228
|
+
\"zone_count\": $zone_count,
|
|
229
|
+
\"system_resources\": $system_resources,
|
|
230
|
+
\"max_coordinators\": $(calculate_max_coordinators "$system_resources"),
|
|
231
|
+
\"resource_plans\": $resource_plans,
|
|
232
|
+
\"redis_allocation\": {
|
|
233
|
+
\"databases_used\": $(printf '%s,' "${redis_dbs[@]}" | sed 's/,$//'),
|
|
234
|
+
\"total_allocated\": $zone_count
|
|
235
|
+
}
|
|
236
|
+
}"
|
|
237
|
+
|
|
238
|
+
# Save allocation plan
|
|
239
|
+
local output_file="/tmp/coordinator-resource-plan-$(date '+%s').json"
|
|
240
|
+
echo "$allocation_plan" > "$output_file"
|
|
241
|
+
|
|
242
|
+
log "✅ Coordinator resource planning completed"
|
|
243
|
+
log "Resource allocation plan saved to: $output_file"
|
|
244
|
+
|
|
245
|
+
# Display summary
|
|
246
|
+
echo
|
|
247
|
+
info "=== Resource Allocation Summary ==="
|
|
248
|
+
echo "Zones to execute: $zone_count"
|
|
249
|
+
echo "System memory: $(echo "$system_resources" | jq -r '.memory_mb') MB"
|
|
250
|
+
echo "System CPUs: $(echo "$system_resources" | jq -r '.cpu_cores')"
|
|
251
|
+
echo "Memory per coordinator: ${DEFAULT_MEMORY_PER_COORDINATOR} MB"
|
|
252
|
+
echo "CPUs per coordinator: ${DEFAULT_CPU_PER_COORDINATOR}"
|
|
253
|
+
echo "Redis databases allocated: ${redis_dbs[*]}"
|
|
254
|
+
echo
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Execute main function with all arguments
|
|
258
258
|
main "$@"
|