A Docker Compose stack that runs the deployed images (quay.io/schulcloudverbund/*, thr theme, tag 33.40 — the versions schulcloud-thueringen.de reports) rather than a rebuild of main, so what we develop against is the deployed artefact. It exists to produce the states we can otherwise only observe read-only: log in as the teacher, grade, then read it back the way the MCP server does. Faithful where it matters and honest where it isn't: - Feature flags in env/api.env are a replay of GET /api/v3/config/public from the live instance, not a hand-picked set; instance identity mirrors the thr group_vars from dof_app_deploy. - The proxy is generated from the deployment's own ingress table (scripts/gen-proxy-conf.py) so the legacy-client / SPA / API path split matches production; getting it wrong tests a different application. - Valkey runs in `single` mode so the JWT whitelist expires sessions the way production does, rather than the in-memory shortcut that hides it. - No external OAuth / Schulportal login (excluded by request and not reproducible locally), no BigBlueButton; each divergence is marked at the line it affects. Everything binds to 127.0.0.1 and uses the upstream dev credentials, which are public. Profiles keep the heavy pieces opt-in: `tools` adds Etherpad/H5P/tldraw/ Collabora, `av` adds ClamAV, `preview` adds thumbnailing. seed.sh loads the upstream demo school (the same call the deployment's init job makes) and registers MinIO as the legacy storage provider, which has no seed data on purpose. The demo data already contains the grading states that are hard to obtain from the real account — a feedback-only grade and a 100% one — which is what surfaced the past-due submitted-text scrape gap. One config finding baked in: file-storage and h5p validate a token's issuer/audience against JWT_DOMAIN (default "localhost"), while the API stamps SC_DOMAIN; without keeping them equal, the homework page's file lookups 401. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
70 lines
2.8 KiB
Bash
Executable File
70 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Seed the local instance with the upstream demo school.
|
|
#
|
|
# This is what the real deployment's init job does (dof_app_deploy
|
|
# .../schulcloud-server-init/templates/configmap_file_init.yml.j2): it asks the
|
|
# management app to load backup/setup/*.json, which ships inside the server
|
|
# image. Safe to re-run — collections are replaced, not appended to.
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
MGMT=http://127.0.0.1:3333/api/management/database
|
|
COMPOSE=(docker compose)
|
|
|
|
echo "==> waiting for the management app"
|
|
for _ in $(seq 1 60); do
|
|
if curl -fsS -o /dev/null "$MGMT/../../docs" 2>/dev/null || curl -fsS -o /dev/null -X POST "$MGMT/sync-indexes" 2>/dev/null; then
|
|
break
|
|
fi
|
|
sleep 5
|
|
done
|
|
|
|
echo "==> seeding collections (this takes a minute or two)"
|
|
curl -fsS --retry 30 --retry-all-errors --retry-delay 10 \
|
|
-X POST "$MGMT/seed?with-indexes=true" >/dev/null
|
|
echo " done"
|
|
|
|
# The legacy file service (course/topic attachments, as opposed to the newer
|
|
# /api/v3/file API) reads its S3 credentials from a storageproviders document
|
|
# rather than from the environment, and there is deliberately no seed data for
|
|
# it. Without this, legacy uploads fail with a provider-not-found error.
|
|
echo "==> registering MinIO as the legacy storage provider"
|
|
S3_KEY=$(grep -E '^S3_KEY=' env/shared.env | cut -d= -f2-)
|
|
SECRET=$(curl -fsS -X POST "$MGMT/encrypt-plain-text" \
|
|
-H 'Content-Type: application/json' \
|
|
-d "$(printf '{"plainText":"miniouser","key":"%s"}' "$S3_KEY")")
|
|
|
|
"${COMPOSE[@]}" exec -T mongo mongosh schulcloud --quiet --eval "
|
|
const id = ObjectId('62949a4003839b6162aa566b');
|
|
db.storageproviders.replaceOne({ _id: id }, {
|
|
_id: id, isShared: true, region: 'eu-central-1', type: 'S3',
|
|
endpointUrl: 'http://minio:9000',
|
|
accessKeyId: 'miniouser',
|
|
secretAccessKey: '$SECRET',
|
|
maxBuckets: 150, freeBuckets: 138,
|
|
createdAt: new Date(), updatedAt: new Date(), __v: 0,
|
|
}, { upsert: true });
|
|
const r = db.schools.updateMany({}, { \$set: { storageProvider: id } });
|
|
print(' schools linked to the provider: ' + r.modifiedCount);
|
|
"
|
|
|
|
cat <<'ACCOUNTS'
|
|
|
|
==> ready — http://localhost:4400
|
|
|
|
Seeded accounts (the demo password differs by account — upstream quirk):
|
|
|
|
demo-schueler@schul-cloud.org student Fritz Schmidt schulcloud
|
|
^ has graded submissions, incl. a feedback-only and a 100% one
|
|
demo-lehrer@schul-cloud.org teacher Erika Meier schulcloud
|
|
klara.fall@schul-cloud.org teacher Klara Fall Schulcloud1!
|
|
^ owns Fritz's graded Biologie submissions
|
|
lehrer@schul-cloud.org teacher Cord Carl Schulcloud1!
|
|
admin@schul-cloud.org admin Thorsten Test Schulcloud1!
|
|
*.qa@schul-cloud.org various Schulcloud1qa!
|
|
|
|
Sign in as the teacher to grade, as the student to see what grading looks
|
|
like from the side our MCP server reads.
|
|
ACCOUNTS
|