Rollback for StepUnregisterApp 23/43923/3
authorTomasz Iwanek <t.iwanek@samsung.com>
Tue, 14 Jul 2015 12:25:31 +0000 (14:25 +0200)
committerTomasz Iwanek <t.iwanek@samsung.com>
Wed, 15 Jul 2015 13:06:03 +0000 (15:06 +0200)
Implement rollback operations for unregistering app.
Package should be fully restored in pkgmgr database
in case of failure of any subsequent step failures.

StepBackupManifest was changed to create copy of manifest
instead of moving it.

Original xml manifest file is used to
unregister application in StepUnregisterApplication and
is removed by uninstallation later.

Backup xml manifest file is used to restore package in
pkgmgr in case of rollback and is removed by StepBackupManifest
(this step is managing lifetime of backup file).

Change-Id: I51a055deb690425151d287262eed73d8b19acbf1

src/common/step/step_backup_manifest.cc
src/common/step/step_unregister_app.cc
src/common/step/step_unregister_app.h
src/tpk/task.cc
src/wgt/wgt_backend.cc

index 9b74f9e..770b867 100644 (file)
@@ -11,6 +11,7 @@
 #include <pkgmgr-info.h>
 #include <pkgmgr_installer.h>
 
+#include <algorithm>
 #include <string>
 
 #include "common/utils/file_util.h"
@@ -33,11 +34,11 @@ Step::Status StepBackupManifest::precheck() {
 Step::Status StepBackupManifest::process() {
   // set backup file path
   bf::path backup_xml_path = context_->xml_path.get();
-  backup_xml_path =  + ".bck";
+  backup_xml_path += ".bck";
   context_->backup_xml_path.set(backup_xml_path);
-
-  if (!MoveFile(context_->xml_path.get(),
-      context_->backup_xml_path.get())) {
+  bs::error_code error;
+  bf::copy(context_->xml_path.get(), context_->backup_xml_path.get(), error);
+  if (error) {
     LOG(ERROR) << "Failed to make a copy of xml manifest file";
     return Status::ERROR;
   }
index 769e4c9..ba111e3 100755 (executable)
@@ -6,8 +6,11 @@
 
 #include <boost/filesystem.hpp>
 #include <pkgmgr_installer.h>
+#include <vcore/Base64.h>
+#include <vcore/Certificate.h>
+
 #include <cassert>
-#include <cstring>
+#include <string>
 
 #include "common/pkgmgr_registration.h"
 #include "common/step/step_unregister_app.h"
@@ -21,17 +24,22 @@ namespace fs = boost::filesystem;
 Step::Status StepUnregisterApplication::precheck() {
   if (context_->pkgid.get().empty()) {
     LOG(ERROR) << "pkgid attribute is empty";
-    return Step::Status::INVALID_VALUE;
+    return Status::INVALID_VALUE;
   }
   if (context_->xml_path.get().empty()) {
     LOG(ERROR) << "xml_path attribute is empty";
-    return Step::Status::INVALID_VALUE;
+    return Status::INVALID_VALUE;
   }
   if (!boost::filesystem::exists(context_->xml_path.get())) {
     LOG(ERROR) << "xml_path ("
                << context_->xml_path.get()
                << ") path does not exist";
-    return Step::Status::INVALID_VALUE;
+    return Status::INVALID_VALUE;
+  }
+
+  if (context_->backup_xml_path.get().empty()) {
+    LOG(ERROR) << "Backup xml path was not set but is required";
+    return Status::INVALID_VALUE;
   }
 
   // TODO(p.sikorski) check context_->uid.get()
@@ -39,7 +47,24 @@ Step::Status StepUnregisterApplication::precheck() {
   return Step::Status::OK;
 }
 
+void StepUnregisterApplication::BackupCertInfo() {
+  std::string base64 = QueryCertificateAuthorCertificate(context_->pkgid.get(),
+                                                         context_->uid.get());
+  if (!base64.empty()) {
+    ValidationCore::Base64Decoder decoder;
+    decoder.append(base64);
+    decoder.finalize();
+    CertificateInfo certificate_info;
+    certificate_info.author_certificate.set(ValidationCore::CertificatePtr(
+        new ValidationCore::Certificate(decoder.get())));
+    context_->certificate_info.set(certificate_info);
+  }
+}
+
 Step::Status StepUnregisterApplication::process() {
+  // Prepare certificate info for rollback operations
+  BackupCertInfo();
+
   if (!UnregisterAppInPkgmgr(context_->xml_path.get(), context_->pkgid.get(),
                              context_->uid.get())) {
     LOG(ERROR) << "Failed to unregister package into database";
@@ -51,5 +76,19 @@ Step::Status StepUnregisterApplication::process() {
   return Status::OK;
 }
 
+Step::Status StepUnregisterApplication::undo() {
+  if (!RegisterAppInPkgmgr(context_->backup_xml_path.get(),
+                           context_->pkgid.get().c_str(),
+                           context_->certificate_info.get(),
+                           context_->uid.get())) {
+    LOG(ERROR) << "Failed to restore the app registration in pkgmgr";
+    // Continue to revert...
+    return Step::Status::OK;
+  }
+
+  LOG(INFO) << "Successfully restored the app registration in pkgmgr";
+  return Status::OK;
+}
+
 }  // namespace unregister_app
 }  // namespace common_installer
index 98e34bb..cc86273 100755 (executable)
@@ -18,14 +18,16 @@ class StepUnregisterApplication : public Step {
 
   Step::Status process() override;
   Step::Status clean() override { return Status::OK; }
-  Step::Status undo() override { return Status::OK; }
+  Step::Status undo() override;
   Status precheck() override;
 
+ private:
+  void BackupCertInfo();
+
   SCOPE_LOG_TAG(Unregister)
 };
 
 }  // namespace unregister_app
 }  // namespace common_installer
 
-
 #endif  // COMMON_STEP_STEP_UNREGISTER_APP_H_
index 5db820a..af0bf23 100644 (file)
@@ -134,6 +134,7 @@ int Task::Uninstall() {
 
   ai.AddStep<ci::configure::StepConfigure>();
   ai.AddStep<ci::parse::StepParse>();
+  ai.AddStep<ci::backup_manifest::StepBackupManifest>();
   ai.AddStep<ci::unregister_app::StepUnregisterApplication>();
   ai.AddStep<ci::remove::StepRemoveFiles>();
   ai.AddStep<ci::remove_icons::StepRemoveIcons>();
index dfd867b..d9ee266 100644 (file)
@@ -85,6 +85,7 @@ int main(int argc, char** argv) {
     case ci::PkgMgrInterface::Type::Uninstall: {
       installer.AddStep<ci::configure::StepConfigure>();
       installer.AddStep<ci::parse::StepParse>();
+      installer.AddStep<ci::backup_manifest::StepBackupManifest>();
       installer.AddStep<ci::unregister_app::StepUnregisterApplication>();
       installer.AddStep<ci::remove::StepRemoveFiles>();
       installer.AddStep<ci::remove_icons::StepRemoveIcons>();