Skip to content

Machine Migration

This document details how to migrate machines, their state, profiles, jobs and/or workorders from one DRP endpoint to another.

Prerequisites

This feature was introduced in tip, prior to v4.11. You will need tip, v4.11 or greater versions of digital-rebar and drpcli.

The source and target endpoints must be configured with Multi Site Manager. Please see .

Operation

There are two endpoints with the following machines.

[admin@drp1 ~]$ drpcli machines list | jq -r '.[].Name'
birdy
drp1.rackn
drp2.rackn

[admin@drp2 ~]$ drpcli machines list | jq -r '.[].Name'
drp2.rackn

Here is an example machine to migrate from drp1 to drp2.

[admin@drp1 ~]$ drpcli machines show Name:birdy
{
    "Address": "",
    "Arch": "amd64",
    "Available": true,
    "BootEnv": "sledgehammer",
    "Bundle": "",
    "Context": "",
    "CurrentJob": "1ed352bc-1303-63f2-94d2-19d9b7aba263",
    "CurrentTask": 2,
    "Description": "",
    "Endpoint": "",
    "Errors": [],
    "Fingerprint": {
        "CSNHash": "",
        "CloudInstanceID": "",
        "MemoryIds": [],
        "SSNHash": "",
        "SystemUUID": ""
    },
    "HardwareAddrs": [],
    "Locked": false,
    "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine"
    },
    "Name": "birdy",
    "OS": "",
    "Params": {},
    "Partial": false,
    "PendingWorkOrders": 0,
    "Pool": "default",
    "PoolAllocated": false,
    "PoolStatus": "Free",
    "Profiles": [
        "example-profile",
        "conflicting-profile"
    ],
    "ReadOnly": false,
    "RetryTaskAttempt": 0,
    "Runnable": true,
    "RunningWorkOrders": 0,
    "Secret": "h5kYqfCu6ehiAVz0",
    "Stage": "hello-world",
    "TaskErrorStacks": [],
    "Tasks": [
        "stage:hello-world",
        "hello-world"
    ],
    "Uuid": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
    "Validated": true,
    "WorkOrderMode": false,
    "Workflow": "hello-world",
    "WorkflowComplete": true
}

Some jobs have been created that are associated with the machine.

[admin@drp1 ~]$ drpcli jobs list Machine=01d8828f-2f7d-4a1c-a1fa-f668274c7c44
[
    {
        "Archived": false,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": false,
        "CurrentIndex": 0,
        "EndTime": "2022-09-15T15:22:35.937596048-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "complete",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine"
        },
        "NextIndex": 1,
        "Previous": "00000000-0000-0000-0000-000000000000",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.937594733-04:00",
        "State": "finished",
        "Task": "stage:hello-world",
        "Uuid": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "Validated": true,
        "Workflow": "hello-world"
    },
    {
        "Archived": false,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": true,
        "CurrentIndex": 1,
        "EndTime": "2022-09-15T15:23:04.49280118-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine"
        },
        "NextIndex": 2,
        "Previous": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.938191239-04:00",
        "State": "finished",
        "Task": "hello-world",
        "Uuid": "1ed352bc-1303-63f2-94d2-19d9b7aba263",
        "Validated": true,
        "Workflow": "hello-world"
    }
]

The machine must not have WorkOrderMode set to true in order to migrate. Migrate the machine.

[admin@drp1 ~]$ drpcli machines migrate Name:birdy to "$(drpcli -E https://drp2:8092 machines migrateTicket)"
Machine Name:birdy migrated to https://drp2:8092

The machine has migrated. Notice the drp1 machine has been locked.

[admin@drp2 ~]$ drpcli machines list | jq -r '.[].Name'
birdy
drp2.rackn

$ drpcli machines show Name:birdy
{
    "Address": "",
    "Arch": "amd64",
    "Available": false,
    "BootEnv": "sledgehammer",
    "Bundle": "",
    "Context": "",
    "CurrentJob": "1ed352bc-1303-63f2-94d2-19d9b7aba263",
    "CurrentTask": 2,
    "Description": "",
    "Endpoint": "",
    "Errors": [],
    "Fingerprint": {
        "CSNHash": "",
        "CloudInstanceID": "",
        "MemoryIds": [],
        "SSNHash": "",
        "SystemUUID": ""
    },
    "HardwareAddrs": [],
    "Locked": false,
    "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine"
    },
    "Name": "birdy",
    "OS": "",
    "Params": {},
    "Partial": false,
    "PendingWorkOrders": 0,
    "Pool": "default",
    "PoolAllocated": false,
    "PoolStatus": "Free",
    "Profiles": [
        "example-profile",
        "conflicting-profile"
    ],
    "ReadOnly": false,
    "RetryTaskAttempt": 0,
    "Runnable": false,
    "RunningWorkOrders": 0,
    "Secret": "h5kYqfCu6ehiAVz0",
    "Stage": "hello-world",
    "TaskErrorStacks": [],
    "Tasks": [
        "stage:hello-world",
        "hello-world"
    ],
    "Uuid": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
    "Validated": true,
    "WorkOrderMode": false,
    "Workflow": "hello-world",
    "WorkflowComplete": true
}

The machine object on drp1 no longer has tasks, profiles, params, etc. Under Meta, we now have a redirect-endpoint that tells the old endpoint where it should redirect to.

[admin@drp1 ~]$ drpcli machines show Name:birdy
{
    "Address": "",
    "Arch": "amd64",
    "Available": true,
    "BootEnv": "local",
    "Bundle": "",
    "Context": "",
    "CurrentJob": "",
    "CurrentTask": 0,
    "Description": "Migrated to https://drp2:8092",
    "Endpoint": "",
    "Errors": [],
    "Fingerprint": {
        "CSNHash": "",
        "CloudInstanceID": "",
        "MemoryIds": [],
        "SSNHash": "",
        "SystemUUID": ""
    },
    "HardwareAddrs": [],
    "Locked": true,
    "Meta": {
        "feature-flags": "change-stage-v2",
        "redirect-endpoint": "https://drp2:8092"
    },
    "Name": "birdy",
    "OS": "",
    "Params": {},
    "Partial": false,
    "PendingWorkOrders": 0,
    "Pool": "",
    "PoolAllocated": false,
    "PoolStatus": "",
    "Profiles": [],
    "ReadOnly": false,
    "RetryTaskAttempt": 0,
    "Runnable": false,
    "RunningWorkOrders": 0,
    "Secret": "h5kYqfCu6ehiAVz0",
    "Stage": "none",
    "TaskErrorStacks": [],
    "Tasks": [],
    "Uuid": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
    "Validated": true,
    "WorkOrderMode": false,
    "Workflow": "",
    "WorkflowComplete": false
}

The jobs have migrated as well.

[admin@drp2 ~]$ drpcli jobs list Machine=01d8828f-2f7d-4a1c-a1fa-f668274c7c44
[
    {
        "Archived": false,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": false,
        "CurrentIndex": 0,
        "EndTime": "2022-09-15T15:22:35.937596048-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "complete",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine"
        },
        "NextIndex": 1,
        "Previous": "00000000-0000-0000-0000-000000000000",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.937594733-04:00",
        "State": "finished",
        "Task": "stage:hello-world",
        "Uuid": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "Validated": true,
        "Workflow": "hello-world"
    },
    {
        "Archived": false,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": true,
        "CurrentIndex": 1,
        "EndTime": "2022-09-15T15:23:04.49280118-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine",
        "redirect-endpoint": "https://drp2:8092"
        },
        "NextIndex": 2,
        "Previous": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.938191239-04:00",
        "State": "finished",
        "Task": "hello-world",
        "Uuid": "1ed352bc-1303-63f2-94d2-19d9b7aba263",
        "Validated": true,
        "Workflow": "hello-world"
    }
]

The original jobs on drp1 will still exist, however they now have the Meta.redirect-endpoint field set similar to the machine on drp1.

$ drpcli jobs list Machine=01d8828f-2f7d-4a1c-a1fa-f668274c7c44
[
    {
        "Archived": true,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": false,
        "CurrentIndex": 0,
        "EndTime": "2022-09-15T15:22:35.937596048-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "complete",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine",
        "redirect-endpoint": "https://drp2:8092"
        },
        "NextIndex": 1,
        "Previous": "00000000-0000-0000-0000-000000000000",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.937594733-04:00",
        "State": "finished",
        "Task": "stage:hello-world",
        "Uuid": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "Validated": true,
        "Workflow": "hello-world"
    },
    {
        "Archived": false,
        "Available": true,
        "BootEnv": "sledgehammer",
        "Bundle": "",
        "Context": "",
        "Current": true,
        "CurrentIndex": 1,
        "EndTime": "2022-09-15T15:23:04.49280118-04:00",
        "Endpoint": "",
        "Errors": [],
        "ExitState": "",
        "Machine": "01d8828f-2f7d-4a1c-a1fa-f668274c7c44",
        "Meta": {
        "feature-flags": "change-stage-v2",
        "machine-role": "machine",
        "redirect-endpoint": "https://drp2:8092"
        },
        "NextIndex": 2,
        "Previous": "1ed352bc-1301-695a-94d2-8dc4daeea809",
        "ReadOnly": false,
        "ResultErrors": null,
        "Stage": "hello-world",
        "StartTime": "2022-09-15T15:22:35.938191239-04:00",
        "State": "finished",
        "Task": "hello-world",
        "Uuid": "1ed352bc-1303-63f2-94d2-19d9b7aba263",
        "Validated": true,
        "Workflow": "hello-world"
    }
]

If a profile has the same name between two endpoints, the destination endpoint profile wins during migration.

[admin@drp1 ~]$ drpcli profiles show conflicting-profile
{
    "Available": true,
    "Bundle": "",
    "Description": "",
    "Documentation": "",
    "Endpoint": "",
    "Errors": [],
    "Meta": {},
    "Name": "conflicting-profile",
    "Params": {
        "drp1-only-param": true
    },
    "Partial": false,
    "Profiles": [],
    "ReadOnly": false,
    "Validated": true
}

[admin@drp2 ~]$ drpcli profiles show conflicting-profile
{
    "Available": true,
    "Bundle": "",
    "Description": "",
    "Documentation": "",
    "Endpoint": "",
    "Errors": [],
    "Meta": {},
    "Name": "conflicting-profile",
    "Params": {
        "drp2-only-param": true
    },
    "Partial": false,
    "Profiles": [],
    "ReadOnly": false,
    "Validated": true
}