def switch_object(obj: Union[Host, ClusterObject], new_prototype: Prototype) -> None: """Upgrade object""" log.info('upgrade switch from %s to %s', proto_ref(obj.prototype), proto_ref(new_prototype)) old_prototype = obj.prototype obj.prototype = new_prototype obj.save() switch_config(obj, new_prototype, old_prototype)
def do_upgrade(obj: Union[Cluster, HostProvider], upgrade: Upgrade) -> dict: old_proto = obj.prototype check_license(obj.prototype.bundle) check_license(upgrade.bundle) ok, msg = check_upgrade(obj, upgrade) if not ok: return err('UPGRADE_ERROR', msg) log.info('upgrade %s version %s (upgrade #%s)', obj_ref(obj), old_proto.version, upgrade.id) if obj.prototype.type == 'cluster': new_proto = Prototype.objects.get(bundle=upgrade.bundle, type='cluster') elif obj.prototype.type == 'provider': new_proto = Prototype.objects.get(bundle=upgrade.bundle, type='provider') else: return err('UPGRADE_ERROR', 'can upgrade only cluster or host provider') with transaction.atomic(): obj.prototype = new_proto obj.before_upgrade['state'] = obj.state if upgrade.state_on_success: obj.state = upgrade.state_on_success obj.save() switch_config(obj, new_proto, old_proto) if obj.prototype.type == 'cluster': switch_services(upgrade, obj) elif obj.prototype.type == 'provider': switch_hosts(upgrade, obj) cm.issue.update_hierarchy_issues(obj) log.info('upgrade %s OK to version %s', obj_ref(obj), obj.prototype.version) cm.status_api.post_event( 'upgrade', obj.prototype.type, obj.id, 'version', str(obj.prototype.version) ) return {'id': obj.id, 'upgradable': bool(get_upgrade(obj))}
def test_non_active_group(self): proto1, proto2 = self.cook_proto() # Old config with activatable group "advance" self.add_conf( prototype=proto1, name='advance', type='group', limits={"activatable": True, "active": False}, ) self.add_conf(prototype=proto1, name='advance', subname='port', type='integer', default=11) # New config with the same activatable group "advance" self.add_conf( prototype=proto2, name='advance', type='group', limits={"activatable": True, "active": False}, ) self.add_conf(prototype=proto2, name='advance', subname='port', type='integer', default=11) cluster = cm.api.add_cluster(proto1, 'Cluster1') old_conf, old_attr = get_config(cluster) self.assertEqual(old_conf, {'advance': {'port': 11}}) self.assertEqual(old_attr, {'advance': {'active': False}}) # Ugrade adcm_config.switch_config(cluster, proto2, proto1) new_conf, new_attr = get_config(cluster) # Check that activatable but not active group does not disappear from new config self.assertEqual(new_conf, {'advance': {'port': 11}}) self.assertEqual(new_attr, {'advance': {'active': False}})
def do_upgrade(obj, upgrade): old_proto = obj.prototype check_license(obj.prototype.bundle) check_license(upgrade.bundle) ok, msg = check_upgrade(obj, upgrade) if not ok: return err('UPGRADE_ERROR', msg) log.info('upgrade %s version %s (upgrade #%s)', obj_ref(obj), old_proto.version, upgrade.id) if obj.prototype.type == 'cluster': new_proto = Prototype.objects.get(bundle=upgrade.bundle, type='cluster') elif obj.prototype.type == 'provider': new_proto = Prototype.objects.get(bundle=upgrade.bundle, type='provider') else: return err('UPGRADE_ERROR', 'can upgrade only cluster or host provider') with transaction.atomic(): obj.prototype = new_proto if upgrade.state_on_success: obj.state = upgrade.state_on_success obj.save() switch_config(obj, new_proto, old_proto) if obj.prototype.type == 'cluster': for p in Prototype.objects.filter(bundle=upgrade.bundle, type='service'): try: co = ClusterObject.objects.get(cluster=obj, prototype__name=p.name) switch_service(co, p) switch_components(obj, co, p) except ClusterObject.DoesNotExist: # co.delete() ?! pass switch_hc(obj, upgrade) elif obj.prototype.type == 'provider': for p in Prototype.objects.filter(bundle=upgrade.bundle, type='host'): for host in Host.objects.filter(provider=obj, prototype__name=p.name): switch_service(host, p) cm.issue.save_issue(obj) log.info('upgrade %s OK to version %s', obj_ref(obj), obj.prototype.version) cm.status_api.post_event('upgrade', obj.prototype.type, obj.id, 'version', str(obj.prototype.version)) return {'id': obj.id, 'upgradable': bool(get_upgrade(obj))}
def upgrade_adcm(adcm, bundle): old_proto = adcm.prototype new_proto = Prototype.objects.get(type='adcm', bundle=bundle) if rpm.compare_versions(old_proto.version, new_proto.version) >= 0: msg = 'Current adcm version {} is more than or equal to upgrade version {}' err('UPGRADE_ERROR', msg.format(old_proto.version, new_proto.version)) with transaction.atomic(): adcm.prototype = new_proto adcm.save() switch_config(adcm, new_proto, old_proto) log.info('upgrade adcm OK from version %s to %s', old_proto.version, adcm.prototype.version) return adcm
def test_from_active_group_to_not_active_group(self): """Scenario: * Create prototype1 with activatable group, active=False * Create prototype2 with activatable group, active=False * Create cluster from prototype1 * Update cluster config, activate group, set value * Update cluster config from prototype2 * Expect that the cluster configuration has not changed """ proto1, proto2 = self.cook_proto() self.add_conf(prototype=proto1, name='advance', type='group', limits={ "activatable": True, "active": False }) self.add_conf(prototype=proto1, name='advance', subname='port', type='integer', default=11) self.add_conf(prototype=proto2, name='advance', type='group', limits={ "activatable": True, "active": False }) self.add_conf(prototype=proto2, name='advance', subname='port', type='integer', default=22) cluster = cm.api.add_cluster(proto1, 'Cluster1') cm.api.update_obj_config(cluster.config, {'advance': { 'port': 33 }}, {'advance': { 'active': True }}) old_conf, old_attr = get_config(cluster) self.assertEqual(old_conf, {'advance': {'port': 33}}) self.assertEqual(old_attr, {'advance': {'active': True}}) adcm_config.switch_config(cluster, proto2, proto1) new_conf, new_attr = get_config(cluster) self.assertEqual(new_conf, {'advance': {'port': 33}}) self.assertEqual(new_attr, {'advance': {'active': True}})
def switch_components(cluster: Cluster, co: ClusterObject, new_co_proto: Prototype) -> None: """Upgrade components""" for sc in ServiceComponent.objects.filter(cluster=cluster, service=co): try: new_sc_prototype = Prototype.objects.get( parent=new_co_proto, type='component', name=sc.prototype.name ) old_sc_prototype = sc.prototype sc.prototype = new_sc_prototype sc.save() switch_config(sc, new_sc_prototype, old_sc_prototype) except Prototype.DoesNotExist: # sc.delete() ?! pass for sc_proto in Prototype.objects.filter(parent=new_co_proto, type='component'): kwargs = dict(cluster=cluster, service=co, prototype=sc_proto) if not ServiceComponent.objects.filter(**kwargs).exists(): sc = ServiceComponent.objects.create(**kwargs) make_object_config(sc, sc_proto)
def switch_service(co, new_proto): log.info('upgrade switch from %s to %s', proto_ref(co.prototype), proto_ref(new_proto)) switch_config(co, new_proto, co.prototype) co.prototype = new_proto co.save()