Skip to content

Commit cc7a1c1

Browse files
committed
feat: add setup scripts for infrastructure tools
Add reusable installation scripts to eliminate workflow duplication: - install-opentofu.sh: Install OpenTofu with version detection - install-ansible.sh: Install Ansible automation platform - install-lxd-ci.sh: Install and configure LXD for CI environments - install-multipass-ci.sh: Install and configure Multipass for CI Features: - Tracing-style logging matching existing linting scripts - CI vs local environment detection - Idempotent installation (safe to run multiple times) - Comprehensive error handling and user guidance - Colored output with INFO/WARN/ERROR levels These scripts replace ~75 lines of duplicated code across GitHub workflows while providing better functionality and maintainability.
1 parent ae49fb5 commit cc7a1c1

File tree

5 files changed

+483
-0
lines changed

5 files changed

+483
-0
lines changed

scripts/setup/README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Setup Scripts
2+
3+
This directory contains installation and configuration scripts for the tools required by the Torrust Tracker Deploy project.
4+
5+
## Available Scripts
6+
7+
### Core Infrastructure Tools
8+
9+
- **`install-opentofu.sh`** - Install OpenTofu (Terraform alternative)
10+
- **`install-ansible.sh`** - Install Ansible automation platform
11+
12+
### Container/VM Providers
13+
14+
- **`install-lxd-ci.sh`** - Install and configure LXD (CI-optimized)
15+
- **`install-multipass-ci.sh`** - Install and configure Multipass (CI-optimized)
16+
17+
## Usage
18+
19+
### Individual Installation
20+
21+
```bash
22+
# Install OpenTofu
23+
./scripts/setup/install-opentofu.sh
24+
25+
# Install Ansible
26+
./scripts/setup/install-ansible.sh
27+
28+
# Install LXD (CI environment)
29+
./scripts/setup/install-lxd-ci.sh
30+
31+
# Install Multipass (CI environment)
32+
./scripts/setup/install-multipass-ci.sh
33+
```
34+
35+
### Batch Installation
36+
37+
```bash
38+
# Install all core tools
39+
./scripts/setup/install-opentofu.sh
40+
./scripts/setup/install-ansible.sh
41+
42+
# Choose your container provider
43+
./scripts/setup/install-lxd-ci.sh # OR
44+
./scripts/setup/install-multipass-ci.sh
45+
```
46+
47+
## CI vs Local Development
48+
49+
### CI Environment Detection
50+
51+
The scripts automatically detect CI environments and apply appropriate configurations:
52+
53+
- **CI Detection**: Checks for `CI=true`, `GITHUB_ACTIONS=true`, or `RUNNER_USER` environment variables
54+
- **CI Optimizations**: Uses `sudo` commands and socket permission fixes
55+
- **Logging**: Provides clear feedback about environment detection
56+
57+
### Local Development
58+
59+
For local development, see the dedicated documentation:
60+
61+
- **LXD**: [config/tofu/lxd/README.md](../../config/tofu/lxd/README.md)
62+
- **LXD Tech Stack**: [docs/tech-stack/lxd.md](../../docs/tech-stack/lxd.md)
63+
64+
**Important**: The CI scripts use `sudo` commands and socket permission modifications that are **NOT recommended** for local development. Use proper group membership for local setups.
65+
66+
## Script Features
67+
68+
### Common Features
69+
70+
- **Idempotent**: Safe to run multiple times
71+
- **Verbose Logging**: Clear progress indicators with colored output
72+
- **Error Handling**: Proper error checking and meaningful messages
73+
- **Version Detection**: Skips installation if tool is already installed
74+
75+
### Error Handling
76+
77+
All scripts use `set -euo pipefail` for strict error handling:
78+
79+
- **`-e`**: Exit on any command failure
80+
- **`-u`**: Exit on undefined variable usage
81+
- **`-o pipefail`**: Exit on pipe command failures
82+
83+
### Logging Levels
84+
85+
- **🟢 INFO**: Normal progress messages
86+
- **🟡 WARN**: Important notices or CI-specific actions
87+
- **🔴 ERROR**: Failure messages
88+
89+
## Integration with Workflows
90+
91+
These scripts replace duplicated installation code in GitHub Actions workflows:
92+
93+
- **`.github/workflows/test-e2e.yml`**
94+
- **`.github/workflows/test-lxd-provision.yml`**
95+
- **`.github/workflows/test-multipass-provision.yml`**
96+
97+
## Troubleshooting
98+
99+
### Permission Issues
100+
101+
If you encounter permission errors:
102+
103+
1. **For CI**: Scripts should handle permissions automatically
104+
2. **For Local**: Follow the group membership setup in the tech stack documentation
105+
106+
### Installation Failures
107+
108+
1. Check internet connectivity for download-based installations
109+
2. Verify system requirements (Ubuntu/Debian for apt-based installs)
110+
3. Check available disk space
111+
4. Review script output for specific error messages
112+
113+
### Tool-Specific Issues
114+
115+
- **OpenTofu**: Requires `curl` and package management tools
116+
- **Ansible**: Requires Python and pip (usually pre-installed)
117+
- **LXD**: Requires snap and sufficient privileges
118+
- **Multipass**: Requires snap and virtualization support
119+
120+
## Future Enhancements
121+
122+
These bash scripts are designed to be simple and maintainable. For more complex installation logic, they may be replaced by Rust utilities in the future while maintaining the same interface.

scripts/setup/install-ansible.sh

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
# Install Ansible automation platform
3+
4+
set -euo pipefail
5+
6+
# Colors for output
7+
RED='\033[0;31m'
8+
GREEN='\033[0;32m'
9+
BLUE='\033[0;34m'
10+
YELLOW='\033[1;33m'
11+
NC='\033[0m' # No Color
12+
13+
# Get script name for structured logging
14+
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}" .sh)"
15+
16+
# Logging functions with tracing-style format
17+
log_info() {
18+
local timestamp
19+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
20+
echo -e "${timestamp} ${BLUE} INFO${NC} ${SCRIPT_NAME}: $1"
21+
}
22+
23+
log_success() {
24+
local timestamp
25+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
26+
echo -e "${timestamp} ${GREEN} INFO${NC} ${SCRIPT_NAME}: $1"
27+
}
28+
29+
log_warn() {
30+
local timestamp
31+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
32+
echo -e "${timestamp} ${YELLOW} WARN${NC} ${SCRIPT_NAME}: $1"
33+
}
34+
35+
log_error() {
36+
local timestamp
37+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
38+
echo -e "${timestamp} ${RED}ERROR${NC} ${SCRIPT_NAME}: $1"
39+
}
40+
41+
# Check if Ansible is already installed
42+
if command -v ansible &> /dev/null; then
43+
CURRENT_VERSION=$(ansible --version | head -n1 | awk '{print $3}')
44+
log_info "Ansible is already installed: ${CURRENT_VERSION}"
45+
log_info "Skipping installation. Use --force to reinstall."
46+
exit 0
47+
fi
48+
49+
log_info "Updating package manager..."
50+
sudo apt-get update
51+
52+
log_info "Installing Ansible..."
53+
sudo apt-get install -y ansible
54+
55+
# Verify installation
56+
if command -v ansible &> /dev/null; then
57+
INSTALLED_VERSION=$(ansible --version | head -n1 | awk '{print $3}')
58+
log_success "✅ Ansible successfully installed: ${INSTALLED_VERSION}"
59+
60+
# Show additional info
61+
log_info "Ansible executable: $(which ansible)"
62+
log_info "Python version: $(ansible --version | grep "python version" | awk '{print $3}')"
63+
else
64+
log_error "❌ Ansible installation failed"
65+
exit 1
66+
fi

scripts/setup/install-lxd-ci.sh

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/bin/bash
2+
# Install and configure LXD for CI environments
3+
#
4+
# IMPORTANT: This script uses CI-specific approaches like 'sudo chmod 666' on the LXD socket
5+
# and 'sudo' with LXD commands. These approaches are NOT recommended for local development.
6+
# For local use, follow the proper group membership approach documented in config/tofu/lxd/README.md
7+
8+
set -euo pipefail
9+
10+
# Colors for output
11+
RED='\033[0;31m'
12+
GREEN='\033[0;32m'
13+
BLUE='\033[0;34m'
14+
YELLOW='\033[1;33m'
15+
NC='\033[0m' # No Color
16+
17+
# Get script name for structured logging
18+
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}" .sh)"
19+
20+
# Logging functions with tracing-style format
21+
log_info() {
22+
local timestamp
23+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
24+
echo -e "${timestamp} ${BLUE} INFO${NC} ${SCRIPT_NAME}: $1"
25+
}
26+
27+
log_success() {
28+
local timestamp
29+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
30+
echo -e "${timestamp} ${GREEN} INFO${NC} ${SCRIPT_NAME}: $1"
31+
}
32+
33+
log_warn() {
34+
local timestamp
35+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
36+
echo -e "${timestamp} ${YELLOW} WARN${NC} ${SCRIPT_NAME}: $1"
37+
}
38+
39+
log_error() {
40+
local timestamp
41+
timestamp=$(date -u +"%Y-%m-%dT%H:%M:%S.%6NZ")
42+
echo -e "${timestamp} ${RED}ERROR${NC} ${SCRIPT_NAME}: $1"
43+
}
44+
45+
# Check if we're in a CI environment
46+
is_ci_environment() {
47+
[[ "${CI:-false}" == "true" ]] || [[ "${GITHUB_ACTIONS:-false}" == "true" ]] || [[ -n "${RUNNER_USER:-}" ]]
48+
}
49+
50+
# Check if LXD is already installed
51+
if command -v lxd &> /dev/null; then
52+
CURRENT_VERSION=$(lxd version | head -n1 | awk '{print $1}')
53+
log_info "LXD is already installed: ${CURRENT_VERSION}"
54+
log_info "Proceeding with configuration..."
55+
else
56+
log_info "Installing LXD via snap..."
57+
sudo snap install lxd
58+
fi
59+
60+
# Wait for LXD to fully initialize
61+
log_info "Waiting for LXD daemon to start..."
62+
sleep 15
63+
64+
# Initialize LXD with default settings
65+
log_info "Initializing LXD with default settings..."
66+
sudo lxd init --auto
67+
68+
# Add current user to lxd group
69+
CURRENT_USER="${USER:-$(whoami)}"
70+
log_info "Adding user '${CURRENT_USER}' to lxd group..."
71+
sudo usermod -a -G lxd "${CURRENT_USER}"
72+
73+
# CI-specific socket permission fix
74+
if is_ci_environment; then
75+
log_warn "CI environment detected - applying socket permission fix"
76+
log_warn "IMPORTANT: This approach is ONLY for CI environments"
77+
log_warn "For local development, use proper group membership instead"
78+
79+
# Fix socket permissions for CI environment (NOT recommended for local use)
80+
sudo chmod 666 /var/snap/lxd/common/lxd/unix.socket
81+
else
82+
log_info "Non-CI environment detected"
83+
log_info "For group membership to take effect, you may need to:"
84+
log_info "1. Run 'newgrp lxd' for immediate effect in current shell"
85+
log_info "2. Or log out and log back in"
86+
log_info "3. Or restart your terminal"
87+
log_info "See config/tofu/lxd/README.md for detailed instructions"
88+
fi
89+
90+
# Test basic LXD functionality
91+
log_info "Testing basic LXD functionality..."
92+
if is_ci_environment; then
93+
sudo lxc list
94+
LXD_VERSION=$(sudo lxc version)
95+
else
96+
# For local development, try without sudo first
97+
if lxc list &> /dev/null; then
98+
lxc list
99+
LXD_VERSION=$(lxc version)
100+
else
101+
log_warn "Direct lxc access failed, you may need to activate group membership"
102+
log_warn "Try: newgrp lxd"
103+
sudo lxc list
104+
LXD_VERSION=$(sudo lxc version)
105+
fi
106+
fi
107+
108+
log_success "✅ LXD successfully configured: ${LXD_VERSION}"
109+
log_info "LXD is ready for use"

0 commit comments

Comments
 (0)