Repository navigation
Releases
Seamless Migrate 0.5.0-rc.1
Seamless Migrate 0.5.0-rc.1
Type: release candidate 1 of 0.5.0 (v0.5.0-rc.1), a GitHub pre-release that never becomes "Latest". The gates of each release candidate (RELEASING.md §3, QASuite §13.5) run against its tag. The final 0.5.0 also waits for two things: the SSH trust lab cases LAB-SSH01 to LAB-SSH08 (SDD §26.10, decision 1), and the notifications' live smoke (SDD §24.11, decision 12).
Commit: 9c8c6e40a0f865ec14594dba11b25817cb0797a1 (the merge commit of #186) · Collection: os_migrate.os_migrate 1.1.0. The collection keeps its version, and its CHANGELOG.rst 1.1.0 section lists the changes since 0.4.0-rc.1.
Image: built from the tag, as for every earlier release candidate - no registry holds it: docker build -f seamless/Containerfile -t seamless-migrate:0.5.0-rc.1 --build-arg SOURCE_COMMIT=9c8c6e40a0f865ec14594dba11b25817cb0797a1 . The image builds the dashboard itself when the context has no dashboard/dist (RELEASING.md §4.3).
Since v0.4.0-rc.1, 84 pull requests have been merged, this release's #186 included:
- Notifications: #106, #142 to #144, #146 to #152 and #154.
- The HA control plane: #109, #158, #161, #164, #165, #169, #171, #173, #175 and #183.
- SSH trust on the data path: #111, #121 to #125, #127 and #140.
- Per-tenant credentials: #114, #157, #159, #160, #163, #166, #167, #170, #172, #174, #177 to #180, #182 and #184.
- Changed-extent tracking: #115, #126, #128 and #140, which landed CE4 to CE13 together with SSH trust's ST7 to ST9.
- The 0.5.0 PRD: #120.
- Fixes, operations, documentation and CI: #101 to #105, #107, #108, #110, #113, #116 to #119, #145, #153, #155, #156, #162, #168, #176, #181, #185 and #186.
- Dependency updates: #29, #46, #47, #50, #129 to #131, #133, #135, #138 and #141.
Highlights
Notifications by email, Slack and signed webhooks (PRD G10, FR-48 to FR-51; SDD §24). They are not a Technology Preview.
- Channels:
- three kinds:
emailthrough the installation's SMTP relay,slackincoming webhooks, andwebhookreceivers whose messages are signed as Standard Webhooks specifies; - an admin keeps the catalog on the dashboard's Notifications page;
- a Slack URL or a signing key is written once and never shown again;
- Send test tries a channel once.
- three kinds:
- Subscriptions:
- an operator subscribes a channel to a plan, and an admin subscribes one to every plan;
- the topics
approval,downtimeandproblemare on by default,outcomeandprogresson request; - a subscription never changes a plan's status.
- Messages:
- 18 triggers, each with a fixed message in three formats;
- a message never carries a credential, an address, an error's text or who acted;
redact_namessends ids instead of names.
- Delivery stays off the migration path:
- at least once, with a dedupe key, in order per channel;
- at most 5 tries over about 5 minutes, honouring a
Retry-Afterof up to 300 s; - one message a second, and none whose event is more than an hour old;
- one audit event per message (
notification.sent,notification.failed), andseamless_notifications_total{kind,outcome}; - no message delays or fails a migration.
SSH trust on the data path (NFR-06; SDD §26; Security.md SEC-02 and SEC-06). It is not a Technology Preview: its lab cases gate the final 0.5.0.
- Every conversion host's key is known before the first connection:
- a host Seamless creates gets an ed25519 host key, injected through cloud-init;
- a host it did not create is pinned once from the keys block its console printed;
- keys declared on the provider (
conversion_host.ssh_host_keys) win over both.
- Checked on every hop:
- ssh, scp, Ansible and the link all check with
StrictHostKeyChecking=yes, against the run's own known_hosts file; - another key fails the run at once and for good, instead of after a 15-minute SSH timeout;
- the events are
conversion_host.key_refusedandconversion_host.key_pinned; - a cutover probes both hosts and its link before the source stops.
- ssh, scp, Ansible and the link all check with
- A link per run:
- the destination host makes its own key for each run;
- the source host admits that key under
restrict, with a forced command (blocksync'sgate),from=, anexpiry-timeand, for a cold run, its export ports alone; - the run removes the link when it ends, and 0.4.0's static link goes with the first 0.5.0 run on each host pair.
- blocksync's copies go into private directories, and their SHA-256 is checked before
sudoruns them (R-02). - Dashboard: a Host keys panel on each provider, and a warning while checking is off.
The HA control plane: a Technology Preview (FR-27; SDD §25).
- One leader, fenced:
- a lease row in PostgreSQL elects the server that runs the orchestrator;
- the store refuses every write of a server whose lease epoch is no longer current.
- The HA component (
deploy/openshift/ha,deploy/kubernetes/ha) runs two replicas on two nodes:- the follower serves the dashboard,
/health,/readyand/metricsitself; - it relays the rest of the API and the event stream to the leader;
- it takes over within about 35 s of losing the leader, and in under 2 s after a clean stop. Both figures come from the design: no lab has measured them yet.
- the follower serves the dashboard,
- Operations:
scripts/seamless-ctl.sh <cluster> scale 2works with the component and a ReadWriteManyseamless-data;statusnames the leading pod;uprefuses a claim whose access modes its overlay would change.
- Observability: the events
leader.acquiredandleader.released, the metricsseamless_leaderandseamless_leader_epoch, and theleaderof/health,/readyandseamless status.
Per-tenant credentials: a Technology Preview (FR-52; SDD §27).
- Project credentials: an OpenStack or RHOSO provider holds a Keystone application credential per project. It is write-only, set with
PUT /providers/{id}/projects/{project_id}/credentials. - A project pair per plan:
- a plan names a
source_projectand adestination_project; - each step uses the credential SDD §27.5 names;
- a project credential is never replaced by the provider's own.
- a plan names a
- Checks:
- the provider check signs in with each project credential and reads its roles, its
restrictedflag and its expiry; - four findings are new:
PROJECT_CREDENTIAL_EXPIRING,PROJECT_CREDENTIAL_UNRESTRICTED,PROJECT_CREDENTIAL_ROLE_MISSINGandDST_KEYPAIR_KEY_MISMATCH; - the cutover gate holds a cutover, its source still running, while a credential it or its rollback would use expires within 24 hours.
- the provider check signs in with each project credential and reads its roles, its
- Dashboard:
- Projects on the provider card;
- a Project pair in the plan form, which then reads the source project's inventory;
- a Project credential select on the Inventory page.
Changed-extent tracking for warm passes: a Technology Preview (FR-26; SDD §28).
-
What it does:
- on the source conversion host,
rbd diffbetween two passes' Cinder snapshots lists what changed on a Ceph volume; - checked passes count what the extents missed;
- after a clean check, the final pass reads only the listed chunks (blocksync protocol v2).
- on the source conversion host,
-
Safe by default: any doubt scans the disk in full and records why, and tracking never fails a pass.
-
Opt-in twice:
- per plan, with
extent_tracking; - per source provider, with
cephand a metadata-only Ceph user's key (PUT /providers/{id}/ceph-key).
The pre-staging then installs
ceph-commonon the source conversion host. - per plan, with
-
Estimates: the estimate gains the query's term (
extent_query_s). In the model, a 200 GiB disk's final pass takes about 287 s on 1 Gbit/s (Performance.md SM-1b).
Dashboard (#153, #155, #156, #181, #118):
- The UI/UX audit's fixes, UI-01 to UI-12:
- keyboard focus that recovers;
- VM selection and focus that work in Safari;
- the draft guard on every way out of a form;
- a one-time token that must be acknowledged before it disappears;
- list state that survives Back;
- Events says "Live" only while connected;
- a page for a missing entity offers a way out, instead of a Retry that cannot work.
- A design pass:
- a softer light theme;
- 44 px controls on narrow screens;
- charts that scroll from the keyboard;
- a Sign in button that no longer jumps;
- a sidebar that scrolls as one column, with every item visible at 1280 px.
- Live rules: time-based rules, such as a cutover window opening, refresh by themselves.
Upgrade notes and breaking changes
-
From 0.4.0-rc.1: set the image tag to
0.5.0-rc.1(Compose'sSEAMLESS_VERSION, the kustomizations'newTag) and follow RELEASING.md §9:- Back up.
- Drain and stop:
scripts/seamless-ctl.sh PLATFORM stop --drain TOKEN_FILE. SSH trust needs the drain, because a cutover that the upgrade cuts off resumes only once its hosts are pinned, and one whose source had stopped is rolled back. - Roll the image.
- Check that
GET /api/v1/healthreports0.5.0-rc.1. - Resume the plans:
scripts/seamless-ctl.sh PLATFORM resume --token-file TOKEN_FILE PLAN_ID....
On a cluster, add
--urlwith the Route's or the Ingress's URL to steps 2 and 5. -
Host-key checking is on by default.
SEAMLESS_ANSIBLE_HOST_KEY_CHECKINGis nowtrue, where it wasfalse. No shipped manifest sets it, so every stock installation changes.- After the upgrade: run each provider's check, or let the next pre-staging do it. It pins the hosts 0.4.0 made from their consoles.
- A host whose console no longer shows its keys block: declare its keys on the provider, or delete it and pre-stage again. Until then, a run to such a managed host fails with "host key unknown", and
CONV_HOST_KEY_UNKNOWNblocks a plan whose host Seamless does not create. - A host you bring:
- set sshd's
AllowTcpForwardingtolocalon the source host and tonoon the destination host, andPermitTunnel no;
...
- set sshd's
Seamless Migrate 0.4.0-rc.1
Seamless Migrate 0.4.0-rc.1
Type: release candidate 1 of 0.4.0 (v0.4.0-rc.1), a GitHub pre-release that never becomes "Latest". 0.4.0-rc.1 follows 0.1.0-rc.2 directly: 0.1.0 final, 0.2.0 and 0.3.0 were never tagged, and their scope ships in this release candidate. The gates of each release candidate (RELEASING.md §3, QASuite §13.5) run against its tag.
Commit: 0533bd45d1e65978dc86b4d3186a400b1e379e58 (the merge commit of #97) · Collection: os_migrate.os_migrate 1.1.0. The collection keeps its version, and its CHANGELOG.rst 1.1.0 section lists the changes since rc.2.
Image: built from the tag, as for rc.1 and rc.2 - no registry holds it: docker build -f seamless/Containerfile -t seamless-migrate:0.4.0-rc.1 --build-arg SOURCE_COMMIT=0533bd45d1e65978dc86b4d3186a400b1e379e58 . The image builds the dashboard itself when the context has no dashboard/dist (RELEASING.md §4.3).
Since v0.1.0-rc.2, 54 pull requests have been merged, with 616 commits:
- GPU workloads: #57, #61 to #74 and #96.
- The network cut-over: #75, #79 to #83, #85 to #95, #98 and #99 (the NetworkPolicy's egress).
- The improvement loops: #44, #45, #56, #58 and #60.
- Documentation and a test diagnostic: #59, #76 and #84.
- Fixes found by this release's review: #100.
- Dependency updates: #23, #30, #31, #33, #48, #49, #51, #55, #77 and #78.
Highlights
GPU workloads (0.3.0's scope): a Technology Preview, validated in simulation (PRD G8, FR-35 to FR-41; SDD §22). VMs with an NVIDIA vGPU, time-sliced or MIG-backed, or with a GPU passed through whole, now migrate instead of being blocked.
- Discovery: Seamless reads each VM's GPUs from its OpenStack flavor (
resources:VGPU,pci_passthrough:alias) or from vCenter (a vGPU profile, or a DirectPath I/O device's ids). The Inventory shows them. - Mapping: the plan maps each GPU to a destination GPU flavor:
mappings.gpusfor a VMware VM,mappings.flavorsfor an OpenStack VM. A GPU VM is never matched to a flavor by size or by name, and without a mapping it stays blocked. - Capacity:
- Validation counts the plan's GPU demand against the destination's free capacity, read from Placement.
- The cutover gate reads the capacity again before the source stops.
- With no room, the migration waits and keeps syncing, and its source keeps running (
migration.gpu_wait,seamless_gpu_waits).
- Verification: the verification checks the server's GPU flavor and its Placement allocations (
gpu_flavor,gpu_allocation).GUEST_GPU_DRIVERandGUEST_GPU_LICENSEname what the guest needs at the destination. - Limits: a VMware VM with a passthrough device moves only with
vmware_cold, while powered off. A GPU VM never goes in the pilot wave. - Not run on GPU hosts: none of this has run on a GPU host, and the lab cases LAB-GPU01 to LAB-GPU08 have not run. Every GPU element says "Technology Preview, validated in simulation".
Network cut-over (0.4.0's scope): a Technology Preview, validated in simulation (PRD G9, FR-28, FR-42 to FR-47; SDD §23).
- Findings for what Seamless does not move:
- a VM in a Heat stack or in an autoscaling group (
SRC_VM_AUTOSCALEDblocks until the plan acknowledges it); - a member of an Octavia pool, and a pool whose members a plan's waves split (
NET_LB_POOL_SPLIT); - a floating IP whose address would change;
- a port with
allowed_address_pairs; - a prefix that a plan's waves would split;
- DNS names the destination cannot publish.
- a VM in a Heat stack or in an autoscaling group (
- Cut-over hooks: an admin registers Ansible playbooks and HTTPS webhooks in a catalog (
/hooks, or the dashboard's Hooks page).- A plan runs them at
pre_stop,post_create,post_verify,on_rollbackandon_finalize. - Each hook has a timeout, an idempotency key and an optional revert hook.
- No credential reaches a hook's context.
- A plan runs them at
- A floating IP that keeps its address: each plan can opt in (
network_cutover.floating_ips: keep_address), on every OpenStack strategy.- The address is reserved at the destination before the window and moves after the source stopped.
- A rollback gives it back to the source before the source starts.
- Finalize releases the source's allocation.
- DNS swap through Designate or an RFC 2136 server:
- It is a compare-and-swap: when the record holds another address, it changes nothing.
- A rollback swaps the record back.
- A TTL longer than the plan's downtime SLO warns.
- BGP: Seamless speaks no BGP. The verification waits until each moved floating IP answers, and the wait counts in the downtime.
- Octavia member helper: it drains the source member before the stop, and joins the migrated VM to the mapped destination pool after its verification. TLS keys are never read.
- Estimates and demo: the downtime estimate includes the
post_createhooks' timeouts and shows the DNS TTL tail apart. The demo shows each rule. - Not run on real clouds: none of this has run on real clouds, and the lab cases LAB-NET01 to LAB-NET09 have not run. Every network cut-over element says "Technology Preview, validated in simulation".
Community OpenStack destinations (0.2.0's destination scope) (PRD G7, FR-29 to FR-34; SDD §21) already shipped in rc.1 and rc.2. They are still not validated in a lab (plan task T10).
Operations (SDD §17):
scripts/seamless-ctl.shbrings a deployment up and down, stops, starts, restarts and scales it, and reports its capacity, status and logs, on Docker, Podman, Kubernetes and OpenShift. A--drainpauses the running plans, andresumestarts them again (docs/Operations.md).make seamless-doctorchecks a machine against the repository's pins and names each fix.
Upgrade notes and breaking changes
-
From 0.1.0-rc.2 or rc.1: set the image tag to
0.4.0-rc.1(ComposeSEAMLESS_VERSION, the kustomizations'newTag) and follow RELEASING.md §9:- Back up.
- Pause the running plans and stop the control plane:
scripts/seamless-ctl.sh PLATFORM stop --drain TOKEN_FILE. - Roll the image.
- Check that
GET /api/v1/healthreports0.4.0-rc.1. - Resume the plans:
scripts/seamless-ctl.sh PLATFORM resume --token-file TOKEN_FILE PLAN_ID....
On a cluster, add
--urlwith the Route's or the Ingress's URL to steps 2 and 5. -
No schema change:
- The tables and indexes are the ones rc.1 created, so
create_schema()adds nothing. With the two-role PostgreSQL setup, no start with the owner role is needed. - Data that rc.2 wrote is read as this version writes it. A text with a NUL or a lone surrogate reads with U+FFFD, and a NaN or an infinity kept from Jev or agentmemory reads as no value (SDD §11).
- The tables and indexes are the ones rc.1 created, so
-
Requests that rc.2 accepted and this version refuses:
- a body holding a NUL or a lone surrogate gets a 422;
- a time outside 0001-01-01 to 9999-12-31 gets a 422 naming the field, where rc.2 answered 500 (audit AA-01);
- a field sent to a route whose request is
{}, such as an option sent to/approve, gets a 422 (AA-04); - a rollback whose reason is only white space gets a 422 "reason is required.", and comments and reasons are stored stripped (RV51-26);
- a plan two of whose migrations name one VM can no longer be validated or started (RV51-18);
- the tokens file and
seamless token createrefuse a token name that is not printable (SDD §13.1).
-
Additions:
- the
/hooksroutes; - the plan fields
network_cutoverandacknowledged_findings, the mappings'gpus, and the providers'gpu_profilesandannounces_tenant_networks; - the events
migration.gpu_wait,hook.created,hook.updatedandhook.deleted; - the metric
seamless_gpu_waits; - 19 new finding codes, which validation reports. Three of them block:
SRC_VM_AUTOSCALED, until the plan acknowledges it;DST_FIP_ADDRESS_UNAVAILABLE, only for a plan that keeps floating IP addresses; andDST_GPU_CAPACITY_INSUFFICIENT, when a plan's GPU VMs need more than the destination has free.
- the
-
Estimates may differ from rc.2's for the same plan, because of the SDD §9.1 model fixes and the hooks' part
hooks_s. The model fixes are the snapshot now counted in the final-downtime estimate, and a scan-rate calibration that matches its model. -
OpenShift and Kubernetes egress (#99):
seamless-allow-egress-externalnow also opens Placement, Heat, Octavia
and Designate on their community ports (8778, 8004, 9876, 9001) and RHOSP 17.1's public ones (13778, 13004, 13876,
13001), and TCP 53 for an RFC 2136 DNS target's server. Apply the newdeploy/openshift/networkpolicy.yaml(or the
Kubernetes overlay) when you upgrade: the GPU capacity reads, the Heat and Octavia reads, the member helper and the
DNS swap need it. A cloud that serves these on other ports, and a webhook served on a port other than 443, still need
their own egress rules. -
Hooks:
- A playbook hook names an absolute path in the control plane's container. The shipped Compose and OpenShift manifests mount no hook playbooks, so add a reviewed, read-only mount (Security.md §12).
- A webhook's bearer token (key
token) and an RFC 2136 target's TSIG key (name,secret,algorithm) are secrets. An admin stores them in the secret store, under the name the hook or the target gives (SDD §13.3, Security.md §7.1).
-
RFC 2136 needs the
dnsextra (dnspython). The image carries it; an install outside the image must add it. -
Demo: the demo seeds only the plans its database lacks. A demo database seeded before 0.4.0 therefore keeps its old plans, without the GPU mappings and the network cut-over rules that the new seeded plans carry. Run
make seamless-reset CONFIRM=yes, which deletes the stack's containers and volumes, thenmake seamless-demo.
Fixes since 0.1.0-rc.2
- rc.2's known issues: each VMware rollback attempt now writes its own keep record, and a record that cannot be written never keeps the source stopped (RV35A-02, RV35A-03).
- Storage handover ...
Seamless Migrate 0.1.0-rc.2
Seamless Migrate 0.1.0-rc.2
Type: release candidate 2 of 0.1.0. This is a pre-release: the lab matrix runs against this tag before 0.1.0 final.
Commit: 9421748 · Collection: os_migrate.os_migrate 1.1.0. The collection is still the in-development 1.1.0 line; it changed since rc.1, see CHANGELOG.rst 1.1.0.
Image: not published to a registry yet. Build it from this tag:
docker build -f seamless/Containerfile -t seamless-migrate:0.1.0-rc.2 --build-arg SOURCE_COMMIT=9421748d6b44f3f0c939836b1ea5d2b55cc6d1ca .
Run cd dashboard && npm ci && npm run build first; see RELEASING.md §4.3.
This candidate takes the hardening of the 2026-10-17/18 improvement loop (PR #42): the executor and API audits' fixes, and independent reviews 26–35 of each fix.
Fixed since rc.1
- VMware migration-kit names: VMs whose name the kit rewrites (a dot, a space, an accent, over 64 characters) are now handled. Their server and ports are found by the kit's name, and VMs the kit names alike are refused as duplicates. This was rc.1's known issue (audit EX-07, EX-18).
- Storage handover:
- A cutover resumed after a failure stops a source that ran again before it goes on, and counts a new outage. It waits out a start or a stop Nova still runs.
- It keeps the source's volumes again after a rollback attempt.
- A deletion Nova accepted, or took with an error or a lost answer, is never given
delete_on_terminationback. Its source is recreated with every volume kept until it runs; a build Nova failed is replaced. - Step 0 checks backend specs as Cinder's scheduler does, volumes held by another server, and disks on the hypervisor.
- Calls retry the SDK's transient errors and reconnect after a credential rotation (EX-04, EX-09, EX-10, EX-12, EX-14, EX-15).
- VMware:
- The cutover's downtime clock opens at the kit's migrate task, and the rollback's power-on closes it.
- The kit's completed CBT copies are tracked: one a cutover or a booted guest may have written to is copied again. A cutover run that never reached the migrate task keeps them.
- The rollback deletes only the server before it powers the source on. It looks a server up by the kit's name only while the source is stopped, and keeps what a server found only by name held.
- Collection:
- The cold rescue's destination cleanup runs first and best effort, by the workload's record, and a wait that gives up ends its phase.
- Each conversion host logs in as its own user (EX-08).
- Warm passes clean up what an interrupted pass left.
- qcow2 sizes are read from the image header.
- A stuck detach stays a permanent failure under the image's ansible-core.
- API and security:
- Unknown request fields are refused at any depth.
- CORS origins are validated as the URL Standard serializes them;
*is refused, and preflights carry the security headers. - With authentication off, role routes refuse cross-site requests.
- Provider edits and plan starts are serialized.
- Secret names are guarded in every spelling.
- Log and evidence redaction is linear-time and covers agentmemory hits.
- Covered audit items: AP-01 to AP-05, AP-07, AP-09 and AP-10, plus the CodeQL alerts that named real weaknesses.
- Dashboard:
- A failed migration is offered only what it can take.
- A failed rollback no longer claims the source runs, and a migration never stopped keeps its Cancel.
- The Roll back dialog says what each strategy's rollback deletes.
Upgrade notes and breaking changes
- From 0.1.0-rc.1, update the image tag (Compose
SEAMLESS_VERSION, the kustomizations'newTag) to0.1.0-rc.2. The schema has no breaking change. - Requests carrying unknown nested fields (plans, providers, advisor policies, plan apply) are now refused with 422.
- With authentication off, cross-site requests to role routes are refused.
Security
- gitleaks: the working tree and the history are clean.
- CI's
imagejob scans the image with trivy (no fixable HIGH or CRITICAL) and writes a CycloneDX SBOM.sbom.cdx.jsonattached here describes the image CI built from this commit. - CodeQL runs on every pull request. Its remaining open alerts are false positives awaiting dismissal (owner question q39).
Known issues and waivers
- Not yet lab-verified. The lab matrix (QASuite §7, M1–M11), integrity, performance and resilience gates run against this RC. The storage handover and the VMware paths need that lab run before production use.
- Open review findings (low):
- A VMware rollback whose keep record cannot be read once (a transient I/O error) may delete, on a retried attempt, the volumes of a same-named server it found by name.
- A keep record that can be read but not written still keeps the source stopped until the run directory is writable again.
- Owner decisions pending:
- A lost answer during a handover unmanage, manage or create (EX-03).
- A deleted source flavor (EX-05), and the source key pair at recreate (EX-06).
- The handover rollback's hard power-off of the destination (EX-11).
- Cross-plan VMware name twins (EX-13, q26, q37).
- A warm retry whose destination server exists (EX-16).
- The console regex budget (AP-06) and auditing the demo power route (AP-08).
- The VMware non-Windows clock (q35), and the kit's power-off after the copy (q38, lab).
- Converted kit volumes on the conversion host (q40), and recording a rollback's start of the source (q41).
- Soft-delete source clouds (q42, lab).
- The container image is not pushed to a registry, and the collection is not published to Ansible Galaxy. It is a modified os-migrate; its tarball is attached here.
- The tag is annotated, not signed. Signed tags start at 1.0.0.
Tested with
- CI on this commit:
- Python 3.11 and 3.13, with SQLite and PostgreSQL 16;
- ansible-core ≥ 2.16 and < 2.19 (the image's pin);
- openstacksdk ≥ 4.5;
- Node 22, and Playwright in mock mode;
- Docker Compose on Linux;
- kustomize and kubeconform for the OpenShift and Kubernetes manifests.
- No lab run yet (see Known issues).
Verify
sha256sum -c SHA256SUMS
Seamless Migrate 0.1.0-rc.1
Seamless Migrate 0.1.0-rc.1
Type: release candidate 1 of 0.1.0 (pre-release: the lab matrix runs against this tag before 0.1.0 final)
Commit: 68479e0 · Collection: os_migrate.os_migrate 1.1.0
Image: not published to a registry yet. Build it from this tag:
docker build -f seamless/Containerfile -t seamless-migrate:0.1.0-rc.1 --build-arg SOURCE_COMMIT=68479e02f7a5323b4fcd0466f45f032e91280d24 .
(after cd dashboard && npm ci && npm run build; see RELEASING.md §4.3)
The first release of Seamless Migrate: move virtual machines from Red Hat OpenStack Platform 17.1, community
OpenStack or VMware vSphere into RHOSO 18.0 or community OpenStack 2023.1 Antelope – 2026.2 Hibiscus, with
the downtime estimated before it starts, approved by the right people, and reversible until you finalize.
Highlights
- Five strategies, chosen per VM:
cold,warm(snapshot pre-copy while the VM runs, then a hash-based
delta after the stop),storage_handover(shared Ceph or NetApp ONTAP: Cinder unmanage and manage, no data
copy),vmware_coldandvmware_warm(CBT), with pre-flight findings and a downtime estimate for each
(PRD FR-04 to FR-10; SDD §3, §9). - Safe by construction: approval and change-window gates, waves with a pilot, per-VM rollback until
finalize, resume after a control-plane restart, an audit trail of every action (FR-11, FR-12, FR-15,
FR-16, FR-19; SDD §5, §8, §13). - Dashboard and API: a WCAG 2.2 AA dashboard, REST with resumable SSE, the
seamlessCLI, provider
management with write-only credentials, Prometheus metrics, a demo mode (FR-17, FR-18, FR-22 to FR-24;
SDD §12, §16, §18). - Community OpenStack destinations 2023.1 – 2026.2 beside RHOSO 18.0, with a role and capability
pre-flight per policy profile (FR-29 to FR-34; SDD §21). - Assisted, never autonomous: optional Jev judgments and agentmemory lessons inside deterministic bounds;
everything works with them off (FR-20, FR-21; SDD §14). - Deploy anywhere: OpenShift, Kubernetes, or one host with Docker Compose (Linux Docker Engine, macOS
with Colima, or Podman), PostgreSQL 16 as the system of record (FR-25; SDD §17).
Upgrade notes and breaking changes
- First release: install fresh (the README's Quick start sections,
deploy/). There is nothing to upgrade from.
Fixes since the last merged audit
- A cancelled storage-handover step now ends only once its call in flight returned, so the rollback starts
from the whole journal (audit EX-01, SDD §7.3). - A stop that may have happened opens the downtime clock, so the automatic rollback restarts the source and a
cancel is refused (audit EX-02, SDD §7.2, §7.3). - Reviews 23 to 25: tenant-chosen names such as
__proto__read safely in the dashboard, the offline mock
answers like the API, the port refusals name the destination provider (PRs #39, #40).
Security
- gitleaks: working tree and history clean. CI's
imagejob scans the image with trivy (no fixable HIGH or
CRITICAL) and writes a CycloneDX SBOM:sbom.cdx.jsonattached here describes the image CI built from this
commit. CodeQL runs on every pull request; its open alerts are being triaged before 0.1.0 final. - Credentials live in mounted files or the platform secret store, written once through the API and never
read back (Security.md).
Known issues and waivers
- Not yet lab-verified. The lab matrix (QASuite §7, M1–M11), integrity, performance and resilience gates
run against this RC. The storage handover and the VMware paths need that lab run before production use. - VMware VMs whose name the migration kit rewrites (a dot, a space, an accent, over 64 characters: the kit
namesweb01.example.com's serverweb01_example_com): Seamless looks the server up by the VM's own name, so
the cutover records no server, verification fails, and the automatic rollback powers the source on while the
kit's server keeps running with the same MACs and addresses (EX-18). Until the next RC, cut such VMs over with
automatic rollback off, and before a rollback delete the kit's server by hand. The fix, with those of EX-04, EX-07
and EX-14, is ready for the next release candidate; it is not in this tag. - Open findings of the 2026-10-17 executor audit (fixes under way): a lost answer to a Cinder unmanage or
manage, or a Nova create, during a handover can strand its rollback (EX-03); a handover whose source flavor
was deleted cannot be rolled back (EX-05); one SSH user serves both conversion hosts (EX-08); the handover
rollback powers the destination server off hard before it hands the volumes back (EX-11); openstacksdk's
503/504/"timed out" errors are not retried (EX-12); without a recorded server the VMware rollback deletes
a same-named server (EX-13); the handover keeps a connection after a credential rotation (EX-14);
handover step 0 misses an ephemeral disk added by a resize after validation (EX-15); a warm retry whose
destination server exists does not reach the cutover that finishes it (EX-16); and lows EX-04, EX-06,
EX-07, EX-09, EX-10. - The container image is not pushed to a registry, and the collection is not published to Ansible Galaxy
(it is a modified os-migrate; its tarball is attached here). The tag is annotated, not signed (signed tags
from 1.0.0).
Tested with
- CI on this commit: Python 3.11 and 3.13 (SQLite and PostgreSQL 16), ansible-core ≥ 2.16, openstacksdk
≥ 4.5, Node 22, Playwright (mock mode), Docker Compose on Linux, kustomize and kubeconform for the
OpenShift and Kubernetes manifests. - No lab run yet (see Known issues).
Verify
sha256sum -c SHA256SUMS