Added error handling for failures during the TAC (#262)
author최종헌/Common Platform Lab(SR)/Engineer/삼성전자 <j-h.choi@samsung.com>
Tue, 18 Aug 2020 07:53:27 +0000 (16:53 +0900)
committer이형주/Common Platform Lab(SR)/Staff Engineer/삼성전자 <leee.lee@samsung.com>
Tue, 18 Aug 2020 07:53:27 +0000 (16:53 +0900)
Change-Id: I723505929933af4132666f42db27d4dac16b6d9a

NativeLauncher/inc/ni_common.h
NativeLauncher/installer-plugin/prefer_nuget_cache_plugin.cc
NativeLauncher/tool/ni_common.cc

index 2b00a6f..bdaba44 100644 (file)
@@ -79,7 +79,7 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags);
  * @param[i] flags additional flags for the image generator
  * @return ni_error_e
  */
-ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags);
+ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags);
 
 /**
  * @brief create native images for all DLLs in a package
@@ -98,7 +98,7 @@ void removeNIPlatform();
  * @brief remove native images under directories
  * @param[i] rootPaths paths to directories
  */
-void removeNIUnderDirs(const std::string rootPaths);
+void removeNIUnderDirs(const std::string& rootPaths);
 
 /**
  * @brief remove native images of a package
index 0a20793..b1f18f3 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <cstring>
 #include <fstream>
+#include <regex>
 #include <sstream>
 #include <vector>
 #include <boost/filesystem.hpp>
@@ -101,14 +102,10 @@ static bool compareSHA256Info(std::string sha256Info, std::string nugetPackage)
        return false;
 }
 
-static int copyAssemblyCreateSymlink(std::string binPath, std::string tacVersionDir, std::string nugetPackage, bool isCreateTacDir)
+static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, std::string nugetPackage, bool isCreateTacDir)
 {
-       std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
-       if (!createDir(tac_dir)) {
-               _ERR("Cannot create directory: %s", tac_dir.c_str());
-               return -1;
-       }
-
+       std::string tac_version_dir = concatPath(__DOTNET_DIR, nugetPackage);
+       bool nuget_restoration = false;
        for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
                std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
                std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
@@ -116,20 +113,36 @@ static int copyAssemblyCreateSymlink(std::string binPath, std::string tacVersion
                if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
                        if (bf::exists(concatPath(binPath, assembly))) {
                                if (isCreateTacDir) {
-                                       if (!copyFile(concatPath(binPath, assembly), concatPath(tacVersionDir, assembly))) {
+                                       if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) {
                                                _ERR("Failed to copy of %s", assembly.c_str());
-                                               return -1;
+                                               nuget_restoration = true;
+                                               break;
                                        }
                                }
-                               bf::create_symlink(concatPath(tacVersionDir, assembly), concatPath(tac_dir, assembly));
+                               bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tacDir, assembly));
+
                                if (!removeFile(concatPath(binPath, assembly))) {
                                        _ERR("Failed to remove of %s", assembly.c_str());
-                                       return -1;
+                                       nuget_restoration = true;
+                                       break;
                                }
                        }
                }
        }
-       return 0;
+
+       if (nuget_restoration) {
+               for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+                       std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
+                       std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
+                       std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
+                       if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
+                               copyFile(concatPath(tac_version_dir, assembly), concatPath(binPath, assembly));
+                               removeFile(concatPath(tacDir, assembly));
+                       }
+               }
+       }
+
+       return nuget_restoration;
 }
 
 static void copyLibraryCreateSymlink(const char* pkgId, std::vector<std::string> LibrariesInfo, std::string tlcDir)
@@ -221,23 +234,29 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
        }
 
        status = "install";
+       if (tacDB.empty()) {
+               _INFO("Not exist data for TAC in %s", pkgId);
+               return 0;
+       }
+
        tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
        if (!tac_db) {
                _ERR("Sqlite create error. So restore the database.");
                if (tac_restoreDB() != TAC_ERROR_NONE) {
                        _ERR("Sqlite create error");
-                       return 0;
+                       return -1;
                }
                tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
                if (!tac_db) {
                        _ERR("Sqlite create error");
-                       return 0;
+                       return -1;
                }
        }
        sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
 
-       if (tacDB.empty()) {
-               _INFO("Not exist data for TAC in %s", pkgId);
+       std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
+       if (!createDir(tac_dir)) {
+               _ERR("Cannot create directory: %s", tac_dir.c_str());
                return 0;
        }
 
@@ -253,53 +272,69 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                        _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
                        if (!createDir(tac_version_dir)) {
                                _ERR("Cannot create directory: %s", tac_version_dir.c_str());
-                               return 0;
+                               status = "restore";
+                               return -1;
                        }
                        createDirectories.push_back(tac_version_dir);
                        if (!bf::is_symlink(sha256_info)) {
                                createSHA256Info(sha256_info, np);
                        } else {
                                _ERR("Failed to create sha256_info. Symbolic link is detected");
+                               status = "restore";
+                               return -1;
+                       }
+
+                       if (!bf::exists(sha256_info)) {
+                               status = "restore";
                                return -1;
                        }
 
-                       if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, true) < 0) {
+                       if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) {
                                _ERR("Failed to create symlink");
+                               status = "restore";
                                return -1;
                        }
 
                        char *sql = sqlite3_mprintf(
                                "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
                                "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
-                       insertDB(tac_db, sql);
+                       if (!insertDB(tac_db, sql)) {
+                               _ERR("Sqlite insert error");
+                               sqlite3_free(sql);
+                               status = "restore";
+                               return -1;
+                       }
                        sqlite3_free(sql);
                } else {
                        _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
                        if (!bf::is_symlink(sha256_info)) {
                                if (compareSHA256Info(sha256_info, np)) {
-                                       if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, false) < 0) {
+                                       if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) {
                                                _ERR("Failed to create symlink");
+                                               status = "restore";
                                                return -1;
                                        }
 
                                        char *sql = sqlite3_mprintf(
                                                "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
                                                "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
-                                       insertDB(tac_db, sql);
+                                       if (!insertDB(tac_db, sql)) {
+                                               _ERR("Sqlite insert error");
+                                               sqlite3_free(sql);
+                                               status = "restore";
+                                               return -1;
+                                       }
                                        sqlite3_free(sql);
                                } else {
                                        _INFO("Different nuget : %s", np.c_str());
+                                       continue;
                                }
                        } else {
                                _ERR("Failed to create sha256_info. Symbolic link is detected");
+                               status = "restore";
                                return -1;
                        }
                }
-               if (!bf::exists(sha256_info)) {
-                       if (!removeAll(tac_version_dir)) {
-                               _ERR("Failed to remove of %s", tac_version_dir.c_str());
-                       }
-               }
        }
 
        ///// TLC /////
@@ -336,7 +371,7 @@ static int sqliteCb(void *count, int argc, char **argv, char **colName)
        return 0;
 }
 
-static int tac_updateDB(sqlite3 *sqlite)
+static void tac_updateDB(sqlite3 *sqlite)
 {
        for (auto& unp : updateTac) {
                int count = -1;
@@ -345,7 +380,7 @@ static int tac_updateDB(sqlite3 *sqlite)
                if (ret != SQLITE_OK) {
                        _ERR("Sqlite select error");
                        sqlite3_free(sql);
-                       return -1;
+                       continue;
                }
                if (count == 0) {
                        std::string tac_version_dir_prev = concatPath(__DOTNET_DIR, unp);
@@ -353,17 +388,16 @@ static int tac_updateDB(sqlite3 *sqlite)
                        if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
                                _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
                                sqlite3_free(sql);
-                               return -1;
+                               continue;
                        }
                        if (!removeAll(tac_version_dir_prev)) {
                                _ERR("Failed to remove of %s", tac_version_dir_prev.c_str());
                                sqlite3_free(sql);
-                               return -1;
+                               continue;
                        }
                }
                sqlite3_free(sql);
        }
-       return 0;
 }
 
 static void tlc_updateDB(sqlite3 *sqlite, std::vector<std::string> updateTlc, std::string tlcDir)
@@ -437,12 +471,12 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                _ERR("Sqlite create error. So restore the database.");
                if (tac_restoreDB() != TAC_ERROR_NONE) {
                        _ERR("Sqlite create error");
-                       return 0;
+                       return -1;
                }
                tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
                if (!tac_db) {
                        _ERR("Sqlite create error");
-                       return 0;
+                       return -1;
                }
        }
        sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
@@ -454,14 +488,24 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
        bool skipTLC = false;
        if (tacDB.empty()) {
                sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId);
-               deleteDB(tac_db, sql);
-               sqlite3_free(sql);
-               if (tac_updateDB(tac_db) < 0) {
+               if (!deleteDB(tac_db, sql)) {
+                       _ERR("Sqlite delete error");
+                       sqlite3_free(sql);
                        return -1;
                }
+               sqlite3_free(sql);
+
+               tac_updateDB(tac_db);
+
                skipTLC = true;
                _INFO("Not exist data for TAC in %s", pkgId);
        } else {
+               std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
+               if (!createDir(tac_dir)) {
+                       _ERR("Cannot create directory: %s", tac_dir.c_str());
+                       return 0;
+               }
+
                for (auto& np : tacDB) {
                        std::string tac_name = np.substr(0, np.find('/'));
                        std::string tac_version = np.substr(np.rfind('/') + 1);
@@ -474,18 +518,26 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
                                if (!createDir(tac_version_dir)) {
                                        _ERR("Cannot create directory: %s", tac_version_dir.c_str());
-                                       return 0;
+                                       status = "restore";
+                                       return -1;
                                }
                                createDirectories.push_back(tac_version_dir);
                                if (!bf::is_symlink(sha256_info)) {
                                        createSHA256Info(sha256_info, np);
                                } else {
                                        _ERR("Failed to create sha256_info. Symbolic link is detected");
+                                       status = "restore";
+                                       return -1;
+                               }
+
+                               if (!bf::exists(sha256_info)) {
+                                       status = "restore";
                                        return -1;
                                }
 
-                               if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, true) < 0) {
+                               if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) {
                                        _ERR("Failed to create symlink");
+                                       status = "restore";
                                        return -1;
                                }
 
@@ -496,6 +548,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                if (ret != SQLITE_OK) {
                                        _ERR("Sqlite select error");
                                        sqlite3_free(sql);
+                                       status = "restore";
                                        return -1;
                                }
                                sqlite3_free(sql);
@@ -503,21 +556,32 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                        sql = sqlite3_mprintf(
                                                "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
                                                tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str());
-                                       updateDB(tac_db, sql);
+                                       if (!updateDB(tac_db, sql)) {
+                                               _ERR("Sqlite update error");
+                                               sqlite3_free(sql);
+                                               status = "restore";
+                                               return -1;
+                                       }
                                        sqlite3_free(sql);
                                } else if (count == 0) {
                                        sql = sqlite3_mprintf(
                                                "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
                                                "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
-                                       insertDB(tac_db, sql);
+                                       if (!insertDB(tac_db, sql)) {
+                                               _ERR("Sqlite insert error");
+                                               sqlite3_free(sql);
+                                               status = "restore";
+                                               return -1;
+                                       }
                                        sqlite3_free(sql);
                                }
                        } else {
                                _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
                                if (!bf::is_symlink(sha256_info)) {
                                        if (compareSHA256Info(sha256_info, np)) {
-                                               if (copyAssemblyCreateSymlink(binPath, tac_version_dir, np, false) < 0) {
+                                               if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) {
                                                        _ERR("Failed to create symlink");
+                                                       status = "restore";
                                                        return -1;
                                                }
 
@@ -528,6 +592,7 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                                if (ret != SQLITE_OK) {
                                                        _ERR("Sqlite select error");
                                                        sqlite3_free(sql);
+                                                       status = "restore";
                                                        return -1;
                                                }
                                                sqlite3_free(sql);
@@ -535,28 +600,35 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                                        sql = sqlite3_mprintf(
                                                                "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
                                                                tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str());
-                                                       updateDB(tac_db, sql);
+                                                       if (!updateDB(tac_db, sql)) {
+                                                               _ERR("Sqlite update error");
+                                                               sqlite3_free(sql);
+                                                               status = "restore";
+                                                               return -1;
+                                                       }
                                                        sqlite3_free(sql);
                                                } else if (count == 0) {
                                                        sql = sqlite3_mprintf(
                                                                "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
                                                                "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
-                                                       insertDB(tac_db, sql);
+                                                       if (!insertDB(tac_db, sql)) {
+                                                               _ERR("Sqlite insert error");
+                                                               sqlite3_free(sql);
+                                                               status = "restore";
+                                                               return -1;
+                                                       }
                                                        sqlite3_free(sql);
                                                }
                                        } else {
                                                _INFO("Different nuget : %s", np.c_str());
+                                               continue;
                                        }
                                } else {
                                        _ERR("Failed to create sha256_info. Symbolic link is detected");
+                                       status = "restore";
                                        return -1;
                                }
                        }
-                       if (!bf::exists(sha256_info)) {
-                               if (!removeAll(tac_version_dir)) {
-                                       _ERR("Failed to remove of %s", tac_version_dir.c_str());
-                               }
-                       }
                }
                for (auto& unp : updateTac) {
                        bool isExits = false;
@@ -568,13 +640,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                        }
                        if (!isExits) {
                                char *sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q AND NUGET = %Q;", pkgId, unp.c_str());
-                               deleteDB(tac_db, sql);
+                               if (!deleteDB(tac_db, sql)) {
+                                       _ERR("Sqlite delete error");
+                                       sqlite3_free(sql);
+                                       status = "restore";
+                                       return -1;
+                               }
                                sqlite3_free(sql);
                        }
                }
-               if (tac_updateDB(tac_db) < 0) {
-                       return -1;
-               }
+               tac_updateDB(tac_db);
        }
 
        ///// TLC /////
@@ -604,12 +679,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
        sqlite3_free(sql);
 
        sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId);
-       deleteDB(tlc_db, sql);
+       if (!deleteDB(tlc_db, sql)) {
+               _ERR("Sqlite delete error");
+               sqlite3_free(sql);
+               return 0;
+       }
        sqlite3_free(sql);
 
-       std::vector<std::string> librariesInfo = getLibrariesInfo(rootPath);
-       if (skipTLC) {
-               librariesInfo.clear();
+       std::vector<std::string> librariesInfo;
+       if (!skipTLC) {
+               librariesInfo = getLibrariesInfo(rootPath);
        }
 
        copyLibraryCreateSymlink(pkgId, librariesInfo, tlcDir);
@@ -637,12 +716,12 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a
                _ERR("Sqlite open error. So restore the database.");
                if (tac_restoreDB() != TAC_ERROR_NONE) {
                        _ERR("Sqlite open error");
-                       return 0;
+                       return -1;
                }
                tac_db = openDB(TAC_APP_LIST_DB);
                if (!tac_db) {
                        _ERR("Sqlite open error");
-                       return 0;
+                       return -1;
                }
        }
        sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
@@ -652,12 +731,16 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a
        sqlite3_free(sql);
 
        sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId);
-       deleteDB(tac_db, sql);
-       sqlite3_free(sql);
 
-       if (tac_updateDB(tac_db) < 0) {
+       if (!deleteDB(tac_db, sql)) {
+               _ERR("Sqlite delete error");
+               sqlite3_free(sql);
+               status = "restore";
                return -1;
        }
+       sqlite3_free(sql);
+
+       tac_updateDB(tac_db);
 
        ///// TLC /////
        tlc_db = openDB(TLC_APP_LIST_DB);
@@ -680,7 +763,11 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a
        sqlite3_free(sql);
 
        sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId);
-       deleteDB(tlc_db, sql);
+       if (!deleteDB(tlc_db, sql)) {
+               _ERR("Sqlite delete error");
+               sqlite3_free(sql);
+               return 0;
+       }
        sqlite3_free(sql);
 
        tlc_updateDB(tlc_db, updateTlc, concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR));
@@ -698,33 +785,19 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_REMOVED(const char *pkgId, const char *app
        return PKGMGR_MDPARSER_PLUGIN_UPGRADE(pkgId, appId, list);
 }
 
-void cleanStep(std::string tac)
+void undoStep(std::string tac)
 {
        std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
        try {
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
                        std::string bck_path = bck.path().string();
                        if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
-                               if (!removeAll(bck_path)) {
-                                       _ERR("Failed to remove of %s", bck_path.c_str());
+                               if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) {
+                                       _ERR("Failed to move %s", bck_path.c_str());
                                }
                                break;
                        }
                }
-
-               bool isExist = false;
-               for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
-                       std::string bck_path = bck.path().string();
-                       if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) {
-                               isExist = true;
-                               break;
-                       }
-               }
-               if (!isExist) {
-                       if (!removeAll(current_tac)) {
-                               _ERR("Failed to remove of %s", current_tac.c_str());
-                       }
-               }
        } catch (const bf::filesystem_error& error) {
                _ERR("Failed to recursive directory: %s", error.what());
                return;
@@ -733,8 +806,8 @@ void cleanStep(std::string tac)
        ///// TLC /////
        auto convert = [](const std::string& path, const std::string& filename) {
                if (filename.rfind(".bck") != std::string::npos) {
-                       if (!removeFile(path)) {
-                               _ERR("Failed to remove of %s", path.c_str());
+                       if (!moveFile(path, replaceAll(path, ".bck", ""))) {
+                               _ERR("Failed to move %s", path.c_str());
                        }
                }
        };
@@ -742,74 +815,101 @@ void cleanStep(std::string tac)
        scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0);
 }
 
-void install_Clean()
+void install_Undo()
 {
-       return;
+       for (auto& cd : createDirectories) {
+               if (!removeAll(cd)) {
+                       _ERR("Failed to remove of %s", cd.c_str());
+               }
+       }
+
+       for (auto& cl : createLibraries) {
+               if (!removeFile(cl)) {
+                       _ERR("Failed to remove of %s", cl.c_str());
+               }
+       }
 }
 
-void unInstall_Clean()
+void unInstall_Undo()
 {
        for (auto& unp : updateTac) {
-               cleanStep(unp);
+               undoStep(unp);
        }
 }
 
-void update_Clean()
+void update_Undo()
 {
+       install_Undo();
        if (!tacDB.empty()) {
                for (auto& np : tacDB) {
-                       cleanStep(np);
+                       undoStep(np);
                }
        }
-       unInstall_Clean();
+       unInstall_Undo();
 }
 
-extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list)
+extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list)
 {
-       _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]");
+       _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
        _INFO("PackageID : %s", pkgId);
 
        // Can be multiple apps in one package
        if (tacPluginFinished) {
-               _INFO("TAC plugin already finished(CLEAN)");
+               _INFO("TAC plugin already finished(UNDO)");
                return 0;
        }
        tacPluginFinished = true;
 
        if (!strcmp("install", status.c_str())) {
-               install_Clean();
+               install_Undo();
        } else if (!strcmp("update", status.c_str())) {
-               update_Clean();
+               update_Undo();
        } else if (!strcmp("uninstall", status.c_str())) {
-               unInstall_Clean();
+               unInstall_Undo();
+       } else if (!strcmp("restore", status.c_str())) {
+               update_Undo();
        }
 
        if (tac_db) {
-               closeDB(tac_db);
+               rollbackDB(tac_db);
                tac_db = NULL;
        }
 
        if (tlc_db) {
-               closeDB(tlc_db);
+               rollbackDB(tlc_db);
                tlc_db = NULL;
        }
 
        return 0;
 }
 
-void undoStep(std::string tac)
+void cleanStep(std::string tac)
 {
        std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
        try {
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
                        std::string bck_path = bck.path().string();
                        if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
-                               if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) {
-                                       _ERR("Failed to move %s", bck_path.c_str());
+                               if (!removeAll(bck_path)) {
+                                       _ERR("Failed to remove of %s", bck_path.c_str());
                                }
                                break;
                        }
                }
+
+               bool isExist = false;
+               for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
+                       std::string bck_path = bck.path().string();
+                       if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) {
+                               isExist = true;
+                               break;
+                       }
+               }
+               if (!isExist) {
+                       if (!removeAll(current_tac)) {
+                               _ERR("Failed to remove of %s", current_tac.c_str());
+                       }
+               }
        } catch (const bf::filesystem_error& error) {
                _ERR("Failed to recursive directory: %s", error.what());
                return;
@@ -818,8 +918,8 @@ void undoStep(std::string tac)
        ///// TLC /////
        auto convert = [](const std::string& path, const std::string& filename) {
                if (filename.rfind(".bck") != std::string::npos) {
-                       if (!moveFile(path, replaceAll(path, ".bck", ""))) {
-                               _ERR("Failed to move %s", path.c_str());
+                       if (!removeFile(path)) {
+                               _ERR("Failed to remove of %s", path.c_str());
                        }
                }
        };
@@ -827,66 +927,90 @@ void undoStep(std::string tac)
        scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0);
 }
 
-void install_Undo()
+void install_Clean()
 {
-       for (auto& cd : createDirectories) {
-               if (!removeAll(cd)) {
-                       _ERR("Failed to remove of %s", cd.c_str());
-               }
-       }
-
-       for (auto& cl : createLibraries) {
-               if (!removeFile(cl)) {
-                       _ERR("Failed to remove of %s", cl.c_str());
-               }
-       }
+       return;
 }
 
-void unInstall_Undo()
+void unInstall_Clean()
 {
        for (auto& unp : updateTac) {
-               undoStep(unp);
+               cleanStep(unp);
        }
 }
 
-void update_Undo()
+void update_Clean()
 {
-       install_Undo();
        if (!tacDB.empty()) {
                for (auto& np : tacDB) {
-                       undoStep(np);
+                       cleanStep(np);
                }
        }
-       unInstall_Undo();
+       unInstall_Clean();
 }
 
-extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list)
+extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list)
 {
-       _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
+       if (!strcmp("restore", status.c_str())) {
+               disableTACPackage(pkgId);
+
+               std::string rootPath = getRootPath(std::string(pkgId));
+               if (!rootPath.empty()) {
+                       std::string binPath = concatPath(rootPath, "bin");
+                       removeAll(concatPath(binPath, TAC_SYMLINK_SUB_DIR));
+               }
+
+               std::string runtimesDir = concatPath(rootPath, "bin/runtimes");
+               if (bf::exists(runtimesDir)) {
+                       char buffer[128];
+                       sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER);
+                       std::regex pattern(buffer);
+
+                       try {
+                               for (auto& path : bf::recursive_directory_iterator(runtimesDir)) {
+                                       std::string symPath = path.path().string();
+                                       if (isDirectory(symPath) || !bf::is_symlink(symPath))
+                                               continue;
+                                       std::string targetDir = symPath.substr(symPath.rfind("/runtimes/") + 10);
+                                       if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern))
+                                               continue;
+                                       if (symPath.rfind(".so") == std::string::npos)
+                                               continue;
+                                       copyFile(bf::read_symlink(symPath).string(), symPath);
+                               }
+                       } catch (const bf::filesystem_error& error) {
+                               _ERR("Failed to recursive directory: %s", error.what());
+                       }
+               }
+
+               return PKGMGR_MDPARSER_PLUGIN_UNDO(pkgId, appId, list);
+       }
+
+       _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]");
        _INFO("PackageID : %s", pkgId);
 
        // Can be multiple apps in one package
        if (tacPluginFinished) {
-               _INFO("TAC plugin already finished(UNDO)");
+               _INFO("TAC plugin already finished(CLEAN)");
                return 0;
        }
        tacPluginFinished = true;
 
        if (!strcmp("install", status.c_str())) {
-               install_Undo();
+               install_Clean();
        } else if (!strcmp("update", status.c_str())) {
-               update_Undo();
+               update_Clean();
        } else if (!strcmp("uninstall", status.c_str())) {
-               unInstall_Undo();
+               unInstall_Clean();
        }
 
        if (tac_db) {
-               rollbackDB(tac_db);
+               closeDB(tac_db);
                tac_db = NULL;
        }
 
        if (tlc_db) {
-               rollbackDB(tlc_db);
+               closeDB(tlc_db);
                tlc_db = NULL;
        }
 
index cabb813..59a32d6 100644 (file)
@@ -529,7 +529,7 @@ ni_error_e createNIDll(const std::string& dllPath, DWORD flags)
        return crossgen(dllPath, std::string(), flags);
 }
 
-ni_error_e createNIUnderDirs(const std::string rootPaths, DWORD flags)
+ni_error_e createNIUnderDirs(const std::string& rootPaths, DWORD flags)
 {
        if (!isCoreLibPrepared(flags)) {
                return NI_ERROR_CORE_NI_FILE;
@@ -639,7 +639,7 @@ void removeNIPlatform()
        removeNIUnderDirs(__pm->getRuntimePath() + ":" + __pm->getTizenFXPath());
 }
 
-void removeNIUnderDirs(const std::string rootPaths)
+void removeNIUnderDirs(const std::string& rootPaths)
 {
        auto convert = [](const std::string& path, const std::string& filename) {
                if (isNativeImage(path)) {