vantage-cli 0.1.3__tar.gz → 0.1.4__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.
Files changed (60) hide show
  1. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/.github/workflows/pages.yml +22 -0
  2. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/PKG-INFO +29 -1
  3. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/README.md +28 -0
  4. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/pyproject.toml +1 -1
  5. vantage_cli-0.1.4/scripts/README.md +55 -0
  6. vantage_cli-0.1.4/scripts/update_docs_version.py +150 -0
  7. vantage_cli-0.1.4/scripts/update_docs_version.sh +44 -0
  8. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/uv.lock +1 -1
  9. vantage_cli-0.1.4/vantage_cli/apps/__init__.py +19 -0
  10. vantage_cli-0.1.4/vantage_cli/apps/slurm_juju_localhost/__init__.py +5 -0
  11. vantage_cli-0.1.4/vantage_cli/apps/slurm_multipass_localhost/__init__.py +5 -0
  12. vantage_cli-0.1.4/vantage_cli/commands/apps/__init__.py +22 -0
  13. vantage_cli-0.1.4/vantage_cli/commands/apps/deploy.py +72 -0
  14. vantage_cli-0.1.4/vantage_cli/commands/apps/list.py +97 -0
  15. vantage_cli-0.1.3/vantage_cli/apps/__init__.py +0 -19
  16. vantage_cli-0.1.3/vantage_cli/apps/juju_localhost/__init__.py +0 -14
  17. vantage_cli-0.1.3/vantage_cli/apps/multipass_singlenode/__init__.py +0 -14
  18. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/.commitlintrc.yml +0 -0
  19. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/.github/workflows/ci.yml +0 -0
  20. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/.github/workflows/publish.yml +0 -0
  21. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/.gitignore +0 -0
  22. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/__init__.py +0 -0
  23. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/apps/common.py +0 -0
  24. {vantage_cli-0.1.3/vantage_cli/apps/juju_localhost → vantage_cli-0.1.4/vantage_cli/apps/slurm_juju_localhost}/app.py +0 -0
  25. {vantage_cli-0.1.3/vantage_cli/apps/juju_localhost → vantage_cli-0.1.4/vantage_cli/apps/slurm_juju_localhost}/bundle_yaml.py +0 -0
  26. {vantage_cli-0.1.3/vantage_cli/apps/microk8s → vantage_cli-0.1.4/vantage_cli/apps/slurm_microk8s_localhost}/README.md +0 -0
  27. {vantage_cli-0.1.3/vantage_cli/apps/microk8s → vantage_cli-0.1.4/vantage_cli/apps/slurm_microk8s_localhost}/__init__.py +0 -0
  28. {vantage_cli-0.1.3/vantage_cli/apps/microk8s → vantage_cli-0.1.4/vantage_cli/apps/slurm_microk8s_localhost}/app.py +0 -0
  29. {vantage_cli-0.1.3/vantage_cli/apps/multipass_singlenode → vantage_cli-0.1.4/vantage_cli/apps/slurm_multipass_localhost}/app.py +0 -0
  30. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/apps/templates.py +0 -0
  31. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/auth.py +0 -0
  32. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/cache.py +0 -0
  33. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/client.py +0 -0
  34. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/command_base.py +0 -0
  35. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/__init__.py +0 -0
  36. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clouds/__init__.py +0 -0
  37. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clouds/add.py +0 -0
  38. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clouds/delete.py +0 -0
  39. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clouds/render.py +0 -0
  40. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clouds/update.py +0 -0
  41. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/__init__.py +0 -0
  42. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/create.py +0 -0
  43. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/delete.py +0 -0
  44. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/get.py +0 -0
  45. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/list.py +0 -0
  46. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/render.py +0 -0
  47. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/schema.py +0 -0
  48. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/clusters/utils.py +0 -0
  49. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/profile/__init__.py +0 -0
  50. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/profile/crud.py +0 -0
  51. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/commands/profile/render.py +0 -0
  52. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/config.py +0 -0
  53. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/constants.py +0 -0
  54. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/exceptions.py +0 -0
  55. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/format.py +0 -0
  56. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/gql_client.py +0 -0
  57. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/main.py +0 -0
  58. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/render.py +0 -0
  59. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/schemas.py +0 -0
  60. {vantage_cli-0.1.3 → vantage_cli-0.1.4}/vantage_cli/time_loop.py +0 -0
@@ -28,6 +28,28 @@ jobs:
28
28
  steps:
29
29
  - name: Checkout
30
30
  uses: actions/checkout@v4
31
+ - name: Update documentation version
32
+ run: |
33
+ # Extract version from pyproject.toml and update docs
34
+ VERSION=$(grep '^version = ' pyproject.toml | sed 's/version = "\(.*\)"/\1/')
35
+ TODAY=$(date +%Y-%m-%d)
36
+ echo "📝 Updating docs with version: $VERSION"
37
+
38
+ # Update all documentation files
39
+ sed -i "s/^version: .*/version: \"$VERSION\"/" docs/_data/project.yml
40
+ sed -i "s/^updated: .*/updated: \"$TODAY\"/" docs/_data/project.yml
41
+
42
+ if grep -q "^version:" docs/_config.yml; then
43
+ sed -i "s/^version: .*/version: \"$VERSION\"/" docs/_config.yml
44
+ else
45
+ sed -i "/^description:/a version: \"$VERSION\"" docs/_config.yml
46
+ fi
47
+
48
+ if grep -q "^version:" docs/index.md; then
49
+ sed -i "s/^version: .*/version: \"$VERSION\"/" docs/index.md
50
+ else
51
+ sed -i "/^permalink:/a version: \"$VERSION\"" docs/index.md
52
+ fi
31
53
  - name: Setup Pages
32
54
  uses: actions/configure-pages@v5
33
55
  - name: Build with Jekyll
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vantage-cli
3
- Version: 0.1.3
3
+ Version: 0.1.4
4
4
  Summary: The Vantage Compute CLI.
5
5
  Author-email: jamesbeedy <james@vantagecompute.ai>
6
6
  License: MIT
@@ -78,6 +78,34 @@ cd vantage-cli && uv sync
78
78
  uv run vantage login
79
79
  ```
80
80
 
81
+ ## Deploy a Slurm Cluster
82
+
83
+ ### Localhost
84
+
85
+ #### Create a Singlenode Slurm Cluster using Multipass
86
+
87
+ ```bash
88
+ vantage clusters create my-slurm-multipass-cluster \
89
+ --cloud localhost \
90
+ --deploy slurm-multipass-localhost
91
+ ```
92
+
93
+ #### Create a Slurm Cluster on LXD
94
+
95
+ ```bash
96
+ vantage clusters create my-slurm-lxd-cluster \
97
+ --cloud localhost \
98
+ --deploy slurm-juju-localhost
99
+ ```
100
+
101
+ #### Create a Slurm Cluster on MicroK8S
102
+
103
+ ```bash
104
+ vantage clusters create my-slurm-microk8s-cluster \
105
+ --cloud localhost \
106
+ --deploy slurm-microk8s-locahost
107
+ ```
108
+
81
109
  ## 📚 Documentation
82
110
 
83
111
  Visit our comprehensive documentation site:
@@ -46,6 +46,34 @@ cd vantage-cli && uv sync
46
46
  uv run vantage login
47
47
  ```
48
48
 
49
+ ## Deploy a Slurm Cluster
50
+
51
+ ### Localhost
52
+
53
+ #### Create a Singlenode Slurm Cluster using Multipass
54
+
55
+ ```bash
56
+ vantage clusters create my-slurm-multipass-cluster \
57
+ --cloud localhost \
58
+ --deploy slurm-multipass-localhost
59
+ ```
60
+
61
+ #### Create a Slurm Cluster on LXD
62
+
63
+ ```bash
64
+ vantage clusters create my-slurm-lxd-cluster \
65
+ --cloud localhost \
66
+ --deploy slurm-juju-localhost
67
+ ```
68
+
69
+ #### Create a Slurm Cluster on MicroK8S
70
+
71
+ ```bash
72
+ vantage clusters create my-slurm-microk8s-cluster \
73
+ --cloud localhost \
74
+ --deploy slurm-microk8s-locahost
75
+ ```
76
+
49
77
  ## 📚 Documentation
50
78
 
51
79
  Visit our comprehensive documentation site:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "vantage-cli"
3
- version = "0.1.3"
3
+ version = "0.1.4"
4
4
  description = "The Vantage Compute CLI."
5
5
  authors = [
6
6
  {name = "jamesbeedy", email = "james@vantagecompute.ai"}
@@ -0,0 +1,55 @@
1
+ # Scripts Directory
2
+
3
+ This directory contains utility scripts for the Vantage CLI project.
4
+
5
+ ## update_docs_version.py
6
+
7
+ **Purpose**: Automatically updates documentation files with the current version from `pyproject.toml`.
8
+
9
+ **Files Updated**:
10
+ - `docs/_data/project.yml` - Updates version and date fields
11
+ - `docs/_config.yml` - Adds/updates version field
12
+ - `docs/index.md` - Adds version to front matter
13
+
14
+ **Usage**:
15
+ ```bash
16
+ # Using justfile (recommended)
17
+ just update-docs-version
18
+
19
+ # Direct execution
20
+ python scripts/update_docs_version.py
21
+
22
+ # Using shell wrapper
23
+ ./scripts/update_docs_version.sh
24
+ ```
25
+
26
+ **Dependencies**:
27
+ - Python 3.7+ with `tomllib` (Python 3.11+) or `tomli` package
28
+
29
+ ## update_docs_version.sh
30
+
31
+ **Purpose**: Shell wrapper for `update_docs_version.py` that handles dependency installation.
32
+
33
+ **Usage**:
34
+ ```bash
35
+ ./scripts/update_docs_version.sh
36
+ ```
37
+
38
+ ## Integration
39
+
40
+ ### Local Development
41
+ Use `just update-docs-version` before building documentation locally.
42
+
43
+ ### CI/CD (GitHub Pages)
44
+ The version update is automatically integrated into the GitHub Pages workflow in `.github/workflows/pages.yml`.
45
+
46
+ ### Manual Execution
47
+ Both Python script and shell wrapper can be run independently for custom build processes.
48
+
49
+ ## When to Use
50
+
51
+ - **Before releasing**: Ensure documentation reflects the current version
52
+ - **Before building docs**: Keep documentation in sync with package version
53
+ - **In CI/CD**: Automatically update version during deployment
54
+
55
+ The scripts are designed to be idempotent - running them multiple times with the same version will not cause issues.
@@ -0,0 +1,150 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Update documentation files with version from pyproject.toml
4
+
5
+ This script reads the version from pyproject.toml and updates:
6
+ 1. docs/_data/project.yml (replaces __VERSION__ placeholder)
7
+ 2. docs/_config.yml (adds version field)
8
+ 3. Any other documentation files that need version updates
9
+ """
10
+
11
+ import re
12
+ import sys
13
+ from datetime import datetime
14
+ from pathlib import Path
15
+ from typing import Any, Dict
16
+
17
+ try:
18
+ import tomllib
19
+ except ImportError:
20
+ # Python < 3.11 fallback
21
+ try:
22
+ import tomli as tomllib
23
+ except ImportError:
24
+ print("Error: tomllib (Python 3.11+) or tomli package required")
25
+ sys.exit(1)
26
+
27
+
28
+ def load_pyproject_version() -> str:
29
+ """Load version from pyproject.toml"""
30
+ pyproject_path = Path(__file__).parent.parent / "pyproject.toml"
31
+
32
+ if not pyproject_path.exists():
33
+ raise FileNotFoundError(f"pyproject.toml not found at {pyproject_path}")
34
+
35
+ with open(pyproject_path, "rb") as f:
36
+ data = tomllib.load(f)
37
+
38
+ version = data.get("project", {}).get("version")
39
+ if not version:
40
+ raise ValueError("Version not found in pyproject.toml")
41
+
42
+ return version
43
+
44
+
45
+ def update_project_yml(version: str) -> None:
46
+ """Update docs/_data/project.yml with the current version"""
47
+ project_yml_path = Path(__file__).parent.parent / "docs" / "_data" / "project.yml"
48
+
49
+ if not project_yml_path.exists():
50
+ print(f"Warning: {project_yml_path} not found, skipping")
51
+ return
52
+
53
+ content = project_yml_path.read_text(encoding="utf-8")
54
+
55
+ # Replace version placeholder
56
+ updated_content = re.sub(
57
+ r'version:\s*["\']?__VERSION__["\']?',
58
+ f'version: "{version}"',
59
+ content
60
+ )
61
+
62
+ # Update the date as well
63
+ today = datetime.now().strftime("%Y-%m-%d")
64
+ updated_content = re.sub(
65
+ r'updated:\s*["\']?[\d-]+["\']?',
66
+ f'updated: "{today}"',
67
+ updated_content
68
+ )
69
+
70
+ project_yml_path.write_text(updated_content, encoding="utf-8")
71
+ print(f"✓ Updated {project_yml_path} with version {version}")
72
+
73
+
74
+ def update_config_yml(version: str) -> None:
75
+ """Update docs/_config.yml with the current version"""
76
+ config_yml_path = Path(__file__).parent.parent / "docs" / "_config.yml"
77
+
78
+ if not config_yml_path.exists():
79
+ print(f"Warning: {config_yml_path} not found, skipping")
80
+ return
81
+
82
+ content = config_yml_path.read_text(encoding="utf-8")
83
+
84
+ # Check if version field already exists
85
+ if re.search(r'^version:\s*', content, re.MULTILINE):
86
+ # Update existing version
87
+ updated_content = re.sub(
88
+ r'^version:\s*.*$',
89
+ f'version: "{version}"',
90
+ content,
91
+ flags=re.MULTILINE
92
+ )
93
+ else:
94
+ # Add version field after description
95
+ updated_content = re.sub(
96
+ r'(description:.*?\n)',
97
+ f'\\1version: "{version}"\n',
98
+ content,
99
+ flags=re.DOTALL
100
+ )
101
+
102
+ config_yml_path.write_text(updated_content, encoding="utf-8")
103
+ print(f"✓ Updated {config_yml_path} with version {version}")
104
+
105
+
106
+ def update_index_md(version: str) -> None:
107
+ """Update docs/index.md with version information if needed"""
108
+ index_md_path = Path(__file__).parent.parent / "docs" / "index.md"
109
+
110
+ if not index_md_path.exists():
111
+ print(f"Warning: {index_md_path} not found, skipping")
112
+ return
113
+
114
+ content = index_md_path.read_text(encoding="utf-8")
115
+
116
+ # Add version to the front matter if it doesn't exist
117
+ if "version:" not in content and "---" in content:
118
+ # Insert version into front matter
119
+ updated_content = re.sub(
120
+ r'(---\n.*?)\n(---)',
121
+ f'\\1\nversion: "{version}"\n\\2',
122
+ content,
123
+ flags=re.DOTALL
124
+ )
125
+
126
+ if updated_content != content:
127
+ index_md_path.write_text(updated_content, encoding="utf-8")
128
+ print(f"✓ Updated {index_md_path} with version {version}")
129
+
130
+
131
+ def main() -> None:
132
+ """Main function to update all documentation files with version"""
133
+ try:
134
+ version = load_pyproject_version()
135
+ print(f"📝 Updating documentation with version: {version}")
136
+
137
+ # Update all documentation files
138
+ update_project_yml(version)
139
+ update_config_yml(version)
140
+ update_index_md(version)
141
+
142
+ print(f"🎉 Successfully updated documentation files with version {version}")
143
+
144
+ except Exception as e:
145
+ print(f"❌ Error updating documentation version: {e}")
146
+ sys.exit(1)
147
+
148
+
149
+ if __name__ == "__main__":
150
+ main()
@@ -0,0 +1,44 @@
1
+ #!/bin/bash
2
+ # Update documentation version from pyproject.toml
3
+ # This script can be run locally or in CI/CD
4
+
5
+ set -e
6
+
7
+ # Get the directory where this script is located
8
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
10
+
11
+ echo "🔄 Updating documentation version..."
12
+
13
+ # Check if we're in a Python environment with the required packages
14
+ if command -v python3 >/dev/null 2>&1; then
15
+ PYTHON_CMD="python3"
16
+ elif command -v python >/dev/null 2>&1; then
17
+ PYTHON_CMD="python"
18
+ else
19
+ echo "❌ Error: Python not found"
20
+ exit 1
21
+ fi
22
+
23
+ # Try to run the update script
24
+ cd "$PROJECT_ROOT"
25
+
26
+ # Check if tomli/tomllib is available
27
+ if ! $PYTHON_CMD -c "import sys; import tomllib if sys.version_info >= (3, 11) else __import__('tomli')" 2>/dev/null; then
28
+ echo "📦 Installing tomli for Python < 3.11..."
29
+ # Try different installation methods
30
+ if command -v pip >/dev/null 2>&1; then
31
+ pip install --quiet tomli
32
+ elif command -v pip3 >/dev/null 2>&1; then
33
+ pip3 install --quiet tomli
34
+ elif $PYTHON_CMD -m pip --version >/dev/null 2>&1; then
35
+ $PYTHON_CMD -m pip install --quiet tomli
36
+ else
37
+ echo "⚠️ Warning: Could not install tomli. Script may fail for Python < 3.11"
38
+ fi
39
+ fi
40
+
41
+ # Run the update script
42
+ $PYTHON_CMD scripts/update_docs_version.py
43
+
44
+ echo "✅ Documentation version update complete!"
@@ -1710,7 +1710,7 @@ wheels = [
1710
1710
 
1711
1711
  [[package]]
1712
1712
  name = "vantage-cli"
1713
- version = "0.1.3"
1713
+ version = "0.1.4"
1714
1714
  source = { editable = "." }
1715
1715
  dependencies = [
1716
1716
  { name = "aiohttp" },
@@ -0,0 +1,19 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """Applications management commands for Vantage CLI."""
4
+
5
+ from vantage_cli import AsyncTyper
6
+ from vantage_cli.commands.apps.deploy import deploy_app
7
+ from vantage_cli.commands.apps.list import list_apps
8
+
9
+ # Create the apps command group
10
+ apps_app = AsyncTyper(
11
+ name="apps",
12
+ help="Deploy and manage applications on Vantage compute clusters.",
13
+ invoke_without_command=True,
14
+ no_args_is_help=True,
15
+ )
16
+
17
+ # Register commands
18
+ apps_app.command("list")(list_apps)
19
+ apps_app.command("deploy")(deploy_app)
@@ -0,0 +1,5 @@
1
+ """Juju localhost deployment app package."""
2
+
3
+ from .app import deploy
4
+
5
+ __all__ = ["deploy"]
@@ -0,0 +1,5 @@
1
+ """Multipass single-node deployment app package."""
2
+
3
+ from .app import deploy
4
+
5
+ __all__ = ["deploy"]
@@ -0,0 +1,22 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """Application deployment commands for Vantage CLI."""
4
+
5
+ from vantage_cli import AsyncTyper
6
+
7
+ from .deploy import deploy_app
8
+ from .list import list_apps
9
+
10
+ # Create the apps command group
11
+ apps_app = AsyncTyper(
12
+ name="apps",
13
+ help="Deploy and manage applications on Vantage compute clusters.",
14
+ invoke_without_command=True,
15
+ no_args_is_help=True,
16
+ )
17
+
18
+ # Register subcommands directly
19
+ apps_app.command("list")(list_apps)
20
+ apps_app.command("deploy")(deploy_app)
21
+
22
+ __all__ = ["apps_app"]
@@ -0,0 +1,72 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """Deploy and register clusters."""
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+ from rich.console import Console
9
+
10
+ from vantage_cli.commands.clusters.utils import get_available_apps, get_cluster_by_name
11
+ from vantage_cli.config import attach_settings
12
+
13
+ console = Console()
14
+
15
+
16
+ @attach_settings
17
+ async def deploy_app(
18
+ ctx: typer.Context,
19
+ app_name: Annotated[
20
+ str, typer.Argument(help="Name of the cluster infrastructure application to deploy")
21
+ ],
22
+ cluster_name: Annotated[
23
+ str, typer.Argument(help="Name of the cluster in Vantage you would like to link to")
24
+ ],
25
+ ) -> None:
26
+ """Deploy a slurm cluster and link it to a cluster entity in Vantage."""
27
+ try:
28
+ # Get available apps
29
+ available_apps = get_available_apps()
30
+
31
+ if app_name not in available_apps:
32
+ console.print(f"[bold red]✗ App '{app_name}' not found[/bold red]")
33
+ console.print(f"\nAvailable apps: {', '.join(available_apps.keys())}")
34
+ console.print("Use [cyan]vantage apps list[/cyan] to see all available applications.")
35
+ raise typer.Exit(1)
36
+
37
+ console.print(
38
+ f"[bold blue]Deploying app '{app_name}' to cluster '{cluster_name}'...[/bold blue]"
39
+ )
40
+
41
+ # Get cluster data
42
+ cluster_data = await get_cluster_by_name(ctx, cluster_name)
43
+ if not cluster_data:
44
+ console.print(f"[bold red]✗ Cluster '{cluster_name}' not found[/bold red]")
45
+ raise typer.Exit(1)
46
+
47
+ # Get the app info
48
+ app_info = available_apps[app_name]
49
+
50
+ # Check if this is a function-based app
51
+ if "deploy_function" in app_info:
52
+ # Function-based app
53
+ deploy_function = app_info["deploy_function"]
54
+
55
+ # Call the deploy function with cluster data
56
+ await deploy_function(ctx, cluster_data)
57
+
58
+ console.print(
59
+ f"[bold green]✓ App '{app_name}' deployed successfully to cluster '{cluster_name}'![/bold green]"
60
+ )
61
+ else:
62
+ console.print(
63
+ f"[bold red]✗ App '{app_name}' does not have a deploy function[/bold red]"
64
+ )
65
+ raise typer.Exit(1)
66
+
67
+ except typer.Exit:
68
+ # Re-raise typer.Exit to maintain exit codes
69
+ raise
70
+ except Exception as e:
71
+ console.print(f"[bold red]✗ Error deploying app '{app_name}': {e}[/bold red]")
72
+ raise typer.Exit(1)
@@ -0,0 +1,97 @@
1
+ # © 2025 Vantage Compute, Inc. All rights reserved.
2
+ # Confidential and proprietary. Unauthorized use prohibited.
3
+ """List available applications for deployment."""
4
+
5
+ from typing import Annotated
6
+
7
+ import typer
8
+ from rich.console import Console
9
+ from rich.table import Table
10
+
11
+ from vantage_cli.commands.clusters.utils import get_available_apps
12
+ from vantage_cli.config import attach_settings
13
+ from vantage_cli.format import render_json
14
+
15
+ console = Console()
16
+
17
+
18
+ @attach_settings
19
+ async def list_apps(
20
+ ctx: typer.Context,
21
+ json_output: Annotated[
22
+ bool, typer.Option("--json", "-j", help="Output in JSON format")
23
+ ] = False,
24
+ ) -> None:
25
+ """List all available applications for deployment."""
26
+ try:
27
+ # Get available apps
28
+ available_apps = get_available_apps()
29
+
30
+ if json_output:
31
+ # Format for JSON output
32
+ apps_data = []
33
+ for app_name, app_info in available_apps.items():
34
+ app_data = {
35
+ "name": app_name,
36
+ "module": app_info["module"].__name__
37
+ if "module" in app_info and hasattr(app_info["module"], "__name__")
38
+ else "unknown",
39
+ }
40
+
41
+ # Try to get description from docstring if available
42
+ if "deploy_function" in app_info:
43
+ func = app_info["deploy_function"]
44
+ if hasattr(func, "__doc__") and func.__doc__:
45
+ app_data["description"] = func.__doc__.strip().split("\n")[0]
46
+ else:
47
+ app_data["description"] = "No description available"
48
+ else:
49
+ app_data["description"] = "No deploy function available"
50
+
51
+ apps_data.append(app_data)
52
+
53
+ render_json({"apps": apps_data})
54
+ return
55
+
56
+ # Rich table output
57
+ if not available_apps:
58
+ console.print("[yellow]No applications found.[/yellow]")
59
+ return
60
+
61
+ table = Table(
62
+ title="Available Applications", show_header=True, header_style="bold magenta"
63
+ )
64
+ table.add_column("App Name", style="cyan", width=20)
65
+ table.add_column("Module", style="green", width=30)
66
+ table.add_column("Description", style="white", width=50)
67
+
68
+ for app_name, app_info in available_apps.items():
69
+ # Get module name
70
+ module_name = "unknown"
71
+ if "module" in app_info:
72
+ module_name = (
73
+ app_info["module"].__name__
74
+ if hasattr(app_info["module"], "__name__")
75
+ else "unknown"
76
+ )
77
+
78
+ # Get description from docstring
79
+ description = "No description available"
80
+ if "deploy_function" in app_info:
81
+ func = app_info["deploy_function"]
82
+ if hasattr(func, "__doc__") and func.__doc__:
83
+ # Get first line of docstring
84
+ description = func.__doc__.strip().split("\n")[0]
85
+ else:
86
+ description = "No description available"
87
+ else:
88
+ description = "No deploy function available"
89
+
90
+ table.add_row(app_name, module_name, description)
91
+
92
+ console.print(table)
93
+ console.print(f"\n[bold]Found {len(available_apps)} application(s)[/bold]")
94
+
95
+ except Exception as e:
96
+ console.print(f"[bold red]Error listing applications: {e}[/bold red]")
97
+ raise typer.Exit(1)
@@ -1,19 +0,0 @@
1
- # © 2025 Vantage Compute, Inc. All rights reserved.
2
- # Confidential and proprietary. Unauthorized use prohibited.
3
- """Cluster management commands for Vantage CLI."""
4
-
5
- from vantage_cli import AsyncTyper
6
- from vantage_cli.apps.juju_localhost import juju_localhost_app
7
- from vantage_cli.apps.multipass_singlenode import multipass_singlenode_app
8
-
9
- # Create the apps command group
10
- apps_app = AsyncTyper(
11
- name="apps",
12
- help="Vantage infrastructure automation applications.",
13
- invoke_without_command=True,
14
- no_args_is_help=True,
15
- )
16
-
17
- # Register subcommand groups
18
- apps_app.add_typer(juju_localhost_app)
19
- apps_app.add_typer(multipass_singlenode_app)
@@ -1,14 +0,0 @@
1
- """Juju localhost deployment app package."""
2
-
3
- from vantage_cli import AsyncTyper
4
-
5
- from .app import deploy_command
6
-
7
- juju_localhost_app = AsyncTyper(
8
- name="juju-localhost",
9
- help="Juju localhost SLURM application commands.",
10
- invoke_without_command=True,
11
- no_args_is_help=True,
12
- )
13
-
14
- juju_localhost_app.command("deploy")(deploy_command)
@@ -1,14 +0,0 @@
1
- """Multipass single-node deployment app package."""
2
-
3
- from vantage_cli import AsyncTyper
4
-
5
- from .app import deploy_command
6
-
7
- multipass_singlenode_app = AsyncTyper(
8
- name="multipass-singlenode",
9
- help="Multipass single-node application commands.",
10
- invoke_without_command=True,
11
- no_args_is_help=True,
12
- )
13
-
14
- multipass_singlenode_app.command("deploy")(deploy_command)
File without changes