Skip to content

Commit 9a8bd4e

Browse files
authored
feat: smart bootstrap and deploy (#168)
* feat: smart bootstrap and deploy * fix: add missing files * fix: code cleanup * fix: add dev mode situation * fix: development build
1 parent ee86e69 commit 9a8bd4e

24 files changed

+1031
-263404
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,6 @@ emd_models/
134134
**artifacts
135135
src/pipeline/emd
136136
*.log
137+
.venv
138+
.idea
139+
.venv-*

assets/s5cmd

-11.8 MB
Binary file not shown.

docs/images/emd-deploy.gif

-7.15 MB
Binary file not shown.

docs/images/status.png

-655 KB
Binary file not shown.

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ readme = "README.md"
1212
[tool.poetry]
1313
packages = [
1414
{ include = "**/*", from = "src/emd", to = "emd" },
15-
{ include = "pipeline", from = "src", to = "emd" },
16-
{ include = "s5cmd", from = "assets", to = "emd/pipeline" }
15+
{ include = "pipeline", from = "src", to = "emd" }
1716
]
1817
exclude = [".venv"]
1918

src/emd/cfn/codepipeline/template.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ Resources:
223223
export PYTHONPATH=.:$PYTHONPATH
224224
pip install --upgrade pip
225225
pip install -r requirements.txt
226+
# Download and setup s5cmd
227+
echo "Downloading s5cmd..."
228+
if [[ "$region" == cn-* ]]; then
229+
s5cmd_url="https://aws-gcr-solutions-cn-north-1.s3.cn-north-1.amazonaws.com.cn/easy-model-deployer/pipeline/s5cmd.zip"
230+
else
231+
s5cmd_url="https://aws-gcr-solutions-us-east-1.s3.us-east-1.amazonaws.com/easy-model-deployer/pipeline/s5cmd.zip"
232+
fi
233+
curl -L -o s5cmd.zip "$s5cmd_url"
234+
unzip -o s5cmd.zip
235+
chmod +x s5cmd
236+
echo "s5cmd setup completed"
226237
python pipeline.py --region $region --model_id $model_id --model_tag $ModelTag --framework_type $FrameworkType --service_type $service --backend_type $backend_name --model_s3_bucket $model_s3_bucket --instance_type $instance_type --extra_params "$extra_params" --skip_deploy
227238
# cd ..
228239
echo model build pipeline completed on `date`

src/emd/commands/bootstrap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def bootstrap(
2424
):
2525

2626
region = get_current_region()
27-
typer.echo("AWS environment is properly configured.")
27+
typer.echo("AWS environment configuration verified.")
2828
layout["main"].update("[bold red]Initalizing environment...[/bold red]")
2929
try:
3030
bucket_name = get_bucket_name(

src/emd/commands/deploy.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import questionary
2727
from emd.utils.accelerator_utils import get_gpu_num,check_cuda_exists,check_neuron_exists
2828
from emd.utils.decorators import catch_aws_credential_errors,check_emd_env_exist,load_aws_profile
29+
from emd.utils.smart_bootstrap import smart_bootstrap_manager
2930
from emd.utils.logger_utils import make_layout
3031
from emd.utils.exceptions import ModelNotSupported,ServiceNotSupported,InstanceNotSupported
3132
from prompt_toolkit import prompt
@@ -252,6 +253,9 @@ def deploy(
252253
else:
253254
region = get_current_region()
254255

256+
if region != LOCAL_REGION:
257+
smart_bootstrap_manager.auto_bootstrap_if_needed(region)
258+
255259
if dockerfile_local_path:
256260
response = sdk_deploy(
257261
model_id='custom-docker',
@@ -571,13 +575,13 @@ def deploy(
571575
engine_info_str = json.dumps(engine_info,indent=2,ensure_ascii=False)
572576
framework_info_str = json.dumps(framework_info, indent=2, ensure_ascii=False)
573577
extra_params_info = json.dumps(extra_params, indent=2, ensure_ascii=False)
574-
console.print(f"[bold blue]Deployment parameters:[/bold blue]")
575-
console.print(f"[bold blue]model_id: {model_id},model_tag: {model_tag}[/bold blue]")
576-
console.print(f"[bold blue]instance_type: {instance_type}[/bold blue]")
577-
console.print(f"[bold blue]service_type: {service_type}[/bold blue]")
578-
console.print(f"[bold blue]engine info:\n {engine_info_str}[/bold blue]")
579-
console.print(f"[bold blue]framework info:\n {framework_info_str}[/bold blue]")
580-
console.print(f"[bold blue]extra_params:\n {extra_params_info}[/bold blue]")
578+
console.print(f"[bold magenta]Deployment parameters:[/bold magenta]")
579+
console.print(f"[bold cyan]model_id: {model_id}, model_tag: {model_tag}[/bold cyan]")
580+
console.print(f"[bold cyan]instance_type: {instance_type}[/bold cyan]")
581+
console.print(f"[bold cyan]service_type: {service_type}[/bold cyan]")
582+
console.print(f"[bold white]engine_parameters:[/bold white]\n[dim cyan]{engine_info_str}[/dim cyan]")
583+
console.print(f"[bold white]framework_parameters:[/bold white]\n[dim cyan]{framework_info_str}[/dim cyan]")
584+
console.print(f"[bold white]extra_parameters:[/bold white]\n[dim cyan]{extra_params_info}[/dim cyan]")
581585
# Start pipeline execution
582586
if service_type != ServiceType.LOCAL:
583587
response = sdk_deploy(
@@ -592,7 +596,7 @@ def deploy(
592596
force_env_stack_update = force_update_env_stack,
593597
waiting_until_deploy_complete=True
594598
)
595-
console.print(f"[bold green]Model deployment pipeline execution initiated. Execution ID: {response['pipeline_execution_id']}[/bold green]")
599+
console.print(f"[bold green]Model deployment pipeline started. Execution ID: {response['pipeline_execution_id']}[/bold green]")
596600
else:
597601
response = sdk_deploy_local(
598602
model_id=model_id,

src/emd/commands/status.py

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,45 @@ def status(
2828
str, typer.Argument(help="Model tag")
2929
] = MODEL_DEFAULT_TAG,
3030
):
31-
# Show loading indicator while fetching model status
32-
with console.status("[bold green]Fetching model status...", spinner="dots"):
31+
with console.status("[bold green]Fetching model deployment status. Please wait patiently", spinner="dots"):
3332
ret = get_model_status(model_id, model_tag=model_tag)
3433

3534
inprogress = ret['inprogress']
3635
completed = ret['completed']
3736

3837
data = []
39-
# Process all in-progress executions (now includes ALL parallel executions)
38+
cli_messages = [] # Store CLI messages for display after the table
39+
40+
# Process all in-progress executions (now includes enhanced pipeline-stack logic)
4041
for d in inprogress:
4142
if d['status'] == "Stopped":
4243
continue
44+
45+
# Use enhanced status if available, otherwise fall back to original logic
46+
if d.get('enhanced_status'):
47+
display_status = d['enhanced_status']
48+
else:
49+
display_status = f"{d['status']} ({d['stage_name']})" if d.get('stage_name') else d['status']
50+
4351
data.append({
4452
"model_id": d['model_id'],
4553
"model_tag": d['model_tag'],
46-
"status": f"{d['status']} ({d['stage_name']})" if d.get('stage_name') else d['status'],
54+
"status": display_status,
4755
"service_type": d.get('service_type', ''),
4856
"instance_type": d.get('instance_type', ''),
4957
"create_time": d.get('create_time', ''),
5058
"outputs": d.get('outputs', ''), # Use .get() to handle missing outputs field
5159
})
5260

61+
# Collect CLI messages for this model
62+
if d.get('cli_message'):
63+
model_name = f"{d['model_id']}/{d['model_tag']}"
64+
cli_messages.append({
65+
'model_name': model_name,
66+
'message_type': d['cli_message'],
67+
'stack_name': d.get('stack_name', '')
68+
})
69+
5370
# Process completed models
5471
for d in completed:
5572
data.append({
@@ -152,6 +169,29 @@ def status(
152169
# Display the table
153170
console.print(models_table)
154171

172+
# Display CLI messages for user guidance
173+
if cli_messages:
174+
console.print("\n" + "=" * 60, style="dim")
175+
console.print("📋 Action Required", style="bold yellow")
176+
console.print("=" * 60, style="dim")
177+
178+
for msg in cli_messages:
179+
model_name = msg['model_name']
180+
message_type = msg['message_type']
181+
182+
if message_type == 'cleanup_warning':
183+
stack_name = msg['stack_name']
184+
console.print(f"\n🔧 [bold]{model_name}[/bold]")
185+
console.print(" [yellow]⚠️ Failed stack detected. Manual cleanup required:[/yellow]")
186+
console.print(f" [dim]aws cloudformation delete-stack --stack-name {stack_name}[/dim]")
187+
188+
elif message_type == 'codepipeline_console':
189+
console.print(f"\n🔍 [bold]{model_name}[/bold]")
190+
console.print(" [blue]💡 Check CodePipeline console for detailed logs:[/blue]")
191+
console.print(" [dim]AWS Console → CodePipeline → EMD-Env-Pipeline[/dim]")
192+
193+
console.print()
194+
155195
# Display the Base URL section after the Models
156196
console.print("\nBase URL", style="bold")
157197
if base_url:

src/emd/sample/vlm_sample_data.jpg

-356 KB
Loading

0 commit comments

Comments
 (0)