336 lines
11 KiB
Python
336 lines
11 KiB
Python
|
#!/usr/bin/env python3
|
||
|
"""
|
||
|
Example usage of the Container Management API Client
|
||
|
"""
|
||
|
|
||
|
import asyncio
|
||
|
import sys
|
||
|
from container_client import ContainerClient, ContainerConfig
|
||
|
|
||
|
|
||
|
async def example_basic_operations():
|
||
|
"""Basic container operations example"""
|
||
|
print("=== Basic Container Operations ===\n")
|
||
|
|
||
|
async with ContainerClient("http://localhost:8080", "admin", "password") as client:
|
||
|
# Check API health
|
||
|
health = await client.health_check()
|
||
|
print(f"✓ API Status: {health.status}")
|
||
|
print(f"✓ Compose Version: {health.compose_version}\n")
|
||
|
|
||
|
# Create a container
|
||
|
print("Creating container...")
|
||
|
container = await client.create_container(
|
||
|
image="python:3.12-slim",
|
||
|
env={
|
||
|
"APP_NAME": "example_app",
|
||
|
"ENV": "development"
|
||
|
},
|
||
|
tags=["example", "test"],
|
||
|
resources={
|
||
|
"cpus": 0.5,
|
||
|
"memory": "512m"
|
||
|
}
|
||
|
)
|
||
|
print(f"✓ Created container: {container.cuid}\n")
|
||
|
|
||
|
# Upload a simple Python script
|
||
|
print("Uploading application code...")
|
||
|
files = {
|
||
|
"boot.py": b"""
|
||
|
import os
|
||
|
import time
|
||
|
|
||
|
print(f"Container {os.environ.get('CONTAINER_UID')} starting...")
|
||
|
print(f"App Name: {os.environ.get('APP_NAME')}")
|
||
|
print(f"Environment: {os.environ.get('ENV')}")
|
||
|
print("Ready!")
|
||
|
|
||
|
# Keep running
|
||
|
for i in range(5):
|
||
|
print(f"Working... {i+1}/5")
|
||
|
time.sleep(1)
|
||
|
|
||
|
print("Done!")
|
||
|
"""
|
||
|
}
|
||
|
await client.upload_zip(container.cuid, files=files)
|
||
|
print("✓ Code uploaded\n")
|
||
|
|
||
|
# Start the container
|
||
|
print("Starting container...")
|
||
|
await client.start_container(container.cuid)
|
||
|
await client.wait_for_status(container.cuid, "running", timeout=10)
|
||
|
print("✓ Container running\n")
|
||
|
|
||
|
# Execute the script and stream output
|
||
|
print("Executing application:")
|
||
|
print("-" * 40)
|
||
|
|
||
|
def print_output(data):
|
||
|
print(data, end="")
|
||
|
|
||
|
exit_code = await client.stream_output(
|
||
|
container.cuid,
|
||
|
"python /app/boot.py",
|
||
|
on_stdout=print_output
|
||
|
)
|
||
|
|
||
|
print("-" * 40)
|
||
|
print(f"✓ Exit code: {exit_code}\n")
|
||
|
|
||
|
# Get container status
|
||
|
status = await client.get_status(container.cuid)
|
||
|
print(f"Container Status: {status.status}")
|
||
|
print(f"Uptime: {status.uptime}\n")
|
||
|
|
||
|
# Clean up
|
||
|
print("Cleaning up...")
|
||
|
await client.stop_container(container.cuid)
|
||
|
await client.delete_container(container.cuid)
|
||
|
print("✓ Container deleted\n")
|
||
|
|
||
|
|
||
|
async def example_interactive_terminal():
|
||
|
"""Interactive terminal example"""
|
||
|
print("=== Interactive Terminal Example ===\n")
|
||
|
|
||
|
async with ContainerClient("http://localhost:8080", "admin", "password") as client:
|
||
|
# Create a container with development tools
|
||
|
print("Creating development container...")
|
||
|
container = await client.create_container(
|
||
|
image="python:3.12",
|
||
|
env={"PS1": "\\u@container:\\w$ "},
|
||
|
tags=["interactive", "development"]
|
||
|
)
|
||
|
print(f"✓ Created container: {container.cuid}\n")
|
||
|
|
||
|
# Upload some sample files
|
||
|
files = {
|
||
|
"boot.py": b"#!/usr/bin/env python3\nprint('Container ready for interactive use!')\n",
|
||
|
"hello.py": b"print('Hello from the container!')\n",
|
||
|
"data.txt": b"Sample data file\n"
|
||
|
}
|
||
|
await client.upload_zip(container.cuid, files=files)
|
||
|
|
||
|
# Start container
|
||
|
await client.start_container(container.cuid)
|
||
|
await client.wait_for_status(container.cuid, "running")
|
||
|
|
||
|
print("Entering interactive terminal...")
|
||
|
print("Commands to try:")
|
||
|
print(" - ls -la")
|
||
|
print(" - python hello.py")
|
||
|
print(" - cat data.txt")
|
||
|
print(" - python --version")
|
||
|
print("\nPress Ctrl+] to exit the terminal\n")
|
||
|
print("=" * 40)
|
||
|
|
||
|
# Enter interactive terminal
|
||
|
await client.enter_container(container.cuid)
|
||
|
|
||
|
# Clean up after terminal session
|
||
|
print("\n" + "=" * 40)
|
||
|
print("\nCleaning up...")
|
||
|
await client.stop_container(container.cuid)
|
||
|
await client.delete_container(container.cuid)
|
||
|
print("✓ Container deleted\n")
|
||
|
|
||
|
|
||
|
async def example_batch_operations():
|
||
|
"""Batch operations example"""
|
||
|
print("=== Batch Operations Example ===\n")
|
||
|
|
||
|
async with ContainerClient("http://localhost:8080", "admin", "password") as client:
|
||
|
# Create multiple containers at once
|
||
|
print("Creating 3 containers in parallel...")
|
||
|
|
||
|
configs = [
|
||
|
ContainerConfig(
|
||
|
image="alpine:latest",
|
||
|
env={"NAME": "Worker 1"},
|
||
|
tags=["worker", "batch"]
|
||
|
),
|
||
|
ContainerConfig(
|
||
|
image="alpine:latest",
|
||
|
env={"NAME": "Worker 2"},
|
||
|
tags=["worker", "batch"]
|
||
|
),
|
||
|
ContainerConfig(
|
||
|
image="alpine:latest",
|
||
|
env={"NAME": "Worker 3"},
|
||
|
tags=["worker", "batch"]
|
||
|
)
|
||
|
]
|
||
|
|
||
|
containers = await client.batch_create(configs)
|
||
|
print(f"✓ Created {len(containers)} containers\n")
|
||
|
|
||
|
# Prepare containers with a simple script
|
||
|
for i, container in enumerate(containers, 1):
|
||
|
files = {
|
||
|
"boot.py": f"""
|
||
|
import os
|
||
|
print(f"Worker {{os.environ.get('NAME')}} ready!")
|
||
|
""".encode()
|
||
|
}
|
||
|
await client.upload_zip(container.cuid, files=files)
|
||
|
await client.start_container(container.cuid)
|
||
|
|
||
|
print("Executing commands on all containers...")
|
||
|
|
||
|
# Execute commands in parallel
|
||
|
commands = {
|
||
|
containers[0].cuid: "echo 'Worker 1 processing...' && sleep 1 && echo 'Worker 1 done!'",
|
||
|
containers[1].cuid: "echo 'Worker 2 processing...' && sleep 1 && echo 'Worker 2 done!'",
|
||
|
containers[2].cuid: "echo 'Worker 3 processing...' && sleep 1 && echo 'Worker 3 done!'"
|
||
|
}
|
||
|
|
||
|
results = await client.batch_execute(commands, timeout=10)
|
||
|
|
||
|
print("\nResults:")
|
||
|
print("-" * 40)
|
||
|
for i, (cuid, (stdout, stderr, exit_code)) in enumerate(results.items(), 1):
|
||
|
print(f"Worker {i}:")
|
||
|
print(f" Output: {stdout.strip()}")
|
||
|
print(f" Exit Code: {exit_code}")
|
||
|
print("-" * 40)
|
||
|
|
||
|
# Clean up all containers
|
||
|
print("\nCleaning up all containers...")
|
||
|
cuids = [c.cuid for c in containers]
|
||
|
errors = await client.batch_delete(cuids)
|
||
|
|
||
|
failed = sum(1 for e in errors if e is not None)
|
||
|
if failed == 0:
|
||
|
print(f"✓ All {len(containers)} containers deleted\n")
|
||
|
else:
|
||
|
print(f"⚠ Deleted {len(containers) - failed} containers, {failed} failed\n")
|
||
|
|
||
|
|
||
|
async def example_file_operations():
|
||
|
"""File upload and download example"""
|
||
|
print("=== File Operations Example ===\n")
|
||
|
|
||
|
async with ContainerClient("http://localhost:8080", "admin", "password") as client:
|
||
|
# Create container
|
||
|
print("Creating container for file operations...")
|
||
|
container = await client.create_container(
|
||
|
image="python:3.12-slim",
|
||
|
tags=["files", "example"]
|
||
|
)
|
||
|
print(f"✓ Created container: {container.cuid}\n")
|
||
|
|
||
|
# Upload multiple files
|
||
|
print("Uploading application files...")
|
||
|
app_files = {
|
||
|
"app.py": b"""
|
||
|
import json
|
||
|
|
||
|
# Generate some data
|
||
|
data = {
|
||
|
'processed': True,
|
||
|
'items': [1, 2, 3, 4, 5],
|
||
|
'message': 'Data processed successfully'
|
||
|
}
|
||
|
|
||
|
# Save to file
|
||
|
with open('output.json', 'w') as f:
|
||
|
json.dump(data, f, indent=2)
|
||
|
|
||
|
print('Data saved to output.json')
|
||
|
""",
|
||
|
"config/settings.json": b'{"debug": true, "version": "1.0"}',
|
||
|
"data/input.txt": b"Sample input data\nLine 2\nLine 3",
|
||
|
"boot.py": b"print('Container ready!')"
|
||
|
}
|
||
|
|
||
|
await client.upload_zip(container.cuid, files=app_files)
|
||
|
print("✓ Files uploaded\n")
|
||
|
|
||
|
# Start container and run the app
|
||
|
await client.start_container(container.cuid)
|
||
|
|
||
|
print("Running application...")
|
||
|
stdout, stderr, exit_code = await client.execute_command(
|
||
|
container.cuid,
|
||
|
"python app.py"
|
||
|
)
|
||
|
print(f"Output: {stdout}")
|
||
|
|
||
|
# Download the generated file
|
||
|
print("\nDownloading generated file...")
|
||
|
content = await client.download_file(
|
||
|
container.cuid,
|
||
|
path="output.json"
|
||
|
)
|
||
|
|
||
|
import json
|
||
|
result = json.loads(content)
|
||
|
print(f"Downloaded content: {json.dumps(result, indent=2)}\n")
|
||
|
|
||
|
# Download entire directory as ZIP
|
||
|
print("Downloading entire container as ZIP...")
|
||
|
zip_data = await client.download_zip(
|
||
|
container.cuid,
|
||
|
path="",
|
||
|
save_to="container_backup.zip"
|
||
|
)
|
||
|
print(f"✓ Saved backup to container_backup.zip ({len(zip_data)} bytes)\n")
|
||
|
|
||
|
# Clean up
|
||
|
await client.stop_container(container.cuid)
|
||
|
await client.delete_container(container.cuid)
|
||
|
print("✓ Container deleted\n")
|
||
|
|
||
|
|
||
|
async def main():
|
||
|
"""Main function to run examples"""
|
||
|
examples = {
|
||
|
"1": ("Basic Operations", example_basic_operations),
|
||
|
"2": ("Interactive Terminal", example_interactive_terminal),
|
||
|
"3": ("Batch Operations", example_batch_operations),
|
||
|
"4": ("File Operations", example_file_operations)
|
||
|
}
|
||
|
|
||
|
print("\nContainer Management API Client Examples")
|
||
|
print("=" * 40)
|
||
|
print("\nAvailable examples:")
|
||
|
for key, (name, _) in examples.items():
|
||
|
print(f" {key}. {name}")
|
||
|
print(" 0. Run all examples")
|
||
|
print(" q. Quit")
|
||
|
|
||
|
choice = input("\nSelect an example (0-4 or q): ").strip().lower()
|
||
|
|
||
|
if choice == 'q':
|
||
|
print("Goodbye!")
|
||
|
return
|
||
|
elif choice == '0':
|
||
|
# Run all examples
|
||
|
for name, func in examples.values():
|
||
|
print(f"\n{'='*50}")
|
||
|
print(f"Running: {name}")
|
||
|
print('='*50 + "\n")
|
||
|
await func()
|
||
|
print("\nPress Enter to continue...")
|
||
|
input()
|
||
|
elif choice in examples:
|
||
|
name, func = examples[choice]
|
||
|
print(f"\n{'='*50}")
|
||
|
print(f"Running: {name}")
|
||
|
print('='*50 + "\n")
|
||
|
await func()
|
||
|
else:
|
||
|
print("Invalid choice!")
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
try:
|
||
|
asyncio.run(main())
|
||
|
except KeyboardInterrupt:
|
||
|
print("\n\nInterrupted by user")
|
||
|
except Exception as e:
|
||
|
print(f"\nError: {e}")
|
||
|
sys.exit(1)
|