Skip to content

Commit 33a06a8

Browse files
committed
feat: implement Docker configuration for E2E configuration testing
- Create docker/provisioned-instance/ directory with Ubuntu 24.04 configuration - Add Dockerfile with supervisor, SSH server, and torrust user setup - Add supervisord.conf for SSH service management - Add entrypoint.sh with container initialization (fixed shellcheck issues) - Create comprehensive README.md documentation - Add docker-phase-architecture.md decision record - Create docker-testing-revision.md superseding original Docker rejection - Update ansible-testing-strategy.md for phase-specific testing approach - Update e2e-docker-config-testing.md with implementation results - Fix markdown linting issues in docker-phase-architecture.md - Add project-words.txt entries for new terminology Architecture implements B.2 step from E2E test split plan: - Phase-specific testing: LXD VMs for provision, Docker for configuration - Supervisor replaces systemd for container-friendly process management - Password auth (torrust:torrust123) plus SSH key support - Represents post-provision, pre-configuration deployment state
1 parent 3c0ebd2 commit 33a06a8

File tree

12 files changed

+969
-108
lines changed

12 files changed

+969
-108
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Docker ignore file for E2E test container builds
2+
# Exclude unnecessary files to optimize build context
3+
4+
# Target directory (Rust build artifacts)
5+
target/
6+
**/target/
7+
8+
# Build directory (generated configurations)
9+
build/
10+
11+
# Git directory
12+
.git/
13+
14+
# VS Code directory
15+
.vscode/
16+
17+
# Documentation (except what's needed)
18+
docs/
19+
!docs/research/e2e-docker-config-testing.md
20+
!docs/refactors/split-e2e-tests-provision-vs-configuration.md
21+
22+
# Examples and fixtures (except SSH keys)
23+
examples/
24+
fixtures/
25+
!fixtures/testing_rsa.pub
26+
27+
# Lock files
28+
*.lock
29+
30+
# Temporary files
31+
*.tmp
32+
*.temp
33+
34+
# Log files
35+
*.log
36+
37+
# OS specific files
38+
.DS_Store
39+
Thumbs.db
40+
41+
# IDE files
42+
*.swp
43+
*.swo
44+
*~
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Dockerfile for Provisioned Instance
2+
# Ubuntu 24.04 LTS representing the state after VM provisioning (before configuration)
3+
# This container simulates a freshly provisioned VM ready for Ansible configuration
4+
# Based on requirements from docs/research/e2e-docker-config-testing.md
5+
6+
FROM ubuntu:24.04
7+
8+
# Metadata
9+
LABEL description="Ubuntu 24.04 provisioned instance - post-provision, pre-configuration state"
10+
LABEL maintainer="Torrust Development Team"
11+
LABEL version="1.0.0"
12+
LABEL deployment-phase="provisioned"
13+
14+
# Set environment variables
15+
ENV DEBIAN_FRONTEND=noninteractive
16+
ENV TZ=UTC
17+
18+
# Update package list and install essential packages
19+
RUN apt-get update && apt-get install -y \
20+
# SSH server for Ansible connectivity
21+
openssh-server \
22+
# Sudo for privilege escalation
23+
sudo \
24+
# Supervisor for process management
25+
supervisor \
26+
# Basic utilities
27+
curl \
28+
wget \
29+
ca-certificates \
30+
gnupg \
31+
lsb-release \
32+
# APT transport for HTTPS repositories
33+
apt-transport-https \
34+
# Clean up package cache
35+
&& apt-get clean \
36+
&& rm -rf /var/lib/apt/lists/*
37+
38+
# Configure SSH server
39+
RUN mkdir -p /var/run/sshd \
40+
# Configure SSH for password authentication initially (tests will set up keys later)
41+
&& sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config \
42+
&& sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config \
43+
&& sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config
44+
45+
# Create torrust user matching LXD VM configuration
46+
RUN useradd -m -s /bin/bash -G sudo torrust \
47+
# Set a simple password for initial SSH access (tests will set up keys later)
48+
&& echo "torrust:torrust123" | chpasswd \
49+
# Configure passwordless sudo
50+
&& echo "torrust ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers \
51+
# Create .ssh directory for authorized keys (to be populated by tests)
52+
&& mkdir -p /home/torrust/.ssh \
53+
&& chmod 700 /home/torrust/.ssh \
54+
&& chown torrust:torrust /home/torrust/.ssh
55+
56+
# SSH public key will be copied by E2E tests during setup
57+
# Create authorized_keys file with proper permissions
58+
RUN touch /home/torrust/.ssh/authorized_keys \
59+
&& chmod 600 /home/torrust/.ssh/authorized_keys \
60+
&& chown torrust:torrust /home/torrust/.ssh/authorized_keys
61+
62+
# Create provision completion marker (matching cloud-init behavior)
63+
RUN mkdir -p /tmp \
64+
&& echo "Container provisioned successfully" > /tmp/provision_complete \
65+
&& chown torrust:torrust /tmp/provision_complete
66+
67+
# Expose SSH port
68+
EXPOSE 22
69+
70+
# Set working directory
71+
WORKDIR /home/torrust
72+
73+
# Create supervisor configuration
74+
COPY docker/provisioned-instance/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
75+
76+
# Create entrypoint script for initialization
77+
COPY docker/provisioned-instance/entrypoint.sh /usr/local/bin/entrypoint.sh
78+
RUN chmod +x /usr/local/bin/entrypoint.sh
79+
80+
# Set entrypoint
81+
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
82+
83+
# Default command - run supervisor
84+
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
# Docker Provisioned Instance Configuration
2+
3+
This directory contains the Docker configuration representing a **provisioned instance** - the state of a VM after provisioning but before configuration in the deployment lifecycle.
4+
5+
## Overview
6+
7+
This Docker configuration provides an Ubuntu 24.04 container that simulates a freshly provisioned VM:
8+
9+
- **SSH Server**: For Ansible connectivity (via supervisor)
10+
- **Base System**: Clean Ubuntu 24.04 LTS installation
11+
- **Sudo User**: `torrust` user with passwordless sudo access
12+
- **Network Access**: For package downloads during configuration phase
13+
- **No App Dependencies**: Docker, Docker Compose, etc. not yet installed (that's the configure phase)
14+
15+
## Files
16+
17+
- `Dockerfile`: Main container configuration for provisioned instance state
18+
- `supervisord.conf`: Supervisor configuration for SSH service management
19+
- `entrypoint.sh`: Container initialization script
20+
- `README.md`: This documentation file
21+
22+
## Deployment Phase Context
23+
24+
This container represents the **provisioned** state in the deployment lifecycle:
25+
26+
```text
27+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
28+
│ Provision │───▶│ Configure │───▶│ Release │───▶│ Run │
29+
│ │ │ │ │ │ │ │
30+
│ • VM Created │ │ • Install Docker│ │ • Deploy Apps │ │ • Start Services│
31+
│ • SSH Ready │ │ • Install Deps │ │ • Config Files │ │ • Validate │
32+
│ • User Setup │ │ • System Config │ │ • Certificates │ │ • Monitor │
33+
└─────────────────┘ └─────────────────┘ └─────────────────┘ └─────────────────┘
34+
35+
THIS CONTAINER
36+
```
37+
38+
**Future Expansion**: Additional containers can represent later phases:
39+
40+
- `docker/configured-instance/` - After Ansible configuration
41+
- `docker/released-instance/` - After application deployment
42+
43+
## Usage
44+
45+
### Building the Container
46+
47+
From the project root directory:
48+
49+
```bash
50+
# Build the provisioned instance Docker image
51+
docker build -f docker/provisioned-instance/Dockerfile -t torrust-provisioned-instance:latest .
52+
```
53+
54+
### Running the Container
55+
56+
#### Basic Run (for testing)
57+
58+
```bash
59+
# Run provisioned instance container with SSH access
60+
docker run -d \
61+
--name torrust-provisioned \
62+
-p 2222:22 \
63+
torrust-provisioned-instance:latest
64+
```
65+
66+
#### Connect via SSH
67+
68+
```bash
69+
# Connect using password authentication (initial setup)
70+
sshpass -p "torrust123" ssh -p 2222 -o StrictHostKeyChecking=no torrust@localhost
71+
72+
# Or copy SSH key and use key authentication
73+
sshpass -p "torrust123" scp -P 2222 -o StrictHostKeyChecking=no fixtures/testing_rsa.pub torrust@localhost:~/.ssh/authorized_keys
74+
ssh -i fixtures/testing_rsa -p 2222 -o StrictHostKeyChecking=no torrust@localhost
75+
```
76+
77+
### Integration with E2E Configuration Tests
78+
79+
The provisioned instance container simulates the state after VM provisioning and is designed for E2E configuration testing:
80+
81+
1. **Container Lifecycle**: Tests manage container creation and cleanup
82+
2. **SSH Authentication**: Initial password authentication (`torrust:torrust123`)
83+
3. **SSH Key Setup**: Tests copy SSH public key during setup phase
84+
4. **Port Mapping**: SSH port (22) is mapped to host for Ansible connectivity
85+
5. **Inventory Generation**: Container IP is added to Ansible inventory
86+
87+
### Configuration Details
88+
89+
#### User Configuration
90+
91+
- **Username**: `torrust` (matches LXD VM configuration)
92+
- **Password**: `torrust123` (for initial SSH access)
93+
- **Groups**: `sudo`
94+
- **Shell**: `/bin/bash`
95+
- **Sudo**: Passwordless sudo access (`NOPASSWD:ALL`)
96+
- **SSH**: Password authentication enabled initially, key-based authentication supported
97+
98+
#### SSH Configuration
99+
100+
- **Port**: 22 (standard SSH port)
101+
- **Authentication**: Password authentication enabled (`torrust123`)
102+
- **Public Key**: Key-based authentication supported (tests copy public key)
103+
- **Root Login**: Disabled
104+
105+
#### Supervisor Configuration
106+
107+
- **Process Manager**: Supervisor instead of systemd (container-friendly)
108+
- **Services**: SSH service managed by supervisor
109+
- **Logging**: Supervisor handles service logging
110+
- **No Privileges**: No `--privileged` flag required
111+
112+
## Requirements
113+
114+
### For Building
115+
116+
- Docker installed on the build system
117+
- Project repository with `fixtures/testing_rsa.pub` file
118+
119+
### For Running
120+
121+
- Docker installed on the system
122+
- No special privileges required (no `--privileged` flag needed)
123+
- SSH client for connectivity testing
124+
125+
## Troubleshooting
126+
127+
### Container Won't Start
128+
129+
1. Check if Docker daemon is running
130+
2. Verify no port conflicts on port 2222
131+
3. Check container logs: `docker logs <container-name>`
132+
133+
### SSH Connection Fails
134+
135+
1. Verify SSH port mapping: `-p 2222:22`
136+
2. Test password authentication: `sshpass -p "torrust123" ssh -p 2222 torrust@localhost`
137+
3. Check if SSH service is running inside container
138+
4. Verify container is accessible: `docker exec -it <container-name> bash`
139+
140+
### Key Authentication Issues
141+
142+
1. Ensure public key is copied correctly to container
143+
2. Verify SSH key file permissions (should be 600)
144+
3. Check authorized_keys file in container: `~/.ssh/authorized_keys`
145+
146+
## Architecture
147+
148+
This container configuration supports the E2E test split architecture:
149+
150+
```text
151+
┌─────────────────────────────────────────┐
152+
│ E2E Config Tests Binary │
153+
│ │
154+
│ ┌─────────────────────────────────────┐│
155+
│ │ Docker Container ││
156+
│ │ ┌─────────────────────────────────┐││
157+
│ │ │ Ubuntu 24.04 LTS │││
158+
│ │ │ - SSH Server (port 22) │││
159+
│ │ │ - Supervisor (process mgmt) │││
160+
│ │ │ - torrust user (sudo access) │││
161+
│ │ │ - Package management (apt) │││
162+
│ │ └─────────────────────────────────┘││
163+
│ └─────────────────────────────────────┘│
164+
│ ▲ │
165+
│ │ SSH (port 2222) │
166+
│ ▼ │
167+
│ ┌─────────────────────────────────────┐│
168+
│ │ Ansible Client ││
169+
│ │ - install-docker.yml ││
170+
│ │ - install-docker-compose.yml ││
171+
│ │ - Dynamic inventory generation ││
172+
│ └─────────────────────────────────────┘│
173+
└─────────────────────────────────────────┘
174+
```
175+
176+
## Related Documentation
177+
178+
- [E2E Tests Split Plan](../../docs/refactors/split-e2e-tests-provision-vs-configuration.md)
179+
- [Docker Configuration Testing Research](../../docs/research/e2e-docker-config-testing.md)
180+
- [E2E Testing Guide](../../docs/e2e-testing.md)
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash
2+
# Entrypoint script for E2E configuration testing container
3+
# Initializes SSH server via supervisor for Ansible connectivity
4+
5+
set -e
6+
7+
# Function to log messages
8+
log() {
9+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >&2
10+
}
11+
12+
log "Starting container initialization..."
13+
14+
# Create supervisor log directory
15+
mkdir -p /var/log/supervisor
16+
17+
# Create SSH host keys if they don't exist
18+
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
19+
log "Generating SSH host keys..."
20+
ssh-keygen -A
21+
fi
22+
23+
# Ensure SSH directory has proper permissions
24+
chown torrust:torrust /home/torrust/.ssh
25+
chmod 700 /home/torrust/.ssh
26+
chmod 600 /home/torrust/.ssh/authorized_keys
27+
28+
# Signal that container is ready
29+
log "Container initialization complete. Starting supervisor..."
30+
31+
# Execute the provided command (supervisor by default)
32+
exec "$@"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[supervisord]
2+
nodaemon=true
3+
user=root
4+
logfile=/var/log/supervisor/supervisord.log
5+
pidfile=/var/run/supervisord.pid
6+
childlogdir=/var/log/supervisor
7+
logfile_maxbytes=50MB
8+
logfile_backups=10
9+
loglevel=info
10+
11+
[program:sshd]
12+
command=/usr/sbin/sshd -D
13+
stdout_logfile=/var/log/supervisor/sshd.log
14+
stderr_logfile=/var/log/supervisor/sshd.log
15+
autorestart=true
16+
startretries=3
17+
priority=1
18+
19+
[unix_http_server]
20+
file=/var/run/supervisor.sock
21+
chmod=0700
22+
23+
[supervisorctl]
24+
serverurl=unix:///var/run/supervisor.sock
25+
26+
[rpcinterface:supervisor]
27+
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

0 commit comments

Comments
 (0)