@jaguilar87/gaia-ops 2.4.2 → 2.4.4
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/bin/gaia-update.js +167 -0
- package/package.json +3 -2
- package/templates/CLAUDE.template.md +2 -4
- package/templates/settings.template.json +16 -82
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @jaguilar87/gaia-ops - Auto-update script
|
|
5
|
+
*
|
|
6
|
+
* Runs automatically on npm install/update (postinstall hook)
|
|
7
|
+
*
|
|
8
|
+
* Purpose:
|
|
9
|
+
* - Regenerate CLAUDE.md from template (preserving existing values)
|
|
10
|
+
* - Regenerate settings.json from template
|
|
11
|
+
* - Only runs if CLAUDE.md already exists (skip first-time install, let gaia-init handle it)
|
|
12
|
+
*
|
|
13
|
+
* Usage: Automatic (npm postinstall hook)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { fileURLToPath } from 'url';
|
|
17
|
+
import { dirname, join } from 'path';
|
|
18
|
+
import fs from 'fs/promises';
|
|
19
|
+
import { existsSync } from 'fs';
|
|
20
|
+
import chalk from 'chalk';
|
|
21
|
+
import ora from 'ora';
|
|
22
|
+
|
|
23
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
24
|
+
const __dirname = dirname(__filename);
|
|
25
|
+
const CWD = process.cwd();
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extract placeholder values from existing CLAUDE.md
|
|
29
|
+
*/
|
|
30
|
+
async function extractExistingValues() {
|
|
31
|
+
const claudeMdPath = join(CWD, 'CLAUDE.md');
|
|
32
|
+
|
|
33
|
+
if (!existsSync(claudeMdPath)) {
|
|
34
|
+
return null; // First time install, skip
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const content = await fs.readFile(claudeMdPath, 'utf-8');
|
|
39
|
+
|
|
40
|
+
// Extract values from CLAUDE.md (simple pattern matching)
|
|
41
|
+
const gitopsMatch = content.match(/- \*\*GitOps Path:\*\* (.+)/);
|
|
42
|
+
const terraformMatch = content.match(/- \*\*Terraform Path:\*\* (.+)/);
|
|
43
|
+
const appServicesMatch = content.match(/- \*\*App Services Path:\*\* (.+)/);
|
|
44
|
+
const projectConfigMatch = content.match(/\*\*This project:\*\*\s+([\s\S]+?)## System Paths/);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
gitops: gitopsMatch ? gitopsMatch[1].trim() : './gitops',
|
|
48
|
+
terraform: terraformMatch ? terraformMatch[1].trim() : './terraform',
|
|
49
|
+
appServices: appServicesMatch ? appServicesMatch[1].trim() : './app-services',
|
|
50
|
+
projectConfig: projectConfigMatch ? projectConfigMatch[1].trim() : ''
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.warn(chalk.yellow(`⚠️ Could not extract existing values: ${error.message}`));
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Regenerate CLAUDE.md from template
|
|
60
|
+
*/
|
|
61
|
+
async function updateClaudeMd() {
|
|
62
|
+
const spinner = ora('Updating CLAUDE.md...').start();
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
// Get template path from gaia-ops package
|
|
66
|
+
const templatePath = join(__dirname, '../templates/CLAUDE.template.md');
|
|
67
|
+
|
|
68
|
+
if (!existsSync(templatePath)) {
|
|
69
|
+
spinner.warn('Template not found, skipping CLAUDE.md update');
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let template = await fs.readFile(templatePath, 'utf-8');
|
|
74
|
+
|
|
75
|
+
// Extract existing values if CLAUDE.md exists
|
|
76
|
+
const existingValues = await extractExistingValues();
|
|
77
|
+
|
|
78
|
+
if (!existingValues) {
|
|
79
|
+
// First time install - don't auto-generate, gaia-init handles it
|
|
80
|
+
spinner.info('First-time installation detected - skipping auto-update');
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Replace placeholders with extracted values
|
|
85
|
+
template = template.replace(/{{GITOPS_PATH}}/g, existingValues.gitops);
|
|
86
|
+
template = template.replace(/{{TERRAFORM_PATH}}/g, existingValues.terraform);
|
|
87
|
+
template = template.replace(/{{APP_SERVICES_PATH}}/g, existingValues.appServices);
|
|
88
|
+
|
|
89
|
+
if (existingValues.projectConfig) {
|
|
90
|
+
template = template.replace(/{{PROJECT_CONFIG}}/g, existingValues.projectConfig);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Write updated CLAUDE.md
|
|
94
|
+
const claudeMdPath = join(CWD, 'CLAUDE.md');
|
|
95
|
+
await fs.writeFile(claudeMdPath, template, 'utf-8');
|
|
96
|
+
|
|
97
|
+
spinner.succeed('CLAUDE.md updated successfully');
|
|
98
|
+
return true;
|
|
99
|
+
} catch (error) {
|
|
100
|
+
spinner.fail(`Failed to update CLAUDE.md: ${error.message}`);
|
|
101
|
+
return false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Regenerate settings.json from template
|
|
107
|
+
*/
|
|
108
|
+
async function updateSettingsJson() {
|
|
109
|
+
const spinner = ora('Updating settings.json...').start();
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const templatePath = join(__dirname, '../templates/settings.template.json');
|
|
113
|
+
const settingsPath = join(CWD, '.claude', 'settings.json');
|
|
114
|
+
|
|
115
|
+
if (!existsSync(templatePath)) {
|
|
116
|
+
spinner.warn('Settings template not found, skipping');
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!existsSync(join(CWD, '.claude'))) {
|
|
121
|
+
spinner.info('First-time installation detected - skipping auto-update');
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Copy template to settings.json (overwrite to get latest)
|
|
126
|
+
const template = await fs.readFile(templatePath, 'utf-8');
|
|
127
|
+
await fs.writeFile(settingsPath, template, 'utf-8');
|
|
128
|
+
|
|
129
|
+
spinner.succeed('settings.json updated successfully');
|
|
130
|
+
return true;
|
|
131
|
+
} catch (error) {
|
|
132
|
+
spinner.fail(`Failed to update settings.json: ${error.message}`);
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Main function
|
|
139
|
+
*/
|
|
140
|
+
async function main() {
|
|
141
|
+
console.log(chalk.cyan('\n🔄 @jaguilar87/gaia-ops auto-update\n'));
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const claudeUpdated = await updateClaudeMd();
|
|
145
|
+
const settingsUpdated = await updateSettingsJson();
|
|
146
|
+
|
|
147
|
+
if (claudeUpdated || settingsUpdated) {
|
|
148
|
+
console.log(chalk.green('\n✅ Auto-update completed\n'));
|
|
149
|
+
console.log(chalk.gray('Next steps:'));
|
|
150
|
+
if (claudeUpdated) {
|
|
151
|
+
console.log(chalk.gray(' • Review CLAUDE.md for any needed adjustments'));
|
|
152
|
+
}
|
|
153
|
+
if (settingsUpdated) {
|
|
154
|
+
console.log(chalk.gray(' • Review settings.json for security rules'));
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
// Silent exit on first-time install (gaia-init will handle it)
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
} catch (error) {
|
|
161
|
+
console.error(chalk.red(`\n❌ Auto-update failed: ${error.message}\n`));
|
|
162
|
+
// Don't fail npm install, just warn
|
|
163
|
+
process.exit(0);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
main();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jaguilar87/gaia-ops",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.4",
|
|
4
4
|
"description": "Multi-agent orchestration system for Claude Code - DevOps automation toolkit",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"validate": "python3 tools/commit_validator.py",
|
|
52
52
|
"lint": "eslint .",
|
|
53
53
|
"clean": "find . -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true",
|
|
54
|
-
"prepublishOnly": "npm run clean"
|
|
54
|
+
"prepublishOnly": "npm run clean",
|
|
55
|
+
"postinstall": "node bin/gaia-update.js"
|
|
55
56
|
},
|
|
56
57
|
"dependencies": {
|
|
57
58
|
"prompts": "^2.4.2",
|
|
@@ -30,13 +30,11 @@
|
|
|
30
30
|
| 0 | Clarification (if ambiguous) | `clarification` module | Conditional |
|
|
31
31
|
| 1 | Route to agent | `agent_router.py` | Yes |
|
|
32
32
|
| 2 | Provision context | `context_provider.py` | Yes |
|
|
33
|
-
| 3 | Invoke (Planning) | `Task`
|
|
33
|
+
| 3 | Invoke (Planning) | `Task(subagent_type=<agent>, prompt=<enriched>)` | Yes |
|
|
34
34
|
| 4 | Approval Gate | `approval_gate.py` | **Yes (T3)** |
|
|
35
35
|
| 5 | Realization | `Task` tool (re-invoke) | Yes |
|
|
36
36
|
| 6 | Update SSOT | Edit `project-context.json`, `tasks.md` | Yes |
|
|
37
37
|
|
|
38
|
-
**See:** `.claude/config/orchestration-workflow.md` for complete details.
|
|
39
|
-
|
|
40
38
|
### Rule 5.0.1 [P0]: Phase 0 Implementation
|
|
41
39
|
|
|
42
40
|
**When to invoke Phase 0:**
|
|
@@ -86,7 +84,7 @@ if result.get("needs_manual_questioning"):
|
|
|
86
84
|
|
|
87
85
|
**See:** `.claude/config/orchestration-workflow.md` lines 25-150 for complete Phase 0 protocol.
|
|
88
86
|
|
|
89
|
-
### Rule 5.1 [P0]:
|
|
87
|
+
### Rule 5.1 [P0]: Phase Checkpoint Enforcement
|
|
90
88
|
- Phase 4 CANNOT be skipped for T3 operations
|
|
91
89
|
- Phase 5 requires `validation["approved"] == True`
|
|
92
90
|
- Phase 6 updates MUST complete after successful realization
|
|
@@ -54,7 +54,6 @@
|
|
|
54
54
|
"mcp__ide__executeCode",
|
|
55
55
|
"WebSearch",
|
|
56
56
|
"WebFetch",
|
|
57
|
-
|
|
58
57
|
"Bash(kubectl get:*)",
|
|
59
58
|
"Bash(kubectl describe:*)",
|
|
60
59
|
"Bash(kubectl logs:*)",
|
|
@@ -64,24 +63,20 @@
|
|
|
64
63
|
"Bash(kubectl top:*)",
|
|
65
64
|
"Bash(kubectl wait:*)",
|
|
66
65
|
"Bash(kubectl run:*)",
|
|
67
|
-
|
|
68
66
|
"Bash(flux check:*)",
|
|
69
67
|
"Bash(flux get:*)",
|
|
70
68
|
"Bash(flux version:*)",
|
|
71
|
-
|
|
72
69
|
"Bash(helm list:*)",
|
|
73
70
|
"Bash(helm status:*)",
|
|
74
71
|
"Bash(helm version:*)",
|
|
75
72
|
"Bash(helm template:*)",
|
|
76
73
|
"Bash(helm lint:*)",
|
|
77
|
-
|
|
78
74
|
"Bash(git status:*)",
|
|
79
75
|
"Bash(git log:*)",
|
|
80
76
|
"Bash(git diff:*)",
|
|
81
77
|
"Bash(git show:*)",
|
|
82
78
|
"Bash(git branch:*)",
|
|
83
79
|
"Bash(git init:*)",
|
|
84
|
-
|
|
85
80
|
"Bash(gcloud version:*)",
|
|
86
81
|
"Bash(gcloud config:*)",
|
|
87
82
|
"Bash(gcloud auth:*)",
|
|
@@ -101,13 +96,20 @@
|
|
|
101
96
|
"Bash(gcloud iam.*describe:*)",
|
|
102
97
|
"Bash(gcloud logging read:*)",
|
|
103
98
|
"Bash(gsutil ls:*)",
|
|
104
|
-
|
|
105
99
|
"Bash(terraform version:*)",
|
|
106
100
|
"Bash(terraform fmt:*)",
|
|
107
101
|
"Bash(terraform validate:*)",
|
|
108
102
|
"Bash(terraform show:*)",
|
|
109
103
|
"Bash(terraform output:*)",
|
|
110
|
-
|
|
104
|
+
"Bash(terraform output:*)",
|
|
105
|
+
"Bash(terragrunt init:*)",
|
|
106
|
+
"Bash(terragrunt plan:*)",
|
|
107
|
+
"Bash(terragrunt output:*)",
|
|
108
|
+
"Bash(terragrunt state list:*)",
|
|
109
|
+
"Bash(terragrunt show:*)",
|
|
110
|
+
"Bash(terragrunt validate:*)",
|
|
111
|
+
"Bash(terragrunt version:*)",
|
|
112
|
+
"Bash(terragrunt fmt:*)",
|
|
111
113
|
"Bash(aws s3 ls:*)",
|
|
112
114
|
"Bash(aws s3api get-:*)",
|
|
113
115
|
"Bash(aws s3api list-:*)",
|
|
@@ -128,7 +130,6 @@
|
|
|
128
130
|
"Bash(aws logs describe-:*)",
|
|
129
131
|
"Bash(aws logs get-log-events:*)",
|
|
130
132
|
"Bash(aws sts get-caller-identity:*)",
|
|
131
|
-
|
|
132
133
|
"Bash(docker ps:*)",
|
|
133
134
|
"Bash(docker images:*)",
|
|
134
135
|
"Bash(docker inspect:*)",
|
|
@@ -141,7 +142,6 @@
|
|
|
141
142
|
"Bash(docker version:*)",
|
|
142
143
|
"Bash(docker info:*)",
|
|
143
144
|
"Bash(docker system df:*)",
|
|
144
|
-
|
|
145
145
|
"Bash(ls:*)",
|
|
146
146
|
"Bash(pwd:*)",
|
|
147
147
|
"Bash(cd:*)",
|
|
@@ -172,33 +172,16 @@
|
|
|
172
172
|
"Bash(gcloud compute networks delete:*)",
|
|
173
173
|
"Bash(gsutil rm.*-r:*)",
|
|
174
174
|
"Bash(gsutil rb:*)",
|
|
175
|
-
|
|
176
175
|
"Bash(kubectl drain:*)",
|
|
177
176
|
"Bash(kubectl cordon:*)",
|
|
178
177
|
"Bash(kubectl uncordon:*)",
|
|
179
|
-
|
|
180
|
-
"Bash(terraform destroy:*)",
|
|
181
|
-
"Bash(terragrunt destroy:*)",
|
|
182
|
-
|
|
183
178
|
"Bash(aws ec2 terminate-instances:*)",
|
|
184
179
|
"Bash(aws rds delete-db-instance:*)",
|
|
185
180
|
"Bash(aws rds delete-db-cluster:*)",
|
|
186
181
|
"Bash(aws iam delete-:*)",
|
|
187
182
|
"Bash(aws iam.*delete.*policy:*)",
|
|
188
183
|
"Bash(aws cloudformation delete-stack:*)",
|
|
189
|
-
"Bash(aws lambda delete-function:*)",
|
|
190
|
-
"Bash(aws s3.*rb :*)",
|
|
191
|
-
"Bash(aws s3 rm.*--recursive:*)",
|
|
192
|
-
|
|
193
|
-
"Bash(docker rm:*)",
|
|
194
|
-
"Bash(docker rmi:*)",
|
|
195
|
-
"Bash(docker volume rm:*)",
|
|
196
|
-
"Bash(docker network rm:*)",
|
|
197
|
-
"Bash(docker system prune.*--all:*)",
|
|
198
|
-
"Bash(docker container prune:*)",
|
|
199
|
-
"Bash(docker image prune.*--all:*)",
|
|
200
|
-
"Bash(docker compose down.*--volumes:*)",
|
|
201
|
-
|
|
184
|
+
"Bash(aws lambda delete-function:*)",
|
|
202
185
|
"Bash(dd:*)",
|
|
203
186
|
"Bash(mkfs:*)",
|
|
204
187
|
"Bash(fdisk:*)"
|
|
@@ -208,7 +191,6 @@
|
|
|
208
191
|
"Edit",
|
|
209
192
|
"Write",
|
|
210
193
|
"NotebookEdit",
|
|
211
|
-
|
|
212
194
|
"Bash(kubectl delete:*)",
|
|
213
195
|
"Bash(kubectl rollout:*)",
|
|
214
196
|
"Bash(kubectl scale:*)",
|
|
@@ -217,41 +199,33 @@
|
|
|
217
199
|
"Bash(kubectl apply:*)",
|
|
218
200
|
"Bash(kubectl replace:*)",
|
|
219
201
|
"Bash(kubectl exec:*)",
|
|
220
|
-
|
|
221
202
|
"Bash(flux delete:*)",
|
|
222
203
|
"Bash(flux reconcile:*)",
|
|
223
204
|
"Bash(flux create:*)",
|
|
224
205
|
"Bash(flux suspend:*)",
|
|
225
206
|
"Bash(flux resume:*)",
|
|
226
|
-
|
|
227
207
|
"Bash(helm install:*)",
|
|
228
208
|
"Bash(helm upgrade:*)",
|
|
229
209
|
"Bash(helm uninstall:*)",
|
|
230
210
|
"Bash(helm delete:*)",
|
|
231
211
|
"Bash(helm rollback:*)",
|
|
232
|
-
|
|
233
212
|
"Bash(git commit:*)",
|
|
234
213
|
"Bash(git push:*)",
|
|
235
214
|
"Bash(git merge:*)",
|
|
236
215
|
"Bash(git rebase:*)",
|
|
237
216
|
"Bash(git cherry-pick:*)",
|
|
238
217
|
"Bash(git add:*)",
|
|
239
|
-
|
|
240
218
|
"Bash(terraform plan:*)",
|
|
241
219
|
"Bash(terraform apply:*)",
|
|
242
220
|
"Bash(terragrunt plan:*)",
|
|
243
221
|
"Bash(terragrunt apply:*)",
|
|
244
|
-
|
|
245
222
|
"Bash(rm:*)",
|
|
246
223
|
"Bash(rmdir:*)",
|
|
247
224
|
"Bash(mv:*)",
|
|
248
225
|
"Bash(cp:*)",
|
|
249
226
|
"Bash(chmod:*)",
|
|
250
227
|
"Bash(chown:*)",
|
|
251
|
-
|
|
252
|
-
"Bash(aws.*--dryrun:*)",
|
|
253
|
-
"Bash(aws s3 mb:*)",
|
|
254
|
-
"Bash(aws s3 cp:*)",
|
|
228
|
+
|
|
255
229
|
"Bash(aws s3api put-:*)",
|
|
256
230
|
"Bash(aws ec2 run-instances:*)",
|
|
257
231
|
"Bash(aws ec2 create-:*)",
|
|
@@ -269,8 +243,6 @@
|
|
|
269
243
|
"Bash(aws lambda update-:*)",
|
|
270
244
|
"Bash(aws cloudformation create-stack:*)",
|
|
271
245
|
"Bash(aws cloudformation update-stack:*)",
|
|
272
|
-
|
|
273
|
-
"Bash(gcloud.*--dryrun:*)",
|
|
274
246
|
"Bash(gcloud compute instances create:*)",
|
|
275
247
|
"Bash(gcloud compute instances stop:*)",
|
|
276
248
|
"Bash(gcloud compute instances start:*)",
|
|
@@ -286,28 +258,10 @@
|
|
|
286
258
|
"Bash(gsutil mb:*)",
|
|
287
259
|
"Bash(gsutil cp:*)",
|
|
288
260
|
"Bash(gcloud functions deploy:*)",
|
|
289
|
-
|
|
290
|
-
"Bash(
|
|
291
|
-
"Bash(
|
|
292
|
-
"Bash(
|
|
293
|
-
"Bash(docker start:*)",
|
|
294
|
-
"Bash(docker stop:*)",
|
|
295
|
-
"Bash(docker restart:*)",
|
|
296
|
-
"Bash(docker pause:*)",
|
|
297
|
-
"Bash(docker unpause:*)",
|
|
298
|
-
"Bash(docker rename:*)",
|
|
299
|
-
"Bash(docker cp:*)",
|
|
300
|
-
"Bash(docker tag:*)",
|
|
301
|
-
"Bash(docker push:*)",
|
|
302
|
-
"Bash(docker pull:*)",
|
|
303
|
-
"Bash(docker volume create:*)",
|
|
304
|
-
"Bash(docker network create:*)",
|
|
305
|
-
"Bash(docker network connect:*)",
|
|
306
|
-
"Bash(docker compose up:*)",
|
|
307
|
-
"Bash(docker compose down:*)",
|
|
308
|
-
"Bash(docker compose stop:*)",
|
|
309
|
-
"Bash(docker compose start:*)",
|
|
310
|
-
"Bash(docker compose restart:*)"
|
|
261
|
+
"Bash(terragrunt apply:*)",
|
|
262
|
+
"Bash(terragrunt destroy:*)",
|
|
263
|
+
"Bash(terraform destroy:*)",
|
|
264
|
+
"Bash(terraform destroy:*)"
|
|
311
265
|
]
|
|
312
266
|
},
|
|
313
267
|
|
|
@@ -345,29 +299,9 @@
|
|
|
345
299
|
"gcloud compute networks delete",
|
|
346
300
|
"gsutil rm.*-r",
|
|
347
301
|
"gsutil rb",
|
|
348
|
-
"terraform destroy",
|
|
349
|
-
"terragrunt destroy",
|
|
350
302
|
"git push.*--force",
|
|
351
|
-
"git push.*-f ",
|
|
352
303
|
"git reset.*--hard",
|
|
353
|
-
"kubectl drain"
|
|
354
|
-
"rm -rf /",
|
|
355
|
-
"dd if=",
|
|
356
|
-
"mkfs\\.",
|
|
357
|
-
"fdisk",
|
|
358
|
-
"aws ec2 terminate-instances",
|
|
359
|
-
"aws rds delete-db-instance",
|
|
360
|
-
"aws rds delete-db-cluster",
|
|
361
|
-
"aws iam delete-",
|
|
362
|
-
"aws cloudformation delete-stack",
|
|
363
|
-
"aws lambda delete-function",
|
|
364
|
-
"aws s3.*rb",
|
|
365
|
-
"docker rm",
|
|
366
|
-
"docker rmi",
|
|
367
|
-
"docker volume rm",
|
|
368
|
-
"docker network rm",
|
|
369
|
-
"docker system prune.*--all",
|
|
370
|
-
"docker compose down.*--volumes"
|
|
304
|
+
"kubectl drain"
|
|
371
305
|
]
|
|
372
306
|
},
|
|
373
307
|
|