From: Sangyoon Jang Date: Fri, 14 May 2021 07:02:32 +0000 (+0900) Subject: Refactor upgraders X-Git-Tag: submit/tizen/20210528.063157~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F72%2F258372%2F5;p=platform%2Fcore%2Fappfw%2Fpkgmgr-tool.git Refactor upgraders Now Ro2Rw / Rw2Ro become a combination of RoUpgrader / RwUpgrader. Change-Id: I7e358ef7f30ca4ae2a280ac3c50b15da98b1828e Signed-off-by: Sangyoon Jang --- diff --git a/src/pkg_upgrade/include/common_type.hh b/src/pkg_upgrade/include/common_type.hh index 2e657e1..abdf6dc 100644 --- a/src/pkg_upgrade/include/common_type.hh +++ b/src/pkg_upgrade/include/common_type.hh @@ -42,6 +42,13 @@ enum class PkgOperation { COMPLEX }; +enum class PkgVersionCompResult { + LOWER, + SAME, + HIGHER, + UNKNOWN +}; + class PkgContext { public: PkgContext(std::string id, std::string version, std::string type, diff --git a/src/pkg_upgrade/include/pkg_upgrader.hh b/src/pkg_upgrade/include/pkg_upgrader.hh index 96f446d..fc7c096 100644 --- a/src/pkg_upgrade/include/pkg_upgrader.hh +++ b/src/pkg_upgrade/include/pkg_upgrader.hh @@ -27,7 +27,7 @@ namespace common_fota { class PkgUpgrader { public: PkgUpgrader(const PkgContext& context, PkgOperation pkg_op); - PkgUpgrader(std::string id); + PkgUpgrader(std::string id, std::string version); virtual ~PkgUpgrader() = default; PkgType GetType() const; @@ -36,7 +36,8 @@ class PkgUpgrader { std::string GetId() const; std::string GetVersion() const; const BackendInvoker& GetBackendInvoker() const; - int CompareVersion(const PkgUpgrader& pkg) const; + bool CompareVersion(const PkgUpgrader& pkg, + PkgVersionCompResult* result) const; virtual bool Upgrade() = 0; diff --git a/src/pkg_upgrade/include/ro2rw_upgrader.hh b/src/pkg_upgrade/include/ro2rw_upgrader.hh index 8a30a85..c5eb3eb 100644 --- a/src/pkg_upgrade/include/ro2rw_upgrader.hh +++ b/src/pkg_upgrade/include/ro2rw_upgrader.hh @@ -21,19 +21,16 @@ namespace common_fota { +class RoUpgrader; +class RwUpgrader; + class Ro2RwUpgrader : public PkgUpgrader { public: - Ro2RwUpgrader(std::unique_ptr old_pkg, - std::unique_ptr new_pkg); + Ro2RwUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg); virtual ~Ro2RwUpgrader() = default; bool Upgrade() override; - private: - int UnzipFiles(const char* dest_path); - int UnzipXml(const std::string& pkgid); - int UnzipData(const std::string& pkgid, const std::string& dest); - int UnzipPkgFromZip(const std::string& pkgid); - private: std::unique_ptr old_pkg_; std::unique_ptr new_pkg_; diff --git a/src/pkg_upgrade/include/ro_upgrader.hh b/src/pkg_upgrade/include/ro_upgrader.hh new file mode 100644 index 0000000..b67028a --- /dev/null +++ b/src/pkg_upgrade/include/ro_upgrader.hh @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RO_UPGRADER_H_ +#define RO_UPGRADER_H_ + +#include + +#include "pkg_upgrader.hh" + +namespace common_fota { + +class RoUpgrader : public PkgUpgrader { + public: + RoUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg); + virtual ~RoUpgrader() = default; + bool Upgrade() override; + + private: + std::unique_ptr old_pkg_; + std::unique_ptr new_pkg_; +}; + +} // common_fota + +#endif // RO_UPGRADER_H_ diff --git a/src/pkg_upgrade/include/rw2ro_upgrader.hh b/src/pkg_upgrade/include/rw2ro_upgrader.hh index 1fb0d01..5e2cb28 100644 --- a/src/pkg_upgrade/include/rw2ro_upgrader.hh +++ b/src/pkg_upgrade/include/rw2ro_upgrader.hh @@ -21,10 +21,13 @@ namespace common_fota { +class RoUpgrader; +class RwUpgrader; + class Rw2RoUpgrader : public PkgUpgrader { public: - Rw2RoUpgrader(std::unique_ptr old_pkg, - std::unique_ptr new_pkg); + Rw2RoUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg); virtual ~Rw2RoUpgrader() = default; bool Upgrade() override; diff --git a/src/pkg_upgrade/include/rw_upgrader.hh b/src/pkg_upgrade/include/rw_upgrader.hh index b2a03bc..a680eed 100644 --- a/src/pkg_upgrade/include/rw_upgrader.hh +++ b/src/pkg_upgrade/include/rw_upgrader.hh @@ -17,15 +17,26 @@ #ifndef RW_UPGRADER_H_ #define RW_UPGRADER_H_ -#include "ro2rw_upgrader.hh" +#include "pkg_upgrader.hh" namespace common_fota { -class RwUpgrader : public Ro2RwUpgrader { +class RwUpgrader : public PkgUpgrader { public: - RwUpgrader(std::unique_ptr new_pkg) - : Ro2RwUpgrader(nullptr, std::move(new_pkg)) {} + RwUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg); virtual ~RwUpgrader() = default; + bool Upgrade() override; + + private: + int UnzipFiles(const char* dest_path); + int UnzipXml(const std::string& pkgid); + int UnzipData(const std::string& pkgid, const std::string& dest); + int UnzipPkgFromZip(const std::string& pkgid); + + private: + std::unique_ptr old_pkg_; + std::unique_ptr new_pkg_; }; } // common_fota diff --git a/src/pkg_upgrade/src/pkg_upgrader.cc b/src/pkg_upgrade/src/pkg_upgrader.cc index f2216c8..e683c8d 100644 --- a/src/pkg_upgrade/src/pkg_upgrader.cc +++ b/src/pkg_upgrade/src/pkg_upgrader.cc @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#include #include #include "pkg_upgrader.hh" @@ -27,9 +27,10 @@ PkgUpgrader::PkgUpgrader(const PkgContext& context, PkgOperation pkg_op) pkg_op, context.IsRemovable()) { } -PkgUpgrader::PkgUpgrader(std::string id) +PkgUpgrader::PkgUpgrader(std::string id, std::string version) : type_(PkgType::UNKNOWN), loc_(PkgLocation::UNKNOWN), - op_(PkgOperation::COMPLEX), id_(std::move(id)) { + op_(PkgOperation::COMPLEX), id_(std::move(id)), + version_(std::move(version)) { } PkgType PkgUpgrader::GetType() const { @@ -56,19 +57,22 @@ const BackendInvoker& PkgUpgrader::GetBackendInvoker() const { return backend_; } -int PkgUpgrader::CompareVersion(const PkgUpgrader& pkg) const { +bool PkgUpgrader::CompareVersion(const PkgUpgrader& pkg, + PkgVersionCompResult* result) const { pkgmgrinfo_version_compare_type compare = PMINFO_VERSION_OLD; int ret = pkgmgrinfo_compare_package_version(version_.c_str(), pkg.GetVersion().c_str(), &compare); if (ret != 0) - return -1; + return false; if (compare == PMINFO_VERSION_NEW) - return -1; + *result = PkgVersionCompResult::HIGHER; else if (compare == PMINFO_VERSION_OLD) - return 1; + *result = PkgVersionCompResult::LOWER; + else + *result = PkgVersionCompResult::SAME; - return 0; + return true; } diff --git a/src/pkg_upgrade/src/pkg_upgrader_factory.cc b/src/pkg_upgrade/src/pkg_upgrader_factory.cc index da59dcd..1712db7 100644 --- a/src/pkg_upgrade/src/pkg_upgrader_factory.cc +++ b/src/pkg_upgrade/src/pkg_upgrader_factory.cc @@ -18,6 +18,7 @@ #include "pkg_upgrader_factory.hh" #include "ro2rw_upgrader.hh" #include "rw2ro_upgrader.hh" +#include "ro_upgrader.hh" #include "rw_upgrader.hh" #include "simple_upgrader.hh" @@ -43,39 +44,53 @@ list> PkgUpgraderFactory::Merge( const auto* old_pkg = FindPkgById(old_pkgs, new_pkg.GetId()); if (old_pkg != nullptr) { // UPDATE - pkgmgrinfo_version_compare_type result; - if (pkgmgrinfo_compare_package_version( - old_pkg->GetVersion().c_str(), - new_pkg.GetVersion().c_str(), - &result) != PMINFO_R_OK) - continue; - - if (old_pkg->IsReadOnly() == new_pkg.IsReadOnly() && - result == PMINFO_VERSION_SAME) - continue; - if (old_pkg->IsReadOnly() && new_pkg.IsReadOnly()) { // RO to RO - pkgs.emplace_back(new SimpleUpgrader(new_pkg, PkgOperation::UPDATE)); + pkgs.emplace_back(new RoUpgrader( + unique_ptr(new SimpleUpgrader(*old_pkg, + PkgOperation::COMPLEX)), + unique_ptr(new SimpleUpgrader(new_pkg, + PkgOperation::UPDATE))) + ); } else if (!old_pkg->IsReadOnly() && !new_pkg.IsReadOnly()) { // RW to RW pkgs.emplace_back(new RwUpgrader( + unique_ptr(new SimpleUpgrader(*old_pkg, + PkgOperation::COMPLEX)), unique_ptr(new SimpleUpgrader(new_pkg, PkgOperation::UPDATE)))); } else if (!old_pkg->IsReadOnly() && new_pkg.IsReadOnly()) { // RW to RO pkgs.emplace_back(new Rw2RoUpgrader( - unique_ptr(new SimpleUpgrader(*old_pkg, - PkgOperation::UNINSTALL_KEEP_RW_DATA)), - unique_ptr(new SimpleUpgrader(new_pkg, - PkgOperation::INSTALL)))); + unique_ptr(new RwUpgrader( + nullptr, + std::unique_ptr(new SimpleUpgrader(*old_pkg, + PkgOperation::UNINSTALL_KEEP_RW_DATA)) + ) + ), + unique_ptr(new RoUpgrader( + nullptr, + std::unique_ptr(new SimpleUpgrader(new_pkg, + PkgOperation::INSTALL)) + ) + )) + ); } else if (old_pkg->IsReadOnly() && !new_pkg.IsReadOnly()) { // RO to RW pkgs.emplace_back(new Ro2RwUpgrader( - unique_ptr(new SimpleUpgrader(*old_pkg, - PkgOperation::UNINSTALL_KEEP_RW_DATA)), - unique_ptr(new SimpleUpgrader(new_pkg, - PkgOperation::INSTALL)))); + unique_ptr(new RoUpgrader( + nullptr, + std::unique_ptr(new SimpleUpgrader(*old_pkg, + PkgOperation::UNINSTALL_KEEP_RW_DATA)) + ) + ), + unique_ptr(new RwUpgrader( + nullptr, + std::unique_ptr(new SimpleUpgrader(new_pkg, + PkgOperation::INSTALL)) + ) + )) + ); } } else { // INSTALL @@ -84,7 +99,7 @@ list> PkgUpgraderFactory::Merge( pkgs.emplace_back(new SimpleUpgrader(new_pkg, PkgOperation::INSTALL)); } else { // RW - pkgs.emplace_back(new RwUpgrader( + pkgs.emplace_back(new RwUpgrader(nullptr, unique_ptr(new SimpleUpgrader(new_pkg, PkgOperation::INSTALL)))); } diff --git a/src/pkg_upgrade/src/ro2rw_upgrader.cc b/src/pkg_upgrade/src/ro2rw_upgrader.cc index 4f36cf8..d7d44a9 100644 --- a/src/pkg_upgrade/src/ro2rw_upgrader.cc +++ b/src/pkg_upgrade/src/ro2rw_upgrader.cc @@ -14,22 +14,23 @@ * limitations under the License. */ -#include "logging.hh" #include "ro2rw_upgrader.hh" -namespace { -constexpr char kOptZipFile[] = "/usr/system/RestoreDir/opt.zip"; -} // namespace +#include "logging.hh" +#include "ro_upgrader.hh" +#include "rw_upgrader.hh" namespace common_fota { -Ro2RwUpgrader::Ro2RwUpgrader(std::unique_ptr old_pkg, - std::unique_ptr new_pkg) - : PkgUpgrader(new_pkg->GetId()), old_pkg_(std::move(old_pkg)), - new_pkg_(std::move(new_pkg)) { +Ro2RwUpgrader::Ro2RwUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg) + : PkgUpgrader(new_pkg->GetId(), new_pkg->GetVersion()), + old_pkg_(std::move(old_pkg)), new_pkg_(std::move(new_pkg)) { } bool Ro2RwUpgrader::Upgrade() { + // RO to RW upgrade does not check version. + // Do force update to RW package always. if (old_pkg_.get() != nullptr) { if (!old_pkg_->Upgrade()) { LOG(ERROR) << "old_pkg_->Upgrade() failed"; @@ -37,11 +38,6 @@ bool Ro2RwUpgrader::Upgrade() { } } - if (UnzipPkgFromZip(new_pkg_->GetId().c_str()) != 0) { - LOG(ERROR) << "UnzipPkgFromZip(" << new_pkg_->GetId() << ") failed"; - return false; - } - if (new_pkg_.get() != nullptr) { if (!new_pkg_->Upgrade()) { LOG(ERROR) << "new_pkg_->Upgrade() failed"; @@ -52,53 +48,4 @@ bool Ro2RwUpgrader::Upgrade() { return true; } -int Ro2RwUpgrader::UnzipFiles(const char* dest_path) { - const char* unzip_argv[] = { "/usr/bin/unzip", "-oXqq", kOptZipFile, - dest_path, "-d", "/", nullptr }; - int ret = BackendInvoker::XSystem(unzip_argv); - - return ret; -} - -int Ro2RwUpgrader::UnzipXml(const std::string& pkgid) { - std::string path = "opt/share/packages/" + pkgid + ".xml"; - int ret = UnzipFiles(path.c_str()); - - return ret; -} - -int Ro2RwUpgrader::UnzipData(const std::string& pkgid, - const std::string& dest) { - std::string path = dest + pkgid + "/*"; - int ret = UnzipFiles(path.c_str()); - if (ret != 0) - return -1; - - return 0; -} - -int Ro2RwUpgrader::UnzipPkgFromZip(const std::string& pkgid) { - int ret = -1; - - ret = UnzipXml(pkgid); - if (ret != 0) { - LOG(ERROR) << "UnzipXml(" << pkgid << ") failed"; - return ret; - } - - ret = UnzipData(pkgid, "opt/usr/globalapps/"); - if (ret != 0) { - LOG(ERROR) << "UnzipData(" << pkgid << ") failed"; - return ret; - } - - ret = UnzipData(pkgid, "opt/etc/skel/apps_rw/"); - if (ret != 0) { - LOG(ERROR) << "UnzipData(" << pkgid << ") failed"; - return ret; - } - - return 0; -} - } // namespace common_fota diff --git a/src/pkg_upgrade/src/ro_upgrader.cc b/src/pkg_upgrade/src/ro_upgrader.cc new file mode 100644 index 0000000..3dadc68 --- /dev/null +++ b/src/pkg_upgrade/src/ro_upgrader.cc @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ro_upgrader.hh" + +#include "common_type.hh" +#include "logging.hh" + +namespace common_fota { + +RoUpgrader::RoUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg) + : PkgUpgrader(new_pkg->GetId(), new_pkg->GetVersion()), + old_pkg_(std::move(old_pkg)), new_pkg_(std::move(new_pkg)) { +} + +bool RoUpgrader::Upgrade() { + if (old_pkg_) { + PkgVersionCompResult result = PkgVersionCompResult::UNKNOWN; + if (!new_pkg_->CompareVersion(*old_pkg_, &result)) { + LOG(ERROR) << "Failed to compare version of package(" << new_pkg_->GetId() + << ")"; + return false; + } + + if (result == PkgVersionCompResult::SAME) { + LOG(INFO) << new_pkg_->GetId() << " has same version(" + << new_pkg_->GetVersion() << "). Nothing to do."; + return true; + } + } + + if (!new_pkg_->Upgrade()) { + LOG(ERROR) << "new_pkg_->Upgrade() failed"; + return false; + } + + return true; +} + +} // namespace common_fota diff --git a/src/pkg_upgrade/src/rw2ro_upgrader.cc b/src/pkg_upgrade/src/rw2ro_upgrader.cc index 51fde37..8fbae7a 100644 --- a/src/pkg_upgrade/src/rw2ro_upgrader.cc +++ b/src/pkg_upgrade/src/rw2ro_upgrader.cc @@ -14,30 +14,43 @@ * limitations under the License. */ -#include "logging.hh" #include "rw2ro_upgrader.hh" +#include "logging.hh" +#include "ro_upgrader.hh" +#include "rw_upgrader.hh" + namespace common_fota { -Rw2RoUpgrader::Rw2RoUpgrader(std::unique_ptr old_pkg, - std::unique_ptr new_pkg) - : PkgUpgrader(new_pkg->GetId()), old_pkg_(std::move(old_pkg)), - new_pkg_(std::move(new_pkg)) { +Rw2RoUpgrader::Rw2RoUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg) + : PkgUpgrader(new_pkg->GetId(), new_pkg->GetVersion()), + old_pkg_(std::move(old_pkg)), new_pkg_(std::move(new_pkg)) { } bool Rw2RoUpgrader::Upgrade() { - if (new_pkg_->CompareVersion(*old_pkg_) >= 0) { - if (!old_pkg_->Upgrade()) { - LOG(ERROR) << "old_pkg_->Upgrade() failed"; - return false; - } - - if (!new_pkg_->Upgrade()) { - LOG(ERROR) << "new_pkg_->Upgrade() failed"; - return false; - } - } else { - LOG(DEBUG) << "new_pkg version < old_pkg version"; + // Update only if New RO package has higher(or same) version. + PkgVersionCompResult result = PkgVersionCompResult::UNKNOWN; + if (!new_pkg_->CompareVersion(*old_pkg_, &result)) { + LOG(ERROR) << "Failed to compare version of package(" << new_pkg_->GetId() + << ")"; + return false; + } + + if (result == PkgVersionCompResult::LOWER) { + LOG(INFO) << old_pkg_->GetId() << " has higher version(" + << old_pkg_->GetVersion() << ") already. Nothing to do."; + return true; + } + + if (!old_pkg_->Upgrade()) { + LOG(ERROR) << "old_pkg_->Upgrade() failed"; + return false; + } + + if (!new_pkg_->Upgrade()) { + LOG(ERROR) << "new_pkg_->Upgrade() failed"; + return false; } return true; diff --git a/src/pkg_upgrade/src/rw_upgrader.cc b/src/pkg_upgrade/src/rw_upgrader.cc new file mode 100644 index 0000000..1fce8d0 --- /dev/null +++ b/src/pkg_upgrade/src/rw_upgrader.cc @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2021 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rw_upgrader.hh" + +#include "common_type.hh" +#include "logging.hh" + +namespace { + +constexpr char kOptZipFile[] = "/usr/system/RestoreDir/opt.zip"; + +} // namespace + +namespace common_fota { + +RwUpgrader::RwUpgrader(std::unique_ptr old_pkg, + std::unique_ptr new_pkg) + : PkgUpgrader(new_pkg->GetId(), new_pkg->GetVersion()), + old_pkg_(std::move(old_pkg)), new_pkg_(std::move(new_pkg)) { +} + +bool RwUpgrader::Upgrade() { + if (old_pkg_) { + PkgVersionCompResult result = PkgVersionCompResult::UNKNOWN; + if (!new_pkg_->CompareVersion(*old_pkg_, &result)) { + LOG(ERROR) << "Failed to compare version of package(" << new_pkg_->GetId() + << ")"; + return false; + } + + if (result == PkgVersionCompResult::SAME) { + LOG(INFO) << new_pkg_->GetId() << " has same version(" + << new_pkg_->GetVersion() << "). Nothing to do."; + return true; + } + } + + if (UnzipPkgFromZip(new_pkg_->GetId().c_str()) != 0) { + LOG(ERROR) << "UnzipPkgFromZip(" << new_pkg_->GetId() << ") failed"; + return false; + } + + if (!new_pkg_->Upgrade()) { + LOG(ERROR) << "new_pkg_->Upgrade() failed"; + return false; + } + + return true; +} + +int RwUpgrader::UnzipFiles(const char* dest_path) { + const char* unzip_argv[] = { "/usr/bin/unzip", "-oXqq", kOptZipFile, + dest_path, "-d", "/", nullptr }; + int ret = BackendInvoker::XSystem(unzip_argv); + + return ret; +} + +int RwUpgrader::UnzipXml(const std::string& pkgid) { + std::string path = "opt/share/packages/" + pkgid + ".xml"; + int ret = UnzipFiles(path.c_str()); + + return ret; +} + +int RwUpgrader::UnzipData(const std::string& pkgid, + const std::string& dest) { + std::string path = dest + pkgid + "/*"; + int ret = UnzipFiles(path.c_str()); + if (ret != 0) + return -1; + + return 0; +} + +int RwUpgrader::UnzipPkgFromZip(const std::string& pkgid) { + int ret = -1; + + ret = UnzipXml(pkgid); + if (ret != 0) { + LOG(ERROR) << "UnzipXml(" << pkgid << ") failed"; + return ret; + } + + ret = UnzipData(pkgid, "opt/usr/globalapps/"); + if (ret != 0) { + LOG(ERROR) << "UnzipData(" << pkgid << ") failed"; + return ret; + } + + ret = UnzipData(pkgid, "opt/etc/skel/apps_rw/"); + if (ret != 0) { + LOG(ERROR) << "UnzipData(" << pkgid << ") failed"; + return ret; + } + + return 0; +} + +} // namespace common_fota