1
1
# Copyright 2016 Cloudbase Solutions Srl
2
2
# All Rights Reserved.
3
3
4
+ import re
5
+
4
6
from oslo_log import log as logging
5
7
6
8
from coriolis import constants
14
16
LOG = logging .getLogger (__name__ )
15
17
16
18
19
+ def _reorder_root_disk (volumes_info , root_device , os_type ):
20
+ """
21
+ Reorders volumes_info so that the root disk will always be the first volume
22
+
23
+ root_device is returned by the OSMount Tools as the root partition device
24
+ (i.e. /dev/vdd2 for linux).
25
+
26
+ For Linux, we need to strip the trailing digits
27
+ to get the actual disk device. After that, we convert the last letter of
28
+ the disk device name into the equivalent index by alphabetical order.
29
+
30
+ Windows OSMount Tools should directly return the root disk index extracted
31
+ from diskpart (as string; i.e. '1').
32
+
33
+ Reordering is done by swapping the indexes of the volumes_info list.
34
+ """
35
+ if not root_device :
36
+ LOG .warn ('os_root_dev was not returned by OSMount Tools. '
37
+ 'Skipping root disk reordering' )
38
+ return
39
+
40
+ # the default disk device of the migrated VM should be /dev/Xdb, because
41
+ # /dev/Xda should be the worker's root disk. Same for Windows: Disk 0
42
+ # should be the worker's root disk, and Disk 1 the migrated VM's root disk
43
+ linux_root_default = 'b'
44
+ windows_root_default = 1
45
+
46
+ supported_os_types = [constants .OS_TYPE_LINUX , constants .OS_TYPE_WINDOWS ]
47
+ if os_type == constants .OS_TYPE_LINUX :
48
+ pattern = r'[0-9]'
49
+ root_disk = re .sub (pattern , '' , root_device )
50
+ disk_index = ord (root_disk [- 1 ]) - ord (linux_root_default )
51
+ elif os_type == constants .OS_TYPE_WINDOWS :
52
+ disk_index = int (root_device ) - windows_root_default
53
+ else :
54
+ LOG .warn ('Root disk reordering only supported for %s. Got OS type: %s.'
55
+ 'Skipping root disk reordering' , supported_os_types , os_type )
56
+ return
57
+
58
+ if disk_index > 0 :
59
+ if disk_index < len (volumes_info ):
60
+ volumes_info [0 ], volumes_info [disk_index ] = (
61
+ volumes_info [disk_index ], volumes_info [0 ])
62
+ else :
63
+ LOG .warn ('Disk device name index out of range: %s for device %s'
64
+ 'Skipping root disk reordering' , disk_index , root_device )
65
+
66
+
67
+
17
68
class OSMorphingTask (base .TaskRunner ):
18
69
19
70
@classmethod
@@ -28,7 +79,7 @@ def get_required_task_info_properties(cls):
28
79
29
80
@classmethod
30
81
def get_returned_task_info_properties (cls ):
31
- return []
82
+ return ["instance_deployment_info" ]
32
83
33
84
@classmethod
34
85
def get_required_provider_types (cls ):
@@ -53,13 +104,14 @@ def _run(self, ctxt, instance, origin, destination, task_info,
53
104
osmorphing_connection_info = base .unmarshal_migr_conn_info (
54
105
task_info ['osmorphing_connection_info' ])
55
106
osmorphing_info = task_info .get ('osmorphing_info' , {})
107
+ instance_deployment_info = task_info .get ('instance_deployment_info' , {})
56
108
57
109
user_scripts = task_info .get ("user_scripts" )
110
+ os_type = osmorphing_info .get ("os_type" )
58
111
instance_script = None
59
112
if user_scripts :
60
113
instance_script = user_scripts .get ("instances" , {}).get (instance )
61
114
if not instance_script :
62
- os_type = osmorphing_info .get ("os_type" )
63
115
if os_type :
64
116
instance_script = user_scripts .get (
65
117
"global" , {}).get (os_type )
@@ -72,7 +124,14 @@ def _run(self, ctxt, instance, origin, destination, task_info,
72
124
instance_script ,
73
125
event_handler )
74
126
75
- return {}
127
+ volumes_info = instance_deployment_info .get ('volumes_info' , [])
128
+ LOG .debug ('Volumes info before root disk reordering: %s' , volumes_info )
129
+ _reorder_root_disk (volumes_info , osmorphing_info .get ('os_root_dev' ),
130
+ os_type )
131
+ LOG .debug ('Volumes info after root disk reordering: %s' , volumes_info )
132
+
133
+ return {
134
+ 'instance_deployment_info' : instance_deployment_info }
76
135
77
136
78
137
class DeployOSMorphingResourcesTask (base .TaskRunner ):
0 commit comments