b4eecb956ad60f2baf2b7289933efa138dbe9236
[platform/core/appfw/rpk-installer.git] / src / rpk / step / configuration / step_parse_rpk_manifest.cc
1 // Copyright (c) 2021 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/configuration/step_parse_rpk_manifest.h"
6
7 #include <pkgmgr-info.h>
8
9 #include <common/installer_context.h>
10 #include <common/step/step.h>
11 #include "common/utils/paths.h"
12 #include "common/utils/pkgmgr_query.h"
13
14 namespace bf = boost::filesystem;
15
16 namespace {
17
18 const char kManifestFileName[] = "tizen-manifest.xml";
19
20 }  // namespace
21
22
23 namespace rpk {
24 namespace configuration {
25
26 StepParseRpkManifest::StepParseRpkManifest(
27     common_installer::InstallerContext* context,
28     ManifestLocation manifest_location,
29     StoreLocation store_location)
30     : Step(context),
31       manifest_location_(manifest_location),
32       store_location_(store_location) {
33 }
34
35 common_installer::Step::Status StepParseRpkManifest::precheck() {
36   return common_installer::Step::Status::OK;
37 }
38
39 common_installer::Step::Status StepParseRpkManifest::process() {
40   if (context_->force_clean_from_db.get())
41     return Step::Status::OK;
42   if (!LocateConfigFile()) {
43     // continue if this is recovery, manifest file may never been created
44     if (manifest_location_ == ManifestLocation::RECOVERY) {
45       LOG(DEBUG) << "Manifest for recovery not found";
46       return Step::Status::OK;
47     }
48     LOG(ERROR) << "No manifest file exists";
49     return Step::Status::MANIFEST_NOT_FOUND;
50   }
51
52   parser_.reset(new rpk::parse::RPKConfigParser());
53   if (!parser_->ParseManifest(path_)) {
54     if (manifest_location_ == ManifestLocation::RECOVERY) {
55       LOG(DEBUG) << "Manifest for recovery is invalid";
56       bf::remove(path_);
57       return Step::Status::OK;
58     }
59     LOG(ERROR) << "[Parse] Parse failed. " <<  parser_->GetErrorMessage();
60     return Step::Status::PARSE_ERROR;
61   }
62
63   return common_installer::Step::Status::OK;
64 }
65
66 bool StepParseRpkManifest::LocateConfigFile() {
67   boost::filesystem::path manifest;
68   switch (manifest_location_) {
69     case ManifestLocation::RECOVERY: {
70       bf::path backup_path = common_installer::GetBackupPathForPackagePath(
71           context_->GetPkgPath()) / kManifestFileName;
72       bf::path in_package_path = context_->GetPkgPath() / kManifestFileName;
73       bf::path install_path =
74           bf::path(getUserManifestPath(context_->uid.get(),
75                       context_->is_readonly_package.get()))
76               / bf::path(context_->pkgid.get());
77       install_path += ".xml";
78       bf::path backup_install_path =
79           common_installer::GetBackupPathForManifestFile(install_path);
80       if (bf::exists(backup_install_path))
81         manifest = backup_install_path;
82       else if (bf::exists(backup_path))
83         manifest = backup_path;
84       else if (bf::exists(install_path))
85         manifest = install_path;
86       else if (bf::exists(in_package_path))
87         manifest = in_package_path;
88       break;
89     }
90     case ManifestLocation::INSTALLED: {
91       uid_t uid;
92       bool is_readonly = context_->is_readonly_package.get();
93       common_installer::PkgQueryInterface pkg_query(
94           context_->pkgid.get(), context_->uid.get());
95       if (pkg_query.IsGlobalPackage())
96         uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
97       else
98         uid = context_->uid.get();
99       bf::path xml_path =
100           bf::path(getUserManifestPath(uid, is_readonly))
101           / bf::path(context_->pkgid.get());
102       xml_path += ".xml";
103       context_->xml_path.set(xml_path);
104       manifest = context_->xml_path.get();
105       if (!boost::filesystem::exists(manifest)) {
106         /* This routine has added for platform update */
107         manifest = context_->unpacked_dir_path.get();
108         manifest /= kManifestFileName;
109       }
110       break;
111     }
112     case ManifestLocation::PACKAGE: {
113       manifest = context_->unpacked_dir_path.get();
114       manifest /= kManifestFileName;
115       break;
116     }
117     default: {
118       LOG(ERROR) << "Unknown manifest location value";
119       return false;
120     }
121   }
122
123   LOG(DEBUG) << "manifest path: " << manifest;
124
125   if (!boost::filesystem::exists(manifest))
126     return false;
127
128   path_ = manifest;
129   return true;
130 }
131
132 }  // namespace configuration
133 }  // namespace rpk