Commit e61f3341 authored by Romain Courteaud's avatar Romain Courteaud Committed by Rafael Monnerat

slapos_upgrader: fixup instance virtual master migration

do not forget to also move the successor to the new virtual master
parent 3266b808
...@@ -9,11 +9,27 @@ instance_tree = context.getObject() ...@@ -9,11 +9,27 @@ instance_tree = context.getObject()
instance_tree_virtual_master = instance_tree.getFollowUpValue() instance_tree_virtual_master = instance_tree.getFollowUpValue()
instance_tree_virtual_master_relative_url = instance_tree_virtual_master.getRelativeUrl() instance_tree_virtual_master_relative_url = instance_tree_virtual_master.getRelativeUrl()
remote_virtual_master_dict = {} # Check recursively the instance tree
# and detect orphaned nodes
is_consistent = True is_orphaned_instance_dict = {}
for successor in instance_tree.getSuccessorList():
is_orphaned_instance_dict[successor] = False
for sql_result in portal.portal_catalog(specialise__uid=instance_tree.getUid()): for sql_result in portal.portal_catalog(specialise__uid=instance_tree.getUid()):
instance = sql_result.getObject() instance = sql_result.getObject()
if instance.getRelativeUrl() not in is_orphaned_instance_dict:
is_orphaned_instance_dict[instance.getRelativeUrl()] = True
for successor in instance.getSuccessorList():
is_orphaned_instance_dict[successor] = False
# Then, browser the roots, and stop as soon as one with a different virtual master is found
# all its successors will be moved to if needed
instance_to_check_list = [portal.restrictedTraverse(x) for x in is_orphaned_instance_dict if is_orphaned_instance_dict[x]]
instance_to_check_list.extend(instance_tree.getSuccessorValueList())
remote_virtual_master_dict = {}
while instance_to_check_list:
instance = instance_to_check_list.pop()
is_consistent = True
partition = instance.getAggregateValue() partition = instance.getAggregateValue()
if partition is not None: if partition is not None:
instance_virtual_master_relative_url = partition.getParentValue().getFollowUp(None) instance_virtual_master_relative_url = partition.getParentValue().getFollowUp(None)
...@@ -23,10 +39,14 @@ for sql_result in portal.portal_catalog(specialise__uid=instance_tree.getUid()): ...@@ -23,10 +39,14 @@ for sql_result in portal.portal_catalog(specialise__uid=instance_tree.getUid()):
remote_virtual_master_dict[instance_virtual_master_relative_url].append(instance.getRelativeUrl()) remote_virtual_master_dict[instance_virtual_master_relative_url].append(instance.getRelativeUrl())
is_consistent = False is_consistent = False
if not is_consistent: if is_consistent:
for instance_virtual_master_relative_url in remote_virtual_master_dict: # Check sub instances only if parent is ok
instance_tree_virtual_master.Project_checkSiteMigrationCreateRemoteNode( instance_to_check_list.extend(instance.getSuccessorValueList())
instance_virtual_master_relative_url,
remote_virtual_master_dict[instance_virtual_master_relative_url], # Trigger migration
activate_kw={'tag': tag, 'serialization_tag': tag, 'limit': 1} for instance_virtual_master_relative_url in remote_virtual_master_dict:
) instance_tree_virtual_master.Project_checkSiteMigrationCreateRemoteNode(
instance_virtual_master_relative_url,
remote_virtual_master_dict[instance_virtual_master_relative_url],
activate_kw={'tag': tag, 'serialization_tag': tag, 'limit': 1}
)
...@@ -18,8 +18,10 @@ try: ...@@ -18,8 +18,10 @@ try:
assert remote_partition.getFollowUp() == remote_node.getDestinationProject() assert remote_partition.getFollowUp() == remote_node.getDestinationProject()
except AssertionError: except AssertionError:
# Something wrong here, maybe the instance was already migrated # Something wrong here, maybe the instance was already migrated
return raise
tag = "%s_%s" % (script.id, instance.getUid())
activate_kw = {'tag': tag}
######################################################### #########################################################
# Move current instance to the remote node # Move current instance to the remote node
######################################################### #########################################################
...@@ -38,7 +40,7 @@ else: ...@@ -38,7 +40,7 @@ else:
raise NotImplementedError('Not supported instance type: %s' % instance.getPortalType()) raise NotImplementedError('Not supported instance type: %s' % instance.getPortalType())
portal.portal_workflow.doActionFor(instance, action='edit_action', comment="Migrated to a remote node") portal.portal_workflow.doActionFor(instance, action='edit_action', comment="Migrated to a remote node")
instance.edit(aggregate_value=new_partition) instance.edit(aggregate_value=new_partition, activate_kw=activate_kw)
assert new_partition.getSlapState() == 'busy' assert new_partition.getSlapState() == 'busy'
######################################################### #########################################################
...@@ -55,9 +57,10 @@ else: ...@@ -55,9 +57,10 @@ else:
# keep the previous allocation partition # keep the previous allocation partition
aggregate_value=remote_partition, aggregate_value=remote_partition,
# keep the original connection xml # keep the original connection xml
connection_xml=connection_xml connection_xml=connection_xml,
activate_kw=activate_kw
) )
instance.edit(connection_xml=connection_xml) instance.edit(connection_xml=connection_xml, activate_kw=activate_kw)
assert remote_partition.getSlapState() == 'busy' assert remote_partition.getSlapState() == 'busy'
# CDN compatibility # CDN compatibility
...@@ -75,21 +78,40 @@ else: ...@@ -75,21 +78,40 @@ else:
remote_instance_tree.edit( remote_instance_tree.edit(
successor_value=instance, successor_value=instance,
title=new_remote_title title=new_remote_title,
activate_kw=activate_kw
) )
instance.edit( instance.edit(
title=remote_instance_tree.getTitle(), title=remote_instance_tree.getTitle(),
specialise_value=remote_instance_tree, specialise_value=remote_instance_tree,
aggregate_value=remote_partition, aggregate_value=remote_partition,
follow_up_value=remote_instance_tree.getFollowUpValue() follow_up_value=remote_instance_tree.getFollowUpValue(),
activate_kw=activate_kw
) )
if original_predecessor is not None: if original_predecessor is not None:
original_predecessor.edit( original_predecessor.edit(
successor_list=successor_list successor_list=successor_list,
activate_kw=activate_kw
) )
requested_software_instance.edit( requested_software_instance.edit(
title=instance_title, title=instance_title,
specialise_value=instance_tree, specialise_value=instance_tree,
aggregate_value=new_partition, aggregate_value=new_partition,
follow_up_value=instance_tree.getFollowUpValue() follow_up_value=instance_tree.getFollowUpValue(),
activate_kw=activate_kw
) )
# Change the specialise value of all successors of the new instance tree
remote_successor_list = instance.getSuccessorValueList()
while remote_successor_list:
remote_successor = remote_successor_list.pop()
remote_successor_list.extend(remote_successor.getSuccessorValueList())
remote_successor.edit(
specialise_value=remote_instance_tree,
follow_up_value=remote_instance_tree.getFollowUpValue(),
activate_kw=activate_kw
)
# Trigger fixup of the newly instance tree if needed
# to continue cleaning up the remaining instances of the tree
remote_instance_tree.activate(after_tag=tag).InstanceTree_fixupSiteMigrationToVirtualMaster()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment