Add/delete certain directory when updating pkg 76/131076/5
authorJunghyun Yeon <jungh.yeon@samsung.com>
Mon, 24 Apr 2017 03:57:31 +0000 (12:57 +0900)
committerjongmyeong ko <jongmyeong.ko@samsung.com>
Fri, 2 Jun 2017 05:04:47 +0000 (05:04 +0000)
- Shared/data should be added/removed depends on api version and privilege
of updated package.
- Installer will check these and update folder by adding/deleteing it.

Related changes:
[tpk-backend] : https://review.tizen.org/gerrit/131077
[wgt-backend] : https://review.tizen.org/gerrit/131078
Change-Id: I6d12620963b31ded9716f318259a82a238a87fd4
Signed-off-by: Junghyun Yeon <jungh.yeon@samsung.com>
src/common/shared_dirs.cc
src/common/shared_dirs.h
src/common/step/filesystem/step_update_per_user_storage_directories.cc [new file with mode: 0644]
src/common/step/filesystem/step_update_per_user_storage_directories.h [new file with mode: 0644]
src/common/step/filesystem/step_update_storage_directories.cc [new file with mode: 0644]
src/common/step/filesystem/step_update_storage_directories.h [new file with mode: 0644]

index 5de70392c5e309a044f304c14546099c0e24c01b..d7000acb3cf85c9b923ec162660ba1e4ab240c25 100644 (file)
@@ -480,6 +480,30 @@ bool CreateSkelDirectories(const std::string& pkgid,
   return result;
 }
 
+bool UpdateSkelDirectories(const std::string& pkgid,
+                           bool is_remove_shareddata) {
+  bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+                  bf::path(kSkelAppDir) / pkgid;
+  bf::path shared_data_path = path / kSharedDataDir;
+  LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
+             << " directory : " << shared_data_path;
+
+  if (!is_remove_shareddata) {
+    if (!CreateDir(shared_data_path))
+      return false;
+
+    std::string error_message;
+    if (!RegisterSecurityContextForPath(pkgid, path, kGlobalUserUid,
+                                        false, &error_message)) {
+      LOG(ERROR) << "Failed to register security context for path: " << path
+                 << ", error_message: " << error_message;
+      return false;
+    }
+  } else {
+    return ci::RemoveAll(shared_data_path);
+  }
+  return true;
+}
 
 bool DeleteSkelDirectories(const std::string& pkgid) {
   bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
@@ -556,6 +580,42 @@ bool CopyUserDirectories(const std::string& pkgid) {
   return true;
 }
 
+bool UpdateUserDirectory(const std::string& pkgid, bool is_remove_shareddata) {
+  UserList list = ci::GetUserList();
+  for (auto l : list) {
+    bf::path apps_rw(std::get<2>(l) / "apps_rw");
+    bf::path root_dst = apps_rw / pkgid;
+    bf::path shareddir_dst = root_dst / kSharedDataDir;
+    uid_t uid = std::get<0>(l);
+    LOG(DEBUG) << ((is_remove_shareddata) ? "Deleting" : "Adding")
+               << " shareddata directory for uid: " << uid;
+
+    if (!is_remove_shareddata) {
+      bs::error_code error;
+      bf::create_directories(shareddir_dst, error);
+      if (error && !bf::exists(shareddir_dst)) {
+        LOG(ERROR) << "Failed to create directory: " << shareddir_dst;
+        return false;
+      }
+
+      gid_t gid = std::get<1>(l);
+      if (!SetDirectoryOwnerAndPermissions(root_dst, uid, gid))
+        return false;
+
+      std::string error_message;
+      if (!RegisterSecurityContextForPath(pkgid, root_dst, std::get<0>(l),
+          false, &error_message)) {
+        LOG(ERROR) << "Failed to register security context for path: "
+                   << root_dst << ", error_message: " << error_message;
+        return false;
+      }
+    } else {
+      return ci::RemoveAll(shareddir_dst);
+    }
+  }
+  return true;
+}
+
 bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
   bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
   if (!bf::exists(src_dir)) {
index 11081f0f91eeb4d56328350c06c747f26fe2cf96..da28bd21638c6626020165563293372ad0e0ddf3 100644 (file)
@@ -91,6 +91,18 @@ bool CreateSkelDirectories(const std::string& pkgid,
  */
 bool DeleteSkelDirectories(const std::string& pkgid);
 
+/**
+ * \brief Update skel directory
+ *
+ * \param pkgid package id
+ * \param is_remove_shareddata shared/data directory add/delete flag
+ *
+ * \return true if succeed, false otherwise
+ *
+ */
+bool UpdateSkelDirectories(const std::string& pkgid,
+                           bool is_remove_shareddata);
+
 /**
  * \brief Delete per-user directories
  *
@@ -111,6 +123,18 @@ bool DeleteUserDirectories(const std::string& pkgid);
  */
 bool CopyUserDirectories(const std::string& pkgid);
 
+/**
+ * \brief Update per-user directory
+ *
+ * \param pkgid package id
+ * \param is_remove_shareddata shared/data directory add/delete flag
+ *
+ * \return true if succeed, false otherwise
+ *
+ */
+bool UpdateUserDirectory(const std::string& pkgid,
+                           bool is_remove_shareddata);
+
 /**
  * \brief Returns path prefix for internal storage, typically '/home'
  *
diff --git a/src/common/step/filesystem/step_update_per_user_storage_directories.cc b/src/common/step/filesystem/step_update_per_user_storage_directories.cc
new file mode 100644 (file)
index 0000000..850fba3
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (c) 2017 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_update_per_user_storage_directories.h"
+
+#include <manifest_parser/utils/version_number.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <string>
+#include <vector>
+
+#include "common/privileges.h"
+
+#include "common/shared_dirs.h"
+#include "common/utils/glist_range.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace {
+
+const utils::VersionNumber ver30("3.0");
+const char kSkelAppDir[] = "skel/apps_rw";
+const char kSharedDataDir[] = "shared/data";
+
+common_installer::Step::Status RemoveSharedDir(const std::string& pkgid) {
+  bf::path shareddir_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      bf::path(kSkelAppDir) / pkgid / kSharedDataDir;
+  if (!bf::exists(shareddir_path))
+    return common_installer::Step::Status::OK;
+
+  if (!common_installer::UpdateSkelDirectories(pkgid, true)) {
+    LOG(ERROR) << "Failed to remove shared data directory";
+    return common_installer::Step::Status::APP_DIR_ERROR;
+  }
+
+  if (!common_installer::UpdateUserDirectory(pkgid, true)) {
+    LOG(ERROR) << "Failed to remove shared data directory";
+    return common_installer::Step::Status::APP_DIR_ERROR;
+  }
+
+  return common_installer::Step::Status::OK;
+}
+
+common_installer::Step::Status CreateSharedDir(const std::string& pkgid) {
+  bf::path shareddir_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      bf::path(kSkelAppDir) / pkgid / kSharedDataDir;
+  if (bf::exists(shareddir_path))
+    return common_installer::Step::Status::OK;
+
+  if (!common_installer::UpdateSkelDirectories(pkgid, false)) {
+    LOG(ERROR) << "Failed to remove shared data directory";
+    return common_installer::Step::Status::APP_DIR_ERROR;
+  }
+
+  if (!common_installer::UpdateUserDirectory(pkgid, false)) {
+    LOG(ERROR) << "Failed to remove shared data directory";
+    return common_installer::Step::Status::APP_DIR_ERROR;
+  }
+
+  return common_installer::Step::Status::OK;
+}
+
+}  // namespace
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepUpdatePerUserStorageDirectories::process() {
+  if (context_->request_mode.get() != RequestMode::GLOBAL)
+    return Step::Status::OK;
+
+  manifest_x* manifest = context_->manifest_data.get();
+  bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+      bf::path(kSkelAppDir) / context_->pkgid.get() / kSharedDataDir;
+  std::string package_id = context_->pkgid.get();
+
+  std::string str_ver(manifest->api_version);
+  utils::VersionNumber api_version(str_ver);
+  if (api_version < ver30) {
+    return CreateSharedDir(package_id);
+  } else {
+    bool shareddata = false;
+    for (auto& priv : GListRange<privilege_x*>(manifest->privileges)) {
+      if (!strcmp(priv->value, privileges::kPrivForSharedData)) {
+        shareddata = true;
+        break;
+      }
+    }
+
+    if (shareddata)
+      return CreateSharedDir(package_id);
+    else
+      return RemoveSharedDir(package_id);
+  }
+}
+
+}  // namespace filesystem
+}  // namespace common_installer
diff --git a/src/common/step/filesystem/step_update_per_user_storage_directories.h b/src/common/step/filesystem/step_update_per_user_storage_directories.h
new file mode 100644 (file)
index 0000000..78b78e8
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (c) 2017 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_UPDATE_PER_USER_STORAGE_DIRECTORIES_H_
+#define COMMON_STEP_FILESYSTEM_STEP_UPDATE_PER_USER_STORAGE_DIRECTORIES_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include <vector>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+class StepUpdatePerUserStorageDirectories : public common_installer::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; }
+
+  STEP_NAME(UpdatePerUserStorageDirectories)
+};
+
+}  // namespace filesystem
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_FILESYSTEM_STEP_UPDATE_PER_USER_STORAGE_DIRECTORIES_H_
diff --git a/src/common/step/filesystem/step_update_storage_directories.cc b/src/common/step/filesystem/step_update_storage_directories.cc
new file mode 100644 (file)
index 0000000..292cb7b
--- /dev/null
@@ -0,0 +1,77 @@
+// Copyright (c) 2017 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_update_storage_directories.h"
+
+#include <manifest_parser/utils/version_number.h>
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+
+#include <string>
+#include <vector>
+
+#include "common/privileges.h"
+#include "common/shared_dirs.h"
+#include "common/utils/file_util.h"
+#include "common/utils/glist_range.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace {
+
+const char kSharedData[] = "shared/data";
+const utils::VersionNumber ver30("3.0");
+
+common_installer::Step::Status CreateSharedDir(bf::path shareddir_path) {
+  if (bf::exists(shareddir_path))
+    return common_installer::Step::Status::OK;
+
+  if (!common_installer::CreateDir(shareddir_path))
+    return common_installer::Step::Status::APP_DIR_ERROR;
+
+  return common_installer::Step::Status::OK;
+}
+
+}  // namespace
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepUpdateStorageDirectories::process() {
+  manifest_x* manifest = context_->manifest_data.get();
+
+  if (!manifest) {
+    LOG(ERROR) << "Failed to get manifest info";
+    return Status::INVALID_VALUE;
+  }
+  std::string str_ver(manifest->api_version);
+  utils::VersionNumber api_version(str_ver);
+
+  bf::path shared_data_path = context_->pkg_path.get() / kSharedData;
+  if (api_version < ver30) {
+    return CreateSharedDir(shared_data_path);
+  } else {
+    bool shareddata = false;
+    for (auto& priv : GListRange<privilege_x*>(manifest->privileges)) {
+      if (!strcmp(priv->value, privileges::kPrivForSharedData)) {
+        shareddata = true;
+        break;
+      }
+    }
+    if (shareddata) {
+      return CreateSharedDir(shared_data_path);
+    } else {
+      if (!RemoveAll(shared_data_path))
+        return Status::APP_DIR_ERROR;
+    }
+  }
+
+  return Status::OK;
+}
+
+}  // namespace filesystem
+}  // namespace common_installer
diff --git a/src/common/step/filesystem/step_update_storage_directories.h b/src/common/step/filesystem/step_update_storage_directories.h
new file mode 100644 (file)
index 0000000..3cf7275
--- /dev/null
@@ -0,0 +1,30 @@
+// Copyright (c) 2017 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_UPDATE_STORAGE_DIRECTORIES_H_
+#define COMMON_STEP_FILESYSTEM_STEP_UPDATE_STORAGE_DIRECTORIES_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+class StepUpdateStorageDirectories : public common_installer::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; }
+
+  STEP_NAME(UpdateStorageDirectories)
+};
+
+}  // namespace filesystem
+}  // namespace common_installer
+
+#endif  // COMMON_STEP_FILESYSTEM_STEP_UPDATE_STORAGE_DIRECTORIES_H_