1 // Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/filesystem/step_move_installed_storage.h"
7 #include <boost/filesystem/path.hpp>
8 #include <boost/system/error_code.hpp>
9 #include <tzplatform_config.h>
14 #include "common/external_storage.h"
15 #include "common/shared_dirs.h"
16 #include "common/utils/file_util.h"
17 #include "common/paths.h"
18 #include "common/pkgmgr_registration.h"
19 #include "common/pkgmgr_query.h"
21 namespace bf = boost::filesystem;
22 namespace bs = boost::system;
26 const char kInternalOnly[] = "internal-only";
30 namespace common_installer {
31 namespace filesystem {
33 Step::Status StepMoveInstalledStorage::process() {
34 std::string installed_storage = QueryStorageForPkgId(context_->pkgid.get(),
37 if ((move_type_ == MoveType::TO_INTERNAL &&
38 installed_storage == "installed_external") ||
39 (move_type_ == MoveType::TO_EXTERNAL &&
40 installed_storage == "installed_internal")) {
42 return Status::APP_DIR_ERROR;
44 (move_type_ == MoveType::TO_INTERNAL &&
45 installed_storage == "installed_extended") ||
46 (move_type_ == MoveType::TO_EXTENDED &&
47 installed_storage == "installed_internal")) {
49 return Status::APP_DIR_ERROR;
54 Step::Status StepMoveInstalledStorage::undo() {
55 if (context_->external_storage) {
56 if (new_tep_location_ != old_tep_location_)
58 return Status::APP_DIR_ERROR;
61 if (!MoveBackExtended())
62 return Status::APP_DIR_ERROR;
67 Step::Status StepMoveInstalledStorage::clean() {
68 if (context_->external_storage)
69 context_->external_storage->Commit();
73 Step::Status StepMoveInstalledStorage::precheck() {
74 move_type_ = context_->move_type.get();
75 if (context_->manifest_data.get()->installlocation == nullptr) {
76 LOG(ERROR) << "Cannot get installlocation value";
77 return Status::INVALID_VALUE;
79 if (!strcmp(context_->manifest_data.get()->installlocation, kInternalOnly)) {
80 LOG(ERROR) << "This package is interanl-only";
81 return Status::OPERATION_NOT_ALLOWED;
86 void StepMoveInstalledStorage::SetTepPaths() {
87 old_tep_location_ = context_->manifest_data.get()->tep_name;
88 if (context_->is_move_to_external.get()) {
89 new_tep_location_ = GetExternalTepPath(context_->request_mode.get(),
91 new_tep_location_ /= old_tep_location_.filename();
94 GetInternalTepPath(context_->pkg_path.get()) / old_tep_location_.filename();
98 bool StepMoveInstalledStorage::MoveTep() {
99 if (!bf::exists(new_tep_location_.parent_path())) {
100 bs::error_code error;
101 bf::create_directory(new_tep_location_.parent_path(), error);
103 LOG(ERROR) << "Failed to destination path for new tep location";
108 if (!MoveFile(old_tep_location_, new_tep_location_)) {
109 LOG(ERROR) << "Cannot move tep file from: " << old_tep_location_
110 << " to " << new_tep_location_;
114 if (!UpdateTepInfoInPkgmgr(new_tep_location_, context_->pkgid.get(),
115 context_->uid.get(), context_->request_mode.get())) {
116 LOG(ERROR) << "Failed to update tep package location in pkgmgr";
122 bool StepMoveInstalledStorage::MoveBackTep() {
123 if (bf::exists(new_tep_location_)) {
124 if (!MoveFile(new_tep_location_, old_tep_location_)) {
125 LOG(ERROR) << "Cannot move tep file from: " << new_tep_location_
126 << " to " << old_tep_location_;
130 if (!UpdateTepInfoInPkgmgr(old_tep_location_, context_->pkgid.get(),
131 context_->uid.get(), context_->request_mode.get())) {
132 LOG(ERROR) << "Failed to update tep package location in pkgmgr";
139 bool StepMoveInstalledStorage::MoveExternal() {
140 context_->external_storage =
141 ExternalStorage::MoveInstalledStorage(context_->request_type.get(),
142 context_->root_application_path.get(),
143 context_->pkgid.get(),
144 context_->pkg_type.get(),
146 context_->is_move_to_external.get());
147 if (!context_->external_storage) {
148 LOG(ERROR) << "Cannot initialize external storage for move";
153 if (context_->manifest_data.get()->tep_name) {
156 if (new_tep_location_ != old_tep_location_)
163 bool StepMoveInstalledStorage::MoveBackExternal() {
164 context_->external_storage->Abort();
168 bool StepMoveInstalledStorage::MoveExtended() {
169 if (move_type_ == MoveType::TO_EXTENDED) {
170 old_pkg_location_ = context_->pkg_path.get();
171 new_pkg_location_ = bf::path(GetExtendedRootAppPath(context_->uid.get())) /
172 context_->pkgid.get();
173 context_->storage.set(Storage::EXTENDED);
175 old_pkg_location_ = bf::path(GetExtendedRootAppPath(context_->uid.get())) /
176 context_->pkgid.get();
177 new_pkg_location_ = bf::path(GetRootAppPath(
178 context_->is_readonly_package.get(), context_->uid.get())) /
179 context_->pkgid.get();
180 context_->storage.set(Storage::INTERNAL);
183 if (move_type_ == MoveType::TO_INTERNAL) {
184 // remove existing symlink
185 if (!Remove(new_pkg_location_))
189 if (!MoveDir(old_pkg_location_, new_pkg_location_))
192 // create symlink for extended path
193 if (move_type_ == MoveType::TO_EXTENDED) {
194 bs::error_code error;
195 bf::create_symlink(new_pkg_location_, old_pkg_location_, error);
197 LOG(ERROR) << "Failed to create symlink for extended path: "
202 if (!SetPackageDirectoryOwnerAndPermissions(new_pkg_location_,
203 context_->uid.get())) {
204 LOG(ERROR) << "Failed to set directory ownership";
208 if (!UpdateInstalledStorageInPkgmgr(context_->storage.get(),
209 new_pkg_location_, context_->pkgid.get(), context_->uid.get()))
214 bool StepMoveInstalledStorage::MoveBackExtended() {
215 if (move_type_ == MoveType::TO_EXTENDED) {
216 // Remove symlink if exist
217 if (bf::exists(old_pkg_location_) &&
218 bf::is_symlink(symlink_status(old_pkg_location_))) {
219 if (!Remove(old_pkg_location_)) {
220 LOG(ERROR) << "Failed to remove symlink for extended path";
225 MoveDir(new_pkg_location_, old_pkg_location_);
226 if (move_type_ == MoveType::TO_INTERNAL) {
227 bs::error_code error;
228 bf::create_symlink(old_pkg_location_, new_pkg_location_, error);
230 LOG(ERROR) << "Failed to create symlink for extended path: "
236 if (!SetPackageDirectoryOwnerAndPermissions(old_pkg_location_,
237 context_->uid.get())) {
238 LOG(ERROR) << "Failed to set directory ownership";
245 } // namespace filesystem
246 } // namespace common_installer