# Pack Installation Actions This document describes the pack installation actions that automate the process of downloading, analyzing, building environments, and registering packs in Attune. ## Overview The pack installation system consists of four core actions that work together to automate pack installation: 1. **`core.download_packs`** - Downloads packs from git, HTTP, or registry sources 2. **`core.get_pack_dependencies`** - Analyzes pack dependencies and runtime requirements 3. **`core.build_pack_envs`** - Creates Python virtualenvs and Node.js environments 4. **`core.register_packs`** - Registers packs with the Attune API and database These actions are designed to be used in workflows (like `core.install_packs`) or independently via the CLI/API. ## Actions ### 1. core.download_packs Downloads packs from various sources to a local directory. **Source Types:** - **Git repositories**: URLs ending in `.git` or starting with `git@` - **HTTP archives**: URLs with `http://` or `https://` (tar.gz, zip) - **Registry references**: Pack name with optional version (e.g., `slack@1.0.0`) **Parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `packs` | array[string] | Yes | - | List of pack sources to download | | `destination_dir` | string | Yes | - | Directory where packs will be downloaded | | `registry_url` | string | No | `https://registry.attune.io/index.json` | Pack registry URL | | `ref_spec` | string | No | - | Git reference (branch/tag/commit) for git sources | | `timeout` | integer | No | 300 | Download timeout in seconds per pack | | `verify_ssl` | boolean | No | true | Verify SSL certificates for HTTPS | | `api_url` | string | No | `http://localhost:8080` | Attune API URL | **Output:** ```json { "downloaded_packs": [ { "source": "https://github.com/attune/pack-slack.git", "source_type": "git", "pack_path": "/tmp/downloads/pack-0-1234567890", "pack_ref": "slack", "pack_version": "1.0.0", "git_commit": "abc123def456", "checksum": "d41d8cd98f00b204e9800998ecf8427e" } ], "failed_packs": [], "total_count": 1, "success_count": 1, "failure_count": 0 } ``` **Example Usage:** ```bash # CLI attune action execute core.download_packs \ --param packs='["https://github.com/attune/pack-slack.git"]' \ --param destination_dir=/tmp/attune-packs \ --param ref_spec=v1.0.0 # Via API curl -X POST http://localhost:8080/api/v1/executions \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "action": "core.download_packs", "parameters": { "packs": ["slack@1.0.0"], "destination_dir": "/tmp/attune-packs" } }' ``` ### 2. core.get_pack_dependencies Parses pack.yaml files to extract dependencies and runtime requirements. **Parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `pack_paths` | array[string] | Yes | - | List of pack directory paths to analyze | | `skip_validation` | boolean | No | false | Skip pack.yaml schema validation | | `api_url` | string | No | `http://localhost:8080` | Attune API URL for checking installed packs | **Output:** ```json { "dependencies": [ { "pack_ref": "core", "version_spec": "*", "required_by": "slack", "already_installed": true } ], "runtime_requirements": { "slack": { "pack_ref": "slack", "python": { "version": "3.11", "requirements_file": "/tmp/slack/requirements.txt" } } }, "missing_dependencies": [], "analyzed_packs": [ { "pack_ref": "slack", "pack_path": "/tmp/slack", "has_dependencies": true, "dependency_count": 1 } ], "errors": [] } ``` **Example Usage:** ```bash # CLI attune action execute core.get_pack_dependencies \ --param pack_paths='["/tmp/attune-packs/slack"]' # Check for missing dependencies result=$(attune action execute core.get_pack_dependencies \ --param pack_paths='["/tmp/attune-packs/slack"]' \ --json) missing=$(echo "$result" | jq '.output.missing_dependencies | length') if [[ $missing -gt 0 ]]; then echo "Missing dependencies detected" fi ``` ### 3. core.build_pack_envs Creates runtime environments and installs dependencies for packs. **Parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `pack_paths` | array[string] | Yes | - | List of pack directory paths | | `packs_base_dir` | string | No | `/opt/attune/packs` | Base directory for permanent pack storage | | `python_version` | string | No | `3.11` | Python version for virtualenvs | | `nodejs_version` | string | No | `20` | Node.js version | | `skip_python` | boolean | No | false | Skip building Python environments | | `skip_nodejs` | boolean | No | false | Skip building Node.js environments | | `force_rebuild` | boolean | No | false | Force rebuild of existing environments | | `timeout` | integer | No | 600 | Timeout in seconds per environment build | **Output:** ```json { "built_environments": [ { "pack_ref": "slack", "pack_path": "/tmp/slack", "environments": { "python": { "virtualenv_path": "/tmp/slack/virtualenv", "requirements_installed": true, "package_count": 15, "python_version": "3.11.5" } }, "duration_ms": 12500 } ], "failed_environments": [], "summary": { "total_packs": 1, "success_count": 1, "failure_count": 0, "python_envs_built": 1, "nodejs_envs_built": 0, "total_duration_ms": 12500 } } ``` **Example Usage:** ```bash # CLI - Build Python environment only attune action execute core.build_pack_envs \ --param pack_paths='["/tmp/attune-packs/slack"]' \ --param skip_nodejs=true # Force rebuild attune action execute core.build_pack_envs \ --param pack_paths='["/tmp/attune-packs/slack"]' \ --param force_rebuild=true ``` ### 4. core.register_packs Validates pack structure and registers packs with the Attune API. **Parameters:** | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `pack_paths` | array[string] | Yes | - | List of pack directory paths to register | | `packs_base_dir` | string | No | `/opt/attune/packs` | Base directory for permanent storage | | `skip_validation` | boolean | No | false | Skip schema validation | | `skip_tests` | boolean | No | false | Skip running pack tests | | `force` | boolean | No | false | Force registration (replace if exists) | | `api_url` | string | No | `http://localhost:8080` | Attune API URL | | `api_token` | string | No | - | API authentication token (secret) | **Output:** ```json { "registered_packs": [ { "pack_ref": "slack", "pack_id": 42, "pack_version": "1.0.0", "storage_path": "/opt/attune/packs/slack", "components_registered": { "actions": 10, "sensors": 2, "triggers": 3, "rules": 1, "workflows": 0, "policies": 0 }, "test_result": { "status": "passed", "total_tests": 5, "passed": 5, "failed": 0 }, "validation_results": { "valid": true, "errors": [] } } ], "failed_packs": [], "summary": { "total_packs": 1, "success_count": 1, "failure_count": 0, "total_components": 16, "duration_ms": 2500 } } ``` **Example Usage:** ```bash # CLI - Register pack with authentication attune action execute core.register_packs \ --param pack_paths='["/tmp/attune-packs/slack"]' \ --param api_token="$ATTUNE_API_TOKEN" # Force registration (replace existing) attune action execute core.register_packs \ --param pack_paths='["/tmp/attune-packs/slack"]' \ --param force=true \ --param skip_tests=true ``` ## Workflow Integration These actions are designed to work together in the `core.install_packs` workflow: ```yaml # Simplified workflow structure workflow: - download_packs: action: core.download_packs input: packs: "{{ parameters.packs }}" destination_dir: "{{ vars.temp_dir }}" - get_dependencies: action: core.get_pack_dependencies input: pack_paths: "{{ download_packs.output.downloaded_packs | map('pack_path') }}" - build_environments: action: core.build_pack_envs input: pack_paths: "{{ download_packs.output.downloaded_packs | map('pack_path') }}" - register_packs: action: core.register_packs input: pack_paths: "{{ download_packs.output.downloaded_packs | map('pack_path') }}" ``` ## Error Handling All actions follow consistent error handling patterns: 1. **Validation Errors**: Return errors in the `errors` or `failed_*` arrays 2. **Partial Failures**: Process continues for other packs; failures are reported 3. **Fatal Errors**: Exit with non-zero code and minimal JSON output 4. **Timeouts**: Commands respect timeout parameters; failures are recorded Example error output: ```json { "downloaded_packs": [], "failed_packs": [ { "source": "https://github.com/invalid/repo.git", "error": "Git clone failed or timed out" } ], "total_count": 1, "success_count": 0, "failure_count": 1 } ``` ## Testing Comprehensive test suite available at: ``` packs/core/tests/test_pack_installation_actions.sh ``` Run tests: ```bash cd packs/core/tests ./test_pack_installation_actions.sh ``` Test coverage includes: - Input validation - JSON output format validation - Error handling (invalid paths, missing files) - Edge cases (spaces in paths, missing version fields) - Timeout handling - API integration (with mocked endpoints) ## Implementation Details ### Directory Structure ``` packs/core/actions/ ├── download_packs.sh # Implementation ├── download_packs.yaml # Schema ├── get_pack_dependencies.sh ├── get_pack_dependencies.yaml ├── build_pack_envs.sh ├── build_pack_envs.yaml ├── register_packs.sh └── register_packs.yaml ``` ### Dependencies **System Requirements:** - `bash` 4.0+ - `jq` (JSON processing) - `curl` (HTTP requests) - `git` (for git sources) - `tar`, `unzip` (for archive extraction) - `python3`, `pip3` (for Python environments) - `node`, `npm` (for Node.js environments) **Optional:** - `md5sum` or `shasum` (checksums) ### Environment Variables Actions receive parameters via environment variables with prefix `ATTUNE_ACTION_`: ```bash export ATTUNE_ACTION_PACKS='["slack@1.0.0"]' export ATTUNE_ACTION_DESTINATION_DIR=/tmp/packs export ATTUNE_ACTION_API_TOKEN="secret-token" ``` ### Output Format All actions output JSON to stdout. Stderr is used for logging/debugging. ```bash # Redirect stderr to see debug logs ./download_packs.sh 2>&1 | tee debug.log # Parse output output=$(./download_packs.sh 2>/dev/null) success_count=$(echo "$output" | jq '.success_count') ``` ## Best Practices 1. **Use Workflows**: Prefer `core.install_packs` workflow over individual actions 2. **Check Dependencies**: Always run `get_pack_dependencies` before installation 3. **Handle Timeouts**: Set appropriate timeout values for large packs 4. **Validate Output**: Check JSON validity and error fields after execution 5. **Clean Temp Directories**: Remove downloaded packs after successful registration 6. **Use API Tokens**: Always provide authentication for production environments 7. **Enable SSL Verification**: Only disable for testing/development ## Troubleshooting ### Issue: Git clone fails with authentication error **Solution**: Use SSH URLs with configured SSH keys or HTTPS with tokens: ```bash # SSH (requires key setup) packs='["git@github.com:attune/pack-slack.git"]' # HTTPS with token packs='["https://token@github.com/attune/pack-slack.git"]' ``` ### Issue: Python virtualenv creation fails **Solution**: Ensure Python 3 and venv module are installed: ```bash sudo apt-get install python3 python3-venv python3-pip ``` ### Issue: Registry lookup fails **Solution**: Check registry URL and network connectivity: ```bash curl -I https://registry.attune.io/index.json ``` ### Issue: API registration fails with 401 Unauthorized **Solution**: Provide valid API token: ```bash export ATTUNE_ACTION_API_TOKEN="$(attune auth token)" ``` ### Issue: Timeout during npm install **Solution**: Increase timeout parameter: ```bash --param timeout=1200 # 20 minutes ``` ## See Also - [Pack Structure](pack-structure.md) - [Pack Registry](pack-registry-spec.md) - [Pack Testing Framework](../packs/PACK_TESTING.md) - [Workflow System](workflow-orchestration.md) - [Pack Installation Workflow](../packs/core/workflows/install_packs.yaml) ## Future Enhancements Planned improvements: - Parallel pack downloads - Resume incomplete downloads - Dependency graph visualization - Pack signature verification - Rollback on installation failure - Delta updates for pack upgrades