Skip to content

Commit f3f93a5

Browse files
Add airstack CLI tool for developer convenience (#272)
* Add airstack CLI tool for developer convenience * change folder for isaac sim docker data * Add 'idle' profile to bring up containers without launching. Also rename ground-control-station to gcs * Update macvo hash * Rename airstack to airstack.sh, add airstack alias to setup * add comment * Tune the tool. Use airstack up and down * Update getting started page * Remove unused config file * Integrate configure.sh functionality into airstack.sh as modules * Remove original configure.sh script * Add WINTAK installation support to airstack.sh * Update WinTAK installation documentation * Add comprehensive AirStack CLI documentation * Fix formatting * Remove old launch.sh tool in favor of airstack cli * Replace launch with up * Replace airstack alias with a function that uses the current working directory * Modify to make work for multiple airstack.sh installs --------- Co-authored-by: openhands <[email protected]>
1 parent 0b0eb0a commit f3f93a5

File tree

20 files changed

+1938
-172
lines changed

20 files changed

+1938
-172
lines changed

.airstack/README.md

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# AirStack CLI Tool
2+
3+
The `airstack` command-line tool provides a unified interface for common development tasks in the AirStack project, including setup, installation, and container management.
4+
5+
## Installation
6+
7+
The `airstack` tool is included in the AirStack repository. To set it up:
8+
9+
1. Clone the AirStack repository:
10+
```bash
11+
git clone https://github.com/castacks/AirStack.git
12+
cd AirStack
13+
```
14+
15+
2. Run the setup command:
16+
```bash
17+
./airstack setup
18+
```
19+
20+
This will add the `airstack` command to your PATH by modifying your shell profile (`.bashrc` or `.zshrc`).
21+
22+
## Basic Usage
23+
24+
```bash
25+
airstack <command> [options]
26+
```
27+
28+
To see all available commands:
29+
```bash
30+
airstack commands
31+
```
32+
33+
To get help for a specific command:
34+
```bash
35+
airstack help <command>
36+
```
37+
38+
## Core Commands
39+
40+
- `install`: Install dependencies (Docker Engine, Docker Compose, etc.)
41+
- `setup`: Configure AirStack settings and add to shell profile
42+
- `up [service]`: Start services using Docker Compose
43+
- `stop [service]`: Stop services
44+
- `connect [container]`: Connect to a running container (supports partial name matching)
45+
- `status`: Show status of all containers
46+
- `logs [container]`: View logs for a container (supports partial name matching)
47+
48+
### Container Name Matching
49+
50+
The `connect` and `logs` commands support partial name matching for container names. This means you can:
51+
52+
1. Use just a portion of the container name (e.g., `airstack connect web` will match `airstack_web_1`)
53+
2. If multiple containers match, you'll be shown a list and prompted to select one
54+
3. The matching is case-insensitive and supports fuzzy matching
55+
56+
Example:
57+
```bash
58+
$ airstack connect web
59+
[WARN] Multiple containers match 'web'. Please be more specific or select from the list below:
60+
NUM CONTAINER NAME IMAGE STATUS
61+
1 airstack_web_1 nginx:latest Up 2 hours
62+
2 airstack_webapi_1 node:14 Up 2 hours
63+
64+
Options:
65+
1. Enter a number to select a container
66+
2. Type 'q' to quit
67+
3. Press Ctrl+C to cancel and try again with a more specific name
68+
69+
Your selection: 1
70+
[INFO] Connecting to container: airstack_web_1
71+
[INFO] Tip: Next time, you can directly use 'airstack connect airstack_web_1' for this container
72+
```
73+
74+
## Development Commands
75+
76+
- `test`: Run tests
77+
- `docs`: Build documentation
78+
- `lint`: Lint code
79+
- `format`: Format code
80+
81+
## Extending the Tool
82+
83+
The `airstack` tool is designed to be easily extensible. You can add new commands by creating module files in the `.airstack/modules/` directory.
84+
85+
### Creating a New Module
86+
87+
1. Create a new `.sh` file in the `.airstack/modules/` directory:
88+
```bash
89+
touch .airstack/modules/mymodule.sh
90+
```
91+
92+
2. Add your command functions and register them:
93+
```bash
94+
#!/usr/bin/env bash
95+
96+
# Function to implement your command
97+
function cmd_mymodule_mycommand {
98+
log_info "Running my command..."
99+
# Your command implementation here
100+
}
101+
102+
# Register commands from this module
103+
function register_mymodule_commands {
104+
COMMANDS["mycommand"]="cmd_mymodule_mycommand"
105+
COMMAND_HELP["mycommand"]="Description of my command"
106+
}
107+
```
108+
109+
3. Make the module executable:
110+
```bash
111+
chmod +x .airstack/modules/mymodule.sh
112+
```
113+
114+
Your new command will be automatically loaded and available as `airstack mycommand`.
115+
116+
### Available Helper Functions
117+
118+
When creating modules, you can use these helper functions:
119+
120+
- `log_info "message"`: Print an info message
121+
- `log_warn "message"`: Print a warning message
122+
- `log_error "message"`: Print an error message
123+
- `check_docker`: Check if Docker is installed and running
124+
125+
## Configuration
126+
127+
The `airstack` tool stores its configuration in `~/.airstack.conf`. This file is created when you run `airstack setup`.
128+
129+
## License
130+
131+
This tool is part of the AirStack project and is subject to the same license terms.

.airstack/modules/config.sh

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env bash
2+
3+
# config.sh - Configuration-related commands for AirStack
4+
# This module provides commands for configuring the AirStack environment
5+
6+
# Helper function for confirmation prompts
7+
function confirm_no {
8+
read -r -p "${1:-Are you sure? [y/N]} " response
9+
case "$response" in
10+
[yY][eE][sS]|[yY])
11+
true
12+
;;
13+
*)
14+
false
15+
;;
16+
esac
17+
}
18+
19+
# Function to configure Isaac Sim settings
20+
function cmd_config_isaac_sim {
21+
log_info "Configuring Isaac Sim settings..."
22+
23+
# Generate user.config.json for IsaacSim settings
24+
local USER_CONFIG_JSON_SOURCE="${PROJECT_ROOT}/simulation/isaac-sim/docker/user_TEMPLATE.config.json"
25+
local USER_CONFIG_JSON_DESTINATION="${PROJECT_ROOT}/simulation/isaac-sim/docker/user.config.json"
26+
27+
log_info "Generating Default IsaacSim Config ($USER_CONFIG_JSON_DESTINATION)"
28+
29+
if [ -d "$USER_CONFIG_JSON_DESTINATION" ] && [ $(ls -A "$USER_CONFIG_JSON_DESTINATION" | wc -l) == 0 ]; then
30+
# delete an empty directory with the same name as $USER_CONFIG_JSON_DESTINATION which gets created when
31+
# docker compose up is run before this script. Doing this will create a directory name user.config.json because
32+
# it is being mounted as a volume but it doesn't exist yet.
33+
rm -rf "$USER_CONFIG_JSON_DESTINATION"
34+
fi
35+
36+
if [ -f "$USER_CONFIG_JSON_DESTINATION" ]; then
37+
log_warn "The file $USER_CONFIG_JSON_DESTINATION already exists."
38+
confirm_no "Do you want to reset it to the default? [y/N]" && cp "$USER_CONFIG_JSON_SOURCE" "$USER_CONFIG_JSON_DESTINATION"
39+
else
40+
cp "$USER_CONFIG_JSON_SOURCE" "$USER_CONFIG_JSON_DESTINATION"
41+
fi
42+
43+
log_info "Isaac Sim configuration complete"
44+
}
45+
46+
# Function to configure AirLab Omniverse Nucleus Server Login
47+
function cmd_config_nucleus {
48+
log_info "Configuring AirLab Nucleus Login..."
49+
50+
# AirLab Omniverse Nucleus Server Login Config
51+
local OMNI_PASS_SOURCE="${PROJECT_ROOT}/simulation/isaac-sim/docker/omni_pass_TEMPLATE.env"
52+
local OMNI_PASS_DESTINATION="${PROJECT_ROOT}/simulation/isaac-sim/docker/omni_pass.env"
53+
54+
log_info "Configure AirLab Nucleus Login ($OMNI_PASS_DESTINATION)"
55+
56+
log_info "Go to https://airlab-storage.andrew.cmu.edu:8443/omni/web3/, log in, then right click on the cloud and click the \"API Tokens\" window to generate an API token and paste it here. Leave this blank if you want to skip this step: "
57+
if [ -f "$OMNI_PASS_DESTINATION" ]; then
58+
log_warn "The file $OMNI_PASS_DESTINATION already exists, leave it blank to skip."
59+
fi
60+
read -r -p "API Token: " API_TOKEN
61+
62+
if [ ! -z "${API_TOKEN}" ]; then
63+
sed "s/PASTE-YOUR-API-TOKEN/$API_TOKEN/g" "$OMNI_PASS_SOURCE" > "$OMNI_PASS_DESTINATION"
64+
log_info "Nucleus login configuration complete"
65+
else
66+
log_info "Skipping Nucleus login configuration"
67+
fi
68+
}
69+
70+
# Function to set up Git Hooks
71+
function cmd_config_git_hooks {
72+
log_info "Setting up Git Hooks..."
73+
74+
# Git Hooks
75+
local HOOKS_SOURCE="${PROJECT_ROOT}/git-hooks/docker-versioning/update-docker-image-tag.pre-commit"
76+
local HOOKS_DESTINATION="${PROJECT_ROOT}/.git/hooks/pre-commit"
77+
78+
if [ -f "$HOOKS_SOURCE" ]; then
79+
cp "$HOOKS_SOURCE" "$HOOKS_DESTINATION"
80+
chmod +x "$HOOKS_DESTINATION"
81+
log_info "Git hooks setup complete"
82+
else
83+
log_error "Git hooks source file not found: $HOOKS_SOURCE"
84+
fi
85+
}
86+
87+
# Function to run all configuration tasks
88+
function cmd_config_all {
89+
log_info "Running all configuration tasks..."
90+
91+
cmd_config_isaac_sim
92+
cmd_config_nucleus
93+
cmd_config_git_hooks
94+
95+
log_info "All configuration tasks complete"
96+
}
97+
98+
# Register commands from this module
99+
function register_config_commands {
100+
COMMANDS["config"]="cmd_config_all"
101+
COMMANDS["config:isaac-sim"]="cmd_config_isaac_sim"
102+
COMMANDS["config:nucleus"]="cmd_config_nucleus"
103+
COMMANDS["config:git-hooks"]="cmd_config_git_hooks"
104+
105+
# Add command help
106+
COMMAND_HELP["config"]="Run all configuration tasks"
107+
COMMAND_HELP["config:isaac-sim"]="Configure Isaac Sim settings"
108+
COMMAND_HELP["config:nucleus"]="Configure AirLab Nucleus login"
109+
COMMAND_HELP["config:git-hooks"]="Set up Git hooks"
110+
}

.airstack/modules/dev.sh

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
3+
# dev.sh - Development-related commands for AirStack
4+
# This module provides commands for development tasks
5+
6+
# Function to run tests
7+
function cmd_dev_test {
8+
log_info "Running tests..."
9+
10+
local test_path="$PROJECT_ROOT/tests"
11+
local test_filter=""
12+
13+
# Parse arguments
14+
for arg in "$@"; do
15+
if [[ "$arg" == --path=* ]]; then
16+
test_path="${arg#--path=}"
17+
elif [[ "$arg" == --filter=* ]]; then
18+
test_filter="${arg#--filter=}"
19+
fi
20+
done
21+
22+
if [ -n "$test_filter" ]; then
23+
log_info "Running tests matching '$test_filter' in $test_path"
24+
# Add your test command here, e.g.:
25+
# pytest "$test_path" -k "$test_filter"
26+
echo "Test command would run here with filter: $test_filter"
27+
else
28+
log_info "Running all tests in $test_path"
29+
# Add your test command here, e.g.:
30+
# pytest "$test_path"
31+
echo "Test command would run here"
32+
fi
33+
}
34+
35+
# Function to build documentation
36+
function cmd_dev_docs {
37+
log_info "Building documentation..."
38+
39+
# Check if mkdocs is installed
40+
if ! command -v mkdocs &> /dev/null; then
41+
log_warn "mkdocs not found. Installing..."
42+
pip install mkdocs mkdocs-material
43+
fi
44+
45+
# Build documentation
46+
cd "$PROJECT_ROOT"
47+
mkdocs build
48+
49+
# Serve documentation if requested
50+
if [[ "$1" == "serve" ]]; then
51+
log_info "Serving documentation at http://localhost:8000"
52+
mkdocs serve
53+
fi
54+
}
55+
56+
# Function to lint code
57+
function cmd_dev_lint {
58+
log_info "Linting code..."
59+
60+
# Add your linting commands here
61+
# For example:
62+
# flake8 "$PROJECT_ROOT"
63+
echo "Linting command would run here"
64+
}
65+
66+
# Function to format code
67+
function cmd_dev_format {
68+
log_info "Formatting code..."
69+
70+
# Add your formatting commands here
71+
# For example:
72+
# black "$PROJECT_ROOT"
73+
echo "Formatting command would run here"
74+
}
75+
76+
# Register commands from this module
77+
function register_dev_commands {
78+
COMMANDS["test"]="cmd_dev_test"
79+
COMMANDS["docs"]="cmd_dev_docs"
80+
COMMANDS["lint"]="cmd_dev_lint"
81+
COMMANDS["format"]="cmd_dev_format"
82+
83+
# Add command help
84+
COMMAND_HELP["test"]="Run tests (options: --path=PATH, --filter=PATTERN)"
85+
COMMAND_HELP["docs"]="Build documentation (options: serve)"
86+
COMMAND_HELP["lint"]="Lint code"
87+
COMMAND_HELP["format"]="Format code"
88+
}

0 commit comments

Comments
 (0)