Skip to content

Verifying the migration

The final run already verifies a sample of accounts on its own, and its report lists every difference that the conversion introduced on purpose. Before 1.0 starts serving users, the operator can go further. This page describes how to compare the stores in more depth, follow the progress of a migration, and read the report.

verify compares the 0.16 and 1.0 stores through the same record layer that the copy uses. Differences that the migration made deliberately, and reported, are therefore not counted as mismatches:

Terminal window
stalwart-migrate verify \
--source /etc/stalwart/config.json \
--target /etc/stalwart-v1/config.json \
--state /var/lib/stalwart-migrate

By default, verify checks a sample. --sample sets the percentage of accounts (1 by default). Every account changed since the last run is added to the sample, which has a minimum of 16 accounts. --full instead checks every account and every row of every change log. The two options exclude each other.

For each checked account, the comparison covers the following:

  • The settings
  • The set of objects in every collection
  • The fields of mailboxes, emails, calendars, contacts, files and Sieve scripts
  • The last change of every change log
  • The counters for document identifiers, UIDs and changes

Calendar and contact data is compared after parsing, so equivalent iCalendar and vCard texts are equal. Blobs are checked more lightly: the presence of every email and file blob in the target is checked, but the blob contents are not read again. The command ends with a summary line such as:

verify: 120 accounts checked, 0 mismatches, 0 not explained by earlier reports (ok)

Every mismatch is written to the report with severity verify. The command exits with status 1 when a mismatch is not explained by an earlier report row.

Timing matters for the result. A verification against a running 0.16 server reports the changes made since the last run as mismatches. A meaningful result therefore requires 0.16 to be stopped and the final run to have completed. run --final and rollback run the same verification automatically.

status summarises a state directory without opening any store, so it can run while another command is in progress:

Terminal window
stalwart-migrate status --state /var/lib/stalwart-migrate

It shows the following:

  • The tool version and build
  • Whether the final run is done
  • The number of accounts in each phase
  • The accounts in error, with their last error
  • The recent runs, with their duration and counters
  • The report counts by severity and kind, for the latest run and for all runs

--format json produces the same data for monitoring.

The report lists every difference between what 0.16 held and what 1.0 received. Some data has no place in 1.0 or exceeds a 1.0 limit, and some settings change meaning. The conversion handles each case with a documented fallback and records it, so nothing is lost silently. Each row has a kind:

KindMeaning
droppedThe object or field has no 1.0 equivalent and was not copied.
changedThe value was converted to a different 1.0 form.
truncatedA list or text exceeded a 1.0 limit and was shortened.
clampedA number was outside the 1.0 range and was set to the nearest allowed value.
skippedThe object could not be read or converted and was not copied.
failedThe write to the target failed.
mismatchVerification found a difference.

Each row also has a severity: info, warning, error or verify. Error rows make a run fail, and keep run --final from finalising until they are fixed or accepted with --allow-errors. The schema differences behind the settings conversions are listed in SCHEMA_CHANGES.md.

report lists the rows. They can be filtered by run (--run), severity (--severity), kind (--category), account identifier (--account) and number of rows (--limit), and printed as text, CSV or JSON (--format). The following commands list the errors, export one run as CSV, and show the truncated objects of one account:

Terminal window
stalwart-migrate report --state /var/lib/stalwart-migrate --severity error
stalwart-migrate report --state /var/lib/stalwart-migrate --run 7 --format csv > run7.csv
stalwart-migrate report --state /var/lib/stalwart-migrate --account 42 --category truncated

Before the switch, review the rows of the final run, and those with severity error and verify.

The state directory contains the following files:

PathContent
answers.tomlThe answers recorded by prepare
prepare-report.txtThe settings conversion plan written by prepare
final-report.txtThe report of a completed final run
state.sqliteProgress, runs and report rows
state.lockThe lock that keeps two commands from writing the same state at once
logs/One log file per command, named after the command, the start time and the process identifier

Console output is controlled separately: --log-format selects text or JSON, and --log-level sets the verbosity.

Every command ends with one of these exit codes, which scripts and CI jobs can test:

CodeMeaning
0The command succeeded.
1The command failed: a run that failed or reported errors, a verification with unexplained mismatches, prepare with open questions, or an error opening a store.
2Invalid usage or a refusal before any work: wrong arguments, a missing answers.toml, an unconfirmed final run, or a tool build that does not match the recorded answers.
130The command was interrupted by a signal.