comfygit-deploy 0.3.7__tar.gz
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.
- comfygit_deploy-0.3.7/.gitignore +87 -0
- comfygit_deploy-0.3.7/PKG-INFO +38 -0
- comfygit_deploy-0.3.7/README.md +28 -0
- comfygit_deploy-0.3.7/comfygit_deploy/__init__.py +3 -0
- comfygit_deploy-0.3.7/comfygit_deploy/cli.py +374 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/__init__.py +5 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/custom.py +218 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/dev.py +356 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/instances.py +506 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/runpod.py +203 -0
- comfygit_deploy-0.3.7/comfygit_deploy/commands/worker.py +272 -0
- comfygit_deploy-0.3.7/comfygit_deploy/config.py +122 -0
- comfygit_deploy-0.3.7/comfygit_deploy/providers/__init__.py +11 -0
- comfygit_deploy-0.3.7/comfygit_deploy/providers/custom.py +238 -0
- comfygit_deploy-0.3.7/comfygit_deploy/providers/runpod.py +549 -0
- comfygit_deploy-0.3.7/comfygit_deploy/startup/__init__.py +1 -0
- comfygit_deploy-0.3.7/comfygit_deploy/startup/scripts.py +210 -0
- comfygit_deploy-0.3.7/comfygit_deploy/worker/__init__.py +12 -0
- comfygit_deploy-0.3.7/comfygit_deploy/worker/mdns.py +154 -0
- comfygit_deploy-0.3.7/comfygit_deploy/worker/native_manager.py +438 -0
- comfygit_deploy-0.3.7/comfygit_deploy/worker/server.py +511 -0
- comfygit_deploy-0.3.7/comfygit_deploy/worker/state.py +268 -0
- comfygit_deploy-0.3.7/pyproject.toml +31 -0
- comfygit_deploy-0.3.7/tests/__init__.py +1 -0
- comfygit_deploy-0.3.7/tests/conftest.py +13 -0
- comfygit_deploy-0.3.7/tests/test_cli.py +95 -0
- comfygit_deploy-0.3.7/tests/test_config.py +95 -0
- comfygit_deploy-0.3.7/tests/test_custom_client.py +211 -0
- comfygit_deploy-0.3.7/tests/test_logs_streaming.py +327 -0
- comfygit_deploy-0.3.7/tests/test_mdns.py +64 -0
- comfygit_deploy-0.3.7/tests/test_mdns_scanner.py +202 -0
- comfygit_deploy-0.3.7/tests/test_native_manager.py +308 -0
- comfygit_deploy-0.3.7/tests/test_runpod_client.py +207 -0
- comfygit_deploy-0.3.7/tests/test_startup_script.py +118 -0
- comfygit_deploy-0.3.7/tests/test_unified_instances.py +407 -0
- comfygit_deploy-0.3.7/tests/test_worker_commands.py +407 -0
- comfygit_deploy-0.3.7/tests/test_worker_server.py +225 -0
- comfygit_deploy-0.3.7/tests/test_worker_state.py +361 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
env/
|
|
8
|
+
venv/
|
|
9
|
+
ENV/
|
|
10
|
+
.venv
|
|
11
|
+
pip-log.txt
|
|
12
|
+
pip-delete-this-directory.txt
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
dist/
|
|
16
|
+
build/
|
|
17
|
+
*.egg
|
|
18
|
+
.coverage
|
|
19
|
+
htmlcov/
|
|
20
|
+
.tox/
|
|
21
|
+
.mypy_cache/
|
|
22
|
+
.dmypy.json
|
|
23
|
+
dmypy.json
|
|
24
|
+
.pyre/
|
|
25
|
+
|
|
26
|
+
# Node
|
|
27
|
+
node_modules/
|
|
28
|
+
npm-debug.log*
|
|
29
|
+
yarn-debug.log*
|
|
30
|
+
yarn-error.log*
|
|
31
|
+
|
|
32
|
+
# Environment variables
|
|
33
|
+
.env
|
|
34
|
+
.env.local
|
|
35
|
+
.env.*.local
|
|
36
|
+
|
|
37
|
+
# IDE
|
|
38
|
+
.vscode/
|
|
39
|
+
.idea/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# OS
|
|
45
|
+
.DS_Store
|
|
46
|
+
Thumbs.db
|
|
47
|
+
|
|
48
|
+
# Docker
|
|
49
|
+
.dockerignore
|
|
50
|
+
|
|
51
|
+
# Test environments
|
|
52
|
+
dev/test-environments/
|
|
53
|
+
|
|
54
|
+
# Documentation build
|
|
55
|
+
docs/site/
|
|
56
|
+
docs/comfydock-docs/site/
|
|
57
|
+
|
|
58
|
+
# Logs
|
|
59
|
+
*.log
|
|
60
|
+
logs/
|
|
61
|
+
|
|
62
|
+
# Temporary files
|
|
63
|
+
*.tmp
|
|
64
|
+
temp/
|
|
65
|
+
tmp/
|
|
66
|
+
|
|
67
|
+
# Local configuration
|
|
68
|
+
local_config.json
|
|
69
|
+
|
|
70
|
+
# LLMD files:
|
|
71
|
+
*llm-context.md
|
|
72
|
+
.llmd
|
|
73
|
+
|
|
74
|
+
# Claude:
|
|
75
|
+
.claude/
|
|
76
|
+
|
|
77
|
+
# Docs:
|
|
78
|
+
docs/archive
|
|
79
|
+
docs/contexts
|
|
80
|
+
|
|
81
|
+
# Helper scripts:
|
|
82
|
+
.setup.sh
|
|
83
|
+
.scripts/
|
|
84
|
+
|
|
85
|
+
# Any test environment exports
|
|
86
|
+
*.tar.gz
|
|
87
|
+
.claude/context
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: comfygit-deploy
|
|
3
|
+
Version: 0.3.7
|
|
4
|
+
Summary: ComfyGit Deploy - Remote deployment and worker management CLI
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
7
|
+
Requires-Dist: comfygit==0.3.7
|
|
8
|
+
Requires-Dist: zeroconf>=0.131.0
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
|
|
11
|
+
# ComfyGit Deploy
|
|
12
|
+
|
|
13
|
+
Remote deployment and worker management CLI for ComfyGit.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install comfygit-deploy
|
|
19
|
+
# or
|
|
20
|
+
uv tool install comfygit-deploy
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Configure RunPod
|
|
27
|
+
cg-deploy runpod config --api-key <your-key>
|
|
28
|
+
|
|
29
|
+
# Deploy to RunPod
|
|
30
|
+
cg-deploy runpod deploy <git-url> --gpu "RTX 4090"
|
|
31
|
+
|
|
32
|
+
# Manage instances
|
|
33
|
+
cg-deploy instances
|
|
34
|
+
cg-deploy stop <instance-id>
|
|
35
|
+
cg-deploy terminate <instance-id>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
See the [documentation](../../docs/comfygit-docs/) for full usage information.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# ComfyGit Deploy
|
|
2
|
+
|
|
3
|
+
Remote deployment and worker management CLI for ComfyGit.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install comfygit-deploy
|
|
9
|
+
# or
|
|
10
|
+
uv tool install comfygit-deploy
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Configure RunPod
|
|
17
|
+
cg-deploy runpod config --api-key <your-key>
|
|
18
|
+
|
|
19
|
+
# Deploy to RunPod
|
|
20
|
+
cg-deploy runpod deploy <git-url> --gpu "RTX 4090"
|
|
21
|
+
|
|
22
|
+
# Manage instances
|
|
23
|
+
cg-deploy instances
|
|
24
|
+
cg-deploy stop <instance-id>
|
|
25
|
+
cg-deploy terminate <instance-id>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
See the [documentation](../../docs/comfygit-docs/) for full usage information.
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"""CLI entry point for comfygit-deploy.
|
|
2
|
+
|
|
3
|
+
Provides command-line interface for deploying ComfyUI environments
|
|
4
|
+
to cloud providers (RunPod) and self-hosted workers.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from . import __version__
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def create_parser() -> argparse.ArgumentParser:
|
|
14
|
+
"""Create the argument parser with all subcommands."""
|
|
15
|
+
parser = argparse.ArgumentParser(
|
|
16
|
+
prog="cg-deploy",
|
|
17
|
+
description="ComfyGit Deploy - Remote deployment and worker management",
|
|
18
|
+
)
|
|
19
|
+
parser.add_argument(
|
|
20
|
+
"--version",
|
|
21
|
+
action="version",
|
|
22
|
+
version=f"%(prog)s {__version__}",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
|
|
26
|
+
|
|
27
|
+
# =========================================================================
|
|
28
|
+
# RunPod commands
|
|
29
|
+
# =========================================================================
|
|
30
|
+
runpod_parser = subparsers.add_parser("runpod", help="RunPod operations")
|
|
31
|
+
runpod_subparsers = runpod_parser.add_subparsers(
|
|
32
|
+
dest="runpod_command", help="RunPod subcommands"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# runpod config
|
|
36
|
+
config_parser = runpod_subparsers.add_parser("config", help="Configure RunPod API key")
|
|
37
|
+
config_parser.add_argument("--api-key", help="Set RunPod API key")
|
|
38
|
+
config_parser.add_argument("--show", action="store_true", help="Show current config")
|
|
39
|
+
config_parser.add_argument("--clear", action="store_true", help="Clear stored API key")
|
|
40
|
+
|
|
41
|
+
# runpod gpus
|
|
42
|
+
gpus_parser = runpod_subparsers.add_parser("gpus", help="List available GPUs with pricing")
|
|
43
|
+
gpus_parser.add_argument("--region", help="Filter by region/data center")
|
|
44
|
+
|
|
45
|
+
# runpod volumes
|
|
46
|
+
runpod_subparsers.add_parser("volumes", help="List network volumes")
|
|
47
|
+
|
|
48
|
+
# runpod regions
|
|
49
|
+
runpod_subparsers.add_parser("regions", help="List data centers")
|
|
50
|
+
|
|
51
|
+
# runpod deploy
|
|
52
|
+
deploy_parser = runpod_subparsers.add_parser("deploy", help="Deploy environment to RunPod")
|
|
53
|
+
deploy_parser.add_argument("import_source", help="Git URL or local path to import")
|
|
54
|
+
deploy_parser.add_argument("--gpu", required=True, help="GPU type (e.g., 'RTX 4090')")
|
|
55
|
+
deploy_parser.add_argument("--volume", help="Network volume ID to attach")
|
|
56
|
+
deploy_parser.add_argument("--name", help="Deployment name")
|
|
57
|
+
deploy_parser.add_argument("--branch", "-b", help="Git branch/tag to use")
|
|
58
|
+
deploy_parser.add_argument(
|
|
59
|
+
"--cloud-type",
|
|
60
|
+
choices=["SECURE", "COMMUNITY"],
|
|
61
|
+
default="SECURE",
|
|
62
|
+
help="Cloud type (default: SECURE)",
|
|
63
|
+
)
|
|
64
|
+
deploy_parser.add_argument(
|
|
65
|
+
"--pricing-type",
|
|
66
|
+
choices=["ON_DEMAND", "SPOT"],
|
|
67
|
+
default="ON_DEMAND",
|
|
68
|
+
help="Pricing type (default: ON_DEMAND)",
|
|
69
|
+
)
|
|
70
|
+
deploy_parser.add_argument("--spot-bid", type=float, help="Spot bid price (for SPOT pricing)")
|
|
71
|
+
|
|
72
|
+
# =========================================================================
|
|
73
|
+
# Instance commands
|
|
74
|
+
# =========================================================================
|
|
75
|
+
instances_parser = subparsers.add_parser("instances", help="List all instances")
|
|
76
|
+
instances_parser.add_argument(
|
|
77
|
+
"--provider",
|
|
78
|
+
choices=["runpod", "custom"],
|
|
79
|
+
help="Filter by provider",
|
|
80
|
+
)
|
|
81
|
+
instances_parser.add_argument(
|
|
82
|
+
"--status",
|
|
83
|
+
choices=["running", "stopped"],
|
|
84
|
+
help="Filter by status",
|
|
85
|
+
)
|
|
86
|
+
instances_parser.add_argument("--json", action="store_true", help="Output as JSON")
|
|
87
|
+
|
|
88
|
+
# start
|
|
89
|
+
start_parser = subparsers.add_parser("start", help="Start a stopped instance")
|
|
90
|
+
start_parser.add_argument("instance_id", help="Instance ID to start")
|
|
91
|
+
|
|
92
|
+
# stop
|
|
93
|
+
stop_parser = subparsers.add_parser("stop", help="Stop a running instance")
|
|
94
|
+
stop_parser.add_argument("instance_id", help="Instance ID to stop")
|
|
95
|
+
|
|
96
|
+
# terminate
|
|
97
|
+
terminate_parser = subparsers.add_parser("terminate", help="Terminate an instance")
|
|
98
|
+
terminate_parser.add_argument("instance_id", help="Instance ID to terminate")
|
|
99
|
+
terminate_parser.add_argument("--force", action="store_true", help="Force termination")
|
|
100
|
+
terminate_parser.add_argument("--keep-env", action="store_true", help="Keep environment directory")
|
|
101
|
+
|
|
102
|
+
# logs
|
|
103
|
+
logs_parser = subparsers.add_parser("logs", help="View instance logs")
|
|
104
|
+
logs_parser.add_argument("instance_id", help="Instance ID")
|
|
105
|
+
logs_parser.add_argument("--follow", "-f", action="store_true", help="Follow log output")
|
|
106
|
+
logs_parser.add_argument("--lines", "-n", type=int, default=100, help="Number of lines")
|
|
107
|
+
|
|
108
|
+
# open
|
|
109
|
+
open_parser = subparsers.add_parser("open", help="Open ComfyUI URL in browser")
|
|
110
|
+
open_parser.add_argument("instance_id", help="Instance ID")
|
|
111
|
+
|
|
112
|
+
# wait
|
|
113
|
+
wait_parser = subparsers.add_parser("wait", help="Wait for instance to be ready")
|
|
114
|
+
wait_parser.add_argument("instance_id", help="Instance ID")
|
|
115
|
+
wait_parser.add_argument("--timeout", type=int, default=300, help="Timeout in seconds")
|
|
116
|
+
|
|
117
|
+
# =========================================================================
|
|
118
|
+
# Custom worker commands (Phase 2)
|
|
119
|
+
# =========================================================================
|
|
120
|
+
custom_parser = subparsers.add_parser("custom", help="Custom worker operations")
|
|
121
|
+
custom_subparsers = custom_parser.add_subparsers(
|
|
122
|
+
dest="custom_command", help="Custom worker subcommands"
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
# custom scan
|
|
126
|
+
scan_parser = custom_subparsers.add_parser("scan", help="Scan for workers via mDNS")
|
|
127
|
+
scan_parser.add_argument("--timeout", type=int, default=5, help="Scan timeout")
|
|
128
|
+
|
|
129
|
+
# custom add
|
|
130
|
+
add_parser = custom_subparsers.add_parser("add", help="Add a custom worker")
|
|
131
|
+
add_parser.add_argument("name", help="Worker name")
|
|
132
|
+
add_parser.add_argument("--host", help="Worker host/IP")
|
|
133
|
+
add_parser.add_argument("--port", type=int, default=9090, help="Worker port")
|
|
134
|
+
add_parser.add_argument("--api-key", help="Worker API key")
|
|
135
|
+
add_parser.add_argument(
|
|
136
|
+
"--discovered", action="store_true", help="Add from last scan results"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# custom remove
|
|
140
|
+
remove_parser = custom_subparsers.add_parser("remove", help="Remove a custom worker")
|
|
141
|
+
remove_parser.add_argument("name", help="Worker name")
|
|
142
|
+
|
|
143
|
+
# custom list
|
|
144
|
+
custom_subparsers.add_parser("list", help="List registered workers")
|
|
145
|
+
|
|
146
|
+
# custom test
|
|
147
|
+
test_parser = custom_subparsers.add_parser("test", help="Test worker connection")
|
|
148
|
+
test_parser.add_argument("name", help="Worker name")
|
|
149
|
+
|
|
150
|
+
# custom deploy
|
|
151
|
+
custom_deploy_parser = custom_subparsers.add_parser(
|
|
152
|
+
"deploy", help="Deploy to custom worker"
|
|
153
|
+
)
|
|
154
|
+
custom_deploy_parser.add_argument("worker_name", help="Worker to deploy to")
|
|
155
|
+
custom_deploy_parser.add_argument("import_source", help="Git URL or local path")
|
|
156
|
+
custom_deploy_parser.add_argument("--branch", "-b", help="Git branch/tag")
|
|
157
|
+
custom_deploy_parser.add_argument(
|
|
158
|
+
"--mode",
|
|
159
|
+
choices=["docker", "native"],
|
|
160
|
+
default="docker",
|
|
161
|
+
help="Deployment mode",
|
|
162
|
+
)
|
|
163
|
+
custom_deploy_parser.add_argument("--name", help="Environment name")
|
|
164
|
+
|
|
165
|
+
# =========================================================================
|
|
166
|
+
# Worker commands (runs on GPU machine, Phase 2)
|
|
167
|
+
# =========================================================================
|
|
168
|
+
worker_parser = subparsers.add_parser("worker", help="Worker server management")
|
|
169
|
+
worker_subparsers = worker_parser.add_subparsers(
|
|
170
|
+
dest="worker_command", help="Worker subcommands"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
# worker setup
|
|
174
|
+
setup_parser = worker_subparsers.add_parser("setup", help="One-time worker setup")
|
|
175
|
+
setup_parser.add_argument("--api-key", help="Set worker API key")
|
|
176
|
+
setup_parser.add_argument("--workspace", help="Workspace path")
|
|
177
|
+
|
|
178
|
+
# worker up
|
|
179
|
+
up_parser = worker_subparsers.add_parser("up", help="Start worker server")
|
|
180
|
+
up_parser.add_argument("--port", type=int, default=9090, help="Server port")
|
|
181
|
+
up_parser.add_argument("--host", default="0.0.0.0", help="Bind host")
|
|
182
|
+
up_parser.add_argument(
|
|
183
|
+
"--mode",
|
|
184
|
+
choices=["docker", "native"],
|
|
185
|
+
default="docker",
|
|
186
|
+
help="Instance mode",
|
|
187
|
+
)
|
|
188
|
+
up_parser.add_argument("--broadcast", action="store_true", help="Enable mDNS broadcast")
|
|
189
|
+
up_parser.add_argument("--port-range", default="8200:8210", help="Instance port range")
|
|
190
|
+
up_parser.add_argument("--dev", action="store_true", help="Use saved dev config (from 'dev setup')")
|
|
191
|
+
up_parser.add_argument("--dev-core", metavar="PATH", help="Use local comfygit-core (editable)")
|
|
192
|
+
up_parser.add_argument("--dev-manager", metavar="PATH", help="Use local comfygit-manager")
|
|
193
|
+
|
|
194
|
+
# worker down
|
|
195
|
+
worker_subparsers.add_parser("down", help="Stop worker server")
|
|
196
|
+
|
|
197
|
+
# worker status
|
|
198
|
+
worker_subparsers.add_parser("status", help="Show worker status")
|
|
199
|
+
|
|
200
|
+
# worker regenerate-key
|
|
201
|
+
worker_subparsers.add_parser("regenerate-key", help="Regenerate API key")
|
|
202
|
+
|
|
203
|
+
# =========================================================================
|
|
204
|
+
# Dev commands (development mode setup)
|
|
205
|
+
# =========================================================================
|
|
206
|
+
dev_parser = subparsers.add_parser("dev", help="Development mode setup")
|
|
207
|
+
dev_subparsers = dev_parser.add_subparsers(dest="dev_command", help="Dev subcommands")
|
|
208
|
+
|
|
209
|
+
# dev setup
|
|
210
|
+
dev_setup_parser = dev_subparsers.add_parser(
|
|
211
|
+
"setup", help="Configure local dev paths for core/manager"
|
|
212
|
+
)
|
|
213
|
+
dev_setup_parser.add_argument("--core", metavar="PATH", help="Path to comfygit-core package")
|
|
214
|
+
dev_setup_parser.add_argument("--manager", metavar="PATH", help="Path to comfygit-manager")
|
|
215
|
+
dev_setup_parser.add_argument("--show", action="store_true", help="Show current dev config")
|
|
216
|
+
dev_setup_parser.add_argument("--clear", action="store_true", help="Clear dev config")
|
|
217
|
+
|
|
218
|
+
# dev patch
|
|
219
|
+
dev_patch_parser = dev_subparsers.add_parser(
|
|
220
|
+
"patch", help="Patch existing environments with dev config"
|
|
221
|
+
)
|
|
222
|
+
dev_patch_parser.add_argument("--env", help="Specific environment to patch (default: all)")
|
|
223
|
+
|
|
224
|
+
# dev add-node
|
|
225
|
+
dev_add_node_parser = dev_subparsers.add_parser(
|
|
226
|
+
"add-node", help="Add a dev node to be symlinked into environments"
|
|
227
|
+
)
|
|
228
|
+
dev_add_node_parser.add_argument("name", help="Node directory name (e.g., ComfyUI-Async-API)")
|
|
229
|
+
dev_add_node_parser.add_argument("path", help="Path to the node source directory")
|
|
230
|
+
|
|
231
|
+
# dev remove-node
|
|
232
|
+
dev_remove_node_parser = dev_subparsers.add_parser(
|
|
233
|
+
"remove-node", help="Remove a dev node from config"
|
|
234
|
+
)
|
|
235
|
+
dev_remove_node_parser.add_argument("name", help="Node name to remove")
|
|
236
|
+
|
|
237
|
+
# dev list-nodes
|
|
238
|
+
dev_subparsers.add_parser("list-nodes", help="List configured dev nodes")
|
|
239
|
+
|
|
240
|
+
return parser
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def main(args: list[str] | None = None) -> int:
|
|
244
|
+
"""Main entry point for cg-deploy CLI.
|
|
245
|
+
|
|
246
|
+
Args:
|
|
247
|
+
args: Command-line arguments (uses sys.argv if None)
|
|
248
|
+
|
|
249
|
+
Returns:
|
|
250
|
+
Exit code (0 for success, non-zero for errors)
|
|
251
|
+
"""
|
|
252
|
+
parser = create_parser()
|
|
253
|
+
parsed = parser.parse_args(args)
|
|
254
|
+
|
|
255
|
+
if not parsed.command:
|
|
256
|
+
parser.print_help()
|
|
257
|
+
return 0
|
|
258
|
+
|
|
259
|
+
# Import command handlers
|
|
260
|
+
from .commands import instances as instance_commands
|
|
261
|
+
from .commands import runpod as runpod_commands
|
|
262
|
+
|
|
263
|
+
# Dispatch to command handlers
|
|
264
|
+
try:
|
|
265
|
+
if parsed.command == "runpod":
|
|
266
|
+
if not parsed.runpod_command:
|
|
267
|
+
parser.parse_args(["runpod", "--help"])
|
|
268
|
+
return 0
|
|
269
|
+
handler_map = {
|
|
270
|
+
"config": runpod_commands.handle_config,
|
|
271
|
+
"gpus": runpod_commands.handle_gpus,
|
|
272
|
+
"volumes": runpod_commands.handle_volumes,
|
|
273
|
+
"regions": runpod_commands.handle_regions,
|
|
274
|
+
"deploy": runpod_commands.handle_deploy,
|
|
275
|
+
}
|
|
276
|
+
handler = handler_map.get(parsed.runpod_command)
|
|
277
|
+
if handler:
|
|
278
|
+
return handler(parsed)
|
|
279
|
+
print(f"Unknown runpod command: {parsed.runpod_command}")
|
|
280
|
+
return 1
|
|
281
|
+
|
|
282
|
+
elif parsed.command == "instances":
|
|
283
|
+
return instance_commands.handle_instances(parsed)
|
|
284
|
+
|
|
285
|
+
elif parsed.command == "start":
|
|
286
|
+
return instance_commands.handle_start(parsed)
|
|
287
|
+
|
|
288
|
+
elif parsed.command == "stop":
|
|
289
|
+
return instance_commands.handle_stop(parsed)
|
|
290
|
+
|
|
291
|
+
elif parsed.command == "terminate":
|
|
292
|
+
return instance_commands.handle_terminate(parsed)
|
|
293
|
+
|
|
294
|
+
elif parsed.command == "open":
|
|
295
|
+
return instance_commands.handle_open(parsed)
|
|
296
|
+
|
|
297
|
+
elif parsed.command == "wait":
|
|
298
|
+
return instance_commands.handle_wait(parsed)
|
|
299
|
+
|
|
300
|
+
elif parsed.command == "logs":
|
|
301
|
+
return instance_commands.handle_logs(parsed)
|
|
302
|
+
|
|
303
|
+
elif parsed.command == "worker":
|
|
304
|
+
from .commands import worker as worker_commands
|
|
305
|
+
|
|
306
|
+
if not parsed.worker_command:
|
|
307
|
+
parser.parse_args(["worker", "--help"])
|
|
308
|
+
return 0
|
|
309
|
+
handler_map = {
|
|
310
|
+
"setup": worker_commands.handle_setup,
|
|
311
|
+
"up": worker_commands.handle_up,
|
|
312
|
+
"down": worker_commands.handle_down,
|
|
313
|
+
"status": worker_commands.handle_status,
|
|
314
|
+
"regenerate-key": worker_commands.handle_regenerate_key,
|
|
315
|
+
}
|
|
316
|
+
handler = handler_map.get(parsed.worker_command)
|
|
317
|
+
if handler:
|
|
318
|
+
return handler(parsed)
|
|
319
|
+
print(f"Unknown worker command: {parsed.worker_command}")
|
|
320
|
+
return 1
|
|
321
|
+
|
|
322
|
+
elif parsed.command == "custom":
|
|
323
|
+
from .commands import custom as custom_commands
|
|
324
|
+
|
|
325
|
+
if not parsed.custom_command:
|
|
326
|
+
parser.parse_args(["custom", "--help"])
|
|
327
|
+
return 0
|
|
328
|
+
handler_map = {
|
|
329
|
+
"scan": custom_commands.handle_scan,
|
|
330
|
+
"add": custom_commands.handle_add,
|
|
331
|
+
"remove": custom_commands.handle_remove,
|
|
332
|
+
"list": custom_commands.handle_list,
|
|
333
|
+
"test": custom_commands.handle_test,
|
|
334
|
+
"deploy": custom_commands.handle_deploy,
|
|
335
|
+
}
|
|
336
|
+
handler = handler_map.get(parsed.custom_command)
|
|
337
|
+
if handler:
|
|
338
|
+
return handler(parsed)
|
|
339
|
+
print(f"Unknown custom command: {parsed.custom_command}")
|
|
340
|
+
return 1
|
|
341
|
+
|
|
342
|
+
elif parsed.command == "dev":
|
|
343
|
+
from .commands import dev as dev_commands
|
|
344
|
+
|
|
345
|
+
if not parsed.dev_command:
|
|
346
|
+
parser.parse_args(["dev", "--help"])
|
|
347
|
+
return 0
|
|
348
|
+
handler_map = {
|
|
349
|
+
"setup": dev_commands.handle_setup,
|
|
350
|
+
"patch": dev_commands.handle_patch,
|
|
351
|
+
"add-node": dev_commands.handle_add_node,
|
|
352
|
+
"remove-node": dev_commands.handle_remove_node,
|
|
353
|
+
"list-nodes": dev_commands.handle_list_nodes,
|
|
354
|
+
}
|
|
355
|
+
handler = handler_map.get(parsed.dev_command)
|
|
356
|
+
if handler:
|
|
357
|
+
return handler(parsed)
|
|
358
|
+
print(f"Unknown dev command: {parsed.dev_command}")
|
|
359
|
+
return 1
|
|
360
|
+
|
|
361
|
+
else:
|
|
362
|
+
print(f"Unknown command: {parsed.command}")
|
|
363
|
+
return 1
|
|
364
|
+
|
|
365
|
+
except KeyboardInterrupt:
|
|
366
|
+
print("\nCancelled.")
|
|
367
|
+
return 130
|
|
368
|
+
except Exception as e:
|
|
369
|
+
print(f"Error: {e}")
|
|
370
|
+
return 1
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
if __name__ == "__main__":
|
|
374
|
+
sys.exit(main())
|