Implement rollback operations for StepRemoveFiles.
If any action after file removal fails then the old
content of package should be restored.
Icons removal was moved to another step.
Change-Id: I532ad5d03bbd99ed29db4db565a6a2ea4d96a7d4
step/step_register_app.cc
step/step_old_manifest.cc
step/step_parse.cc
+ step/step_remove_icons.cc
step/step_remove_files.cc
step/step_revoke_security.cc
step/step_register_security.cc
// Use of this source code is governed by an apache 2.0 license that can be
// found in the LICENSE file.
-
#include "common/step/step_remove_files.h"
-#include <pkgmgr-info.h>
-
-#include <cstring>
+#include <boost/system/error_code.hpp>
#include "common/utils/file_util.h"
namespace common_installer {
namespace remove {
+namespace bs = boost::system;
namespace fs = boost::filesystem;
Step::Status StepRemoveFiles::precheck() {
LOG(ERROR) << "pkg_path ("
<< context_->pkg_path.get()
<< ") path does not exist";
-
- if (context_->xml_path.get().empty())
- LOG(ERROR) << "xml_path attribute is empty";
- else if (!fs::exists(context_->xml_path.get()))
- LOG(ERROR) << "xml_path ("
- << context_->xml_path.get()
- << ") path does not exist";
-
// TODO(p.sikorski) check context_->uid.get()
return Step::Status::OK;
}
Step::Status StepRemoveFiles::process() {
- uiapplication_x* ui = context_->manifest_data.get()->uiapplication;
-
- fs::remove_all(context_->pkg_path.get());
- for (; ui != nullptr; ui = ui->next) {
- fs::path app_icon = fs::path(getIconPath(context_->uid.get()))
- / fs::path(ui->appid);
- app_icon += fs::path(".png");
- if (fs::exists(app_icon))
- fs::remove_all(app_icon);
+ fs::path backup_path = GetBackupPathForPackagePath(context_->pkg_path.get());
+ if (!MoveDir(context_->pkg_path.get(), backup_path)) {
+ LOG(ERROR) << "Cannot remove widget files from its location";
+ return Status::ERROR;
}
- fs::remove_all(context_->xml_path.get());
-
- LOG(DEBUG) << "Removing dir: " << context_->pkg_path.get();
-
+ LOG(DEBUG) << "Removed directory: " << context_->pkg_path.get();
return Status::OK;
}
Step::Status StepRemoveFiles::clean() {
+ bs::error_code error;
+ fs::path backup_path = GetBackupPathForPackagePath(context_->pkg_path.get());
+ fs::remove_all(backup_path, error);
return Status::OK;
}
Step::Status StepRemoveFiles::undo() {
+ fs::path backup_path = GetBackupPathForPackagePath(context_->pkg_path.get());
+ if (fs::exists(backup_path)) {
+ LOG(DEBUG) << "Restoring directory: " << context_->pkg_path.get();
+ if (!MoveDir(backup_path, context_->pkg_path.get())) {
+ LOG(ERROR) << "Cannot restore widget files";
+ return Status::OK;
+ }
+ }
+
return Status::OK;
}
--- /dev/null
+// Copyright (c) 2015 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/step_remove_icons.h"
+
+#include <boost/system/error_code.hpp>
+#include <pkgmgr-info.h>
+
+#include <cstring>
+
+#include "common/utils/clist_helpers.h"
+#include "common/utils/file_util.h"
+
+namespace common_installer {
+namespace remove_icons {
+
+namespace bs = boost::system;
+namespace fs = boost::filesystem;
+
+Step::Status StepRemoveIcons::precheck() {
+ if (!context_->manifest_data.get()) {
+ LOG(ERROR) << "manifest_data attribute is empty";
+ return Status::ERROR;
+ }
+
+ return Status::OK;
+}
+
+Step::Status StepRemoveIcons::process() {
+ uiapplication_x* ui = nullptr;
+ PKGMGR_LIST_MOVE_NODE_TO_HEAD(context_->manifest_data.get()->uiapplication,
+ ui);
+ for (; ui != nullptr; ui = ui->next) {
+ fs::path app_icon = fs::path(getIconPath(context_->uid.get()))
+ / fs::path(ui->appid);
+ app_icon += fs::path(".png");
+ if (fs::exists(app_icon)) {
+ fs::path backup_icon_file = app_icon;
+ backup_icon_file += ".bck";
+ if (!MoveFile(app_icon, backup_icon_file)) {
+ LOG(ERROR) << "Failed to create backup for icon: " << app_icon;
+ return Status::ERROR;
+ }
+ backups_.emplace_back(backup_icon_file, app_icon);
+ }
+ }
+ return Status::OK;
+}
+
+Step::Status StepRemoveIcons::clean() {
+ bs::error_code error;
+ if (!backups_.empty()) {
+ LOG(DEBUG) << "Clean up icons files...";
+ for (auto& pair : backups_) {
+ fs::remove(pair.first, error);
+ if (error) {
+ LOG(WARNING) << "Failed to remove: " << pair.first;
+ }
+ }
+ }
+ return Status::OK;
+}
+
+Step::Status StepRemoveIcons::undo() {
+ if (!backups_.empty()) {
+ LOG(DEBUG) << "Restoring icons files...";
+ for (auto& pair : backups_) {
+ if (!MoveFile(pair.first, pair.second)) {
+ LOG(ERROR) << "Failed to restore: " << pair.second;
+ // We need to try to restore all icons anyway...
+ }
+ }
+ }
+ return Status::OK;
+}
+} // namespace remove_icons
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2015 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_STEP_REMOVE_ICONS_H_
+#define COMMON_STEP_STEP_REMOVE_ICONS_H_
+
+#include <boost/filesystem/path.hpp>
+
+#include <utility>
+#include <vector>
+
+#include "common/context_installer.h"
+#include "common/step/step.h"
+#include "common/utils/logging.h"
+
+namespace common_installer {
+namespace remove_icons {
+
+class StepRemoveIcons : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override;
+ Status undo() override;
+ Status precheck() override;
+
+ private:
+ std::vector<std::pair<boost::filesystem::path, boost::filesystem::path>>
+ backups_;
+
+ SCOPE_LOG_TAG(RemoveIcons)
+};
+
+} // namespace remove_icons
+} // namespace common_installer
+
+#endif // COMMON_STEP_STEP_REMOVE_ICONS_H_
#include "common/step/step_old_manifest.h"
#include "common/step/step_parse.h"
#include "common/step/step_register_app.h"
+#include "common/step/step_remove_icons.h"
#include "common/step/step_remove_files.h"
#include "common/step/step_revoke_security.h"
#include "common/step/step_register_security.h"
ai.AddStep<ci::parse::StepParse>();
ai.AddStep<ci::unregister_app::StepUnregisterApplication>();
ai.AddStep<ci::remove::StepRemoveFiles>();
+ ai.AddStep<ci::remove_icons::StepRemoveIcons>();
ai.AddStep<ci::revoke_security::StepRevokeSecurity>();
return ai.Run();
#include "common/step/step_generate_xml.h"
#include "common/step/step_parse.h"
#include "common/step/step_register_app.h"
+#include "common/step/step_remove_icons.h"
#include "common/step/step_remove_files.h"
#include "common/step/step_revoke_security.h"
#include "common/step/step_register_security.h"
installer.AddStep<ci::parse::StepParse>();
installer.AddStep<ci::unregister_app::StepUnregisterApplication>();
installer.AddStep<ci::remove::StepRemoveFiles>();
+ installer.AddStep<ci::remove_icons::StepRemoveIcons>();
installer.AddStep<ci::revoke_security::StepRevokeSecurity>();
break;
}