Skip to content

Instantly share code, notes, and snippets.

@reubenmiller
Last active February 9, 2026 13:21
Show Gist options
  • Select an option

  • Save reubenmiller/2898a1b9b6c02fb1118537496cb8eb30 to your computer and use it in GitHub Desktop.

Select an option

Save reubenmiller/2898a1b9b6c02fb1118537496cb8eb30 to your computer and use it in GitHub Desktop.
Migrate tedge-standalone to a new tenant

Overview

This describes how to migrate a tedge-standalone installation which is connected to Cumulocity using BASIC AUTH (e.g. username/password) to a new tenant.

The migration script does the following steps:

  1. Backup the existing settings (tedge.toml and credentials.toml)
  2. Set the new tenant id in the credentials.toml file (used for basic auth)
  3. Set the new c8y.url to point to the new tenant
  4. Try reconnecting to the new tenant, then one of the following is done: a. If the new connection is successful, then delete the backed up files b. If the new connection is not successful, then rollback the settings, and then try to send the logs with info about the migration to the original Cumulocity tenant.

Procedure

  1. In the new tenant, register the same device credentials in a new tenant (The credentials MUST be kept the same).

    This can be done using the Bulk Registration API, below shows an example of the go-c8y-cli command to register a device on the new tenant.

    c8y deviceregistration register-basic --id "<external_id>" --password "<device_password>"

    Note: The credentials should be kept the same to avoid having to send the credentials via the c8y_Command (shell) operation in clear text.

  2. On the device, create a new file migrate-device.sh (the script contents are within the same Github Gist) under the tedge/bin folder

    For example, if tedge in installed under /data, then you would create the following file (using vi):

    vi /data/tedge/bin/migrate-device.sh

    Then make the file executable

    chmod +x /data/tedge/bin/migrate-device.sh
  3. Then you can create a Cumulocity shell operation to execute the command

    migrate-device.sh "<new_c8y_url>" "<new_c8y_tenant_id>"

    Where,

    • <new_c8y_url> is the Cumulocity URL (without the https:// prefix) of the new tenant
    • <new_c8y_tenant_id> is the Cumulocity Tenant ID of the new tenant

    Example

    migrate-device.sh mytenant.example.cumulocity.com t12345

    Notes

    • The c8y_Command (shell) operation will be set to SUCCESSFUL before the migration is done. The operation status is meant to only indicate that the migration activity was successfully started. This is done because the device will be switching to a new tenant, so if the migration wouldn't be done in the background, then the operation status would never be updated as the switch to the new tenant would be completed before the status is reported back.
    • Check the device's event page (in the original tenant) for events to indicate when the migration has started, and in the event of an error, there will be an event with a log file that you can use for debugging.
#!/bin/sh -e
#
# Migrate a device which is using BASIC AUTH to a new Cumulocity tenant
# with the same credentials.
#
# USAGE
# migrate-device.sh <new_c8y_url> <new_tenant_id>
#
# EXAMPLES
# migrate-device.sh "example.cumulocity.com" "t12345"
#
SCRIPT_DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
BASE_DIR="$(dirname "$SCRIPT_DIR")"
TO_TENANT="$1"
TO_TENANT_ID="$2"
if [ $# -lt 2 ]; then
echo "ERROR: Missing required arguments, <tenant_url> <tenant_id>"
exit 1
fi
. "$BASE_DIR/env" || {
echo "ERROR: Failed to import tedge environment variables."
exit 1
}
if ! command -V tedge >/dev/null 2>&1; then
echo "ERROR: Aborting as the tedge binary could not be found"
exit 1
fi
start_background_migration() {
echo "INFO: Waiting 10s before migrating" >&2
sleep 10
TO_TENANT="$1"
TO_TENANT_ID="$2"
echo "INFO: Publishing event to existing tenant" >&2
tedge mqtt pub -q 1 te/device/main///e/migration "{\"text\":\"Migrating device to a different tenant. url=$TO_TENANT, tenantId=$TO_TENANT_ID\",\"url\":\"$TO_TENANT\",\"tenantId\":\"$TO_TENANT_ID\"}" ||:
sleep 5
echo "INFO: Backing up configuration files"
cp "$BASE_DIR/credentials.toml" "$BASE_DIR/credentials.toml.bak"
cp "$BASE_DIR/tedge.toml" "$BASE_DIR/tedge.toml.bak"
echo "INFO: Changing the tenant id for base auth settings"
sed -i 's|username = "t[0-9]\+/|username = "'"$TO_TENANT_ID"'/|' "$BASE_DIR/credentials.toml"
echo "INFO: Setting c8y.url to '$TO_TENANT'"
tedge config set c8y.url "$TO_TENANT"
echo "INFO: Reconnecting mapper"
if tedge reconnect c8y; then
echo "INFO: Successfully migrate device to new tenant"
tedge mqtt pub -q 1 te/device/main///e/migration "{\"text\":\"Migrated device successfully from another tenant\"}" ||:
else
echo "ERROR: Migration failed, rolling back settings"
cp "$BASE_DIR/credentials.toml.bak" "$BASE_DIR/credentials.toml" ||:
cp "$BASE_DIR/tedge.toml.bak" "$BASE_DIR/tedge.toml" ||:
if ! tedge reconnect c8y; then
echo "WARN: Reconnect failed, trying again in offline mode as the device may have lost its connectivity"
tedge reconnect c8y --offline ||:
fi
echo "ERROR: Rolled back successfully after the failed migration"
echo "INFO: Uploading migration log as event"
tedge upload c8y \
--file "/tmp/migrate.log" \
--text "Migration failed (url=$TO_TENANT, tenantId=$TO_TENANT_ID). See attached log for details" \
--json "{\"url\":\"$TO_TENANT\",\"tenantId\":\"$TO_TENANT_ID\"}" \
--type "migration_failed" ||:
fi
}
(start_background_migration "$TO_TENANT" "$TO_TENANT_ID" > /tmp/migrate.log 2>&1 &)
# Workaround: currently required to mark the operation as completed
tedge mqtt pub -q 1 c8y/s/us '503,c8y_Command' ||:
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment