11# Copyright 2016 Cloudbase Solutions Srl
22# All Rights Reserved.
33
4+ import re
5+
46from oslo_log import log as logging
57
68from coriolis import constants
1416LOG = logging .getLogger (__name__ )
1517
1618
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+
1768class OSMorphingTask (base .TaskRunner ):
1869
1970 @classmethod
@@ -28,7 +79,7 @@ def get_required_task_info_properties(cls):
2879
2980 @classmethod
3081 def get_returned_task_info_properties (cls ):
31- return []
82+ return ["instance_deployment_info" ]
3283
3384 @classmethod
3485 def get_required_provider_types (cls ):
@@ -53,13 +104,14 @@ def _run(self, ctxt, instance, origin, destination, task_info,
53104 osmorphing_connection_info = base .unmarshal_migr_conn_info (
54105 task_info ['osmorphing_connection_info' ])
55106 osmorphing_info = task_info .get ('osmorphing_info' , {})
107+ instance_deployment_info = task_info .get ('instance_deployment_info' , {})
56108
57109 user_scripts = task_info .get ("user_scripts" )
110+ os_type = osmorphing_info .get ("os_type" )
58111 instance_script = None
59112 if user_scripts :
60113 instance_script = user_scripts .get ("instances" , {}).get (instance )
61114 if not instance_script :
62- os_type = osmorphing_info .get ("os_type" )
63115 if os_type :
64116 instance_script = user_scripts .get (
65117 "global" , {}).get (os_type )
@@ -72,7 +124,14 @@ def _run(self, ctxt, instance, origin, destination, task_info,
72124 instance_script ,
73125 event_handler )
74126
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 }
76135
77136
78137class DeployOSMorphingResourcesTask (base .TaskRunner ):
0 commit comments