diff --git a/0029-Service-configuration-remains-after-migration.patch b/0029-Service-configuration-remains-after-migration.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ff3ed8fdad817a45201cbdd1c9a68b386c420f3 --- /dev/null +++ b/0029-Service-configuration-remains-after-migration.patch @@ -0,0 +1,255 @@ +From 26581abc7eac1dae5bd07380d26703d4f1e0439a Mon Sep 17 00:00:00 2001 +From: Weisson +Date: Thu, 1 Sep 2022 13:16:55 +0800 +Subject: [PATCH] Service configuration should remain the same after migration. + +--- + .../serviceconfigurationcollector/actor.py | 27 +++++ + .../serviceconfigurationsynchronizer/actor.py | 102 ++++++++++++++++++ + .../models/configurationsynchronization.py | 7 ++ + .../tags/configurationcollectionphase.py | 5 + + .../tags/configurationsynchronizationphase.py | 5 + + .../topics/configurationsynchronization.py | 5 + + .../el7toel8/workflows/inplace_upgrade.py | 26 +++++ + 7 files changed, 177 insertions(+) + create mode 100644 repos/system_upgrade/el7toel8/actors/serviceconfigurationcollector/actor.py + create mode 100644 repos/system_upgrade/el7toel8/actors/serviceconfigurationsynchronizer/actor.py + create mode 100644 repos/system_upgrade/el7toel8/models/configurationsynchronization.py + create mode 100644 repos/system_upgrade/el7toel8/tags/configurationcollectionphase.py + create mode 100644 repos/system_upgrade/el7toel8/tags/configurationsynchronizationphase.py + create mode 100644 repos/system_upgrade/el7toel8/topics/configurationsynchronization.py + +diff --git a/repos/system_upgrade/el7toel8/actors/serviceconfigurationcollector/actor.py b/repos/system_upgrade/el7toel8/actors/serviceconfigurationcollector/actor.py +new file mode 100644 +index 0000000..fbee732 +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/actors/serviceconfigurationcollector/actor.py +@@ -0,0 +1,27 @@ ++import subprocess ++import json ++ ++from leapp.actors import Actor ++from leapp.tags import ConfigurationCollectionPhaseTag, IPUWorkflowTag ++from leapp.models import ConfigurationSynchronization ++ ++ ++class ServiceConfigurationCollector(Actor): ++ """ ++ No documentation has been provided for the service_configuration_collector actor. ++ """ ++ ++ name = 'service_configuration_collector' ++ consumes = () ++ produces = (ConfigurationSynchronization, ) ++ tags = (ConfigurationCollectionPhaseTag, IPUWorkflowTag, ) ++ ++ def process(self): ++ self.log.info("Starting to backup service configurations.") ++ services_config_raw = subprocess.check_output("systemctl list-unit-files | egrep 'enabled|disabled'", shell=True).decode("utf-8").strip() ++ services_config = { ++ line.strip().split()[0]: line.strip().split()[1][:-1] ++ for line in services_config_raw.split('\n') ++ } ++ self.produce(ConfigurationSynchronization(services_configuration=json.dumps(services_config))) ++ +diff --git a/repos/system_upgrade/el7toel8/actors/serviceconfigurationsynchronizer/actor.py b/repos/system_upgrade/el7toel8/actors/serviceconfigurationsynchronizer/actor.py +new file mode 100644 +index 0000000..7856bea +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/actors/serviceconfigurationsynchronizer/actor.py +@@ -0,0 +1,102 @@ ++import json ++import subprocess ++ ++from leapp.actors import Actor ++from leapp.tags import ConfigurationSynchronizationPhaseTag, IPUWorkflowTag ++from leapp.models import ConfigurationSynchronization ++ ++ ++class ServiceConfigurationSynchronizer(Actor): ++ """ ++ No documentation has been provided for the service_configuration_synchronizer actor. ++ """ ++ ++ name = 'service_configuration_synchronizer' ++ consumes = (ConfigurationSynchronization, ) ++ produces = () ++ tags = (IPUWorkflowTag, ConfigurationSynchronizationPhaseTag, ) ++ ++ def service_configuration_backup(self): ++ try: ++ self.log.info("backing up service configurations after migration.") ++ services_config_raw = str(subprocess.check_output("systemctl list-unit-files | egrep 'enabled |disabled ' | awk '{print $1,$2}'")).strip() ++ services_config = { ++ line.strip().split()[0]: line.strip().split()[1][:-1] ++ for line in services_config_raw.split('\n') ++ } ++ ++ return services_config ++ except Exception as e: ++ self.log.warning(" fail to backup service, ignore it. " + str(e)) ++ ++ return {} ++ ++ def do_config_services(self, config): ++ config_report = [] ++ for service, status in config.items(): ++ self.log.info("".join((service, " -> ", status))) ++ report = { ++ "service": service, ++ "old status": status, ++ "current status": status, ++ } ++ ++ try: ++ print("systemctl %s %s" % (status, service)) ++ output = str(subprocess.check_call("systemctl %s %s" % (status, service), shell=True)).strip() ++ report.update({ ++ "information": output, ++ "result": "succeed" ++ }) ++ ++ except Exception as e: ++ self.log.warning("fail to %s %s" % (status, service)) ++ ++ report.update({ ++ "information": str(e), ++ "result": "fail", ++ }) ++ ++ config_report += [report] ++ ++ return config_report ++ ++ def config_services(self, config, backup): ++ _config_report = self.do_config_services(config) ++ ++ config_report = [] ++ for line in _config_report: ++ if line["result"] == "fail": ++ line["current status"] = backup.get(line["service"] , "does not exist") ++ ++ config_report += [line] ++ ++ return config_report ++ ++ def service_configuration_restore(self, backup_configuration): ++ try: ++ self.log.info("Starting to roll back services configurations.") ++ self.do_config_services(backup_configuration) ++ ++ except Exception as e: ++ self.log.warning("fail to roll back services configurations: " + str(e)) ++ self.log.warning("default service configuration : " + str(backup_configuration)) ++ with open("/var/log/leapp/service-default.log", "w") as f: ++ json.dump(str(backup_configuration), f, indent=4) ++ ++ def process(self): ++ backup_configuratuon = self.service_configuration_backup() ++ ++ try: ++ self.log.info("Starting to synchronize services configurations.") ++ for configuration in self.consume(ConfigurationSynchronization): ++ services_configuration = json.loads(configuration.services_configuration) ++ config_report = self.config_services(services_configuration, backup_configuratuon) ++ ++ with open("/var/log/leapp/service-configuration-report.json", "w") as f: ++ json.dump(config_report, f, indent=4) ++ print("Service configuration output: /var/log/leapp/service-configuration-report.json") ++ ++ except Exception as e: ++ self.log.warning("fail to synchronize services configurations, rolling back. " + str(e)) ++ +diff --git a/repos/system_upgrade/el7toel8/models/configurationsynchronization.py b/repos/system_upgrade/el7toel8/models/configurationsynchronization.py +new file mode 100644 +index 0000000..349ac3d +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/models/configurationsynchronization.py +@@ -0,0 +1,7 @@ ++from leapp.models import Model, fields ++from leapp.topics import ConfigurationSynchronizationTopic ++ ++class ConfigurationSynchronization(Model): ++ topic = ConfigurationSynchronizationTopic ++ services_configuration = fields.Nullable(fields.String()) ++ +diff --git a/repos/system_upgrade/el7toel8/tags/configurationcollectionphase.py b/repos/system_upgrade/el7toel8/tags/configurationcollectionphase.py +new file mode 100644 +index 0000000..a24ec82 +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/tags/configurationcollectionphase.py +@@ -0,0 +1,5 @@ ++from leapp.tags import Tag ++ ++ ++class ConfigurationCollectionPhaseTag(Tag): ++ name = 'configuration_collection_phase' +diff --git a/repos/system_upgrade/el7toel8/tags/configurationsynchronizationphase.py b/repos/system_upgrade/el7toel8/tags/configurationsynchronizationphase.py +new file mode 100644 +index 0000000..81610a8 +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/tags/configurationsynchronizationphase.py +@@ -0,0 +1,5 @@ ++from leapp.tags import Tag ++ ++ ++class ConfigurationSynchronizationPhaseTag(Tag): ++ name = 'configuration_synchronization_phase' +diff --git a/repos/system_upgrade/el7toel8/topics/configurationsynchronization.py b/repos/system_upgrade/el7toel8/topics/configurationsynchronization.py +new file mode 100644 +index 0000000..8d01b38 +--- /dev/null ++++ b/repos/system_upgrade/el7toel8/topics/configurationsynchronization.py +@@ -0,0 +1,5 @@ ++from leapp.topics import Topic ++ ++ ++class ConfigurationSynchronizationTopic(Topic): ++ name = 'configuration_synchronization' +diff --git a/repos/system_upgrade/el7toel8/workflows/inplace_upgrade.py b/repos/system_upgrade/el7toel8/workflows/inplace_upgrade.py +index 8e48d8c..c0dd27e 100644 +--- a/repos/system_upgrade/el7toel8/workflows/inplace_upgrade.py ++++ b/repos/system_upgrade/el7toel8/workflows/inplace_upgrade.py +@@ -16,6 +16,19 @@ class IPUWorkflow(Workflow): + configuration = IPUConfig + description = """The IPU workflow takes care of an in-place upgrade (IPU) of RHEL 7 to Anolis 8.""" + ++ class ConfigurationCollectionPhase(Phase): ++ """ ++ This phase and ConfigurationSynchronizationPhase must appear in pairs to ensure the configuration ++ before and after migration remains as similar as possible. ++ ++ This part is configuration collection phase. ++ """ ++ name = "ConfigurationCollection" ++ filter = TagFilter(tags.ConfigurationCollectionPhaseTag) ++ policies = Policies(Policies.Errors.FailPhase, ++ Policies.Retry.Phase) ++ flags = Flags() ++ + class FactsCollectionPhase(Phase): + """ + Get information (facts) about the system (e.g. installed packages, configuration, ...). +@@ -210,6 +223,19 @@ class IPUWorkflow(Workflow): + Policies.Retry.Phase) + flags = Flags(restart_after_phase=True) + ++ class ConfigurationSynchronizationPhase(Phase): ++ """ ++ This phase and ConfigurationCollectionPhase must appear in pairs to ensure the configuration ++ before and after migration remains as similar as possible. ++ ++ This part is configuration Synchronization phase. ++ """ ++ name = "ConfigurationSynchronization" ++ filter = TagFilter(tags.ConfigurationSynchronizationPhaseTag) ++ policies = Policies(Policies.Errors.FailPhase, ++ Policies.Retry.Phase) ++ flags = Flags() ++ + class FirstBootPhase(Phase): + """Actions to be done right after booting into the upgraded system.""" + +-- +2.31.1 + diff --git a/leapp-repository.spec b/leapp-repository.spec index b3a84591df049bb3b9c8cb42507b90ec8e348132..9b3bbf406aedbd3baa4dc46f358229620dcb3eea 100644 --- a/leapp-repository.spec +++ b/leapp-repository.spec @@ -11,7 +11,7 @@ }\ py2_byte_compile "%1" "%2"} -%define anolis_release 4 +%define anolis_release 5 Name: leapp-repository Version: 0.13.0 @@ -54,6 +54,7 @@ Patch25: 0025-add-check-openssl11-libs.patch Patch26: 0026-Add-checkbaota-actor.patch Patch27: 0027-upgrade-write-efi-vars-for-ecs-firmware.patch Patch28: 0028-support-upgrade-kernel-to-ANCK.patch +Patch29: 0029-Service-configuration-remains-after-migration.patch BuildArch: noarch BuildRequires: python-devel @@ -176,6 +177,9 @@ done; # no files here %changelog +* Tue Sep 6 2022 Weisson - 0.13.0-2.5 +- Service configuration remains after migration + * Tue Sep 6 2022 mgb01105731 - 0.13.0-2.4 - support upgrade kernel to ANCK