Fix removing packaged rw directories
[platform/core/appfw/app-installers.git] / src / common / step / mount / step_mount_install.cc
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.
4
5 #include "step/mount/step_mount_install.h"
6
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/filesystem/path.hpp>
9
10 #include <string>
11
12 #include "common/shared_dirs.h"
13 #include "common/utils/paths.h"
14 #include "common/tzip_interface.h"
15 #include "common/zip_interface.h"
16 #include "common/utils/file_util.h"
17 #include "common/utils/request.h"
18
19 namespace bf = boost::filesystem;
20 namespace bs = boost::system;
21 namespace ci = common_installer;
22
23 namespace common_installer {
24 namespace mount {
25
26 Step::Status StepMountInstall::process() {
27   auto zip_unpack = CreateZipInterface(context_->unpacked_dir_path.get());
28   if (!zip_unpack->UnmountZip()) {
29     LOG(ERROR) << "Failed to unmount zip package from temporary path";
30     return Status::APP_DIR_ERROR;
31   }
32
33   bf::path zip_destination_path =
34       GetZipPackageLocation(context_->GetPkgPath(), context_->pkgid.get());
35   if (!bf::exists(zip_destination_path.parent_path())) {
36     bs::error_code error;
37     bf::create_directories(zip_destination_path.parent_path(), error);
38     if (error) {
39       LOG(ERROR) << "Failed to create diretory: "
40                  << zip_destination_path.parent_path();
41       return Status::APP_DIR_ERROR;
42     }
43   }
44
45   if (!CopyFile(context_->file_path.get(), zip_destination_path)) {
46     return Status::APP_DIR_ERROR;
47   }
48   ci::RemoveRWDirectories(zip_destination_path);
49   context_->manifest_data.get()->zip_mount_file =
50       strdup(zip_destination_path.c_str());
51
52   bf::path mount_point = GetMountLocation(context_->GetPkgPath());
53   auto zip_final = CreateZipInterface(mount_point);
54   if (!zip_final->MountZip(zip_destination_path)) {
55     LOG(ERROR) << "Failed to mount zip package in installation path";
56     return Status::APP_DIR_ERROR;
57   }
58
59   LOG(INFO) << "Successfully mount zip package in: " << mount_point;
60   return Status::OK;
61 }
62
63 Step::Status StepMountInstall::UmountPackagePath() {
64   bf::path mount_point = GetMountLocation(context_->GetPkgPath());
65   auto zip_final = CreateZipInterface(mount_point);
66   if (!zip_final->UnmountZip()) {
67     LOG(ERROR) << "Failed to unmount zip package after installation";
68     return Status::APP_DIR_ERROR;
69   }
70
71   return Status::OK;
72 }
73
74 Step::Status StepMountInstall::undo() {
75   bs::error_code error;
76   UmountPackagePath();
77   bf::remove(GetZipPackageLocation(context_->GetPkgPath(),
78                                    context_->pkgid.get()), error);
79   if (error) {
80     LOG(ERROR) << "Failed to remove zip package";
81     return Status::APP_DIR_ERROR;
82   }
83   bf::remove_all(context_->GetPkgPath(), error);
84   if (error) {
85     LOG(ERROR) << "Failed to remove package content";
86     return Status::APP_DIR_ERROR;
87   }
88   return Status::OK;
89 }
90
91 Step::Status StepMountInstall::precheck() {
92   if (context_->root_application_path.get().empty()) {
93     LOG(ERROR) << "root_application_path attribute is empty";
94     return Step::Status::INVALID_VALUE;
95   }
96   if (!bf::exists(context_->root_application_path.get())) {
97     LOG(ERROR) << "root_application_path ("
98                << context_->root_application_path.get()
99                << ") path does not exist";
100     return Step::Status::INVALID_VALUE;
101   }
102
103   if (context_->unpacked_dir_path.get().empty()) {
104     LOG(ERROR) << "unpacked_dir_path attribute is empty";
105     return Step::Status::INVALID_VALUE;
106   }
107   if (!bf::exists(context_->unpacked_dir_path.get())) {
108     LOG(ERROR) << "unpacked_dir_path ("
109                << context_->unpacked_dir_path.get()
110                << ") path does not exist";
111     return Step::Status::INVALID_VALUE;
112   }
113
114   if (context_->pkgid.get().empty()) {
115     LOG(ERROR) << "pkgid attribute is empty";
116     return Step::Status::PACKAGE_NOT_FOUND;
117   }
118
119   return Step::Status::OK;
120 }
121
122 std::unique_ptr<IZipInterface> StepMountInstall::CreateZipInterface(
123     const boost::filesystem::path& mount_path) {
124   std::unique_ptr<IZipInterface> zip_interface(
125       new TzipInterface(mount_path));
126   return zip_interface;
127 }
128
129 }  // namespace mount
130 }  // namespace common_installer