Skip to content

EUD Emulator Fleet

The EUD emulator fleet runs ten containerized Android emulators that present as real End-User Devices against a running MAGK backend. Each EUD boots ATAK-CIV with the same plugin stack a field operator would have, pointed at the staging TAK service, TAK Update Server, and enrollment endpoint.

Use the fleet for:

  • End-to-end integration testing of ATAK flows (stream, chat, missions)
  • Load testing the TAK service with realistic CoT cadence
  • Smoke testing the TAK Update Server after a plugin rollout
  • Demos and screen recordings with real ATAK UIs

Prerequisites

The fleet runs on the staging runner (/home/allipry/magk-staging) or any Linux host with:

  • KVM enabled and /dev/kvm accessible
  • ~20 vCPU and ~30 GB RAM available concurrently
  • Docker ≥ 20.10 with the compose v2 plugin
  • The staging backend already running (docker compose … up -d) so EUDs can reach tak-service, nginx, and web over the magk-network Docker bridge

Quick start

# Start the fleet (staggered 3 at a time)
scripts/eud-fleet.sh start

# Provision all 10 EUDs: sideload ATAK + plugins, register MAGK
# users, push ATAK prefs, launch the app
scripts/eud-fleet.sh provision

# Check per-EUD status
scripts/eud-fleet.sh status

# Open the ATAK UI of EUD #3 in a browser
open "$(scripts/eud-fleet.sh novnc 3)"

# Tear it all down
scripts/eud-fleet.sh stop

See .env.template (# EUD EMULATOR FLEET) for the full list of configurable variables.

Identity and users

The fleet does not require Google accounts. Instead, each EUD is registered as a real MAGK user via the Better Auth sign-up API, using a Gmail-style + alias on a single base address:

FLEET_BASE_EMAIL_USER=ops
FLEET_BASE_EMAIL_DOMAIN=magktech.com

produces ops+eud1@magktech.com through ops+eud10@magktech.com, which all route to the same inbox (ops@magktech.com) on any mail provider that implements sub-addressing (Gmail, Google Workspace, FastMail, iCloud, etc.). Rotate FLEET_USER_PASSWORD after real use.

Callsigns default to MAGK-01 through MAGK-10 and appear on the MAGK tactical map the moment each EUD's ATAK connects to tak-service:8089.

APK inventory

Every APK under tools/eud-test-harness/apks/ is sideloaded by scripts/eud-provision.sh. The FLEET_PLUGIN_SKIPLIST env var excludes specific filenames — default skiplist entries:

Filename Reason
ATAK-Plugin-taktalk-1.0.0-…-civ-release.apk Download appears corrupted (~1.5 GB; expected < 100 MB). Flagged by the update-server builder. Replace with a clean APK to re-enable.

Missing plugins

Vx (com.atakmap.android.gbr.vx.plugin) is not in the repo because Guerrilla Dynamics distributes it primarily via Google Play. To include it on the fleet and in the TAK Update Server, obtain the APK from an authorised source (Aurora Store export or vendor direct) and drop it into tools/eud-test-harness/apks/. The builder and provisioner will pick it up with no further changes.

Mumla and Meshtastic are available on F-Droid at stable, hash-verified URLs:

scripts/download-fdroid-apks.sh

fetches both into the APK directory. Re-run scripts/build-tak-update-server.py afterwards to regenerate the manifest with their hashes.

Resource tuning

Ten emulators booting in parallel will peg CPU and stall on /dev/kvm. The default is to boot three at a time (FLEET_BOOT_BATCH=3) and wait for each batch to reach healthy before launching the next. On hosts with less capacity:

FLEET_SIZE=4 FLEET_BOOT_BATCH=2 scripts/eud-fleet.sh start

The fleet compose file reserves 2 GB + 1 vCPU per container and allows burst up to 3 GB + 2 vCPU.

Known gaps

  • Appium tests are not yet integrated with the existing tools/eud-test-harness/ Python harness. The fleet publishes Appium on ports 4723–4732 so this wiring is trivial; follow-up spec.

Certificate enrollment

scripts/eud-provision.sh automates the enrollment flow end-to-end via the admin-only eudFleet.enrollCert oRPC endpoint:

  1. The provisioner signs in as admin (using ADMIN_EMAIL / ADMIN_PASSWORD from .env.staging).
  2. For each EUD it POSTs { callsign, clientUid } to /api/rpc/eudFleet.enrollCert.
  3. The server generates a 2048-bit RSA keypair, builds a CSR with CN=<callsign>, signs it with the MAGK TAK CA (same path as the public signClient/v2 endpoint), packages the result into a PKCS#12 bundle with password atakatak, and returns base64-encoded clientP12 + truststoreP12.
  4. The provisioner decodes the bundles inside the web container, copies them out, and adb pushes them to /sdcard/atak/cert/<callsign>.p12 and /sdcard/atak/cert/truststore.p12 on the emulator.
  5. The ATAK preferences template (config/atak/preferences.xml.template) already points at those paths; ATAK picks up the certs on next launch.

No QR codes and no Basic-Auth tokens — those remain the path for real field EUDs enrolling over port 8446. Fleet EUDs are issued player_registrations rows with eventId=null so they appear in the admin tooling alongside real enrollments.

Admin actions visible in /admin/logs:

  • eud_fleet.enroll_cert — one per EUD per provision run
  • eud_fleet.revoke_enrollment — on scripts/eud-fleet.sh destroy
  • certificate.enrollment_sign — emitted by the shared signing path