Skip to content

Commit a23b539

Browse files
committed
feat: add hooks features
Add hooks features for app install.
1 parent a77322a commit a23b539

7 files changed

Lines changed: 423 additions & 0 deletions

File tree

configure.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#define LINGLONG_CLIENT_NAME "@LINGLONG_CLI_BIN@"
2323
#define LINGLONG_CLIENT_PATH "@CMAKE_INSTALL_FULL_BINDIR@/@LINGLONG_CLI_BIN@"
2424
#define LINGLONG_EXPORT_PATH "@LINGLONG_EXPORT_PATH@"
25+
// The directory where the package install hooks reside.
26+
#define LINGLONG_INSTALL_HOOKS_DIR "@CMAKE_INSTALL_FULL_SYSCONFDIR@/linglong/config.d"
2527

2628
#define LINGLONG_EXPORT_VERSION "1.0.0.2"
2729
// The package's locale domain.

libs/linglong/src/linglong/package_manager/package_manager.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "linglong/utils/command/env.h"
2727
#include "linglong/utils/error/error.h"
2828
#include "linglong/utils/finally/finally.h"
29+
#include "linglong/utils/hooks.h"
2930
#include "linglong/utils/packageinfo_handler.h"
3031
#include "linglong/utils/serialize/json.h"
3132
#include "linglong/utils/transaction.h"
@@ -738,6 +739,12 @@ QVariantMap PackageManager::installFromLayer(const QDBusUnixFileDescriptor &fd,
738739
<< "after install" << packageRef.toString() << ":"
739740
<< ret.error().message();
740741
}
742+
743+
ret = executePostInstallHooks(*newRef);
744+
if (!ret) {
745+
taskRef.reportError(std::move(ret).error());
746+
return;
747+
}
741748
};
742749

743750
auto refSpec =
@@ -768,6 +775,18 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd,
768775
return toDBusReply(-1, "invalid file descriptor");
769776
}
770777

778+
std::unique_ptr<utils::InstallHookManager> installHookManager =
779+
std::make_unique<utils::InstallHookManager>();
780+
auto ret = installHookManager->parseInstallHooks();
781+
if (!ret) {
782+
return toDBusReply(ret);
783+
}
784+
785+
ret = installHookManager->executeInstallHooks(fd.fileDescriptor());
786+
if (!ret) {
787+
return toDBusReply(-1, "uab package signature verification failed.");
788+
}
789+
771790
auto uabRet = package::UABFile::loadFromFile(fd.fileDescriptor());
772791
if (!uabRet) {
773792
return toDBusReply(uabRet);
@@ -1072,6 +1091,12 @@ QVariantMap PackageManager::installFromUAB(const QDBusUnixFileDescriptor &fd,
10721091
}
10731092
}
10741093

1094+
auto ret = executePostInstallHooks(newAppRef);
1095+
if (!ret) {
1096+
taskRef.reportError(std::move(ret).error());
1097+
return;
1098+
}
1099+
10751100
transaction.commit();
10761101
taskRef.updateState(linglong::api::types::v1::State::Succeed, "install uab successfully");
10771102
};
@@ -1439,6 +1464,13 @@ void PackageManager::Install(PackageTask &taskContext,
14391464
}
14401465
}
14411466

1467+
auto ret = executePostInstallHooks(newRef);
1468+
if (!ret) {
1469+
taskContext.updateState(linglong::api::types::v1::State::Failed,
1470+
"Failed to execute postInstall hooks.\n" + ret.error().message());
1471+
return;
1472+
}
1473+
14421474
transaction.commit();
14431475
taskContext.updateState(linglong::api::types::v1::State::Succeed,
14441476
"Install " + newRef.toString() + " (from repo: "
@@ -1713,6 +1745,11 @@ void PackageManager::Uninstall(PackageTask &taskContext,
17131745
return;
17141746
}
17151747

1748+
auto ret = executePostUninstallHooks(ref);
1749+
if (!ret) {
1750+
qWarning() << "failed to execute postUninstall hooks" << ret.error();
1751+
}
1752+
17161753
transaction.commit();
17171754

17181755
taskContext.updateState(linglong::api::types::v1::State::Succeed,
@@ -2001,12 +2038,25 @@ void PackageManager::pullDependency(PackageTask &taskContext,
20012038
return;
20022039
}
20032040

2041+
auto ret = executePostInstallHooks(*runtime);
2042+
if (!ret) {
2043+
taskContext.updateState(linglong::api::types::v1::State::Failed,
2044+
LINGLONG_ERRV(ret).message());
2045+
return;
2046+
}
2047+
20042048
transaction.addRollBack([this, runtimeRef = *runtime, module]() noexcept {
20052049
auto result = this->repo.remove(runtimeRef.reference, module);
20062050
if (!result) {
20072051
qCritical() << result.error();
20082052
Q_ASSERT(false);
20092053
}
2054+
2055+
result = executePostUninstallHooks(runtimeRef);
2056+
if (!result) {
2057+
qCritical() << result.error();
2058+
Q_ASSERT(false);
2059+
}
20102060
});
20112061
}
20122062
}
@@ -2041,6 +2091,27 @@ void PackageManager::pullDependency(PackageTask &taskContext,
20412091
if (isTaskDone(taskContext.subState())) {
20422092
return;
20432093
}
2094+
2095+
auto ret = executePostInstallHooks(*base);
2096+
if (!ret) {
2097+
taskContext.updateState(linglong::api::types::v1::State::Failed,
2098+
LINGLONG_ERRV(ret).message());
2099+
return;
2100+
}
2101+
2102+
transaction.addRollBack([this, baseRef = *base, module]() noexcept {
2103+
auto result = this->repo.remove(baseRef, module);
2104+
if (!result) {
2105+
qCritical() << result.error();
2106+
Q_ASSERT(false);
2107+
}
2108+
2109+
result = executePostUninstallHooks(baseRef);
2110+
if (!result) {
2111+
qCritical() << result.error();
2112+
Q_ASSERT(false);
2113+
}
2114+
});
20442115
}
20452116

20462117
transaction.commit();
@@ -2431,4 +2502,51 @@ auto PackageManager::GenerateCache(const QString &reference) noexcept -> QVarian
24312502
return result;
24322503
}
24332504

2505+
utils::error::Result<void>
2506+
PackageManager::executePostInstallHooks(const package::Reference &ref) noexcept
2507+
{
2508+
LINGLONG_TRACE("execute post install hooks for: " + ref.toString());
2509+
2510+
std::unique_ptr<utils::InstallHookManager> installHookManager =
2511+
std::make_unique<utils::InstallHookManager>();
2512+
auto ret = installHookManager->parseInstallHooks();
2513+
if (!ret) {
2514+
return LINGLONG_ERR(ret);
2515+
}
2516+
2517+
auto layerDir = this->repo.getLayerDir(ref);
2518+
if (!layerDir) {
2519+
return LINGLONG_ERR(layerDir);
2520+
}
2521+
2522+
auto appPath = layerDir->absolutePath();
2523+
2524+
ret = installHookManager->executePostInstallHooks(ref.id.toStdString(), appPath.toStdString());
2525+
if (!ret) {
2526+
return LINGLONG_ERR(ret);
2527+
}
2528+
2529+
return LINGLONG_OK;
2530+
}
2531+
2532+
utils::error::Result<void>
2533+
PackageManager::executePostUninstallHooks(const package::Reference &ref) noexcept
2534+
{
2535+
LINGLONG_TRACE("execute post uninstall hooks for: " + ref.toString());
2536+
2537+
std::unique_ptr<utils::InstallHookManager> installHookManager =
2538+
std::make_unique<utils::InstallHookManager>();
2539+
auto ret = installHookManager->parseInstallHooks();
2540+
if (!ret) {
2541+
return LINGLONG_ERR(ret);
2542+
}
2543+
2544+
ret = installHookManager->executePostUninstallHooks(ref.id.toStdString());
2545+
if (!ret) {
2546+
return LINGLONG_ERR(ret);
2547+
}
2548+
2549+
return LINGLONG_OK;
2550+
}
2551+
24342552
} // namespace linglong::service

libs/linglong/src/linglong/package_manager/package_manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ public
156156
utils::error::Result<void> generateCache(const package::Reference &ref) noexcept;
157157
utils::error::Result<void> tryGenerateCache(const package::Reference &ref) noexcept;
158158
utils::error::Result<void> removeCache(const package::Reference &ref) noexcept;
159+
utils::error::Result<void> executePostInstallHooks(const package::Reference &ref) noexcept;
160+
utils::error::Result<void> executePostUninstallHooks(const package::Reference &ref) noexcept;
159161
linglong::repo::OSTreeRepo &repo; // NOLINT
160162
PackageTaskQueue tasks;
161163

libs/utils/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ pfl_add_library(
4545
src/linglong/utils/xdg/desktop_entry.h
4646
src/linglong/utils/xdg/directory.h
4747
src/linglong/utils/gkeyfile_wrapper.h
48+
src/linglong/utils/hooks.cpp
49+
src/linglong/utils/hooks.h
4850
COMPILE_FEATURES
4951
PUBLIC
5052
cxx_std_17

0 commit comments

Comments
 (0)