partial install/update feature.
keep-rwdata feature.
clean feature
- if manifest not exist but pkg exists in db.
pkg_initdb option added
Requires :
https://review.tizen.org/gerrit/#/c/100625/
https://review.tizen.org/gerrit/#/c/100891/
Usage:
#tpk-backend -y {pkgid} --preload --partial-rw
#tpk-backend -d {pkgid} --preload --force-remove --partial-rw
#tpk-backend -d {pkgid} --preload-rw --keep-rwdata
#tpk-backend -y {pkgid} --u {userid} --bg-operation
#pkg_initdb --partial-rw (for 2.4 -> 3.0 migration)
#pkg_initdb --ro (for MIC)
Change-Id: Ib6066332fd9e462a3b8afe446c15c94971745ca6
Signed-off-by: jongmyeongko <jongmyeong.ko@samsung.com>
Name: app-installers
Summary: Application installers
-Version: 1.10
+Version: 1.11
Release: 1
Group: Application Framework/Package Management
License: Apache-2.0
is_preload_rw_package(false),
force_remove(false),
no_remove(false),
+ keep_rwdata(false),
+ partial_rw(false),
+ force_clean_from_db(false),
cross_app_rules(false) {}
InstallerContext::~InstallerContext() {
Property<bool> is_preload_rw_package;
/**
- * \brief force-remove request received from pkgmgr_installer
+ * \brief force-remove flag received from pkgmgr_installer
*/
Property<bool> force_remove;
/**
- * \brief no-remove request received from pkgmgr_installer
+ * \brief no-remove flag received from pkgmgr_installer
*/
Property<bool> no_remove;
/**
+ * \brief keep-rwdata flag received from pkgmgr_installer
+ */
+ Property<bool> keep_rwdata;
+
+ /**
+ * \brief partial-rw flag received from pkgmgr_installer
+ */
+ Property<bool> partial_rw;
+
+ /**
+ * \brief Describes force clean behaviour from db data. It set to ture,
+ * the uninstallation will be done to the end of steps.
+ */
+ Property<bool> force_clean_from_db;
+
+ /**
* \brief Describes behaviour for security manager. It set to true, this will
* force to generates n-to-n rules for package's apps.
* This will be used for hybrid apps.
}
}
case PKGMGR_REQ_UNINSTALL:
- return RequestType::Uninstall;
+ if (GetIsPreloadRequest() && GetIsPartialRW())
+ return RequestType::PartialUninstall;
+ else
+ return RequestType::Uninstall;
case PKGMGR_REQ_REINSTALL:
return RequestType::Reinstall;
case PKGMGR_REQ_CLEAR:
case PKGMGR_REQ_MOVE:
return RequestType::Move;
case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
- if (!is_app_installed_.get())
- return RequestType::ManifestDirectInstall;
- else
- return RequestType::ManifestDirectUpdate;
+ if (!is_app_installed_.get()) {
+ if (GetIsPreloadRequest() && GetIsPartialRW())
+ return RequestType::ManifestPartialInstall;
+ else
+ return RequestType::ManifestDirectInstall;
+ } else {
+ if (GetIsPreloadRequest() && GetIsPartialRW())
+ return RequestType::ManifestPartialUpdate;
+ else
+ return RequestType::ManifestDirectUpdate;
+ }
case PKGMGR_REQ_MOUNT_INSTALL:
if (!is_app_installed_.get())
return RequestType::MountInstall;
return boost::filesystem::path(pkgmgr_installer_get_tep_path(pi_));
}
-bool PkgMgrInterface::GetIsTepMove() {
+bool PkgMgrInterface::GetIsTepMove() const {
return (pkgmgr_installer_get_tep_move_type(pi_) == 1);
}
-bool PkgMgrInterface::GetIsMoveToExternal() {
+bool PkgMgrInterface::GetIsMoveToExternal() const {
return (pkgmgr_installer_get_move_type(pi_) == 1);
}
-bool PkgMgrInterface::GetIsPreloadRequest() {
+bool PkgMgrInterface::GetIsPreloadRequest() const {
return (pkgmgr_installer_get_is_preload(pi_) == 1);
}
-bool PkgMgrInterface::GetIsPreloadRWRequest() {
+bool PkgMgrInterface::GetIsPreloadRWRequest() const {
return (pkgmgr_installer_get_is_preload_rw(pi_) == 1);
}
+bool PkgMgrInterface::GetIsKeepRWData() const {
+ return (pkgmgr_installer_get_keep_rwdata(pi_) == 1);
+}
+
+bool PkgMgrInterface::GetIsPartialRW() const {
+ return (pkgmgr_installer_get_partial_rw(pi_) == 1);
+}
+
std::unique_ptr<PkgmgrSignal> PkgMgrInterface::CreatePkgmgrSignal() const {
if (!pkgmgr_installer_interface_->ShouldCreateSignal())
return nullptr;
return std::unique_ptr<PkgmgrSignal>(new PkgmgrSignal(pi_, GetRequestType()));
}
-bool PkgMgrInterface::GetIsForceRemoval() {
+bool PkgMgrInterface::GetIsForceRemoval() const {
return (pkgmgr_installer_get_force_removal(pi_) == 1);
}
-bool PkgMgrInterface::GetIsNoRemoval() {
+bool PkgMgrInterface::GetIsNoRemoval() const {
return (pkgmgr_installer_get_no_removal(pi_) == 1);
}
*
* \return True if TEP file should be moved. Otherwise, return false
*/
- bool GetIsTepMove();
+ bool GetIsTepMove() const;
/**
* Returns True if move request is to external. Otherwise, return false
*
* \return True if move request is to external. Otherwise, return false
*/
- bool GetIsMoveToExternal();
+ bool GetIsMoveToExternal() const;
/**
* Returns True if the request is for preload. Otherwise, return false
*
* \return True if the request is for preload. Otherwise, return false
*/
- bool GetIsPreloadRequest();
+ bool GetIsPreloadRequest() const;
/**
* Returns True if the request is for preload-rw. Otherwise, return false
*
* \return True if the request is for preload-rw. Otherwise, return false
*/
- bool GetIsPreloadRWRequest();
+ bool GetIsPreloadRWRequest() const;
/**
- * Returns True if the request is for force-remove. Otherwise, return false
+ * Returns True if the request has force-remove flag. Otherwise, return false
*
- * \return True if the request is for force-remove. Otherwise, return false
+ * \return True if the request has force-remove flag. Otherwise, return false
*/
- bool GetIsForceRemoval();
+ bool GetIsForceRemoval() const;
/**
- * Returns True if the request is for no-remove. Otherwise, return false
+ * Returns True if the request has no-remove flag. Otherwise, return false
*
- * \return True if the request is for no-remove. Otherwise, return false
+ * \return True if the request has no-remove flag. Otherwise, return false
*/
- bool GetIsNoRemoval();
+ bool GetIsNoRemoval() const;
+
+ /**
+ * Returns True if the request has keep-rwdata flag. Otherwise, return false
+ *
+ * \return True if the request has keep-rwdata flag. Otherwise, return false
+ */
+ bool GetIsKeepRWData() const;
+
+ /**
+ * Returns True if the request has partial-rw flag. Otherwise, return false
+ *
+ * \return True if the request has partial-rw flag. Otherwise, return false
+ */
+ bool GetIsPartialRW() const;
/**
* Get Raw pointer to pkgmgr_installer object
bool QueryIsPackageInstalled(const std::string& pkg_id, uid_t uid) {
pkgmgrinfo_pkginfo_h handle;
- int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(), uid, &handle);
+ int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(),
+ uid, &handle);
if (ret != PMINFO_R_OK) {
if (ret != PMINFO_R_ENOENT)
LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_all_pkginfo";
bool QueryIsGlobalPackage(const std::string& pkg_id, uid_t uid) {
pkgmgrinfo_pkginfo_h handle;
- int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(), uid, &handle);
+ int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(),
+ uid, &handle);
if (ret != PMINFO_R_OK) {
if (ret != PMINFO_R_ENOENT)
LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_all_pkginfo";
bool QueryIsReadonlyPackage(const std::string& pkg_id, uid_t uid) {
pkgmgrinfo_pkginfo_h handle;
- int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(), uid, &handle);
+ int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(pkg_id.c_str(),
+ uid, &handle);
if (ret != PMINFO_R_OK) {
if (ret != PMINFO_R_ENOENT)
LOG(ERROR) << "Failed to call pkgmgrinfo_pkginfo_get_usr_all_pkginfo";
return is_readonly;
}
+bool QueryIsDisabledPackage(const std::string& pkg_id, uid_t uid) {
+ pkgmgrinfo_pkginfo_h handle;
+ int ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(pkg_id.c_str(),
+ uid, &handle);
+ if (ret != PMINFO_R_OK) {
+ if (ret != PMINFO_R_ENOENT)
+ LOG(ERROR) <<
+ "Failed to call pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo";
+ return false;
+ }
+
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ return true;
+}
+
} // namespace common_installer
*/
bool QueryIsReadonlyPackage(const std::string& pkg_id, uid_t uid);
+/**
+ * \brief Adapter interface for external PkgMgr module used for checking
+ * if given package is disabled package
+ *
+ * \param pkg_id package id
+ * \param uid user id
+ *
+ * \return true if package is disable.
+ */
+bool QueryIsDisabledPackage(const std::string& pkg_id, uid_t uid);
+
} // namespace common_installer
#endif // COMMON_PKGMGR_QUERY_H_
{ci::RequestType::Reinstall, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::Clear, PKGMGR_INSTALLER_CLEAR_EVENT_STR},
{ci::RequestType::Uninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
+ {ci::RequestType::PartialUninstall, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
{ci::RequestType::Update, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::Delta, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::Move, PKGMGR_INSTALLER_MOVE_EVENT_STR},
{ci::RequestType::MountUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::ManifestDirectInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
{ci::RequestType::ManifestDirectUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
+ {ci::RequestType::ManifestPartialInstall, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
+ {ci::RequestType::ManifestPartialUpdate, PKGMGR_INSTALLER_UPGRADE_EVENT_STR},
{ci::RequestType::DisablePkg, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR},
{ci::RequestType::EnablePkg, PKGMGR_INSTALLER_INSTALL_EVENT_STR},
{ci::RequestType::Unknown, PKGMGR_INSTALLER_UNKNOWN_EVENT_STR}
MountUpdate,
ManifestDirectInstall,
ManifestDirectUpdate,
+ ManifestPartialInstall,
+ ManifestPartialUpdate,
+ PartialUninstall,
DisablePkg,
EnablePkg
};
context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
}
break;
+ case RequestType::PartialUninstall:
+ SetupIsPartialRW();
case RequestType::Uninstall:
+ if (context_->is_preload_rw_package.get())
+ SetupIsKeepRWData();
SetupIsForceRemoval();
context_->pkgid.set(pkgmgr_->GetRequestInfo());
context_->file_path.set(kStrEmpty);
context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
}
break;
+ case RequestType::ManifestPartialInstall:
+ case RequestType::ManifestPartialUpdate:
+ SetupIsPartialRW();
case RequestType::ManifestDirectInstall:
case RequestType::ManifestDirectUpdate: {
context_->pkgid.set(pkgmgr_->GetRequestInfo());
Step::Status StepConfigure::precheck() {
SetupIsPreloadRequest();
SetupIsPreloadRWRequest();
- SetupIsNoRemoval();
+ if (context_->is_readonly_package.get())
+ SetupIsNoRemoval();
bool is_readonly = context_->is_readonly_package.get();
bool is_preload_rw = context_->is_preload_rw_package.get();
context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
}
+void StepConfigure::SetupIsKeepRWData() {
+ context_->keep_rwdata.set(pkgmgr_->GetIsKeepRWData());
+}
+
+void StepConfigure::SetupIsPartialRW() {
+ context_->partial_rw.set(pkgmgr_->GetIsPartialRW());
+}
+
} // namespace configuration
} // namespace common_installer
void SetupIsPreloadRWRequest();
void SetupIsForceRemoval();
void SetupIsNoRemoval();
+ void SetupIsKeepRWData();
+ void SetupIsPartialRW();
PkgMgrPtr pkgmgr_;
}
Step::Status StepParseManifest::process() {
+ if (context_->force_clean_from_db.get())
+ return Step::Status::OK;
if (!LocateConfigFile()) {
// continue if this is recovery, manifest file may never been created
if (manifest_location_ == ManifestLocation::RECOVERY) {
destination_path += source.extension();
else
destination_path += ".png";
- bf::copy_file(source, destination_path, error);
+ bf::copy_file(source, destination_path,
+ bf::copy_option::overwrite_if_exists, error);
if (error) {
LOG(ERROR) << "Cannot create package icon: " << destination_path
<< " , error: " << error;
const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
-bool SkipDirectoryIfGlobal(const bf::path& path) {
+bool SkipRWDirectories(const bf::path& path) {
static const std::vector<std::string> dirs_to_ignore = {
{"cache"},
{"data"},
if (context_->external_storage)
context_->external_storage->Commit();
- if (QueryIsPackageInstalled(context_->pkgid.get(), kGlobalUserUid)) {
+ if (QueryIsPackageInstalled(context_->pkgid.get(), kGlobalUserUid) ||
+ context_->keep_rwdata.get()) {
for (bf::directory_iterator itr(pkg_path); itr != bf::directory_iterator();
++itr) {
- if (bf::is_symlink(symlink_status(itr->path()))) {
- // for removing symlink to .mmc/bin,lib,res
- bf::remove_all(itr->path(), error);
- } else if (bf::is_directory(itr->status())) {
- if (SkipDirectoryIfGlobal(itr->path().leaf())) {
+ if (bf::is_directory(itr->status())) {
+ if (SkipRWDirectories(itr->path().leaf())) {
LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
continue;
}
bf::remove_all(itr->path(), error);
- if (error) {
- LOG(ERROR) << "Can't remove dir:" << context_->pkg_path.get().c_str();
- }
- } else if (bf::is_regular_file(itr->status())) {
+ } else {
bf::remove_all(itr->path(), error);
}
+ if (error)
+ LOG(ERROR) << "Can't remove path:" << itr->path().c_str();
}
} else {
bf::remove_all(pkg_path, error);
- if (error) {
+ if (error)
LOG(ERROR) << "Can't remove directory:" <<
context_->pkg_path.get().c_str();
- } else {
- LOG(DEBUG) << "Removed directory: " << context_->pkg_path.get();
- }
}
-
return Status::OK;
}
namespace filesystem {
Step::Status StepRemovePerUserStorageDirectories::process() {
- if (context_->request_mode.get() != RequestMode::GLOBAL)
+ if (context_->request_mode.get() != RequestMode::GLOBAL ||
+ context_->keep_rwdata.get())
return Step::Status::OK;
std::string package_id = context_->pkgid.get();
--- /dev/null
+// Copyright (c) 2016 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/pkgmgr/step_check_force_clean.h"
+
+#include <pkgmgr/pkgmgr_parser.h>
+#include <pkgmgr-info.h>
+#include <tzplatform_config.h>
+
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/path.hpp>
+
+#include "common/pkgmgr_query.h"
+#include "common/installer_context.h"
+
+namespace bf = boost::filesystem;
+
+namespace {
+
+int PkgmgrAppInfoCallback(const pkgmgrinfo_appinfo_h handle,
+ void *user_data) {
+ manifest_x *mfx = static_cast<manifest_x*>(user_data);
+ application_x* application =
+ static_cast<application_x*>(calloc(1, sizeof(application_x)));
+ if (!application)
+ return PMINFO_R_ERROR;
+
+ char* app_id = nullptr;
+ if (pkgmgrinfo_appinfo_get_appid(handle, &app_id))
+ return PMINFO_R_ERROR;
+
+ icon_x* icon = static_cast<icon_x*>(calloc(1, sizeof(icon_x)));
+ if (!icon)
+ return PMINFO_R_ERROR;
+
+ char* icon_text = nullptr;
+ if (pkgmgrinfo_appinfo_get_icon(handle, &icon_text))
+ return PMINFO_R_ERROR;
+
+ if (!mfx->root_path) {
+ char *root_path = nullptr;
+ if (pkgmgrinfo_appinfo_get_root_path(handle, &root_path))
+ return PMINFO_R_ERROR;
+ mfx->root_path = strdup(root_path);
+ }
+
+ application->appid = strdup(app_id);
+ icon->text = strdup(icon_text);
+ application->icon = g_list_append(application->icon, icon);
+ mfx->application = g_list_append(mfx->application, application);
+
+ return PMINFO_R_OK;
+}
+
+int PkgmgrGenerateManifestInfoFromDB(manifest_x *mfx,
+ const char *pkgid, uid_t uid) {
+ pkgmgrinfo_appinfo_filter_h filter;
+ mfx->package = strdup(pkgid);
+
+ if (pkgmgrinfo_appinfo_filter_create(&filter))
+ return PMINFO_R_ERROR;
+
+ if (pkgmgrinfo_appinfo_filter_add_string(filter,
+ PMINFO_APPINFO_PROP_APP_PACKAGE, pkgid)) {
+ pkgmgrinfo_appinfo_filter_destroy(filter);
+ return PMINFO_R_ERROR;
+ }
+
+ if (pkgmgrinfo_appinfo_usr_filter_foreach_appinfo(filter,
+ PkgmgrAppInfoCallback, mfx, uid)) {
+ pkgmgrinfo_appinfo_filter_destroy(filter);
+ return PMINFO_R_ERROR;
+ }
+
+ pkgmgrinfo_appinfo_filter_destroy(filter);
+
+ return PMINFO_R_OK;
+}
+
+} // namespace
+
+namespace common_installer {
+namespace pkgmgr {
+
+Step::Status StepCheckForceClean::process() {
+ if (context_->request_type.get() != RequestType::Uninstall)
+ return Status::OK;
+
+ uid_t uid;
+ bool is_readonly;
+ if (QueryIsGlobalPackage(context_->pkgid.get(), context_->uid.get())) {
+ uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+ is_readonly = QueryIsReadonlyPackage(context_->pkgid.get(),
+ context_->uid.get());
+ } else {
+ uid = context_->uid.get();
+ is_readonly = context_->is_readonly_package.get();
+ }
+ bf::path xml_path = bf::path(getUserManifestPath(uid, is_readonly))
+ / bf::path(context_->pkgid.get());
+ xml_path += ".xml";
+
+ // if manifeset not found but pkg exist in db for target uid, do clean
+ if (!bf::exists(xml_path) &&
+ QueryIsPackageInstalled(context_->pkgid.get(), context_->uid.get())) {
+ context_->force_clean_from_db.set(true);
+ manifest_x* manifest =
+ static_cast<manifest_x*>(calloc(1, sizeof(manifest_x)));
+ if (!PkgmgrGenerateManifestInfoFromDB(manifest,
+ reinterpret_cast<const char*>(context_->pkgid.get().c_str()),
+ context_->uid.get())) {
+ context_->manifest_data.set(manifest);
+ context_->pkg_path.set(manifest->root_path);
+ }
+ }
+
+ return Status::OK;
+}
+
+} // namespace pkgmgr
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 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_PKGMGR_STEP_CHECK_FORCE_CLEAN_H_
+#define COMMON_STEP_PKGMGR_STEP_CHECK_FORCE_CLEAN_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace pkgmgr {
+
+class StepCheckForceClean : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(CheckForceClean)
+};
+
+} // namespace pkgmgr
+} // namespace common_installer
+
+#endif // COMMON_STEP_PKGMGR_STEP_CHECK_FORCE_CLEAN_H_
class StepCheckInstallable : public Step {
public:
using Step::Step;
+
Status process() override;
Status clean() override { return Status::OK; }
Status undo() override { return Status::OK; }
Status precheck() override;
- STEP_NAME(StepCheckInstallable)
+ STEP_NAME(CheckInstallable)
};
} // namespace pkgmgr
#include <pkgmgr-info.h>
#include "common/app_installer.h"
-#include "common/step/step.h"
namespace common_installer {
namespace pkgmgr {
return Status::OK;
pkgmgrinfo_pkginfo_h handle;
- int ret = pkgmgrinfo_pkginfo_get_usr_all_pkginfo(context_->pkgid.get().c_str(),
- context_->uid.get(), &handle);
+ int ret =
+ pkgmgrinfo_pkginfo_get_usr_all_pkginfo(context_->pkgid.get().c_str(),
+ context_->uid.get(), &handle);
if (ret != PMINFO_R_OK) {
LOG(ERROR) << "This package is not installed";
return Status::INVALID_VALUE;
#ifndef COMMON_STEP_PKGMGR_STEP_CHECK_REMOVABLE_H_
#define COMMON_STEP_PKGMGR_STEP_CHECK_REMOVABLE_H_
+#include <manifest_parser/utils/logging.h>
+
#include "common/step/step.h"
namespace common_installer {
}
Step::Status StepRunParserPlugin::process() {
+ if (context_->force_clean_from_db.get())
+ return Status::OK;
return ProcessPlugins(context_->xml_path.get(), context_->manifest_data.get(),
action_type_);
}
return Status::PACKAGE_NOT_FOUND;
}
if (context_->xml_path.get().empty()) {
+ if (context_->force_clean_from_db.get())
+ return Step::Status::OK;
LOG(ERROR) << "xml_path attribute is empty";
return Status::MANIFEST_NOT_FOUND;
}
if (!boost::filesystem::exists(context_->xml_path.get())) {
+ if (context_->force_clean_from_db.get())
+ return Step::Status::OK;
LOG(ERROR) << "xml_path ("
<< context_->xml_path.get()
<< ") path does not exist";
LOG(ERROR) << "Failed to unregister package into database";
}
- // remove manifest file
- bs::error_code error;
- bf::remove(context_->xml_path.get(), error);
+ if (!context_->partial_rw.get()) {
+ // remove manifest file
+ bs::error_code error;
+ bf::remove(context_->xml_path.get(), error);
+ }
LOG(DEBUG) << "Successfully unregister the application";
int InstallManifestOffline(const std::string& pkgid,
const std::string& type,
- uid_t uid,
- bool preload) {
+ uid_t uid, bool preload,
+ bool rw_only) {
bf::path backend_path(kBackendDirectoryPath);
backend_path /= type;
ci::Subprocess backend(backend_path.string());
std::cerr << "Preload request for non-root user" << std::endl;
return -1;
}
- backend.Run("-y", pkgid.c_str(), "--preload");
+ if (rw_only)
+ backend.Run("-y", pkgid.c_str(), "--preload");
+ else
+ backend.Run("-y", pkgid.c_str(), "--preload", "--partial-rw");
} else {
std::string str_uid = std::to_string(uid);
backend.Run("-y", pkgid.c_str(), "-u", str_uid.c_str());
return uid == kRootUserUid || uid == kGlobalUserUid;
}
-void InitdbLoadDirectory(uid_t uid, const bf::path& directory, bool preload) {
+void InitdbLoadDirectory(uid_t uid, const bf::path& directory,
+ bool preload, bool rw_only) {
std::cerr << "Loading manifest files from " << directory << std::endl;
for (bf::directory_iterator iter(directory); iter != bf::directory_iterator();
++iter) {
if (!bf::is_regular_file(iter->path()))
continue;
- std::cerr << "Manifest : " << iter->path() << std::endl;
+ std::cerr << "Manifest : " << iter->path() <<
+ (rw_only? " (rw-only)":" (all)") << std::endl;
tpk::parse::TPKConfigParser parser;
if (!parser.ParseManifest(iter->path())) {
if (type.empty())
type = "tpk";
- InstallManifestOffline(package_info->package(), type, uid, preload);
+ InstallManifestOffline(package_info->package(), type, uid,
+ preload, rw_only);
}
}
bpo::options_description options("Allowed options");
bpo::variables_map opt_map;
uid_t uid;
+ bool rw_only = false;
+ bool initial = false;
try {
options.add_options()
("uid,u", bpo::value<int>()->default_value(kRootUserUid), "user id")
+ ("partial-rw", "rw-partition only")
+ ("ro", "readonly package only")
("help,h", "display this help message");
bpo::store(bpo::parse_command_line(argc, argv, options), opt_map);
if (opt_map.count("help")) {
std::cerr << options << std::endl;
return -1;
}
+ if (opt_map.count("partial-rw"))
+ rw_only = true;
+ if (opt_map.count("ro"))
+ initial = true;
bpo::notify(opt_map);
uid = opt_map["uid"].as<int>();
} catch (const bpo::error& error) {
if (IsGlobal(uid)) {
// RO location
bf::path ro_dir(tzplatform_getenv(TZ_SYS_RO_PACKAGES));
- InitdbLoadDirectory(uid, ro_dir, true);
+ InitdbLoadDirectory(uid, ro_dir, true, rw_only);
+
+ if (initial)
+ return ret;
// RW location
bf::path rw_dir(tzplatform_getenv(TZ_SYS_RW_PACKAGES));
- InitdbLoadDirectory(uid, rw_dir, false);
+ InitdbLoadDirectory(uid, rw_dir, false, false);
} else {
// Specified user location
tzplatform_set_user(uid);
bf::path dir(tzplatform_getenv(TZ_USER_PACKAGES));
- InitdbLoadDirectory(uid, dir, false);
+ InitdbLoadDirectory(uid, dir, false, false);
tzplatform_reset_user();
}