Skip to content

Commit 6ae870d

Browse files
committed
feat(lab-01): Nextcloud standalone -- SQLite, admin setup, occ checks, WebDAV
1 parent 4032b36 commit 6ae870d

3 files changed

Lines changed: 111 additions & 87 deletions

File tree

.github/workflows/ci.yml

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,37 +72,29 @@ jobs:
7272
sarif_file: trivy-results.sarif
7373

7474
lab-01-smoke:
75-
name: Lab 01 — Smoke Test
75+
name: Lab 01 — Nextcloud standalone (status.php, occ, WebDAV)
7676
runs-on: ubuntu-latest
7777
needs: validate
78-
continue-on-error: true # scaffold stubs; full lab runs on real VMs
78+
continue-on-error: true
7979
steps:
8080
- uses: actions/checkout@v4
8181

82-
- name: Generate CI env file
83-
run: |
84-
# Copy example env and inject CI-safe defaults for any unset port vars
85-
if [ -f .env.example ]; then cp .env.example .env; fi
86-
# Set port placeholder vars used in scaffold compose files
87-
echo "firstPort=389" >> .env
88-
echo "secondPort=9090" >> .env
82+
- name: Install tools
83+
run: sudo apt-get install -y curl
8984

90-
- name: Validate standalone compose can start
85+
- name: Validate standalone compose
9186
run: |
92-
docker compose -f docker/docker-compose.standalone.yml config --no-interpolate -q
93-
echo "Standalone compose structure is valid"
87+
docker compose -f docker/docker-compose.standalone.yml config -q
88+
echo "Standalone compose valid"
9489
9590
- name: Start standalone stack
9691
run: docker compose -f docker/docker-compose.standalone.yml up -d
9792

98-
- name: Wait for health
99-
run: |
100-
echo "Waiting for services..."
101-
sleep 30
102-
docker compose -f docker/docker-compose.standalone.yml ps
93+
- name: Wait for Nextcloud (first-boot SQLite setup ~2 min)
94+
run: timeout 300 bash -c 'until curl -sf http://localhost:8080/status.php | grep -q \'"installed":true\'; do sleep 10; done'
10395

104-
- name: Run Lab 01 test script
105-
run: bash tests/labs/test-lab-01.sh
96+
- name: Run Lab 06-01 test script
97+
run: bash tests/labs/test-lab-06-01.sh
10698

10799
- name: Collect logs on failure
108100
if: failure()
Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
1-
# Lab 01 — Standalone: Complete Nextcloud file sync, calendar, and office suite in isolation
2-
# No external dependencies required.
1+
# Lab 01 — Standalone: Nextcloud file sync, calendar, and office suite
2+
# Self-contained — uses SQLite (auto). No PostgreSQL or Redis required.
3+
# Access: http://localhost:8080 Admin: admin / Lab01Password!
34
---
45
services:
56
nextcloud:
6-
image: nextcloud:28-apache
7-
container_name: it-stack-nextcloud
7+
image: nextcloud:29-apache
8+
container_name: it-stack-nextcloud-standalone
89
restart: unless-stopped
910
ports:
10-
- "80:$firstPort"
11+
- "8080:80"
1112
environment:
12-
- IT_STACK_ENV=lab-01-standalone
13+
NEXTCLOUD_ADMIN_USER: admin
14+
NEXTCLOUD_ADMIN_PASSWORD: Lab01Password!
15+
NEXTCLOUD_TRUSTED_DOMAINS: "localhost 127.0.0.1"
1316
volumes:
14-
- nextcloud_data:/var/lib/nextcloud
17+
- nextcloud-standalone-data:/var/www/html
1518
healthcheck:
16-
test: ["CMD-SHELL", "curl -sf http://localhost/health || exit 1"]
19+
test: ["CMD-SHELL", "curl -sf http://localhost/status.php | grep -q '\"installed\":true' || exit 1"]
1720
interval: 30s
18-
timeout: 10s
19-
retries: 5
20-
start_period: 60s
21+
timeout: 15s
22+
retries: 12
23+
start_period: 120s
2124
networks:
22-
- it-stack-net
25+
- nextcloud-standalone-net
26+
deploy:
27+
resources:
28+
limits:
29+
memory: 512m
2330

2431
networks:
25-
it-stack-net:
32+
nextcloud-standalone-net:
2633
driver: bridge
2734

2835
volumes:
29-
nextcloud_data:
36+
nextcloud-standalone-data:
37+
driver: local

tests/labs/test-lab-06-01.sh

Lines changed: 78 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,95 @@
11
#!/usr/bin/env bash
2-
# test-lab-06-01.sh Lab 06-01: Standalone
3-
# Module 06: Nextcloud file sync, calendar, and office suite
4-
# Basic nextcloud functionality in complete isolation
2+
# test-lab-06-01.sh -- Nextcloud Lab 01: Standalone
3+
# Tests: HTTP health, status.php, occ status, user list, WebDAV, version
4+
# Usage: bash test-lab-06-01.sh
55
set -euo pipefail
66

7-
LAB_ID="06-01"
8-
LAB_NAME="Standalone"
9-
MODULE="nextcloud"
10-
COMPOSE_FILE="docker/docker-compose.standalone.yml"
11-
PASS=0
12-
FAIL=0
7+
PASS=0; FAIL=0
8+
ok() { echo "[PASS] $1"; ((PASS++)); }
9+
fail(){ echo "[FAIL] $1"; ((FAIL++)); }
10+
info(){ echo "[INFO] $1"; }
1311

14-
# ── Colors ────────────────────────────────────────────────────────────────────
15-
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'
16-
CYAN='\033[0;36m'; NC='\033[0m'
12+
# -- Section 1: Container running --------------------------------------------
13+
info "Section 1: Container health"
14+
container_status=$(docker inspect --format '{{.State.Status}}' it-stack-nextcloud-standalone 2>/dev/null || echo "not-found")
15+
info "Container status: $container_status"
16+
[[ "$container_status" == "running" ]] && ok "Container running" || fail "Container running (got: $container_status)"
1717

18-
pass() { echo -e "${GREEN}[PASS]${NC} $1"; ((PASS++)); }
19-
fail() { echo -e "${RED}[FAIL]${NC} $1"; ((FAIL++)); }
20-
info() { echo -e "${CYAN}[INFO]${NC} $1"; }
21-
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
18+
# -- Section 2: HTTP endpoint -------------------------------------------------
19+
info "Section 2: HTTP :8080 responds"
20+
http_code=$(curl -so /dev/null -w "%{http_code}" http://localhost:8080/ 2>/dev/null || echo "000")
21+
info "GET http://localhost:8080/ -> $http_code"
22+
if [[ "$http_code" =~ ^(200|301|302)$ ]]; then ok "HTTP :8080 responds ($http_code)"; else fail "HTTP :8080 (got $http_code)"; fi
2223

23-
echo -e "${CYAN}======================================${NC}"
24-
echo -e "${CYAN} Lab ${LAB_ID}: ${LAB_NAME}${NC}"
25-
echo -e "${CYAN} Module: ${MODULE}${NC}"
26-
echo -e "${CYAN}======================================${NC}"
27-
echo ""
24+
# -- Section 3: status.php ----------------------------------------------------
25+
info "Section 3: /status.php reports installed"
26+
status_json=$(curl -sf http://localhost:8080/status.php 2>/dev/null || echo '{}')
27+
info "status.php: $status_json"
28+
if echo "$status_json" | grep -q '"installed":true'; then
29+
ok "Nextcloud installed (status.php)"
30+
else
31+
fail "Nextcloud not installed yet (status.php: $status_json)"
32+
fi
2833

29-
# ── PHASE 1: Setup ────────────────────────────────────────────────────────────
30-
info "Phase 1: Setup"
31-
docker compose -f "${COMPOSE_FILE}" up -d
32-
info "Waiting 30s for ${MODULE} to initialize..."
33-
sleep 30
34+
# -- Section 4: Extract version -----------------------------------------------
35+
info "Section 4: Nextcloud version"
36+
version=$(echo "$status_json" | grep -o '"version":"[^"]*"' | cut -d'"' -f4 || echo "unknown")
37+
info "Version: $version"
38+
[[ -n "$version" && "$version" != "unknown" ]] && ok "Nextcloud version: $version" || fail "Nextcloud version not readable"
3439

35-
# ── PHASE 2: Health Checks ────────────────────────────────────────────────────
36-
info "Phase 2: Health Checks"
40+
# -- Section 5: Maintenance mode OFF ------------------------------------------
41+
info "Section 5: Maintenance mode"
42+
maintenance=$(echo "$status_json" | grep -o '"maintenance":[^,}]*' | cut -d: -f2 | tr -d ' ' || echo "unknown")
43+
info "Maintenance: $maintenance"
44+
[[ "$maintenance" == "false" ]] && ok "Maintenance mode: off" || fail "Maintenance mode (got: $maintenance)"
3745

38-
if docker compose -f "${COMPOSE_FILE}" ps | grep -q "running\|Up"; then
39-
pass "Container is running"
46+
# -- Section 6: occ status (via docker exec) ----------------------------------
47+
info "Section 6: occ status inside container"
48+
if docker exec it-stack-nextcloud-standalone php occ status 2>/dev/null | grep -q "installed: true"; then
49+
ok "occ status: installed = true"
4050
else
41-
fail "Container is not running"
51+
fail "occ status: installed not true"
4252
fi
4353

44-
# ── PHASE 3: Functional Tests ─────────────────────────────────────────────────
45-
info "Phase 3: Functional Tests (Lab 01 — Standalone)"
46-
47-
# TODO: Add module-specific functional tests here
48-
# Example:
49-
# if curl -sf http://localhost:80/health > /dev/null 2>&1; then
50-
# pass "Health endpoint responds"
51-
# else
52-
# fail "Health endpoint not reachable"
53-
# fi
54+
# -- Section 7: occ user:list shows admin ------------------------------------
55+
info "Section 7: Admin user exists (occ user:list)"
56+
if docker exec it-stack-nextcloud-standalone php occ user:list 2>/dev/null | grep -qi "admin"; then
57+
ok "Admin user present in occ user:list"
58+
else
59+
fail "Admin user not found in occ user:list"
60+
fi
5461

55-
warn "Functional tests for Lab 06-01 pending implementation"
62+
# -- Section 8: WebDAV endpoint accessible ------------------------------------
63+
info "Section 8: WebDAV endpoint"
64+
webdav_code=$(curl -sf -X PROPFIND http://localhost:8080/remote.php/dav/ \
65+
-H "Depth: 0" -u admin:Lab01Password! -o /dev/null -w "%{http_code}" 2>/dev/null || echo "000")
66+
info "WebDAV PROPFIND -> $webdav_code"
67+
if [[ "$webdav_code" =~ ^(207|401)$ ]]; then ok "WebDAV :8080 endpoint present ($webdav_code)"; else fail "WebDAV endpoint (got $webdav_code)"; fi
5668

57-
# ── PHASE 4: Cleanup ──────────────────────────────────────────────────────────
58-
info "Phase 4: Cleanup"
59-
docker compose -f "${COMPOSE_FILE}" down -v --remove-orphans
60-
info "Cleanup complete"
69+
# -- Section 9: OCS capabilities API -----------------------------------------
70+
info "Section 9: OCS Capabilities API"
71+
ocs_code=$(curl -sf -u admin:Lab01Password! \
72+
"http://localhost:8080/ocs/v2.php/cloud/capabilities?format=json" \
73+
-o /dev/null -w "%{http_code}" 2>/dev/null || echo "000")
74+
info "OCS capabilities -> $ocs_code"
75+
[[ "$ocs_code" == "200" ]] && ok "OCS Capabilities API: 200" || fail "OCS Capabilities API (got $ocs_code)"
6176

62-
# ── Results ───────────────────────────────────────────────────────────────────
63-
echo ""
64-
echo -e "${CYAN}======================================${NC}"
65-
echo -e " Lab ${LAB_ID} Complete"
66-
echo -e " ${GREEN}PASS: ${PASS}${NC} | ${RED}FAIL: ${FAIL}${NC}"
67-
echo -e "${CYAN}======================================${NC}"
77+
# -- Section 10: Files app enabled --------------------------------------------
78+
info "Section 10: Files app enabled"
79+
if docker exec it-stack-nextcloud-standalone php occ app:list --enabled 2>/dev/null | grep -q "files:"; then
80+
ok "Files app enabled"
81+
else
82+
fail "Files app not enabled"
83+
fi
6884

69-
if [ "${FAIL}" -gt 0 ]; then
70-
exit 1
85+
# -- Section 11: Integration score -------------------------------------------
86+
info "Section 11: Lab 01 standalone integration score"
87+
TOTAL=$((PASS + FAIL))
88+
echo "Results: $PASS/$TOTAL passed"
89+
if [[ $FAIL -eq 0 ]]; then
90+
echo "[SCORE] 6/6 -- All standalone checks passed"
91+
exit 0
92+
else
93+
echo "[SCORE] FAIL ($FAIL failures)"
94+
exit 1
7195
fi

0 commit comments

Comments
 (0)