From b4bcf1093a5b3810021fcb9748d4a95ddedb3c9b Mon Sep 17 00:00:00 2001
From: Davide Gardenal <davide.gardenal@huawei.com>
Date: Thu, 28 Jul 2022 10:27:12 +0200
Subject: [PATCH] upgrade_oniro: improve backup and restore

Now in the backup it's saved a metadata file containing
all the folders that have been backed up. This is used
when restoring it, in fact we need to delete those otherwise
added files in the upgrade are not deleted and we may end up
with an inconsistent build.

Signed-off-by: Davide Gardenal <davide.gardenal@huawei.com>
---
 scripts/upgrade_oniro/upgrade_oniro.py | 41 ++++++++++++++++++++++++--
 1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/scripts/upgrade_oniro/upgrade_oniro.py b/scripts/upgrade_oniro/upgrade_oniro.py
index 02809f89..cc8214fe 100644
--- a/scripts/upgrade_oniro/upgrade_oniro.py
+++ b/scripts/upgrade_oniro/upgrade_oniro.py
@@ -45,6 +45,8 @@
 
 import argparse
 import pathlib
+import tarfile
+import os
 
 script_description = "[WIP] A tool to upgrade to a newer version of Oniro"
 
@@ -58,6 +60,9 @@ conf_directory = pathlib.Path()
 dry_run = False
 store_backup = False
 
+# Global vars
+backup_archive_name = ""
+
 def init_script_options():
     parser = argparse.ArgumentParser(description=script_description)
 
@@ -112,8 +117,7 @@ def backup_oniro():
     # TODO add more verbose log
     from upgrade_oniro_utils import get_manifest_projects
     from datetime import datetime
-    import tarfile
-
+    
     backup_folders = [layer["path"] for layer in get_manifest_projects()] # add all manifest layers
     backup_folders.append(".repo")
     if build_directory.exists():
@@ -121,16 +125,44 @@ def backup_oniro():
             if child.is_dir() and "tmp" not in child.name and child.name != "downloads":
                 backup_folders.append(f"{build_directory.name}/{child.name}")
     
+    # Create a metadata file containing all the folders that have been backed up
+    with open("backup_folders", "w") as f:
+        for folder in backup_folders:
+            f.write(f"{folder}\n")
+
     archive_name = f"upgrade_oniro_backup-{datetime.timestamp(datetime.now())}.tar.gz"
     with tarfile.open(archive_name, "w:gz") as tar_archive:
+        tar_archive.add("backup_folders")
         for folder in backup_folders:
             tar_archive.add(folder)
             print(f"{folder} has been backed up")
     
+    # Remove the uncompressed copy of backup_folders
+    os.remove("backup_folders")
+
+    # Save the name of the backup for later use in the script
+    global backup_archive_name
+    backup_archive_name = archive_name
     return
 
 def restore_oniro():
-    # TODO
+    # TODO implement a way to scan the directory and find the latest backup
+    # TODO add a subcommand to restore oniro from a backup
+    import shutil
+    print(f"Restoring {backup_archive_name}")
+    with tarfile.open(backup_archive_name) as backup_archive:
+        # Extract the metadata file and delete all the old folders
+        backup_folders_file = backup_archive.extract("backup_folders")
+        with open("backup_folders") as bf:
+            for folder in bf.readlines():
+                shutil.rmtree(folder.strip())
+        # Restore the backed up folders
+        backup_archive.extractall(".")
+
+    # Remove the uncompressed copy of backup_folders
+    os.remove("backup_folders")
+
+    print(f"{backup_archive_name} successfully restored!")
     return
 
 def upgrade_oniro():
@@ -142,4 +174,7 @@ if __name__ == "__main__":
     upgrade_tool()
     perform_pre_upgrade_checks()
     backup_oniro()
+    with open("oe-core/test.txt", "w") as f:
+        f.write("sos")
+    restore_oniro()
     upgrade_oniro()
\ No newline at end of file
-- 
GitLab