Mount install steps 61/65361/16
authorTomasz Iwanek <t.iwanek@samsung.com>
Fri, 8 Apr 2016 13:48:53 +0000 (15:48 +0200)
committerjongmyeong ko <jongmyeong.ko@samsung.com>
Wed, 4 May 2016 04:45:16 +0000 (21:45 -0700)
Due to mounting res/ directory tep package is copied
to tep/ directory instead of res/.

Requires:
 - https://review.tizen.org/gerrit/65788/
 - https://review.tizen.org/gerrit/66961/
 - https://review.tizen.org/gerrit/67457/
 - https://review.tizen.org/gerrit/67822/

Change-Id: I37974991f0d5fa2248e0a40aa1a999cc389f7485

22 files changed:
src/common/CMakeLists.txt
src/common/backup_paths.cc
src/common/backup_paths.h
src/common/pkgmgr_interface.cc
src/common/pkgmgr_signal.cc
src/common/request.cc
src/common/request.h
src/common/security_registration.cc
src/common/step/configuration/step_block_cross_update.cc [new file with mode: 0644]
src/common/step/configuration/step_block_cross_update.h [new file with mode: 0644]
src/common/step/configuration/step_configure.cc
src/common/step/filesystem/step_copy_tep.cc
src/common/step/filesystem/step_remove_zip_image.cc [new file with mode: 0644]
src/common/step/filesystem/step_remove_zip_image.h [new file with mode: 0644]
src/common/step/mount/step_mount_install.cc [new file with mode: 0644]
src/common/step/mount/step_mount_install.h [new file with mode: 0644]
src/common/step/mount/step_mount_unpacked.cc [new file with mode: 0644]
src/common/step/mount/step_mount_unpacked.h [new file with mode: 0644]
src/common/step/mount/step_mount_update.cc [new file with mode: 0644]
src/common/step/mount/step_mount_update.h [new file with mode: 0644]
src/common/step/pkgmgr/step_update_tep.cc
src/common/step/step.h

index bc4f8ec..f706ac6 100644 (file)
@@ -24,6 +24,7 @@ SET(SRCS
   step/backup/step_backup_icons.cc
   step/backup/step_backup_manifest.cc
   step/backup/step_copy_backup.cc
+  step/configuration/step_block_cross_update.cc
   step/configuration/step_configure.cc
   step/configuration/step_fail.cc
   step/configuration/step_parse_manifest.cc
@@ -43,7 +44,11 @@ SET(SRCS
   step/filesystem/step_remove_icons.cc
   step/filesystem/step_remove_per_user_storage_directories.cc
   step/filesystem/step_remove_temporary_directory.cc
+  step/filesystem/step_remove_zip_image.cc
   step/filesystem/step_unzip.cc
+  step/mount/step_mount_install.cc
+  step/mount/step_mount_unpacked.cc
+  step/mount/step_mount_update.cc
   step/pkgmgr/step_check_blacklist.cc
   step/pkgmgr/step_check_removable.cc
   step/pkgmgr/step_kill_apps.cc
index d4495db..5aba5d1 100644 (file)
@@ -4,14 +4,19 @@
 
 #include "common/backup_paths.h"
 
+#include <tzplatform_config.h>
+
 namespace bf = boost::filesystem;
 
 namespace {
 
+const char kImageDir[] = ".image";
+const char kBckExtension[] = ".bck";
+
 boost::filesystem::path GetBackupPath(
     const boost::filesystem::path& pkg_path) {
   bf::path backup_path = pkg_path;
-  backup_path += ".bck";
+  backup_path += kBckExtension;
   return backup_path;
 }
 
@@ -35,7 +40,21 @@ boost::filesystem::path GetBackupPathForIconFile(
 }
 
 std::string GetIconFileBackupExtension() {
-  return ".bck";
+  return kBckExtension;
+}
+
+boost::filesystem::path GetBackupPathForZipFile(const bf::path& zip_path) {
+  return GetBackupPath(zip_path);
+}
+
+boost::filesystem::path GetMountLocation(const bf::path& pkg_path) {
+  return pkg_path / ".pkg";
+}
+
+boost::filesystem::path GetZipPackageLocation(
+    const boost::filesystem::path& pkg_path,
+    const std::string& pkgid) {
+  return pkg_path / kImageDir / pkgid;
 }
 
 }  // namespace common_installer
index cc5fe15..b244dff 100644 (file)
@@ -50,6 +50,43 @@ boost::filesystem::path GetBackupPathForIconFile(
  */
 std::string GetIconFileBackupExtension();
 
+/**
+ * \brief Helper function for getting backup path of zip (used for recovery)
+ *        based on zip path
+ *
+ * \param zip_path path to zip file
+ *
+ * \return backup path of zip
+ */
+boost::filesystem::path GetBackupPathForZipFile(
+    const boost::filesystem::path& zip_path);
+
+/**
+ * @brief GetZipPackageLocation
+ *        Returns location where zip package file must be copied during package
+ *        installation.
+ *
+ * @param pkg_path package path
+ * @param pkgid package id
+ *
+ * @return full path of zip package location
+ */
+boost::filesystem::path GetZipPackageLocation(
+    const boost::filesystem::path& pkg_path,
+    const std::string& pkgid);
+
+/**
+ * @brief GetMountLocation
+ *        Returns the mount point of zip package. This location is used to
+ *        mount package.
+ *
+ * @param pkg_path package path for which zip mount location is being obtained
+ *
+ * @return full path of package mount point
+ */
+boost::filesystem::path GetMountLocation(
+    const boost::filesystem::path& pkg_path);
+
 }  // namespace common_installer
 
 #endif  // COMMON_BACKUP_PATHS_H_
index 4bdeea8..223409f 100644 (file)
@@ -129,6 +129,11 @@ RequestType PkgMgrInterface::GetRequestType() const {
         return RequestType::ManifestDirectInstall;
       else
         return RequestType::ManifestDirectUpdate;
+    case PKGMGR_REQ_MOUNT_INSTALL:
+      if (!is_app_installed_)
+        return RequestType::MountInstall;
+      else
+        return RequestType::MountUpdate;
     default:
       return RequestType::Unknown;
   }
index b6a55c0..db8391c 100644 (file)
@@ -27,6 +27,8 @@ const std::map<ci::RequestType, const char*> kEventStr = {
   {ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
   {ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
   {ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
+  {ci::RequestType::MountInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
+  {ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
   {ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
   {ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR}
 };
index 279a719..ca9e796 100644 (file)
@@ -6,6 +6,8 @@
 #include <tzplatform_config.h>
 #include <unistd.h>
 
+namespace bf = boost::filesystem;
+
 namespace common_installer {
 
 RequestMode GetRequestMode() {
index 20632cc..e97f578 100644 (file)
@@ -5,6 +5,10 @@
 #ifndef COMMON_REQUEST_H_
 #define COMMON_REQUEST_H_
 
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+
 namespace common_installer {
 
 /** Request type received from pkgmgr_installer */
@@ -17,6 +21,8 @@ enum class RequestType : int {
   Clear,
   Delta,
   Recovery,
+  MountInstall,
+  MountUpdate,
   ManifestDirectInstall,
   ManifestDirectUpdate
 };
index e8a4c7f..7935a64 100644 (file)
@@ -25,16 +25,18 @@ namespace {
 const std::vector<std::pair<const char*,
                             app_install_path_type>> kSecurityPolicies = {
   {"/", SECURITY_MANAGER_PATH_PUBLIC_RO},
-  {"bin/", SECURITY_MANAGER_PATH_RO},
-  {"data/", SECURITY_MANAGER_PATH_RW},
-  {"cache/", SECURITY_MANAGER_PATH_RW},
-  {"lib/", SECURITY_MANAGER_PATH_RO},
-  {"res/", SECURITY_MANAGER_PATH_RO},
-  {"shared/", SECURITY_MANAGER_PATH_PUBLIC_RO},
+  {"bin", SECURITY_MANAGER_PATH_RO},
+  {"data", SECURITY_MANAGER_PATH_RW},
+  {"cache", SECURITY_MANAGER_PATH_RW},
+  {"lib", SECURITY_MANAGER_PATH_RO},
+  {"res", SECURITY_MANAGER_PATH_RO},
+  {"shared", SECURITY_MANAGER_PATH_PUBLIC_RO},
   {"shared/data", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
   {"shared/cache", SECURITY_MANAGER_PATH_OWNER_RW_OTHER_RO},
   {"shared/trusted", SECURITY_MANAGER_PATH_TRUSTED_RW},
-  {"tmp/", SECURITY_MANAGER_PATH_RW}
+  {"tep", SECURITY_MANAGER_PATH_RO},
+  {".image", SECURITY_MANAGER_PATH_RO},
+  {"tmp", SECURITY_MANAGER_PATH_RW}
 };
 
 bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
@@ -131,6 +133,11 @@ bool PrepareRequest(const std::string& app_id, const std::string& pkg_id,
     for (auto& policy : kSecurityPolicies) {
       bf::path subpath = path / policy.first;
       if (bf::exists(subpath)) {
+        if (bf::is_symlink(subpath)) {
+          LOG(DEBUG) << "Path " << subpath << " is a symlink."
+                     << "Path will not be registered";
+          continue;
+        }
         if (policy.second == SECURITY_MANAGER_PATH_TRUSTED_RW &&
             author_id.empty()) {
           LOG(WARNING) << "the path " << policy.first
diff --git a/src/common/step/configuration/step_block_cross_update.cc b/src/common/step/configuration/step_block_cross_update.cc
new file mode 100644 (file)
index 0000000..6cc0ca5
--- /dev/null
@@ -0,0 +1,51 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/configuration/step_block_cross_update.h"
+
+#include <boost/filesystem/operations.hpp>
+
+#include "common/backup_paths.h"
+
+namespace bf = boost::filesystem;
+
+namespace common_installer {
+namespace configuration {
+
+Step::Status StepBlockCrossUpdate::process() {
+  // TODO(t.iwanek): check for file is not the best method
+  // information about if package was mount-installed should be stored in pkgmgr
+  // database
+  bool is_mount_installed =
+      bf::exists(GetZipPackageLocation(context_->pkg_path.get(),
+                                       context_->pkgid.get()));
+  if (is_mount_installed) {
+    if (context_->request_type.get() == RequestType::Reinstall) {
+      LOG(ERROR) << "Reinstall / RDS mode is not allowed for "
+                 << "mount-installed packages";
+      return Status::OPERATION_NOT_ALLOWED;
+    }
+    if (context_->request_type.get() == RequestType::Delta) {
+      LOG(ERROR) << "Delta mode is not allowed for mount-installed packages";
+      return Status::OPERATION_NOT_ALLOWED;
+    }
+    if (context_->request_type.get() == RequestType::Update) {
+      LOG(ERROR) << "Normal update mode is not allowed for "
+                 << "mount-installed packages";
+      return Status::OPERATION_NOT_ALLOWED;
+    }
+  } else {
+    if (context_->request_type.get() == RequestType::MountUpdate) {
+      LOG(ERROR) << "Mount update mode is not allowed for "
+                 << "installed packages in normal manner";
+      return Status::OPERATION_NOT_ALLOWED;
+    }
+  }
+
+  LOG(DEBUG) << "Update is allowed to proceed";
+  return Status::OK;
+}
+
+}  // namespace configuration
+}  // namespace common_installer
diff --git a/src/common/step/configuration/step_block_cross_update.h b/src/common/step/configuration/step_block_cross_update.h
new file mode 100644 (file)
index 0000000..01fa1e7
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_CONFIGURATION_STEP_BLOCK_CROSS_UPDATE_H_
+#define COMMON_STEP_CONFIGURATION_STEP_BLOCK_CROSS_UPDATE_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace configuration {
+
+/**
+ * @brief The StepBlockCrossUpdate class
+ *        This step is used to block update of package in case when installation
+ *        was performed in different way than update.
+ *
+ * Packages that where installed by mount-install cannot be update with normal
+ * installation and packages that where installed by normal installation cannot
+ * be updated with mount update.
+ *
+ * We cannot use reinstall, RDS and delta update with mount-installed package
+ * in current version.
+ */
+class StepBlockCrossUpdate : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; }
+  Status undo() override { return Status::OK; }
+  Status precheck() override { return Status::OK; }
+
+  SCOPE_LOG_TAG(BlockCrossUpdate)
+};
+
+}  // namespace configuration
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_CONFIGURATION_STEP_BLOCK_CROSS_UPDATE_H_
index 2ea2b13..63d7389 100644 (file)
@@ -73,6 +73,15 @@ Step::Status StepConfigure::process() {
       context_->file_path.set(pkgmgr_->GetRequestInfo());
       context_->pkgid.set(kStrEmpty);
       break;
+    case RequestType::MountInstall:
+    case RequestType::MountUpdate:
+      context_->file_path.set(pkgmgr_->GetRequestInfo());
+      context_->pkgid.set(kStrEmpty);
+      if (!pkgmgr_->GetTepPath().empty()) {
+        context_->tep_path.set(pkgmgr_->GetTepPath());
+        context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
+      }
+      break;
     case RequestType::ManifestDirectInstall:
     case RequestType::ManifestDirectUpdate: {
       context_->pkgid.set(pkgmgr_->GetRequestInfo());
index 16aaa2a..7199ff0 100644 (file)
@@ -46,7 +46,7 @@ Step::Status StepCopyTep::process() {
     context_->root_application_path.get() / context_->pkgid.get());
 
   bf::path tep_path =
-      context_->pkg_path.get() / "res" / context_->tep_path.get().filename();
+      context_->pkg_path.get() / "tep" / context_->tep_path.get().filename();
 
   if (context_->is_tep_move.get()) {
     if (!MoveFile(context_->tep_path.get(), tep_path)) {
diff --git a/src/common/step/filesystem/step_remove_zip_image.cc b/src/common/step/filesystem/step_remove_zip_image.cc
new file mode 100644 (file)
index 0000000..31517b6
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_remove_zip_image.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include "common/backup_paths.h"
+#include "common/pkgmgr_registration.h"
+
+namespace bs = boost::system;
+namespace bf = boost::filesystem;
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepRemoveZipImage::precheck() {
+  if (!context_->manifest_data.get())
+    LOG(ERROR) << "manifest_data is not set";
+  return Step::Status::OK;
+}
+
+Step::Status StepRemoveZipImage::process() {
+  bf::path zip_image_path =
+      GetZipPackageLocation(context_->pkg_path.get(), context_->pkgid.get());
+  if (bf::exists(zip_image_path)) {
+    bs::error_code error;
+    bf::remove(zip_image_path, error);
+    LOG(INFO) << "Zip image file removed: " << zip_image_path;
+  }
+  return Status::OK;
+}
+
+}  // namespace filesystem
+}  // namespace common_installer
diff --git a/src/common/step/filesystem/step_remove_zip_image.h b/src/common/step/filesystem/step_remove_zip_image.h
new file mode 100644 (file)
index 0000000..91b008e
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_REMOVE_ZIP_IMAGE_H_
+#define COMMON_STEP_FILESYSTEM_STEP_REMOVE_ZIP_IMAGE_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * @brief The StepRemoveZipImage class
+ *        This step removes zip file from directory if it exists.
+ *
+ * Mount installation will leave zip file outside package path
+ */
+class StepRemoveZipImage : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; }
+  Status undo() override  { return Status::OK; }
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(RemoveZipImage)
+};
+
+}  // namespace filesystem
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_FILESYSTEM_STEP_REMOVE_ZIP_IMAGE_H_
diff --git a/src/common/step/mount/step_mount_install.cc b/src/common/step/mount/step_mount_install.cc
new file mode 100644 (file)
index 0000000..a5f39a5
--- /dev/null
@@ -0,0 +1,127 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "step/mount/step_mount_install.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+
+#include "common/backup_paths.h"
+#include "common/request.h"
+#include "common/tzip_interface.h"
+#include "common/utils/file_util.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace common_installer {
+namespace mount {
+
+Step::Status StepMountInstall::process() {
+  context_->pkg_path.set(
+      context_->root_application_path.get() / context_->pkgid.get());
+
+  TzipInterface tzip_unpack(context_->unpacked_dir_path.get());
+  if (!tzip_unpack.UnmountZip()) {
+    LOG(ERROR) << "Failed to unmount zip package from temporary path";
+    return Status::APP_DIR_ERROR;
+  }
+
+  bf::path zip_destination_path =
+      GetZipPackageLocation(context_->pkg_path.get(), context_->pkgid.get());
+  if (!bf::exists(zip_destination_path.parent_path())) {
+    bs::error_code error;
+    bf::create_directories(zip_destination_path.parent_path(), error);
+    if (error) {
+      LOG(ERROR) << "Failed to create diretory: "
+                 << zip_destination_path.parent_path();
+      return Status::APP_DIR_ERROR;
+    }
+  }
+
+  if (!CopyFile(context_->file_path.get(), zip_destination_path)) {
+    return Status::APP_DIR_ERROR;
+  }
+
+  bf::path mount_point = GetMountLocation(context_->pkg_path.get());
+  if (!bf::exists(mount_point)) {
+    bs::error_code error;
+    bf::create_directories(mount_point, error);
+    if (error) {
+      LOG(ERROR) << "Failed to create mount point directory: " << mount_point;
+      return Status::APP_DIR_ERROR;
+    }
+  }
+  TzipInterface tzip_final(mount_point);
+  if (!tzip_final.MountZip(zip_destination_path)) {
+    LOG(ERROR) << "Failed to mount zip package in installation path";
+    return Status::APP_DIR_ERROR;
+  }
+
+  LOG(INFO) << "Successfully mount zip package in: " << mount_point;
+  return Status::OK;
+}
+
+Step::Status StepMountInstall::clean() {
+  bf::path mount_point = GetMountLocation(context_->pkg_path.get());
+  TzipInterface tzip_final(mount_point);
+  if (!tzip_final.UnmountZip()) {
+    LOG(ERROR) << "Failed to unmount zip package after installation";
+    return Status::APP_DIR_ERROR;
+  }
+  bs::error_code error;
+  bf::remove(mount_point, error);
+  return Status::OK;
+}
+
+Step::Status StepMountInstall::undo() {
+  bs::error_code error;
+  bf::path mount_point = GetMountLocation(context_->pkg_path.get());
+  TzipInterface tzip_final(mount_point);
+  tzip_final.UnmountZip();
+  bf::remove(GetZipPackageLocation(context_->pkg_path.get(),
+                                   context_->pkgid.get()), error);
+  bf::remove(context_->pkg_path.get(), error);
+  if (error) {
+    LOG(ERROR) << "Failed to remove package content";
+    return Status::APP_DIR_ERROR;
+  }
+  return Status::OK;
+}
+
+Step::Status StepMountInstall::precheck() {
+  if (context_->root_application_path.get().empty()) {
+    LOG(ERROR) << "root_application_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!bf::exists(context_->root_application_path.get())) {
+    LOG(ERROR) << "root_application_path ("
+               << context_->root_application_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  if (context_->unpacked_dir_path.get().empty()) {
+    LOG(ERROR) << "unpacked_dir_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!bf::exists(context_->unpacked_dir_path.get())) {
+    LOG(ERROR) << "unpacked_dir_path ("
+               << context_->unpacked_dir_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  if (context_->pkgid.get().empty()) {
+    LOG(ERROR) << "pkgid attribute is empty";
+    return Step::Status::PACKAGE_NOT_FOUND;
+  }
+
+  return Step::Status::OK;
+}
+
+}  // namespace mount
+}  // namespace common_installer
diff --git a/src/common/step/mount/step_mount_install.h b/src/common/step/mount/step_mount_install.h
new file mode 100644 (file)
index 0000000..5d37dcc
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_MOUNT_STEP_MOUNT_INSTALL_H_
+#define COMMON_STEP_MOUNT_STEP_MOUNT_INSTALL_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace mount {
+
+/**
+ * \brief Responsible for mounting package zip in package installation directory
+ *        in process of new installation request.
+ *
+ * Mounts package zip in installation location to enable step to access package
+ * content for security applying and others. This step copies package zip into
+ * $HOME/$PKGID/.image. This location will be used in runtime to mount package
+ * when applcation from package is about being started.
+ *
+ * Resources to following directory:
+ * * TZ_SYS_RW/$PKGID (/usr/apps/$PKGID)
+ * * TZ_SER_APPS/$PKGID  (/{HOME}/apps_rw/$PKGID)
+ */
+class StepMountInstall : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override;
+  Status undo() override;
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(MountInstall)
+};
+
+}  // namespace mount
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_MOUNT_STEP_MOUNT_INSTALL_H_
diff --git a/src/common/step/mount/step_mount_unpacked.cc b/src/common/step/mount/step_mount_unpacked.cc
new file mode 100644 (file)
index 0000000..9b588ca
--- /dev/null
@@ -0,0 +1,85 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/mount/step_mount_unpacked.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <unistd.h>
+
+#include <string>
+
+#include "common/utils/file_util.h"
+#include "common/tzip_interface.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace common_installer {
+namespace mount {
+
+Step::Status StepMountUnpacked::process() {
+  bf::path tmp_dir = GenerateTmpDir(context_->root_application_path.get());
+
+  // TODO(t.iwanek): generally, support recovery for mount install/update
+  // Here: fix write unpacked directory to recovery file...
+  // consider how this will affect recovery mode
+
+  if (!CreateDir(tmp_dir)) {
+    LOG(ERROR) << "Failed to create temp directory: " << tmp_dir;
+    return Step::Status::APP_DIR_ERROR;
+  }
+  context_->unpacked_dir_path.set(tmp_dir);
+
+  TzipInterface tzip(context_->unpacked_dir_path.get());
+  if (!tzip.MountZip(context_->file_path.get())) {
+    LOG(ERROR) << "Failed to mount zip file: " << context_->file_path.get();
+    return Status::IMAGE_ERROR;
+  }
+  LOG(DEBUG) << "Zip mounted in unpacked_dir: "
+             << context_->unpacked_dir_path.get();
+  return Status::OK;
+}
+
+Step::Status StepMountUnpacked::undo() {
+  TzipInterface tzip(context_->unpacked_dir_path.get());
+  if (!tzip.UnmountZip()) {
+    LOG(ERROR) << "Failed to unmount zip file: " << context_->file_path.get();
+    return Status::IMAGE_ERROR;
+  }
+
+  if (bf::exists(context_->unpacked_dir_path.get())) {
+    bs::error_code error;
+    bf::remove_all(context_->unpacked_dir_path.get(), error);
+    LOG(DEBUG) << "remove temp dir: " << context_->unpacked_dir_path.get();
+  }
+  return Status::OK;
+}
+
+Step::Status StepMountUnpacked::precheck() {
+  if (context_->file_path.get().empty()) {
+    LOG(ERROR) << "file_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!bf::exists(context_->file_path.get())) {
+    LOG(ERROR) << "file_path ("
+               << context_->file_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (context_->root_application_path.get().empty()) {
+    LOG(ERROR) << "root_application_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!bf::exists(context_->root_application_path.get())) {
+    LOG(ERROR) << "root_application_path ("
+               << context_->root_application_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+  return Status::OK;
+}
+
+}  // namespace mount
+}  // namespace common_installer
diff --git a/src/common/step/mount/step_mount_unpacked.h b/src/common/step/mount/step_mount_unpacked.h
new file mode 100644 (file)
index 0000000..d914275
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_MOUNT_STEP_MOUNT_UNPACKED_H_
+#define COMMON_STEP_MOUNT_STEP_MOUNT_UNPACKED_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace mount {
+
+/**
+ * \brief Responsible for mounting package zip in temporary directory (wgt/tpk)
+ *
+ * Mounts package zip in temporary location to enable step to access package
+ * content for parsing, signature check and others.
+ *
+ * Following directories are used as mount points:
+ * * TZ_SYS_RW/tmpuniquedir (/usr/apps/tmpuniquedir)
+ * * TZ_SER_APPS/tmpdir  (/{HOME}/apps_rw/tmpuniquedir)
+ */
+class StepMountUnpacked : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override { return Status::OK; }
+  Status undo() override;
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(MountUnpacked)
+};
+
+}  // namespace mount
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_MOUNT_STEP_MOUNT_UNPACKED_H_
diff --git a/src/common/step/mount/step_mount_update.cc b/src/common/step/mount/step_mount_update.cc
new file mode 100644 (file)
index 0000000..595745d
--- /dev/null
@@ -0,0 +1,132 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/mount/step_mount_update.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include <string>
+
+#include "common/backup_paths.h"
+#include "common/request.h"
+#include "common/tzip_interface.h"
+#include "common/utils/file_util.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace common_installer {
+namespace mount {
+
+Step::Status StepMountUpdate::process() {
+  context_->pkg_path.set(
+     context_->root_application_path.get() / context_->pkgid.get());
+
+  TzipInterface tzip_unpack(context_->unpacked_dir_path.get());
+  if (!tzip_unpack.UnmountZip()) {
+    LOG(ERROR) << "Failed to unmount zip package from temporary path";
+    return Status::APP_DIR_ERROR;
+  }
+
+  bf::path zip_destination_path =
+      GetZipPackageLocation(context_->pkg_path.get(), context_->pkgid.get());
+  bf::path backup_zip_location = GetBackupPathForZipFile(zip_destination_path);
+
+  if (!MoveFile(zip_destination_path, backup_zip_location)) {
+    LOG(ERROR) << "Files to create backup of zip package file";
+    return Status::APP_DIR_ERROR;
+  }
+
+  if (!CopyFile(context_->file_path.get(), zip_destination_path)) {
+    return Status::APP_DIR_ERROR;
+  }
+
+  bf::path mount_point = GetMountLocation(context_->pkg_path.get());
+  TzipInterface tzip_final(mount_point);
+  if (!tzip_final.MountZip(zip_destination_path)) {
+    LOG(ERROR) << "Failed to mount zip package in installation path";
+    return Status::APP_DIR_ERROR;
+  }
+
+  LOG(INFO) << "Successfully mount zip package in: " << mount_point;
+  return Status::OK;
+}
+
+Step::Status StepMountUpdate::clean() {
+  bf::path backup_zip_location =
+      GetBackupPathForZipFile(GetZipPackageLocation(
+          context_->pkg_path.get(), context_->pkgid.get()));
+  bs::error_code error;
+  bf::remove(backup_zip_location, error);
+
+  bf::path mount_point = GetMountLocation(context_->pkg_path.get());
+  TzipInterface tzip_final(mount_point);
+  if (!tzip_final.UnmountZip()) {
+    LOG(ERROR) << "Failed to unmount zip package after installation";
+    return Status::APP_DIR_ERROR;
+  }
+  return Status::OK;
+}
+
+Step::Status StepMountUpdate::undo() {
+  bf::path zip_location = GetZipPackageLocation(
+        context_->pkg_path.get(), context_->pkgid.get());
+  bf::path backup_zip_location = GetBackupPathForZipFile(zip_location);
+
+  if (bf::exists(backup_zip_location)) {
+    bs::error_code error;
+    bf::remove(zip_location, error);
+    if (error) {
+      LOG(ERROR) << "Failed to remove: " << zip_location;
+      return Status::APP_DIR_ERROR;
+    }
+    if (!MoveFile(backup_zip_location, zip_location)) {
+      LOG(ERROR) << "Failed to restore backup of zip file: "
+                 << backup_zip_location;
+      return Status::APP_DIR_ERROR;
+    }
+  }
+  bs::error_code error;
+  bf::remove(context_->pkg_path.get(), error);
+  if (error) {
+    LOG(ERROR) << "Failed to remove package content";
+    return Status::APP_DIR_ERROR;
+  }
+  return Status::OK;
+}
+
+Step::Status StepMountUpdate::precheck() {
+  if (context_->root_application_path.get().empty()) {
+    LOG(ERROR) << "root_application_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!boost::filesystem::exists(context_->root_application_path.get())) {
+    LOG(ERROR) << "root_application_path ("
+               << context_->root_application_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  if (context_->unpacked_dir_path.get().empty()) {
+    LOG(ERROR) << "unpacked_dir_path attribute is empty";
+    return Step::Status::INVALID_VALUE;
+  }
+  if (!boost::filesystem::exists(context_->unpacked_dir_path.get())) {
+    LOG(ERROR) << "unpacked_dir_path ("
+               << context_->unpacked_dir_path.get()
+               << ") path does not exist";
+    return Step::Status::INVALID_VALUE;
+  }
+
+  if (context_->pkgid.get().empty()) {
+    LOG(ERROR) << "pkgid attribute is empty";
+    return Step::Status::PACKAGE_NOT_FOUND;
+  }
+
+  return Step::Status::OK;
+}
+
+}  // namespace mount
+}  // namespace common_installer
diff --git a/src/common/step/mount/step_mount_update.h b/src/common/step/mount/step_mount_update.h
new file mode 100644 (file)
index 0000000..b374a15
--- /dev/null
@@ -0,0 +1,44 @@
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_MOUNT_STEP_MOUNT_UPDATE_H_
+#define COMMON_STEP_MOUNT_STEP_MOUNT_UPDATE_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace mount {
+
+/**
+ * \brief Responsible for mounting package zip in package installation directory
+ *        in process of update installation request.
+ *
+ * Mounts package zip in installation location to enable step to access package
+ * content for security applying and others. This step copies package zip into
+ * $HOME/$PKGID/.image. This location will be used in runtime to mount package
+ * when applcation from package is about being started.
+ *
+ * Resources to following directory:
+ * * TZ_SYS_RW/$PKGID (/usr/apps/$PKGID)
+ * * TZ_SER_APPS/$PKGID  (/{HOME}/apps_rw/$PKGID)
+ */
+class StepMountUpdate : public Step {
+ public:
+  using Step::Step;
+
+  Status process() override;
+  Status clean() override;
+  Status undo() override;
+  Status precheck() override;
+
+  SCOPE_LOG_TAG(MountUpdate)
+};
+
+}  // namespace mount
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_MOUNT_STEP_MOUNT_UPDATE_H_
index c759b71..87ffb4d 100644 (file)
@@ -30,7 +30,7 @@ Step::Status StepUpdateTep::process() {
 
     bf::path old_tep_location =
         GetBackupPathForPackagePath(
-            context_->pkg_path.get()) / "res" / old_tep.filename();
+            context_->pkg_path.get()) / "tep" / old_tep.filename();
     bf::path new_tep_location = old_tep;
     if (!MoveFile(old_tep_location, new_tep_location)) {
       LOG(ERROR) << "Failed to copy tep file";
@@ -48,7 +48,7 @@ Step::Status StepUpdateTep::undo() {
     // restore old tep location during update rollback
     bf::path old_tep_location =
         GetBackupPathForPackagePath(
-            context_->pkg_path.get()) / "res" / old_tep.filename();
+            context_->pkg_path.get()) / "tep" / old_tep.filename();
     bf::path new_tep_location = old_tep;
     if (!MoveFile(new_tep_location, old_tep_location)) {
       LOG(ERROR) << "Failed to copy tep file";
index 1c8965d..b072c36 100644 (file)
@@ -45,6 +45,7 @@ class Step {
  public:
   /** Possible code returned by process, undo, clean, precheck methods. */
   enum class Status {
+    IMAGE_ERROR = -200,  // TODO(t.iwanek): fix value of error code...
     UNZIP_ERROR = PKGCMD_ERRCODE_UNZIP_ERROR,
     SECURITY_ERROR = PKGCMD_ERRCODE_SECURITY_ERROR,
     REGISTER_ERROR = PKGCMD_ERRCODE_REGISTER_ERROR,