Support legacy image for backward-compatibility 85/108485/5
authorjongmyeongko <jongmyeong.ko@samsung.com>
Wed, 4 Jan 2017 12:42:59 +0000 (21:42 +0900)
committerjongmyeongko <jongmyeong.ko@samsung.com>
Thu, 5 Jan 2017 11:08:47 +0000 (20:08 +0900)
Refer to:
https://review.tizen.org/gerrit/#/c/104823/

Change-Id: I2e48c94def90181b6522fd8f3d9508ea636d693e
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
src/hybrid/hybrid_installer.cc
src/unit_tests/smoke_test.cc
src/unit_tests/test_samples/smoke/InstallExternalMode.wgt [new file with mode: 0644]
src/unit_tests/test_samples/smoke/MigrateLegacyExternalImageMode.wgt [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/smokeapp36 [new file with mode: 0644]
src/wgt/wgt_installer.cc

index 73f212f..6d3ec58 100644 (file)
@@ -27,6 +27,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_recover_change_owner.h>
 #include <common/step/filesystem/step_recover_files.h>
 #include <common/step/filesystem/step_recover_icons.h>
@@ -538,6 +539,12 @@ HybridInstaller::HybridInstaller(common_installer::PkgMgrPtr pkgmgr)
       AddStep<ci::pkgmgr::StepRunParserPlugin>(
         ci::Plugin::ActionType::Uninstall);
       break;
+    case ci::RequestType::MigrateExtImg: {
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      AddStep<ci::security::StepMigrateLegacyExtImage>();
+      AddStep<ci::filesystem::StepChangeOwnershipAndPermission>();
+      break;
+    }
     default:
       AddStep<ci::configuration::StepFail>();
       break;
index 0ca4f80..bbcc1ec 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>
@@ -44,11 +46,15 @@ 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);
 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 kDefaultUserIdStr = std::to_string(kDefaultUserUid);
+const char kLegacyExtImageDir[] = "legacy_extimage_dir";
+const char kMigrateTestDBName[] = "app2sd_migrate.db";
 
 const bf::path kSmokePackagesDirectory =
     "/usr/share/wgt-backend-ut/test_samples/smoke/";
@@ -59,6 +65,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";
@@ -278,7 +286,8 @@ void ValidatePackageFS(const std::string& pkgid,
       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);
@@ -319,6 +328,39 @@ void ValidatePackage(const std::string& pkgid,
   }
 }
 
+void ValidateExternalPackageFS(const std::string& pkgid,
+                               const std::vector<std::string>& appids,
+                               uid_t uid, gid_t gid) {
+  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" / "res"));
+  ValidatePackageFS(pkgid, appids, uid, gid);
+  ASSERT_EQ(app2ext_usr_disable_external_pkg(pkgid.c_str(), uid), 0);
+}
+
+void ValidateExternalPackage(const std::string& pkgid,
+                             const std::vector<std::string>& appids) {
+  ASSERT_TRUE(ci::QueryIsPackageInstalled(
+      pkgid, ci::GetRequestMode(kTestUserId),
+      kTestUserId));
+  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");
+  }
+  ValidateExternalPackageFS(pkgid, appids, kTestUserId, kTestGroupId);
+  if (kTestUserId == kGlobalUserUid) {
+    ci::UserList list = ci::GetUserList();
+    for (auto& l : list)
+      ValidatePackageRWFS(pkgid, std::get<0>(l));
+  } else {
+    ValidatePackageRWFS(pkgid, kTestUserId);
+  }
+}
+
 void CheckPackageNonExistance(const std::string& pkgid,
                               const std::vector<std::string>& appids) {
   ASSERT_FALSE(ci::QueryIsPackageInstalled(
@@ -385,6 +427,97 @@ ci::AppInstaller::Result Install(const bf::path& path,
   return CallBackend(SIZEOFARRAY(argv), argv, type, 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,
+                                 PackageType type,
+                                 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, type, 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,
+                                 PackageType type,
+                                 RequestResult mode = RequestResult::NORMAL) {
+  if (InstallExternal(path, type) != 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, type, mode);
+}
+
 ci::AppInstaller::Result MountInstall(const bf::path& path,
     PackageType type, RequestResult mode = RequestResult::NORMAL) {
   const char* argv[] = {"", "-w", path.c_str(), "-u", kTestUserIdStr.c_str()};
@@ -488,7 +621,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) {
@@ -1008,6 +1141,27 @@ TEST_F(SmokeTest, UserDefinedPlugins) {
   ASSERT_TRUE(std::find(res.begin(), res.end(), power_privilege) != res.end());
 }
 
+TEST_F(SmokeTest, InstallExternalMode) {
+  ASSERT_TRUE(CheckAvailableExternalPath());
+  bf::path path = kSmokePackagesDirectory / "InstallExternalMode.wgt";
+  std::string pkgid = "smokeapp35";
+  std::string appid = "smokeapp35.web";
+  ASSERT_EQ(InstallExternal(path, PackageType::WGT),
+      ci::AppInstaller::Result::OK);
+  ValidateExternalPackage(pkgid, {appid});
+}
+
+TEST_F(SmokeTest, MigrateLegacyExternalImageMode) {
+  ASSERT_TRUE(CheckAvailableExternalPath());
+  bf::path path = kSmokePackagesDirectory / "MigrateLegacyExternalImageMode.wgt";
+  std::string pkgid = "smokeapp36";
+  std::string appid = "smokeapp36.web";
+  bf::path legacy_path = kSmokePackagesDirectory / kLegacyExtImageDir;
+  ASSERT_EQ(MigrateLegacyExternalImage(pkgid, path, legacy_path,
+      PackageType::WGT), ci::AppInstaller::Result::OK);
+  ValidateExternalPackage(pkgid, {appid});
+}
+
 }  // namespace common_installer
 
 int main(int argc,  char** argv) {
diff --git a/src/unit_tests/test_samples/smoke/InstallExternalMode.wgt b/src/unit_tests/test_samples/smoke/InstallExternalMode.wgt
new file mode 100644 (file)
index 0000000..ef4f46f
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/InstallExternalMode.wgt differ
diff --git a/src/unit_tests/test_samples/smoke/MigrateLegacyExternalImageMode.wgt b/src/unit_tests/test_samples/smoke/MigrateLegacyExternalImageMode.wgt
new file mode 100644 (file)
index 0000000..160f91c
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/MigrateLegacyExternalImageMode.wgt 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..a119369
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/smokeapp36 b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp36
new file mode 100644 (file)
index 0000000..c440787
Binary files /dev/null and b/src/unit_tests/test_samples/smoke/legacy_extimage_dir/smokeapp36 differ
index e90da5c..337f446 100755 (executable)
@@ -30,6 +30,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>
@@ -603,6 +604,12 @@ WgtInstaller::WgtInstaller(ci::PkgMgrPtr pkgrmgr)
         ci::Plugin::ActionType::Uninstall);
       break;
     }
+    case ci::RequestType::MigrateExtImg: {
+      AddStep<ci::configuration::StepConfigure>(pkgmgr_);
+      AddStep<ci::security::StepMigrateLegacyExtImage>();
+      AddStep<ci::filesystem::StepChangeOwnershipAndPermission>();
+      break;
+    }
     default: {
       AddStep<ci::configuration::StepFail>();
     }