Controller v3.8 is a greenfield release aligned with Edgelet. There is no upgrade path from v3.7: use a fresh database and redeploy Controller + Edgelet together.
- Edgelet only — v3.7 legacy field agents are not supported.
- Requires Edgelet v1.0.0-rc.1+ on the same release train (pin e.g.
v1.0.0-rc.1with Controllerv3.8.0). - Provision accepts
containerEngine:edgelet|docker|podman(was docker-implied). - Agent config:
dockerUrl→containerEngineUrl;dockerPruningFrequency→pruningFrequency. - Agent architecture:
fogType/fogTypeId→arch/archId(ids: 0=auto, 1=amd64, 2=arm64, 3=riscv64, 4=arm). - Agent status: removed
processedMessages,messageSpeed; addedavailableRuntimes, optionalruntimeAgentPhase,controlPlaneQuiesced. - Default container registry:
docker.io(wasregistry.hub.docker.com). - Reserved ports: 54321, 54322, 53.
- New field-agent endpoint:
POST /api/v3/agent/controller/register(system fogs only; Edgelet rc.1+). Register body accepts full container workload fields (cmd,isPrivileged,healthCheck,capAdd/capDrop,extraHosts, resources, etc.) with the same semantics as user microservice deploy; excludesserviceAccount,natsConfig, and ownership fields.
GET /api/v3/fog-types→GET /api/v3/architectures/(public)./api/v3/flow/*→/api/v3/application/*; RBAC resourceflows→applications.- Microservice create:
applicationstring (name) in body —flowIdquery param removed. - Error codes:
INVALID_FLOW_*→INVALID_APPLICATION_*. - Catalog and microservice images:
images[]with{ containerImage, archId }(up to 4 per arch 1–4); single-image-only create removed. - Microservice
runtimemust be in agentavailableRuntimes. - Service account volume type
serviceAccount(immutable);roleRef.apiGroupedgelet.iofog.org/v1(wasagent.datasance.com/v3). - System microservice
controllerin applicationsystem-{agentName}; user delete → 403, user PATCH → 400. - TCP bridge connector
hostdepends on target agent router mode and service type. A router is required (routerMode≠none) formicroserviceandagentservices. Interior router:127.0.0.1. Edge router:edgelet.default.svc.bridge.localfor host-network microservices andagentservices;{appName}.{microserviceName}for pod-network microservices (removediofog,iofog_{uuid}, andedgelet.default.bridge.local). - Skupper router
siteIdremoved from persistedtcpConnector/tcpListenerentries in router microservice config (target router is implied by which router microservice holds the config). - NATS system microservice env and config templates:
NATS_SSL_DIR→NATS_TLS_DIR. - Debug catalog image:
ghcr.io/eclipse-iofog/node-debugger→ghcr.io/eclipse-iofog/debugger(seeders andconfig.yaml).
- EdgeResource APIs, models, and RBAC.
- Diagnostics, strace, image snapshot / download APIs.
- All
/api/v3/flowroutes.
- Microservice exec REST removed —
POST/DELETE /api/v3/microservices/:uuid/execand…/system/:uuid/execno longer exist. Open exec with direct WebSocket only:WS /api/v3/microservices/exec/:uuid(or…/system/exec/:uuid). - 3 concurrent exec sessions per microservice (was 1 user exec WS per MS).
- Per-session lifecycle — closing one exec session deletes only that session row only (no microservice-level exec flag).
execEnabledremoved — droppedmicroservices.exec_enabledcolumn and agent MS list field; exec attach is poll-driven only (GET /agent/exec/sessions).- Agent exec discovery — new
GET /api/v3/agent/exec/sessionswhen change tracking reportsexecSessions: true. - Agent exec WebSocket —
WS /api/v3/agent/exec/microservice/:microserviceUuid/:sessionIdonly; legacyWS /api/v3/agent/exec/:microserviceUuidwith initial MessagePack pairing frame removed. - User session announce — Controller sends ACTIVATION (type 5) to user with
{ sessionId, microserviceUuid }on connect. - Fog debug —
POST/DELETE /api/v3/iofog/:uuid/execunchanged (provisions debug system MS); interactive shell viaWS /api/v3/microservices/system/exec/:debugMsUuid(system path — debug MS is a system microservice).
keycloak-connectremoved — generic OIDC (openid-client+ JWKS discovery).- Keycloak-specific env removed:
KC_*,auth.realm,auth.realmKey, realm public key. - Canonical OIDC env:
OIDC_ISSUER_URL(full issuer URL),OIDC_CLIENT_ID,OIDC_CLIENT_SECRET,OIDC_CONSOLE_CLIENT_ID,AUTH_MODE(embedded|external). - Embedded issuer at
{CONTROLLER_PUBLIC_URL}/oidcwhenAUTH_MODE=embedded. - TLS env renamed:
SSL_*→TLS_*; useCONTROLLER_PUBLIC_URL+TRUST_PROXYbehind reverse proxies. - Browser login: OAuth BFF (
GET /api/v3/user/oauth/authorize) — not browserPOST /user/login. - Bootstrap admin:
OIDC_BOOTSTRAP_ADMIN_USERNAME,OIDC_BOOTSTRAP_ADMIN_PASSWORD(embedded first boot).
-
Container-only ship — no npm publish of
@datasance/iofogcontrolleror@datasance/ecn-viewer. -
EdgeOps Console static SPA embedded in the Controller image (replaces
@datasance/ecn-viewer/@iofog/ecn-viewernpm package). -
Build flavors:
datasance|iofogviaEDGEOPS_CONSOLE_FLAVOR/EDGEOPS_CONSOLE_VERSION. -
Env renames (no aliases):
Remove Canonical VIEWER_URLCONSOLE_URLVIEWER_PORTCONSOLE_PORTECN_VIEWER_PATHEDGEOPS_CONSOLE_PATHOIDC_VIEWER_CLIENT_IDOIDC_CONSOLE_CLIENT_IDAUTH_VIEWER_CLIENT_ENABLEDAUTH_CONSOLE_CLIENT_ENABLED -
Runtime
controller-config.jsusesconsoleUrl(notviewerUrl);auth.*endpoints only — nokeycloak*oroidcIssuerUrlkeys in Console config. -
Dual-port default: API 51121, Console 8008.
-
Status API field
versions.ecnViewerretained for compatibility; value is the embedded Console version string.
- Greenfield schema — new install required; no v3.7 → v3.8 database migrator.
- PKI: central router/NATS local CAs; legacy per-agent CAs migrated via one-time rotation job.
- Node.js 24.x required for dev and CI (was 16/18).
- Dual-mirror container images:
ghcr.io/eclipse-iofog/controllerandghcr.io/datasance/controllerfrom the same commit SHA; publish onv*tags only via repo variableIMAGE_REGISTRY.
- Embedded OIDC identity service with TOTP MFA (
mfaRequiredper auth group; all system groups default to MFA off on install). GET /api/v3/user/profile(embedded mode) — includesmfaEnabledfor the authenticated user.POST /api/v3/auth/migration/export— one-way embedded → external IdP migration.POST /api/v3/auth/jwks/rotate— manual JWKS rotation (embedded mode).- Built-in rate limiting on auth endpoints.
- HA BFF session store support for multi-replica Controller deployments.
- NOTICE file replaces per-file copyright headers.
- Neutral in-tree identity: RBAC
iofog.org/v3, default namespaceiofog,package.jsonnamecontroller. - NATS account/user rule JWT Latin-1 validation — rejects rules whose fields cannot be encoded in a NATS JWT (create/update on rules, applications, microservices, and NATS API).
- RBAC route catalog utils (
isPublicCatalogRoute) — shared lookup of public routes fromrbac-resources.yaml(empty verb list = no auth required). - Fog + service platform reconcile — declarative router/NATS and service endpoint lifecycle replaces fire-and-forget
setImmediateiniofog-service.jsandservices-service.js. - Tables:
FogPlatformSpecs,FogPlatformStatuses,FogPlatformReconcileTasks,ServicePlatformReconcileTasks,HubRouterConfigLocks(greenfield migrations amended for sqlite, mysql, postgres). platform-reconcile-worker-job.js— one worker, two DB-backed claim paths (fog + service); stale reclaim, exponential backoff, max attempts.fog-platform-sweep-job.js— periodic drift detection for fog and service platform state.GET /api/v3/iofog/{uuid}— optionalplatformStatus(phase,generation,lastError, conditions).POST /api/v3/iofog/{uuid}/reconcileandPOST /api/v3/services/{name}/reconcile— manual retry after failed or stuck reconcile.- Service
provisioningStatus— hub semantics:readywhen hub connector/listener and K8s Service reconcile succeed; edge TCP bridges converge asynchronously via fog platform reconcile fan-out. - K8s control plane: hub
iofog-routerConfigMap patches serialized via DB lock; K8s Service create/update/delete with LoadBalancer watch timeout. service-bridge-config.js— full recompute of service-derived TCP bridge config per fog on reconcile (preserves router base config).- SQLite single-node production hardening — WAL +
busy_timeoutpragmas, reconcile task claim retry onSQLITE_BUSY, staggered startup for reconcile-heavy background jobs (settings.jobStartupDelaySeconds). - WebSocket exec & log session hardening — quotas (3 exec / 3 log WS per resource), per-session exec lifecycle, 60s/120s pending timeouts, 8h exec max, 30s graceful drain, OTEL metrics, HA AMQP fail-fast, integration tests, swagger WS protocol docs, operator guide (
docs/operations/ws-sessions.md). - Multi exec sessions —
GET /api/v3/agent/exec/sessions; agent exec WS…/agent/exec/microservice/:uuid/:sessionId; user ACTIVATION withsessionId;MicroserviceExecSessionstable;execMaxConcurrentPerResourceconfig (default 3). - WebSocket relay production — unified
WsRelayTransportabstraction; cross-replica exec/log relay backend selected at startup bynats.enabled(NATS_ENABLED): AMQP router pool (8 connections per replica, overflow recovery, sendable gating) whenfalse, NATS Core pub/sub on platform hub (controller-relayaccount) whentrue. Fail-fast activation on both transports; log backpressure dropsLOG_LINEunder pressure. Config:server.webSocket.relay.amqp.*,server.webSocket.relay.nats.*. No new relay env var; HA swagger/docs updated per R112.
- NATS relay and AMQP router connection resolvers — Remote CP uses Edgelet bridge DNS then DB host only (no
*.svc.cluster.local); Kubernetes CP usesnats-server.{namespace}.svc.cluster.local/router.{namespace}.svc.cluster.localwith DB host fallback; connect failures log and throw aggregate errors for all attempts; relay log messages are transport-aware. - NATS relay
controller-relaycreds loading — read Opaque secret values as plain UTF-8.credstext (matchesnats-service.jsand DB storage); fixesunable to parse credentialson hub connect whenNATS_ENABLED=true. - NATS platform relay identity renamed to account/user
controllerwith rulescontroller-account/controller-user;GET /nats/accounts/controller/users/controller/credssupported for operator cred export. - Exec AMQP relay re-attaches queue receivers whenever user or agent WebSocket connects (fixes user-first sessions where ACTIVATION and STDIN never reached Edgelet); ACTIVATION is resent on agent WS reconnect.
- Controller register accepts optional
schedule: 0; server always enforces schedule 0 on create, re-register, andPATCH /api/v3/microservices/system/:uuidfor controller workloads. - Agent version command (
GET /api/v3/agent/version) refreshes the provision key on each pull instead of returning a stale or deleted key. - Controller AMQP certificate provisioning uses shared
default-router-local-cainstead of per-fog router local CA secret names. - Central local CAs (
default-router-local-ca,default-nats-local-ca) are ensured on first agent provision (or via operator direct import before first agent), not at Controller boot — allows custom local CAs before agent deployment. - Fog teardown drops obsolete per-fog
nats-local-ca-*androuter-local-ca-*secret names from cleanup lists. - OIDC discovery with
AUTH_INSECURE_ALLOW_HTTPuses the supportedopenid-clientinsecure-request hook for localhttp://issuers. - Embedded OAuth BFF builds the in-process issuer client from local metadata and trusts listener TLS material (
TLS_PATH_*/TLS_BASE64_*) for token exchange — fixesfetch failedonGET /api/v3/user/oauth/authorizewith self-signed HTTPS certs withoutNODE_EXTRA_CA_CERTS. - Provisioning key and
GET /api/v3/agent/certderivecaCertfrom listener TLS material (TLS_PATH_*/TLS_BASE64_*) via sharedtls-config— always base64-encoded for Edgelet trust store; fixes emptycaCertwhen legacySSL_CERT/INTERMEDIATE_CERTwere unset. - Config keys
auth.bootstrap.adminUsername/adminPasswordrenamed toauth.bootstrap.username/password(OIDC_BOOTSTRAP_ADMIN_*env vars unchanged). - Microservice create/update strips user-supplied
serviceAccountvolume mappings instead of rejecting them — allows GET → PATCH round-trips; system still injects the canonical binding. - OIDC middleware skips Bearer validation on public catalog routes (e.g.
GET /api/v3/status,GET /api/v3/architectures/, OAuth BFF) so agent/controller tokens on health checks no longer spam JWKS warnings. - TCP bridge background provisioning resolves agent router mode via
RouterManager.findOne(fixesTypeErrorwhenfakeTransactionis used in background jobs). - TCP bridge / router provisioning background error logging uses pino object-first
{ err, msg, … }so failures are no longer logged as empty errors. - Router microservice
siteConfig.platformdefaults toedgelet(wasdocker) when the agent uses the Edgelet runtime. - Boolean env vars (
TRUST_PROXY,SERVER_DEV_MODE,DB_USE_SSL,VAULT_ENABLED,ENABLE_TELEMETRY, and other mapped flags) are parsed consistently from Kubernetes string values (true/false,1/0) via sharedconfig.getBoolean()— fixes startup crash whenTRUST_PROXY=truewas passed as a string to Express. - Postgres/MySQL SSL reads canonical
DB_SSL_CA(via config) instead of undocumentedDB_SSL_CA_B64;database.*.useSSLconfig key honored (wasuseSsltypo). - Spurious
routerMode/natsModenoneon fog list/get when runtime rows were pending — read path now falls back toFogPlatformSpecsduring reconcile. PATCH /api/v3/iofog/{uuid}on system fogs with full config (potctl redeploy) — 400Invalid NATS mode 'undefined'whennatsModewas omitted from PATCH body.- Partial fog delete orphans when router/NATS teardown failed mid-flight — delete is async via platform reconcile
Deletingphase. - Service provisioning races and lost hub ConfigMap updates under multi-Controller — serialized hub lock and DB-backed service reconcile tasks.
- Dual writers to router microservice bridge config from fog create/update and service create/update/delete — single full-recompute path on fog reconcile.
- SQLite startup lock contention on single-controller deployments — WAL +
busy_timeoutpragmas on connect,withDbBusyRetryon fog/service/NATS task claims, staggered reconcile-heavy job startup. reconcileFogtransaction parameter — removed unusedoptionsargument so worker-decorated calls receive the transaction correctly.
- Embedded auth login MFA challenge — users with enrolled TOTP (
mfaEnabled) are always prompted for TOTP at login, including voluntary My Account enrollment when all groups havemfaRequired: false. GroupmfaRequiredstill forces enrollment for members who have not enrolled. - OpenTelemetry SDK dependencies bumped to 0.219.x; telemetry init simplified (removed custom resource detector wrapper).
js-yamlbumped to 4.2.0.
- v3.7 legacy field-agent wire protocol and deprecated agent field names.
- npm package distribution of Controller and ECN-Viewer.
- EdgeResource, diagnostics, strace, and legacy flow APIs.
- Keycloak-specific configuration and
keycloak-connectdependency. processedMessages,messageSpeed, and dual-read aliases for deprecated agent fields.
- Updated ecn-viewer to v3.0.2
- Updated job schedular logic
- Removed sentry from the code (#744)
- Removed sentry and analytics from the code as they were obsolete.
- Updated the down migration of TrackingEvent table
- Added timeZone in agentConfig
- Removed node 10 tests and added node 16 tests
- Removed node 12
- Minimum node version is now >= 12
- Updated Docker Node.js version to Gallium
- Updated API to use name instead of uuid as primary identifier
- Allow password update without sending email
- Update ECN Viewer version to 2.0.1
- Fixed issue when rebuild flag was not set to true when images are updated
- Fixed issue when microservice states were inconsistent on moving from one agent to another
- Add Edge Resources API endpoints and functionality
- Add Application Templates API endpoints and functionality
- Add Applications API endpionts
- Use LiquidJS templating engine for any incoming request
- Update Docker Node.js version to Fermium
- Add UDP port mapping support
- Return microservice download percentage
- Fix default available disk threshold being too high
- Replace Winston logger with Pino
- Make flowId query param optional for GET microservices endpoint
- Add graceful shutdown of servers when SIGTERM is received
- Add plugin support for Public Port allocation
v2.0.0-rc1 - 2020-04-28
- Volume mapping types
- Add logic to initDB to prevent CLI command to override values configured using env variables
- Remove connector from iofog-controller
- Update ECN Viewer
- Make system images configurable
- Add versions to status
- Fix migration column name
- Check for Agent duplicate name
- Fixed updating proxy config when an agent is deleted
- Set agent/ms status to UNKNOWN
v2.0.0-beta2 - 2020-04-06
- Sort ioFog and Microservice list response
- Updated default value of dockerPruningFreq to 1
- Add system query param to /iofog-list endpoint
- Changed router images to
iofog/router - Update messageSpeed datatype to float
- Update diskThreshold to availableDiskThreshold
- Check for reserved ports
- Only log error and warnings
- Bump ECN Viewer version
- Fix list agents query param logic
v2.0.0-beta - 2020-03-12
No changes
v2.0.0-alpha - 2020-03-11
- Added endpoint to return public ports
- Add agent docker pruning endpoint
- Support websocket proxy
- Added rotation to log files
- Allow creation of microservice without catalog item
- Bump ECN Viewer to 1.0.4
- Support mixed k8s and non-k8s flows
- Throw error if router host is not provided
- Fix update microservice image command
- Fixed proxy deletion bug
- Fixed the bug for moving msvcs to new Agent
- Fix optional catalog-item in provisioning check of microservices
- Fixed k8s get pod issue
- Fixed
ProviderFailedon k8s deployments - Removed HA dependencies
- Fix catalog item id validation if no image provided
- Always return populated array for k8s get node addresses
- Fixed k8s deployment bug
- Add CLI support for microservice without catalog item
- Allow patch without catalogitem
v1.2.1 - 2019-07-13
- Return Agent's external IP for Kubelet
- Add uptime to status endpoint
- Requests not failing if with additional properties
v1.1.1 - 2019-07-03
- Added support for setting and passing through environment variables in docker containers at runtime (see iofog-controller CLI)
- Added support for overriding container CMD directives at runtime (see iofog-controller CLI)
- Added capability to return a microservice's public url when a public port is set
- New metrics being tracked:
- Total CPU usage
- Available disk
- Available memory
- Controller Docker images now build from iofog-docker-images for stability
- Update microservice did always get picked up by Agent
- High CPU usage when Controller was running for couple of weeks
- Fixed log rotation (should work infinitely now)
- Fixed regression where Ports public directive was not honored
1.0.28 (2018-12-14
1.0.27 (2018-12-06)
- npm-scripts: allow to use only one image on catalog item creation (#415) (2a3e5d4)
- npm-scripts: init db automatically after installation (#413) (a77bea3)
- tests: rename logLimit -> logSize (#416) (7b6b310)
- transactions: fix transaction validation if last method's arg is undefined (#414) (5369b05