Bondy Connect
Skip to content

Upgrading to 1.0.0 ​

Bondy 1.0.0 replaces the storage and replication engine end to end: PlumDB and its RocksDB backend are gone, replaced by bondy_db, bondy_oplog, and bondy_mst (see Architecture). The on-disk format changed with it, and there is no in-place migration — a node running a pre-1.0.0 release cannot simply be upgraded and restarted; its data directory is unreadable by 1.0.0.

This guide covers the supported migration path: back up your data using the backup mechanism your current release already has, stand up a fresh 1.0.0 deployment, and import that backup — 1.0.0's importer recognises the old file format and translates it automatically. It ends with a checklist of the other breaking changes in this release worth reviewing before you cut over.

No in-place upgrade

Starting a 1.0.0 node against a pre-1.0.0 data directory does not migrate it and does not fail loudly — the new storage engine simply doesn't recognise the old files and starts with an empty database. Follow the migration procedure below instead.

Upgrading from a 1.0.0 pre-release

None of the migration below applies to a cluster already running a 1.0.0 pre-release that carries bondy_db (for example 1.0.0-rc.olive, 1.0.0-rc.pear or 1.0.0-rc.pistachio). Follow Upgrade from a bondy_db pre-release instead.

Prerequisites ​

  • Erlang/OTP 29 or later on every host that builds or runs 1.0.0 from source (see Install from Source for the full toolchain). This is a hard requirement. The Docker images include their own Erlang runtime, OTP 29.1.2.
  • A WAMP session on the old deployment's master realm (com.leapsight.bondy) with wamp.call permission, to invoke the backup procedures. The examples below use wick, the WAMP CLI client used throughout the WAMP API reference.
  • Filesystem access to copy a file from the old node(s) to the new node(s) — the backup is a single file, not a WAMP-transported payload.
  • Enough free disk space on the old node for the backup file (proportional to your security, realm, API gateway, bridge, ticket, token, and retained-message data — not your live routing state, which the new deployment rebuilds as clients reconnect and re-register).
  • A maintenance window. The backup is a point-in-time snapshot taken while the old deployment keeps running; anything written after it completes will not carry over.

Migrate your data ​

1. Back up the database on the old node ​

Your pre-1.0.0 release doesn't have 1.0.0's bondy_export module — it has the module it replaces, bondy_backup, exposed as bondy.backup.create. Call it on the old deployment, passing the directory the backup file should be written to. The call is asynchronous — it validates the request, schedules the backup, and returns immediately with the generated filename:

bash
./wick --url ws://old-node-host:18080/ws --realm com.leapsight.bondy \
  call bondy.backup.create '{"path": "/var/backups/bondy"}' | jq
json
{
  "filename": "/var/backups/bondy/bondy_backup.1774598400.bak",
  "timestamp": 1774598400
}

The target directory has to exist already — the call doesn't create it. The filename is generated for you; a call succeeding only means the backup was scheduled, not that it finished, since the actual work happens asynchronously (see the next step).

Running Bondy in Docker

If the old deployment runs in Docker, path is a path inside the container (e.g. /bondy/data/backup). Mount a host directory there so the resulting file is reachable from outside the container to copy it to the new node.

Only one backup (or restore) can run at a time per node. A second bondy.backup.create call while one is already in progress on that node fails immediately with the current status rather than queuing.

2. Verify the backup finished ​

Poll bondy.backup.status, or subscribe to the completion events — the latter is more reliable for automation, since it doesn't require guessing a poll interval:

bash
./wick --url ws://old-node-host:18080/ws --realm com.leapsight.bondy \
  call bondy.backup.status '{"filename": "/var/backups/bondy/bondy_backup.1774598400.bak"}' | jq

While the backup is running, the call reports the operation and elapsed time. Once it has finished, the old release publishes bondy.backup.finished (or bondy.backup.failed on error) on the master realm, each carrying the backup's filename. Don't proceed to the next step until you've seen one of these two signals — a scheduled backup can still fail (for example, if the target directory turned out not to exist).

Once you're on 1.0.0

bondy.backup.create, .status, and .restore are kept in 1.0.0 as deprecated aliases of bondy.export.create, .status, and .import — same procedures, same argument shape. Use bondy.export.* for any backup automation you set up after the upgrade; reach for bondy.backup.* only because it's what your current, pre-1.0.0 release actually has.

3. Copy the backup file to the new node(s) ​

Copy the file named in step 1 (e.g. via scp or rsync) to a location readable by the new deployment. If you're migrating a cluster, you only need to import it once — see step 7 — but you're free to stage the copy on every new node in advance.

4. Retire the old on-disk data ​

If you're reusing the same hosts for the 1.0.0 release, remove the old storage engine's data before starting it — 1.0.0 does not read it, and leaving it in place only wastes disk space. The path is whatever platform_data_dir was set to on the old node (./data relative to the release, by default):

bash
# On each host being reused for 1.0.0, after the backup above is confirmed
bin/bondy-connect stop
rm -rf /path/to/bondy/data

Do this only after step 2 has confirmed the backup succeeded

This step is irreversible. 1.0.0's storage engine writes its own layout under <platform_data_dir>/bondy_db/ on first boot, so there's no need to pre-create anything — just make sure the directory doesn't still hold stale pre-1.0.0 files.

If you're moving to new hosts instead, there's nothing to do here — just point the new nodes at a fresh platform_data_dir.

5. Install 1.0.0 and check bondy.conf against its schema ​

Install the 1.0.0 release (see Install from Source, Install using Docker, or your usual packaging) on each new node and carry over your bondy.conf. Do not start the node yet.

Check the file before the first start, because a wrong bondy.conf does not stop the boot. The release's pre-start hook runs cuttlefish with --allow_extra --silent. With --allow_extra, cuttlefish skips a key that no schema maps, so an old key is dropped without a message and its subsystem runs on the default. With --silent, a value that cuttlefish cannot parse prints nothing; cuttlefish then generates no configuration for the whole file, so none of its settings apply.

The check tool is scripts/migrate_conf.escript in the Bondy source tree; the release does not ship it. It needs escript (Erlang/OTP) on the PATH and finds cuttlefish and the schemas relative to the current directory, so run it from one of two places:

  • the root of a 1.0.0 source checkout, after rebar3 compile;
  • the root of the unpacked 1.0.0 release, with the script copied there. It reads bin/cuttlefish and the schemas under releases/<vsn>/.
  1. Check the file. Nothing is written.

    bash
    ./scripts/migrate_conf.escript check /etc/bondy/bondy.conf

    From a source checkout, just conf-check /etc/bondy/bondy.conf runs the same command. To check against another schema set, add --schema-dir DIR (repeatable).

    The report has one section per kind of finding, and the RESULT line comes last:

    text
    /etc/bondy/bondy.conf
      4 keys, schemas: schema schema/hidden _build/default/lib/riak_sysmon/priv
    
      KEYS: 3 of 4 are set but this release maps none of them, so each
      is dropped in silence at boot and the setting does not apply.
    
      RENAME -- same setting, new key (2)
        oplog.aae.interval                             = 1m             ->  db.aae.interval
        oplog.core.shard_count                         = 16             ->  db.main.shard_count
    
      DROP -- no equivalent on this release (1)
        store.rocksdb.max_open_files                   = 1000
            the RocksDB tuning surface; this release has no equivalent
    
      INVALID VALUE (1) -- this release reads this key, but cannot parse the value.
      ...
        db.wal.fsync_mode                              = sometimes
            not a valid one of per_write, batched. Generation stops at phase
            transform_datatypes.
    
      LISTENERS: this file writes no listeners.* key, so the node
      starts the built-in default inventory and nothing else:
        admin
        api_gateway_http
        wamp_tcp
    
    RESULT  3 keys not read, 1 invalid value, 0 listener findings -- see above
    SectionMeaning
    KEYSKeys that 1.0.0 does not read, grouped by what to do: RENAME (same setting, new key), CONTESTED (the rename changes behaviour), ALREADY SET (the new key is also in the file with another value), DROP (no equivalent), BY HAND (no mechanical equivalent; the tool names candidates), NOT ON THIS RELEASE, and NO RULE. KEYS: all recognised means none.
    INVALID VALUEKeys that 1.0.0 reads but whose value it cannot parse. One such value discards the whole file, so fix these first.
    CHANGED MEANINGKeys still read, but not as before. Confirm each value still says what you meant. These do not affect the exit code.
    LISTENERSThe listeners the file will start, and any listener finding.

    If an advanced.config sits next to the file, the tool checks it too and reports stanzas that no longer take effect. The exit code is 0 when RESULT reads clean, 1 when there are findings, and 2 when the check could not run (for example, the file does not exist or cuttlefish cannot be found).

  2. Write a converted file. If the check reports findings, let the tool apply the mechanical renames:

    bash
    ./scripts/migrate_conf.escript migrate /etc/bondy/bondy.conf \
      --out /etc/bondy/bondy.conf.new

    migrate never edits the input and refuses an --out file that already exists (exit 2). In the new file, renamed keys carry their new names. Dropped keys and keys that need a decision are commented out, each under ## migrate_conf: lines that say why. Search the new file for ## migrate_conf: needs a decision and resolve each one by hand. The exit code reports the check of the file just written, not whether the rewrite ran.

  3. Check the result. Run check on the new file until RESULT reads clean -- every key is read, every value parses, every listener is declared and the exit code is 0. Then put it in place as the node's bondy.conf.

From a source checkout, ./scripts/migrate_conf.escript selftest checks the tool's own rules against the schemas it runs with and prints selftest OK on success. It needs the source tree's shipped configuration files, so it does not run from a release root.

The release also contains bin/validate-config. It does not check keys or values: the pre-start hook runs it on every start to confirm that bondy.conf (or bondy.conf.template) and vm.extra.args exist in the etc directory. Do not use it as a schema check.

6. Boot the new 1.0.0 node(s) ​

Start each node.

If you're running (or moving to) more than one node, join them into a cluster now, before importing — see Running a Cluster.

Set cluster.enabled = off on a single node

cluster.enabled defaults to on. A node that runs alone with clustering on never compacts its history. Under the default fence policy (db.aae = on, db.aae.fence.on_isolation = refuse), it also refuses every authentication, anonymous included, once its security tables stay unconfirmed for longer than db.aae.fence.max_lag. Set cluster.enabled = off in the bondy.conf of a node meant to run alone, and keep the default on on every member of a cluster. See Enabling clustering, which also explains why a node that ran with off can later join only nodes with empty data directories.

Auto-clustering nodes with an insecure Partisan peer plane

If cluster.peer_discovery.enabled = on and the Partisan peer plane isn't secured (TLS off, or TLS on without peer certificate verification), 1.0.0 refuses to start rather than cluster over an unauthenticated connection. Configure cluster.tls.enabled = on with verify_peer and a private cluster CA, or set cluster.tls.allow_insecure = on to acknowledge the risk explicitly. See the Cluster Configuration Reference.

7. Import the backup file ​

Call bondy.export.import on the new deployment with the path to the file you copied over. This is 1.0.0's importer, and it recognises the pre-1.0.0 file format by its header: it transparently translates each old record into a write against the new storage engine as it reads, so you don't need to convert anything yourself.

Run the import on one node only. Every table it writes is replicated, so the imported data reaches the other members through anti-entropy, as any other write does.

bash
./wick --url ws://new-node-host:18080/ws --realm com.leapsight.bondy \
  call bondy.export.import '{"filename": "/data/imports/bondy_backup.1774598400.bak"}' | jq

This returns immediately; the import itself runs asynchronously. Watch for bondy.export.import_finished or bondy.export.import_failed (filename-bearing events on the master realm), or poll bondy.export.status, to confirm it actually completed. Writes are batched (500 records per transaction) rather than fsynced individually, so a large dataset imports in a fraction of the time a naive per-record write would take.

The import is a set of fresh writes, not a byte-for-byte restore: replication metadata (clocks, causal history) from the old deployment is not — and should not be — preserved. From an old-format backup, the importer translates only these domains: users, groups, user and group grants, sources, API Gateway specifications, and OAuth2 refresh tokens. It skips every other record and counts it by reason. These rules apply to the translated domains:

  • Only the latest, still-valid OAuth2 refresh token per (realm, user) survives. Expired tokens are dropped; the retained one is transparently upgraded to the current token format the first time a client uses it to refresh.
  • Realms are not recreated. The old realm record has no upgrade path, so the importer skips it. The users, groups, grants, sources and refresh tokens of each realm still import, because they are keyed by the realm URI.
  • Tickets, bridge relays and retained messages are not imported. Clients request new tickets and publish again. Recreate each bridge relay from your configuration.

Recreate your realms separately

Recreate each realm from your configuration or with bondy.realm.create calls, the same way you provisioned it originally — before or after the import, it doesn't matter for the data. It does matter for your clients, though: they can't attach to a realm, and so can't exercise the imported users and grants, until it exists again.

Change the admin password after the import

The import writes the old deployment's master-realm admin user, old password included, over the one the new node created at first boot. security.admin_user.password does not change it: Bondy reads that key only when it creates the master realm, at a node's first boot. Change the password with bondy.user.change_password on com.leapsight.bondy once the import has finished. While it is still the former default, bondy-admin, every boot logs a warning.

When the import finishes, the node logs one notice, "Import skipped some legacy records by reason", whose skipped field counts each record it did not write, by reason:

ReasonRecord
tombstoneA record deleted on the old deployment.
realm_recreate_from_configA realm. Recreate it, as described above.
security_status_deadA security-status flag. A realm's security_enabled replaces it.
legacy_source_formatA source stored in the format before 1.1, which the importer does not translate. Recreate it if no 1.1-format entry covers it.
token_expiredAn OAuth2 refresh token that has expired.
oauth_token_unparsableAn OAuth2 refresh token in a shape the importer does not recognise.
{token_import, Reason}A refresh token the importer recognised but could not store.
{table_not_provisioned, Table}A record for a table this node does not provision.
{unsupported_prefix, Prefix}A record of a domain the importer does not translate (see the list above).
import_errorA record the importer failed to translate. Each one is also logged at warning as "Skipping a legacy record that could not be imported".
unrecognised_termSomething in the file that is not a record.

A refresh token older than the one kept for the same user is dropped without being counted.

8. Verify and decommission the old deployment ​

Spot-check that realms, users, and API gateway specs are present on the new deployment before you decommission the old one. Once you're satisfied, take the old nodes out of service.

Other breaking changes to check ​

Review these before you finalise your bondy.conf and cutover plan — none of them are part of the export/import procedure above, but each can stop the new release from starting or behaving as your existing configuration or clients expect. If you upgrade from a bondy_db pre-release, review them as well: your pre-release might not carry all of them.

Release, image and repository names ​

The release and its start script are named bondy-connect.

  • Run bin/bondy-connect in place of bin/bondy. The tarball is bondy-connect-1.0.0.tar.gz.
  • Pull leapsight/bondy-connect from Docker Hub or ghcr.io/bondy-io/bondy-connect from GHCR. The images start bondy-connect foreground. The leapsight/bondy and ghcr.io/bondy-io/bondy images get no new tags.
  • Point your git remotes at github.com/bondy-io/bondy-connect.

The /bondy paths, the node names, the BONDY_* environment variables and etc/bondy.conf keep their names.

Listeners ​

The fixed per-scheme listener keys are removed: admin_api.{http,https}.*, api_gateway.{http,https}.*, wamp.{tcp,tls}.* and bridge.listener.{tcp,tls}.*. Declare each listener by name under listeners.$name.*.

  • A file with no listeners.* key starts three plaintext listeners only: admin (18081), api_gateway_http (18080) and wamp_tcp (18082). Declare every other listener, TLS and bridge relay listeners included.
  • Every enabled transport = tls listener has to set tls.certfile and tls.keyfile. No default certificate path applies.
  • listeners.$name.linger.timeout is in seconds. A value written with a unit suffix used to be read as milliseconds.

The check in step 5 reports each of these, and migrate rewrites the old blocks. See Migrating from the pre-1.0 keys.

Other renamed and removed keys ​

Old keyIn 1.0.0
wamp.transport_queue.*wamp.http_transport.*. See HTTP Transports.
wamp.websocket.*, wamp.sse.*, wamp.longpoll.*Removed. Set carrier options on each listener. See Carrier settings.
wamp.broker.* and wamp.dealer.* feature flagsRemoved. The WAMP features are build capabilities, not configuration.
wamp.dealer.pattern_based_registration, wamp.broker.pattern_based_subscriptionRemoved. Pattern-based registration and subscription are always on.
rpc_gateway.*http_connector.*, with the same sub-keys. See the HTTP Connector Configuration Reference.

scripts/migrate_conf.escript reports and rewrites each of these keys.

Storage and AAE key renames ​

Every storage-related bondy.conf key changed name as part of the storage-engine replacement. Bondy does not refuse to boot on a key it doesn't recognise: the release's pre-start hook runs cuttlefish with --allow_extra, so an old key carried over unchanged is dropped without a message and its setting does not apply. The check in step 5 reports every such key and its replacement.

The oplog. prefix is now db., unconditionally. If you didn't customise any of these, there's nothing to do — the defaults are unchanged:

Old key (≤ 1.0.0-rc.65)New key
oplog.aaedb.aae
oplog.aae.intervaldb.aae.interval
oplog.aae.live_syncdb.aae.live_sync
oplog.aae.live_sync.maxdb.aae.live_sync.max
oplog.aae.max_concurrencydb.aae.max_concurrency
oplog.aae.max_pages_in_flightdb.aae.max_pages_in_flight
oplog.aae.load_adaptivedb.aae.load_adaptive
oplog.aae.load_run_queue_thresholddb.aae.load_run_queue_threshold
oplog.aae.fanoutdb.aae.fanout
oplog.aae.fence.max_lagdb.aae.fence.max_lag
oplog.aae.fence.on_isolationdb.aae.fence.on_isolation

Four more keys move from oplog.core.* to a bare db.* — the core. segment drops because these settings were never specific to one database; they govern every replicated table node-wide:

Old keyNew key
oplog.core.gc_intervaldb.gc_interval
oplog.core.gc_heap_deltadb.gc_heap_delta
oplog.core.pack_auto_seal_bytesdb.pack_auto_seal_bytes
oplog.core.pack_seal_modedb.pack_seal_mode

Bondy's durable database itself is renamed: core is now main, to stop it being confused with the unrelated bondy_oplog_core substrate module. If your bondy.conf sets any of the durable database's topology, rename these too:

Old keyNew key
oplog.core.shard_countdb.main.shard_count
oplog.core.partition_strategydb.main.partition_strategy
oplog.core.realm_prefix_depthdb.main.realm_prefix_depth
oplog.core.on_topology_mismatchdb.main.on_topology_mismatch

The value and its meaning are identical for every rename above — only the key name moved. The on-disk directory for the durable database is also renamed, from <platform_data_dir>/bondy_db/core to <platform_data_dir>/bondy_db/main — irrelevant if you wiped the data directory per step 4 above, but worth knowing if you scripted anything against the old path. The Data Storage & Active Anti-entropy Configuration Reference also lists every old key inline, greyed out, linking to its replacement.

Removed keys ​

These keys have no replacement — remove them from your bondy.conf rather than renaming them:

  • oplog.catalog — never had a consumer; setting it did nothing in any released version.
  • oplog.core.scan_max_concurrency — same; never wired to any code path.
  • Any store.* key (RocksDB tuning) — RocksDB is gone, and 1.0.0 has no equivalent bondy.conf keys.

advanced.config application names ​

Two application identifiers changed. Both are silently inert under the old name rather than a boot error, which makes them easy to miss — Erlang doesn't fail when configuring an application that isn't loaded, it just stops taking effect:

  • bondy → bondy_router. The router's OTP application changed name (source now lives under apps/bondy_router). This is transparent to normal operation — the release name, node name, bondy.conf file, and every WAMP URI are unchanged. It only matters if you reach into the application name directly: a custom sys.config/advanced.config stanza keyed on {bondy, [...]}, or a release hook or health check that calls application:get_env(bondy, ...). Rename those stanzas to {bondy_router, [...]}.
  • plum_db removed. If you have an advanced.config with a {plum_db, [...]} stanza (for store.* settings that had no bondy.conf mapping, or anything else), delete it. The plum_db application no longer exists in 1.0.0, so the stanza does nothing — but it's dead weight and worth removing so it doesn't look like it's still taking effect.

Module names changed as well. If you call Bondy modules from a remote console or a script, use the names in step 6 of the pre-release upgrade.

A custom bondy_oplog_cache_adapter module has to implement ticket/1 and fill/5 in place of put/4.

WAMP procedures and options ​

Update clients that call these procedures or set these options:

  • The wamp.registration.*, wamp.subscription.*, wamp.session.get and wamp.reflection.* procedures take the arguments that the WAMP specification gives, and read the caller's realm. Remove a leading realm argument from these calls.
  • A master-realm session that reads another realm calls the realm-first bondy.* procedure instead: bondy.registration.get, bondy.registration.list_callees, bondy.registration.count_callees, bondy.subscription.get, bondy.subscription.list_subscribers or bondy.subscription.count_subscribers.
  • wamp.registration.match returns one registration id. wamp.registration.get and wamp.subscription.get take no details argument.
  • bondy.registration.callee.list, bondy.user.change_password and bondy.source.match require the realm URI as their first argument.
  • REGISTER.Options.invoke accepts only single, roundrobin, random, first and last. The router refuses jump_consistent_hash, queue_least_loaded, queue_least_loaded_sample, jch, qll and qlls.
  • The _routing_key option of CALL, CANCEL and PUBLISH is removed. A partitioned CALL names its key with rkey.

See the WAMP API Reference.

API Gateway and Admin API ​

  • The API Gateway refuses a specification that contains a key the parser does not know. This rule applies at the host, version, path, method, action and response levels, in defaults, and in a security scheme. Fix misspelt keys before you load the specification.
  • A security scheme refuses scopes. The API Gateway checks no OAuth2 scope.
  • The wamp_call action has no retry_timeout. When the action's options set no _retries, the action's retries becomes the CALL option _retries. The dealer retries only a registration that set _idempotent.
  • The Admin API endpoints /realms/:realm_uri/registrations_summary and /realms/:realm_uri/subscriptions_summary are removed. Use /realms/:realm_uri/registrations and /realms/:realm_uri/subscriptions, which list every id with its match policy.

See the API Gateway Specification Reference.

New optional keys ​

None of these existed at 1.0.0-rc.65 in any form — there's nothing to migrate, and the defaults are safe to run with unchanged, but they're worth knowing about: db.registry.shard_count (the ephemeral registry's shard count); db.wal.fsync_mode, db.wal.max_segment_bytes, db.wal.batched_fsync_interval, db.wal.batched_fsync_bytes (write-ahead log durability and batching); db.reclaim, db.reclaim.interval, db.reclaim.batch_cells, db.origin_retirement, db.origin_retirement.interval, db.gc_max_concurrency (previously internal-only reclamation/retirement tuning, now real bondy.conf keys — see the Reclamation Configuration Reference); cluster.max_message_size (Partisan inter-node frame size cap); and load_regulation.aae_reactor.pool.size, load_regulation.router.flow_pool.capacity (see the Overload Protection reference).

Other changes ​

  • Erlang/OTP 29 minimum. Upgrade the Erlang runtime on every host that builds or runs a release from source before you install 1.0.0.
  • The query-string/form-field cap. Cowboy is upgraded from 2.13.0 to 2.18.0. Cowboy rejects any request that carries more than 100 query-string parameters or application/x-www-form-urlencoded form fields, and Bondy does not override that limit. This affects API Gateway routes that read query parameters, the OAuth2 token endpoint, and the OIDC login/callback endpoints. Audit any client that sends unusually wide query strings or large forms before cutting over.
  • Partisan peer-plane TLS gate. Covered in step 6 above — an auto-clustering node with an insecure peer plane now refuses to start instead of clustering insecurely. Only relevant if cluster.peer_discovery.enabled = on.
  • HTTP/2 on every http listener. Each listener offers listeners.$name.http.versions = 2, 1.1 by default: a TLS listener negotiates h2 through ALPN, and a plaintext listener accepts HTTP/2 prior-knowledge and Upgrade. Set http.versions = 1.1 to switch HTTP/2 off on one listener. One HTTP/2 connection carries up to http.max_concurrent_streams requests at once (Cowboy's default is 100), so alarms that count connections undercount the request load. See Listeners.

Not a breaking change, but worth considering while you're already re-provisioning nodes: realm private keys can now be encrypted at rest via security.master_key.*. See Security Configuration Reference → Realm Signing Keys.

If you're building from source rather than installing a packaged release, config/bondy.conf.defaults (regenerate it with just conf) lists every current key and its default, and is a useful diff target against your existing bondy.conf.

Upgrade from a bondy_db pre-release ​

Follow these steps for a cluster that runs a 1.0.0 pre-release that already carries bondy_db, such as 1.0.0-rc.olive, 1.0.0-rc.pear or 1.0.0-rc.pistachio. The data directories stay in place, and nothing is exported or imported.

  1. Check bondy.conf. Run the check in step 5 against each node's file, and fix every finding.

  2. Remove db.compaction.peer_timeout. The key does not exist in 1.0.0. Compaction on every database, the in-memory registry included, waits for every cluster member however long it stays silent. A member stops holding compaction only when it leaves the cluster. A bondy.conf that still sets the key boots, because the release ignores keys that no schema maps, and the key has no effect. See Convergence.

  3. Set cluster.enabled = off on a node that runs alone. The key is new in 1.0.0 and defaults to on. A single node left on on never compacts its history, and it logs a "GC stalled" warning with reason no_members. With the defaults db.aae = on and db.aae.fence.on_isolation = refuse, the node also refuses every authentication with temporarily_unavailable once its security tables have gone uncertified for longer than db.aae.fence.max_lag (default 60s). Keep the default on every member of a cluster. See Enabling clustering.

  4. Stop every node, then start them all on 1.0.0. Rolling upgrades are not supported. The registry is held in memory, so it starts empty on every node; clients reconnect, and register and subscribe again.

  5. Update dashboards and alerts.

    • bondy_oplog_peer_exclusions_total is not exported. Remove the queries and alerts that use it.
    • bondy_oplog_gc_scheduler_events_total carries a scheduler label as well as event. A query that selects by event without aggregating over scheduler returns one series per scheduler.
    • bondy_cluster_channel_connections is labelled by peer and channel. Aggregate over peer for a per-channel total.

    See the Metrics Reference.

  6. Update remote-console calls to renamed modules. If you call Bondy modules from a remote console or a script, use these names:

    Pre-release moduleModule in 1.0.0
    bondybondy_router_peer
    bondy_appbondy_router_app
    bondy_supbondy_router_sup
    bondy_utilsbondy_router_utils
    bondy_stdlibbondy_connect_lib
    bondy_consult, bondy_error, bondy_humanized, bondy_interval_set, bondy_itc, bondy_retry, bondy_secret_resolver, bondy_table_manager, bondy_uuidv7The same name with bondy_connect_ in place of bondy_, in the bondy_connect_lib application (bondy_stdlib in the pre-release)
    bondy_secret_resolver_aws_smbondy_connect_secret_resolver_aws_sm, in the bondy_http_connector application
    bondy_oplog_hlcbondy_connect_hlc
    bondy_oplog_wal_codec, _frame, _idx, _key_registry, _manifest, _reader, _recovery, _scrubber, _segment, _statebondy_log_codec, bondy_log_frame, and so on, in the bondy_log application

    bondy_oplog_wal, bondy_oplog_wal_mem and bondy_oplog_wal_mem_reader keep their names.

You now have the cluster running 1.0.0 on its existing data.

Result ​

You now have a 1.0.0 deployment that runs on the new storage engine. Your realms are recreated, and the users, groups, grants, sources, API Gateway specifications and OAuth2 refresh tokens from your pre-1.0.0 deployment are imported into them. The old nodes are decommissioned.

See also ​