1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/rds/step_rds_modify.h"
7 #include <boost/system/error_code.hpp>
9 #include <manifest_parser/utils/logging.h>
11 #include <common/utils/file_util.h>
13 namespace common_installer {
16 namespace bf = boost::filesystem;
17 namespace bs = boost::system;
18 namespace ci = common_installer;
20 StepRDSModify::StepRDSModify(InstallerContext* context)
23 Step::Status StepRDSModify::precheck() {
24 if (context_->unpacked_dir_path.get().empty()) {
25 LOG(ERROR) << "unpacked dir path is not set";
26 return common_installer::Step::Status::INVALID_VALUE;
28 if (!bf::exists(context_->unpacked_dir_path.get())) {
29 LOG(ERROR) << "unpacked_dir_path ("
30 << context_->unpacked_dir_path.get()
31 << ") path does not exist";
32 return Step::Status::INVALID_VALUE;
34 if (context_->root_application_path.get().empty()) {
35 LOG(ERROR) << "pkgid is not set";
36 return Step::Status::PACKAGE_NOT_FOUND;
38 if (context_->pkgid.get().empty()) {
39 LOG(ERROR) << "pkgid is not set";
40 return Step::Status::PACKAGE_NOT_FOUND;
42 if (!context_->manifest_data.get()) {
43 LOG(ERROR) << "no manifest info available";
44 return Step::Status::INVALID_VALUE;
46 return Step::Status::OK;
49 Step::Status StepRDSModify::process() {
50 LOG(INFO) << "entered process of step modify";
51 if (!SetUpTempBackupDir()) {
52 LOG(ERROR) << "unable to setup temp directory";
53 return Step::Status::ERROR;
55 bf::path install_path = context_->GetPkgPath();
56 bf::path unzip_path = context_->unpacked_dir_path.get();
57 if (!AddFiles(unzip_path, install_path) ||
58 !ModifyFiles(unzip_path, install_path) ||
59 !DeleteFiles(install_path)) {
60 LOG(ERROR) << "error during file operation";
61 return Step::Status::ERROR;
63 return Step::Status::OK;
66 Step::Status StepRDSModify::undo() {
68 return Step::Status::OK;
71 Step::Status StepRDSModify::clean() {
72 RemoveAll(backup_temp_dir_);
73 return Step::Status::OK;
76 bool StepRDSModify::AddFiles(bf::path unzip_path, bf::path install_path) {
77 LOG(INFO) << "about to add files";
79 for (const auto& file : context_->files_to_add.get()) {
80 if (!PerformBackup(file, Operation::ADD)) {
81 LOG(ERROR) << "unable to perform backup of added file";
84 bf::path temp_install_path(install_path / file);
85 if (bf::is_directory(temp_install_path)) {
86 if (!bf::exists(temp_install_path) &&
87 (!CreateDir(temp_install_path))) {
88 LOG(ERROR) << "unable to create dir for temp backup data";
92 if (!bf::exists(temp_install_path.parent_path()) &&
93 !CreateDir(temp_install_path.parent_path())) {
94 LOG(ERROR) << "unable to create dir for temp backup data";
97 bf::path temp_unzip_path(unzip_path / file);
98 bf::copy_file(temp_unzip_path, temp_install_path, error);
100 LOG(ERROR) << "unable to add file " << error.message();
108 bool StepRDSModify::ModifyFiles(bf::path unzip_path, bf::path install_path) {
109 LOG(INFO) << "about to modify files";
110 bs::error_code error;
111 for (const auto& file : context_->files_to_modify.get()) {
112 bf::path temp_install_path(install_path / file);
113 bf::path temp_unzip_path(unzip_path / file);
114 if (!PerformBackup(file, Operation::MODIFY)) {
115 LOG(ERROR) << "unable to perform backup of to be modified file";
118 bf::copy_file(temp_unzip_path, temp_install_path,
119 bf::copy_option::overwrite_if_exists, error);
121 LOG(ERROR) << "unable to modify file " << error.message();
128 bool StepRDSModify::DeleteFiles(bf::path install_path) {
129 LOG(INFO) << "about to delete files";
130 for (const auto& file : context_->files_to_delete.get()) {
131 if (!PerformBackup(file, Operation::DELETE)) {
132 LOG(ERROR) << "unable to perform backup of to be deleted file";
135 if (!Remove(install_path / file))
141 bool StepRDSModify::SetUpTempBackupDir() {
142 LOG(INFO) << "about to setup tmp backup dir";
143 bs::error_code error;
144 backup_temp_dir_ = "/tmp/" /
145 bf::unique_path("%%%%-%%%%-%%%%-%%%%", error);
146 if (error || !CreateDir(backup_temp_dir_)) {
147 LOG(ERROR) << "unable to create backup data temp dir";
154 bool StepRDSModify::PerformBackup(std::string relative_path,
155 Operation operation) {
156 if (backup_temp_dir_.empty())
158 if (operation == Operation::DELETE || operation == Operation::MODIFY) {
159 bf::path app_path = context_->GetPkgPath();
160 bf::path source_path = app_path / relative_path;
161 if (bf::is_directory(source_path)) {
162 if (!CreateDir(backup_temp_dir_ / relative_path)) {
163 LOG(ERROR) << "unable to create dir for temp backup data";
167 bs::error_code error;
168 bf::path tmp_dest_path = backup_temp_dir_ / relative_path;
169 if (!bf::exists((tmp_dest_path).parent_path()) &&
170 (!CreateDir((tmp_dest_path).parent_path()))) {
171 LOG(ERROR) << "unable to create dir for temp backup data";
174 bf::copy_file(source_path, tmp_dest_path, error);
176 LOG(ERROR) << "unable to backup file: "
177 << source_path << " : " << error.message();
182 success_modifications_.push_back(std::make_pair(relative_path, operation));
186 void StepRDSModify::RestoreFiles() {
187 LOG(ERROR) << "error occured about to restore files";
188 bf::path app_path(context_->GetPkgPath());
189 for (std::pair<std::string, Operation>& modification :
190 success_modifications_) {
191 bf::path source_path(backup_temp_dir_ / modification.first);
192 bf::path destination_path(app_path / modification.first);
193 if (modification.second == Operation::ADD) {
194 if (bf::is_directory(source_path)) {
195 bf::remove_all(destination_path);
197 bf::remove(destination_path);
199 } else if (modification.second == Operation::MODIFY) {
200 bf::copy_file(source_path, destination_path,
201 bf::copy_option::overwrite_if_exists);
203 if (bf::is_directory(source_path)) {
204 if (!CreateDir(destination_path))
205 LOG(ERROR) << "Failed to create dir: " << destination_path;
207 bf::copy_file(source_path, destination_path,
208 bf::copy_option::overwrite_if_exists);
212 // after files are restore delete temporary location
213 bf::remove_all(backup_temp_dir_);
217 } // namespace common_installer