Support legacy image for backward-compatibility 25/107125/15
authorjongmyeongko <jongmyeong.ko@samsung.com>
Mon, 26 Dec 2016 16:10:26 +0000 (01:10 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Thu, 5 Jan 2017 11:29:49 +0000 (20:29 +0900)
Refer to:
https://review.tizen.org/gerrit/#/c/104823/

Change-Id: Iecd555fc211e9b5f85df51d4effdeea525af43d3
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
src/tpk/tpk_installer.cc
src/tpk/tpk_installer.h
src/unit_tests/smoke_test.cc
src/unit_tests/test_samples/smoke/InstallExternal_Tpk.tpk [new file with mode: 0644]
src/unit_tests/test_samples/smoke/InstallExternal_Tpk_2.tpk [new file with mode: 0644]
src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db [new file with mode: 0644]
src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp28 [new file with mode: 0644]

index 3c71f8c..7530641 100644 (file)
@@ -26,6 +26,7 @@
 #include <common/step/filesystem/step_delta_patch.h>
 #include <common/step/filesystem/step_disable_external_mount.h>
 #include <common/step/filesystem/step_enable_external_mount.h>
+#include <common/step/filesystem/step_migrate_legacy_external_image.h>
 #include <common/step/filesystem/step_move_installed_storage.h>
 #include <common/step/filesystem/step_recover_change_owner.h>
 #include <common/step/filesystem/step_recover_files.h>
@@ -160,6 +161,9 @@ void TpkInstaller::Prepare() {
     case ci::RequestType::DisablePkg:
       DisablePkgSteps();
       break;
+    case ci::RequestType::MigrateExtImg:
+      MigrateLegacyExtImageSteps();
+      break;
     default:
       AddStep<ci::configuration::StepFail>();
       break;
@@ -638,4 +642,10 @@ void TpkInstaller::EnablePkgSteps() {
     ci::Plugin::ActionType::Install);
 }
 
+void TpkInstaller::MigrateLegacyExtImageSteps() {
+  AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+  AddStep<ci::security::StepMigrateLegacyExtImage>();
+  AddStep<ci::filesystem::StepChangeOwnershipAndPermission>();
+}
+
 }  // namespace tpk
index 198e6ad..55b8d66 100644 (file)
@@ -48,6 +48,7 @@ class TPK_BACKEND_EXPORT_API TpkInstaller
   void ReadonlyUpdateInstallSteps();
   void ReadonlyUpdateUninstallSteps();
   void ClearSteps();
+  void MigrateLegacyExtImageSteps();
 
   SCOPE_LOG_TAG(TpkInstaller)
 };
index ca7e56c..d7fc48f 100644 (file)
@@ -23,6 +23,8 @@
 #include <signal.h>
 #include <unistd.h>
 #include <tzplatform_config.h>
+#include <vconf.h>
+#include <vconf-internal-keys.h>
 
 #include <array>
 #include <cstdio>
@@ -42,15 +44,18 @@ namespace {
 
 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
 const uid_t kGlobalUserGid = tzplatform_getgid(TZ_SYS_GLOBALAPP_USER);
+const uid_t kDefaultUserUid = tzplatform_getuid(TZ_SYS_DEFAULT_USER);
 // TODO(s89.jang): Test local case also
 const uid_t kTestUserId = kGlobalUserUid;
 const gid_t kTestGroupId = kGlobalUserGid;
 const char kSystemShareGroupName[] = "system_share";
-const std::string kTestUserIdStr =
-    std::to_string(kTestUserId);
+const std::string kTestUserIdStr = std::to_string(kTestUserId);
+const std::string kDefaultUserIdStr = std::to_string(kDefaultUserUid);
+const char kLegacyExtImageDir[] = "legacy_extimage_dir";
+const char kMigrateTestDBName[] = "app2sd_migrate.db";
 
 const bf::path kSmokePackagesDirectory =
-"/usr/share/tpk-backend-ut/test_samples/smoke/";
+    "/usr/share/tpk-backend-ut/test_samples/smoke/";
 
 // common entries
 const std::vector<std::string> kDBEntries = {
@@ -58,6 +63,8 @@ const std::vector<std::string> kDBEntries = {
   {".pkgmgr_parser.db-journal"},
   {".pkgmgr_cert.db"},
   {".pkgmgr_cert.db-journal"},
+  {".app2sd.db"},
+  {".app2sd.db-journal"},
 };
 // globaluser entries
 const char kGlobalManifestDir[] = "/opt/share/packages";
@@ -216,7 +223,8 @@ void ValidatePackageFS(const std::string& pkgid, const std::string& appid,
       iter != bf::recursive_directory_iterator(); ++iter) {
     if (bf::is_symlink(symlink_status(iter->path())))
       continue;
-    if (iter->path().filename() == "data")
+    if (iter->path().filename() == "data" ||
+        iter->path().filename() == ".mmc")
       continue;
     struct stat stats;
     stat(iter->path().c_str(), &stats);
@@ -257,6 +265,30 @@ void ValidatePackage(const std::string& pkgid, const std::string& appid) {
   }
 }
 
+void ValidateExternalPackage_FS(const std::string& pkgid,
+    const std::string& appid, uid_t uid) {
+  ASSERT_EQ(app2ext_usr_enable_external_pkg(pkgid.c_str(), uid), 0);
+  bf::path root_path = ci::GetRootAppPath(false, uid);
+  ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "bin"));
+  ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "lib"));
+  ASSERT_TRUE(bf::exists(root_path / pkgid / ".mmc" / "res"));
+  ValidatePackage(pkgid, appid);
+  ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0);
+}
+
+void ValidateExternalPackage(const std::string& pkgid,
+    const std::string& appid) {
+  std::string storage = ci::QueryStorageForPkgId(pkgid, kTestUserId);
+  bf::path ext_mount_path = ci::GetExternalCardPath();
+  if (bf::is_empty(ext_mount_path)) {
+    LOG(INFO) << "Sdcard not exists!";
+    ASSERT_EQ(storage, "installed_internal");
+  } else {
+    ASSERT_EQ(storage, "installed_external");
+  }
+  ValidateExternalPackage_FS(pkgid, appid, kTestUserId);
+}
+
 void CheckPackageNonExistance(const std::string& pkgid,
                               const std::string& appid) {
   ASSERT_FALSE(ci::QueryIsPackageInstalled(
@@ -311,6 +343,94 @@ ci::AppInstaller::Result Install(const bf::path& path,
   return CallBackend(SIZEOFARRAY(argv), argv, mode);
 }
 
+bool CheckAvailableExternalPath() {
+  bf::path ext_mount_path = ci::GetExternalCardPath();
+  LOG(DEBUG) << "ext_mount_path :" << ext_mount_path;
+  if (bf::is_empty(ext_mount_path)) {
+    LOG(ERROR) << "Sdcard not exists!";
+    return false;
+  }
+  return true;
+}
+
+ci::AppInstaller::Result InstallExternal(const bf::path& path,
+                                 RequestResult mode = RequestResult::NORMAL) {
+  int default_storage = 0;
+  vconf_get_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
+                &default_storage);
+  vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT, 1);
+
+  const char* argv[] = {"", "-i", path.c_str(), "-u", kTestUserIdStr.c_str()};
+  ci::AppInstaller::Result result = CallBackend(SIZEOFARRAY(argv), argv, mode);
+
+  vconf_set_int(VCONFKEY_SETAPPL_DEFAULT_MEM_INSTALL_APPLICATIONS_INT,
+                default_storage);
+  return result;
+}
+
+ci::AppInstaller::Result MigrateLegacyExternalImage(const std::string& pkgid,
+                                 const bf::path& path,
+                                 const bf::path& legacy_path,
+                                 RequestResult mode = RequestResult::NORMAL) {
+  if (InstallExternal(path) != ci::AppInstaller::Result::OK) {
+    LOG(ERROR) << "Failed to install application. Cannot perform Migrate";
+    return ci::AppInstaller::Result::ERROR;
+  }
+
+  bf::path ext_mount_path = ci::GetExternalCardPath();
+  if (bf::is_empty(ext_mount_path)) {
+    LOG(ERROR) << "Sdcard not exists!";
+    return ci::AppInstaller::Result::ERROR;
+  }
+  bf::path app2sd_path = ext_mount_path / "app2sd";
+
+  char *image_name = app2ext_usr_getname_image(pkgid.c_str(),
+                     kGlobalUserUid);
+  if (!image_name) {
+    LOG(ERROR) << "Failed to get external image name";
+    return ci::AppInstaller::Result::ERROR;
+  }
+  bf::path org_image = app2sd_path / image_name;
+  free(image_name);
+
+  bs::error_code error;
+  bf::remove(org_image, error);
+  if (error) {
+    LOG(ERROR) << "Failed to remove org image";
+    return ci::AppInstaller::Result::ERROR;
+  }
+
+  bf::path db_path = tzplatform_getenv(TZ_SYS_DB);
+  bf::path app2sd_db = db_path / ".app2sd.db";
+  bf::path app2sd_db_journal = db_path / ".app2sd.db-journal";
+  bf::remove(app2sd_db, error);
+  if (error) {
+    LOG(ERROR) << "Failed to remove app2sd db";
+    return ci::AppInstaller::Result::ERROR;
+  }
+  bf::remove(app2sd_db_journal, error);
+  if (error) {
+    LOG(ERROR) << "Failed to remove app2sd journal db";
+    return ci::AppInstaller::Result::ERROR;
+  }
+
+  bf::path app2sd_migrate_db = legacy_path / kMigrateTestDBName;
+  if (!ci::CopyFile(app2sd_migrate_db, app2sd_db)) {
+    LOG(ERROR) << "Failed to copy test db";
+    return ci::AppInstaller::Result::ERROR;
+  }
+
+  bf::path legacy_src = legacy_path / pkgid;
+  bf::path legacy_dst = app2sd_path / pkgid;
+  if (!ci::CopyFile(legacy_src, legacy_dst)) {
+    LOG(ERROR) << "Failed to copy test image";
+    return ci::AppInstaller::Result::ERROR;
+  }
+  const char* argv[] = {"", "--migrate-extimg", pkgid.c_str(),
+                       "-u", kDefaultUserIdStr.c_str()};
+  return CallBackend(SIZEOFARRAY(argv), argv, mode);
+}
+
 ci::AppInstaller::Result InstallWithTEP(
     const bf::path& path,
     const bf::path& tep,
@@ -437,7 +557,7 @@ void RestorePath(const bf::path& path) {
 
 std::vector<bf::path> SetupBackupDirectories(uid_t uid) {
   std::vector<bf::path> entries;
-  bf::path db_dir = bf::path("/opt/dbspace");
+  bf::path db_dir = bf::path(tzplatform_getenv(TZ_SYS_DB));
   if (uid != kGlobalUserUid)
     db_dir = db_dir / "user" / std::to_string(uid);
   for (auto e : kDBEntries) {
@@ -640,6 +760,26 @@ TEST_F(SmokeTest, MountUpdateMode_Tpk) {
   ASSERT_TRUE(ValidateFileContentInPackage(pkgid, "res/VERSION", "2\n"));
 }
 
+TEST_F(SmokeTest, MigrateLegacyExternalImage_Tpk) {
+  ASSERT_TRUE(CheckAvailableExternalPath());
+  bf::path path = kSmokePackagesDirectory / "InstallExternal_Tpk_2.tpk";
+  std::string pkgid = "smokeapp28";
+  std::string appid = "smokeapp28.InstallExternalTpk";
+  bf::path legacy_path = kSmokePackagesDirectory / kLegacyExtImageDir;
+  ASSERT_EQ(MigrateLegacyExternalImage(pkgid, path, legacy_path),
+      ci::AppInstaller::Result::OK);
+  ValidateExternalPackage(pkgid, appid);
+}
+
+TEST_F(SmokeTest, InstallExternal_Tpk) {
+  ASSERT_TRUE(CheckAvailableExternalPath());
+  bf::path path = kSmokePackagesDirectory / "InstallExternal_Tpk.tpk";
+  std::string pkgid = "smokeapp29";
+  std::string appid = "smokeapp29.InstallExternalTpk";
+  ASSERT_EQ(InstallExternal(path), ci::AppInstaller::Result::OK);
+  ValidateExternalPackage(pkgid, appid);
+}
+
 #define TEP_TEST_STARTING_BLOCK(NUMBER)                                        \
   bf::path path = kSmokePackagesDirectory / "TEP_Tpk";                         \
   path += #NUMBER;                                                             \
diff --git a/src/unit_tests/test_samples/smoke/InstallExternal_Tpk.tpk b/src/unit_tests/test_samples/smoke/InstallExternal_Tpk.tpk
new file mode 100644 (file)
index 0000000..b9f9ec1
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/InstallExternal_Tpk.tpk differ
diff --git a/src/unit_tests/test_samples/smoke/InstallExternal_Tpk_2.tpk b/src/unit_tests/test_samples/smoke/InstallExternal_Tpk_2.tpk
new file mode 100644 (file)
index 0000000..21dce6c
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/InstallExternal_Tpk_2.tpk differ
diff --git a/src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db
new file mode 100644 (file)
index 0000000..f2f336a
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/app2sd_migrate.db differ
diff --git a/src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp28 b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp28
new file mode 100644 (file)
index 0000000..7f96369
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp28 differ