kadi-deploy 0.19.0
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/.env.example +6 -0
- package/.prettierrc +6 -0
- package/README.md +589 -0
- package/agent.json +23 -0
- package/index.js +11 -0
- package/package.json +42 -0
- package/quick-command.txt +92 -0
- package/scripts/preflight.js +458 -0
- package/scripts/preflight.sh +300 -0
- package/src/cli/bid-selector.ts +222 -0
- package/src/cli/colors.ts +216 -0
- package/src/cli/index.ts +11 -0
- package/src/cli/prompts.ts +190 -0
- package/src/cli/spinners.ts +165 -0
- package/src/commands/deploy-local.ts +475 -0
- package/src/commands/deploy.ts +1342 -0
- package/src/commands/down.ts +679 -0
- package/src/commands/index.ts +10 -0
- package/src/commands/lock.ts +571 -0
- package/src/config/agent-loader.ts +177 -0
- package/src/config/index.ts +9 -0
- package/src/display/deployment-info.ts +220 -0
- package/src/display/pricing.ts +137 -0
- package/src/display/resources.ts +234 -0
- package/src/enhanced-registry-manager.ts +892 -0
- package/src/index.ts +307 -0
- package/src/infrastructure/registry.ts +269 -0
- package/src/schemas/profiles.ts +529 -0
- package/src/secrets/broker-urls.ts +109 -0
- package/src/secrets/handshake.ts +407 -0
- package/src/secrets/index.ts +69 -0
- package/src/secrets/inject-env.ts +171 -0
- package/src/secrets/nonce.ts +31 -0
- package/src/secrets/normalize.ts +204 -0
- package/src/secrets/prepare.ts +152 -0
- package/src/secrets/validate.ts +243 -0
- package/src/secrets/vault.ts +80 -0
- package/src/types/akash.ts +116 -0
- package/src/types/container-registry-ability.d.ts +158 -0
- package/src/types/external.ts +49 -0
- package/src/types.ts +211 -0
- package/src/utils/akt-price.ts +74 -0
- package/tests/agent-loader.test.ts +239 -0
- package/tests/autonomous.test.ts +244 -0
- package/tests/down.test.ts +1143 -0
- package/tests/lock.test.ts +1148 -0
- package/tests/nonce.test.ts +34 -0
- package/tests/normalize.test.ts +270 -0
- package/tests/secrets-schema.test.ts +301 -0
- package/tests/types.test.ts +198 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +9 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Service Resources Display Utilities
|
|
3
|
+
*
|
|
4
|
+
* Formats and displays service resource allocations from deploy-ability's
|
|
5
|
+
* AkashDeploymentData.services field.
|
|
6
|
+
*
|
|
7
|
+
* @module display/resources
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type { AkashDeploymentData } from '@kadi.build/deploy-ability/types';
|
|
11
|
+
import { formatKeyValue, dim, bold, info } from '../cli/colors.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Displays service resources in a formatted manner
|
|
15
|
+
*
|
|
16
|
+
* Shows both aggregated totals and detailed resource specs for each service.
|
|
17
|
+
*
|
|
18
|
+
* @param services - Services array from AkashDeploymentData
|
|
19
|
+
* @param indent - Indentation level (default: 2)
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* displayServiceResources(deploymentData.services);
|
|
24
|
+
* // Output:
|
|
25
|
+
* // Services:
|
|
26
|
+
* // web (4 replicas):
|
|
27
|
+
* // Total: 5.0 CPU, 10Gi RAM, 5Gi Storage
|
|
28
|
+
* // Specs:
|
|
29
|
+
* // - 3× 1.0 CPU, 2Gi RAM, 1Gi Storage
|
|
30
|
+
* // - 1× 2.0 CPU, 4Gi RAM, 2Gi Storage
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function displayServiceResources(
|
|
34
|
+
services: AkashDeploymentData['services'],
|
|
35
|
+
indent: number = 2
|
|
36
|
+
): void {
|
|
37
|
+
if (!services || services.length === 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const prefix = ' '.repeat(indent);
|
|
42
|
+
|
|
43
|
+
for (const service of services) {
|
|
44
|
+
console.log(`${prefix}${bold(service.name)} ${dim(`(${service.replicaCount} ${service.replicaCount === 1 ? 'replica' : 'replicas'})`)}:`);
|
|
45
|
+
|
|
46
|
+
// Display aggregated totals
|
|
47
|
+
console.log(
|
|
48
|
+
`${prefix} ${formatKeyValue('Total Resources', `${service.totalResources.cpu} CPU, ${service.totalResources.memory} RAM, ${service.totalResources.storage} Storage`)}`
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
// Display detailed specs if there are multiple configurations
|
|
52
|
+
if (service.resourceSpecs.length > 1) {
|
|
53
|
+
console.log(`${prefix} ${dim('Resource Specs:')}`);
|
|
54
|
+
for (const spec of service.resourceSpecs) {
|
|
55
|
+
console.log(
|
|
56
|
+
`${prefix} ${dim('•')} ${info(`${spec.count}×`)} ${spec.cpu} CPU, ${spec.memory} RAM, ${spec.storage} Storage`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
} else if (service.resourceSpecs.length === 1) {
|
|
60
|
+
// Single spec - show replica configuration
|
|
61
|
+
const spec = service.resourceSpecs[0];
|
|
62
|
+
console.log(
|
|
63
|
+
`${prefix} ${formatKeyValue('Per Replica', `${spec.cpu} CPU, ${spec.memory} RAM, ${spec.storage} Storage`)}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
console.log('');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Gets a compact one-line resource summary for a service
|
|
73
|
+
*
|
|
74
|
+
* Useful for displaying in summaries or lists.
|
|
75
|
+
*
|
|
76
|
+
* @param service - Service object from AkashDeploymentData.services
|
|
77
|
+
* @returns Formatted resource string
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const summary = getResourceSummary(service);
|
|
82
|
+
* console.log(`web: ${summary}`);
|
|
83
|
+
* // Output: "web: 4 replicas • 5.0 CPU, 10Gi RAM, 5Gi Storage"
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export function getResourceSummary(
|
|
87
|
+
service: NonNullable<AkashDeploymentData['services']>[number]
|
|
88
|
+
): string {
|
|
89
|
+
return `${service.replicaCount} ${service.replicaCount === 1 ? 'replica' : 'replicas'} • ${service.totalResources.cpu} CPU, ${service.totalResources.memory} RAM, ${service.totalResources.storage} Storage`;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Displays all services in a compact table format
|
|
94
|
+
*
|
|
95
|
+
* Shows service name, replica count, and total resources in a clean layout.
|
|
96
|
+
*
|
|
97
|
+
* @param services - Services array from AkashDeploymentData
|
|
98
|
+
* @param indent - Indentation level (default: 0)
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* displayServicesTable(deploymentData.services);
|
|
103
|
+
* // Output:
|
|
104
|
+
* // Services:
|
|
105
|
+
* // web 4 replicas 5.0 CPU 10Gi RAM 5Gi Storage
|
|
106
|
+
* // api 2 replicas 2.0 CPU 4Gi RAM 2Gi Storage
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export function displayServicesTable(
|
|
110
|
+
services: AkashDeploymentData['services'],
|
|
111
|
+
indent: number = 0
|
|
112
|
+
): void {
|
|
113
|
+
if (!services || services.length === 0) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const prefix = ' '.repeat(indent);
|
|
118
|
+
|
|
119
|
+
console.log(`${prefix}${bold('Services:')}`);
|
|
120
|
+
|
|
121
|
+
// Calculate column widths
|
|
122
|
+
const nameWidth = Math.max(...services.map(s => s.name.length), 7);
|
|
123
|
+
const replicaWidth = 12;
|
|
124
|
+
const cpuWidth = 10;
|
|
125
|
+
const memWidth = 10;
|
|
126
|
+
const storageWidth = 12;
|
|
127
|
+
|
|
128
|
+
// Display each service
|
|
129
|
+
for (const service of services) {
|
|
130
|
+
const name = service.name.padEnd(nameWidth);
|
|
131
|
+
const replicas = `${service.replicaCount} ${service.replicaCount === 1 ? 'replica ' : 'replicas'}`.padEnd(replicaWidth);
|
|
132
|
+
const cpu = service.totalResources.cpu.padEnd(cpuWidth);
|
|
133
|
+
const mem = service.totalResources.memory.padEnd(memWidth);
|
|
134
|
+
const storage = service.totalResources.storage.padEnd(storageWidth);
|
|
135
|
+
|
|
136
|
+
console.log(
|
|
137
|
+
`${prefix} ${name} ${dim(replicas)} ${info(cpu)} ${info(mem)} ${info(storage)}`
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
console.log('');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Calculates total resources across all services
|
|
146
|
+
*
|
|
147
|
+
* Useful for showing overall deployment resource usage.
|
|
148
|
+
*
|
|
149
|
+
* @param services - Services array from AkashDeploymentData
|
|
150
|
+
* @returns Total CPU, memory, and storage
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const totals = calculateTotalResources(deploymentData.services);
|
|
155
|
+
* console.log(`Total: ${totals.cpu} CPU, ${totals.memory} RAM, ${totals.storage} Storage`);
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export function calculateTotalResources(
|
|
159
|
+
services: AkashDeploymentData['services']
|
|
160
|
+
): { cpu: number; memory: number; storage: number } {
|
|
161
|
+
if (!services || services.length === 0) {
|
|
162
|
+
return { cpu: 0, memory: 0, storage: 0 };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
let totalCpu = 0;
|
|
166
|
+
let totalMemory = 0;
|
|
167
|
+
let totalStorage = 0;
|
|
168
|
+
|
|
169
|
+
for (const service of services) {
|
|
170
|
+
// Parse CPU (e.g., "5.0" -> 5.0)
|
|
171
|
+
totalCpu += parseFloat(service.totalResources.cpu) || 0;
|
|
172
|
+
|
|
173
|
+
// Parse memory (e.g., "10Gi" -> bytes)
|
|
174
|
+
totalMemory += parseResourceValue(service.totalResources.memory);
|
|
175
|
+
|
|
176
|
+
// Parse storage (e.g., "5Gi" -> bytes)
|
|
177
|
+
totalStorage += parseResourceValue(service.totalResources.storage);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
cpu: totalCpu,
|
|
182
|
+
memory: totalMemory,
|
|
183
|
+
storage: totalStorage
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Parses a resource string to bytes
|
|
189
|
+
*
|
|
190
|
+
* Converts strings like "10Gi", "512Mi", "1Ti" to byte values.
|
|
191
|
+
*
|
|
192
|
+
* @param value - Resource string
|
|
193
|
+
* @returns Value in bytes
|
|
194
|
+
*/
|
|
195
|
+
function parseResourceValue(value: string): number {
|
|
196
|
+
const match = value.match(/^([\d.]+)(Ki|Mi|Gi|Ti|Pi)?$/);
|
|
197
|
+
if (!match) return 0;
|
|
198
|
+
|
|
199
|
+
const num = parseFloat(match[1]);
|
|
200
|
+
const unit = match[2] || '';
|
|
201
|
+
|
|
202
|
+
const multipliers: Record<string, number> = {
|
|
203
|
+
'': 1,
|
|
204
|
+
'Ki': 1024,
|
|
205
|
+
'Mi': 1024 * 1024,
|
|
206
|
+
'Gi': 1024 * 1024 * 1024,
|
|
207
|
+
'Ti': 1024 * 1024 * 1024 * 1024,
|
|
208
|
+
'Pi': 1024 * 1024 * 1024 * 1024 * 1024
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return num * (multipliers[unit] || 1);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Formats bytes to human-readable string
|
|
216
|
+
*
|
|
217
|
+
* @param bytes - Byte value
|
|
218
|
+
* @returns Formatted string (e.g., "10Gi", "512Mi")
|
|
219
|
+
*/
|
|
220
|
+
export function formatBytes(bytes: number): string {
|
|
221
|
+
if (bytes === 0) return '0';
|
|
222
|
+
|
|
223
|
+
const units = ['', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi'];
|
|
224
|
+
let unitIndex = 0;
|
|
225
|
+
let value = bytes;
|
|
226
|
+
|
|
227
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
228
|
+
value /= 1024;
|
|
229
|
+
unitIndex++;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const formatted = value.toFixed(2).replace(/\.?0+$/, '');
|
|
233
|
+
return `${formatted}${units[unitIndex]}`;
|
|
234
|
+
}
|