Skip to content

Commit 49c8c6d

Browse files
committed
refactor: Remove Qt dependencies from the utils
Changes: - Reimplement `linglong::utils::Cmd`. - Add unit tests for the new `Cmd` implementation and file operations. - Use thred-safe errorString instead of strerror. - submodules only affects git kind source. - Remove unused code. Signed-off-by: reddevillg <reddevillg@gmail.com>
1 parent 44a361e commit 49c8c6d

43 files changed

Lines changed: 1030 additions & 619 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ exclude: |
1212
misc/image/|
1313
po/|
1414
tools/quicktype/|
15-
tools/openapi-c-libcurl-client/|
15+
tools/openapi-c-libcurl-client/
1616
)
1717
1818
repos:

apps/ll-cli/src/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ int lockCheck() noexcept
112112
return 0;
113113
}
114114

115-
qCritical() << "failed to open lock" << lock << ::strerror(errno);
115+
qCritical() << "failed to open lock" << lock << errorString(errno);
116116
return -1;
117117
}
118118

apps/ll-driver-detect/src/main.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include "driver_detection_config.h"
99
#include "driver_detection_manager.h"
1010
#include "driver_detector.h"
11-
#include "linglong/utils/command/cmd.h"
11+
#include "linglong/utils/cmd.h"
1212
#include "linglong/utils/error/error.h"
1313
#include "linglong/utils/gettext.h"
1414
#include "linglong/utils/global/initialize.h"
@@ -105,8 +105,7 @@ installDriverPackage(const std::vector<GraphicsDriverInfo> &drivers)
105105
}
106106

107107
// Execute ll-cli install command to install the package
108-
auto ret = linglong::utils::command::Cmd("ll-cli").exec(
109-
{ "install", QString::fromStdString(driverInfo.packageName) });
108+
auto ret = linglong::utils::Cmd("ll-cli").exec({ "install", driverInfo.packageName });
110109
if (!ret) {
111110
return LINGLONG_ERR("Installation command failed: " + ret.error().message());
112111
}

apps/ll-driver-detect/src/nvidia_driver_detector.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#include "nvidia_driver_detector.h"
66

7-
#include "linglong/utils/command/cmd.h"
7+
#include "linglong/utils/cmd.h"
88
#include "linglong/utils/error/error.h"
99
#include "linglong/utils/log/log.h"
1010

@@ -53,13 +53,12 @@ utils::error::Result<void> NVIDIADriverDetector::checkPackageExists(const std::s
5353
{
5454
LINGLONG_TRACE("Check if NVIDIA driver package exists in repository");
5555
// Execute ll-cli search command to check driver package existence
56-
auto ret = linglong::utils::command::Cmd("ll-cli").exec(
57-
{ "search", QString::fromStdString(packageName) });
56+
auto ret = linglong::utils::Cmd("ll-cli").exec({ "search", packageName });
5857
if (!ret) {
5958
return LINGLONG_ERR("Search command failed: " + ret.error().message());
6059
}
6160

62-
if (!ret->contains(QString::fromStdString(packageName))) {
61+
if (ret->find(packageName) == std::string::npos) {
6362
return LINGLONG_ERR("Driver package not found in linglong repo: " + packageName);
6463
}
6564
return LINGLONG_OK;
@@ -72,12 +71,12 @@ NVIDIADriverDetector::checkPackageInstalled(const std::string &packageName)
7271

7372
try {
7473
// First execute ll-cli info to get the package info
75-
auto listResult =
76-
linglong::utils::command::Cmd("ll-cli").exec({ "info", packageName.c_str() });
74+
auto listResult = linglong::utils::Cmd("ll-cli").exec({ "info", packageName });
7775

7876
if (!listResult) {
79-
LogD("Can not get package info with `ll-cli info`, maybe the package is not installed: {}",
80-
listResult.error().message());
77+
LogD(
78+
"Can not get package info with `ll-cli info`, maybe the package is not installed: {}",
79+
listResult.error().message());
8180
return false;
8281
}
8382

libs/linglong/src/linglong/builder/linglong_builder.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
#include "linglong/repo/config.h"
2121
#include "linglong/repo/ostree_repo.h"
2222
#include "linglong/runtime/container.h"
23-
#include "linglong/utils/command/cmd.h"
23+
#include "linglong/utils/cmd.h"
2424
#include "linglong/utils/error/error.h"
2525
#include "linglong/utils/file.h"
2626
#include "linglong/utils/global/initialize.h"
@@ -985,11 +985,8 @@ utils::error::Result<void> Builder::generateAppConf() noexcept
985985
scriptFile = dir->filePath("app-conf-generator");
986986
QFile::copy(":/scripts/app-conf-generator", scriptFile);
987987
}
988-
auto output =
989-
utils::command::Cmd("bash").exec({ "-e",
990-
scriptFile,
991-
QString::fromStdString(project.package.id),
992-
QString::fromStdString(buildOutput.string()) });
988+
auto output = utils::Cmd("bash").exec(
989+
{ "-e", scriptFile.toStdString(), project.package.id, buildOutput.string() });
993990
if (!output) {
994991
return LINGLONG_ERR(output);
995992
}
@@ -1700,8 +1697,8 @@ utils::error::Result<void> Builder::extractLayer(const QString &layerPath,
17001697
return LINGLONG_ERR(layerDir);
17011698
}
17021699

1703-
auto output =
1704-
utils::command::Cmd("cp").exec({ "-r", layerDir->absolutePath(), destDir.absolutePath() });
1700+
auto output = utils::Cmd("cp").exec(
1701+
{ "-r", layerDir->absolutePath().toStdString(), destDir.absolutePath().toStdString() });
17051702
if (!output) {
17061703
return LINGLONG_ERR(output);
17071704
}

libs/linglong/src/linglong/builder/source_fetcher.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "source_fetcher.h"
88

99
#include "configure.h"
10-
#include "linglong/utils/command/cmd.h"
1110
#include "linglong/utils/error/error.h"
1211
#include "linglong/utils/global/initialize.h"
1312
#include "linglong/utils/log/log.h"
@@ -55,15 +54,15 @@ auto SourceFetcher::fetch(QDir destination) noexcept -> utils::error::Result<voi
5554
LogD("Dumping {} from qrc to {}", scriptName, scriptFile);
5655
QFile::copy(":/scripts/" + scriptName, scriptFile);
5756
}
58-
auto output =
59-
m_cmd->setEnv("GIT_SUBMODULES", source.submodules.value_or(true) ? "true" : "")
60-
.exec({
61-
scriptFile,
62-
destination.absoluteFilePath(getSourceName()),
63-
QString::fromStdString(*source.url),
64-
QString::fromStdString(source.kind == "git" ? *source.commit : *source.digest),
65-
this->cacheDir.absolutePath(),
66-
});
57+
if (source.kind == "git") {
58+
m_cmd->setEnv("GIT_SUBMODULES", source.submodules.value_or(true) ? "true" : "");
59+
}
60+
auto output = m_cmd->exec(
61+
std::vector<std::string>{ scriptFile.toStdString(),
62+
destination.absoluteFilePath(getSourceName()).toStdString(),
63+
*source.url,
64+
source.kind == "git" ? *source.commit : *source.digest,
65+
this->cacheDir.absolutePath().toStdString() });
6766
if (!output.has_value()) {
6867
LogE("output error: {}", output.error());
6968
return LINGLONG_ERR("stderr:", output);

libs/linglong/src/linglong/builder/source_fetcher.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#include "linglong/api/types/v1/BuilderConfig.hpp"
1010
#include "linglong/api/types/v1/BuilderProjectSource.hpp"
11-
#include "linglong/utils/command/cmd.h"
11+
#include "linglong/utils/cmd.h"
1212
#include "linglong/utils/error/error.h"
1313

1414
#include <QDir>
@@ -25,13 +25,13 @@ class SourceFetcher
2525

2626
auto fetch(QDir destination) noexcept -> utils::error::Result<void>;
2727

28-
void setCommand(std::shared_ptr<utils::command::Cmd> cmd) { this->m_cmd = cmd; }
28+
void setCommand(std::shared_ptr<utils::Cmd> cmd) { this->m_cmd = cmd; }
2929

3030
private:
3131
QString getSourceName();
3232
QDir cacheDir;
3333
api::types::v1::BuilderProjectSource source;
34-
std::shared_ptr<utils::command::Cmd> m_cmd = std::make_shared<utils::command::Cmd>("sh");
34+
std::shared_ptr<utils::Cmd> m_cmd = std::make_shared<utils::Cmd>("sh");
3535
};
3636

3737
} // namespace linglong::builder

libs/linglong/src/linglong/cli/cli.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,8 +483,7 @@ int Cli::run(const RunOptions &options)
483483
// placeholder file
484484
auto fd = ::open(pidFile.c_str(), O_WRONLY | O_CREAT | O_EXCL, mode);
485485
if (fd == -1) {
486-
qCritical()
487-
<< QString{ "create file %1 error: %2" }.arg(pidFile.c_str()).arg(::strerror(errno));
486+
LogE("create file {} error: {}", pidFile, errorString(errno));
488487
QCoreApplication::exit(-1);
489488
return -1;
490489
}
@@ -1712,7 +1711,7 @@ int Cli::content(const ContentOptions &options)
17121711
if (real != nullptr) {
17131712
target = real;
17141713
} else {
1715-
qCritical() << "resolve symlink " << file.c_str() << " error: " << ::strerror(errno);
1714+
LogE("resolve symlink {} error: {}", file, errorString(errno));
17161715
}
17171716
}
17181717

@@ -1992,7 +1991,7 @@ Cli::RequestDirectories(const api::types::v1::PackageInfoV2 &info) noexcept
19921991

19931992
auto fd = ::shm_open(info.id.c_str(), O_RDWR | O_CREAT, 0600);
19941993
if (fd < 0) {
1995-
return LINGLONG_ERR(QString{ "shm_open error:" } + ::strerror(errno));
1994+
return LINGLONG_ERR("shm_open error:" + errorString(errno));
19961995
}
19971996
auto closeFd = utils::finally::finally([fd] {
19981997
::close(fd);
@@ -2017,7 +2016,7 @@ Cli::RequestDirectories(const api::types::v1::PackageInfoV2 &info) noexcept
20172016
continue;
20182017
}
20192018

2020-
return LINGLONG_ERR(QString{ "fcntl lock error: " } + ::strerror(errno));
2019+
return LINGLONG_ERR("fcntl lock error: " + errorString(errno));
20212020
}
20222021

20232022
if (!anotherRunning) {
@@ -2027,7 +2026,7 @@ Cli::RequestDirectories(const api::types::v1::PackageInfoV2 &info) noexcept
20272026
lock.l_type = F_UNLCK;
20282027
ret = ::fcntl(fd, F_SETLK, &lock);
20292028
if (ret == -1) {
2030-
return LINGLONG_ERR(QString{ "fcntl unlock error: " } + ::strerror(errno));
2029+
return LINGLONG_ERR("fcntl unlock error: " + errorString(errno));
20312030
}
20322031

20332032
return LINGLONG_OK;
@@ -2037,11 +2036,11 @@ Cli::RequestDirectories(const api::types::v1::PackageInfoV2 &info) noexcept
20372036
auto releaseResource = utils::finally::finally([&info, &lock, fd] {
20382037
lock.l_type = F_UNLCK;
20392038
if (::fcntl(fd, F_SETLK, &lock) == -1) {
2040-
qDebug() << "failed to unlock mem file:" << ::strerror(errno);
2039+
LogD("failed to unlock mem file: {}", errorString(errno));
20412040
}
20422041

20432042
if (::shm_unlink(info.id.c_str()) == -1) {
2044-
qDebug() << "shm_unlink error:" << ::strerror(errno);
2043+
LogD("shm_unlink error: {}", errorString(errno));
20452044
}
20462045
});
20472046

libs/linglong/src/linglong/package/layer_file.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#include "linglong/api/types/v1/Generators.hpp"
1010
#include "linglong/api/types/v1/LayerInfo.hpp"
11+
#include "linglong/utils/error/error.h"
12+
#include "linglong/utils/log/formatter.h"
1113
#include "linglong/utils/serialize/json.h"
1214

1315
#include <QDataStream>
@@ -31,7 +33,7 @@ utils::error::Result<QSharedPointer<LayerFile>> LayerFile::New(const QString &pa
3133
LINGLONG_TRACE("install layer file from path")
3234
auto fd = ::open(path.toLocal8Bit(), O_RDONLY);
3335
if (fd < 0) {
34-
return LINGLONG_ERR("failed to open " + path + ":" + ::strerror(errno));
36+
return LINGLONG_ERR(fmt::format("failed to open {}: {}", path, ::errorString(errno)));
3537
}
3638

3739
return New(fd);

libs/linglong/src/linglong/package/layer_packager.cpp

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
#include "linglong/api/types/v1/Generators.hpp"
1010
#include "linglong/api/types/v1/LayerInfo.hpp"
11-
#include "linglong/utils/command/cmd.h"
12-
#include "linglong/utils/command/env.h"
11+
#include "linglong/utils/cmd.h"
12+
#include "linglong/utils/file.h"
1313
#include "linglong/utils/log/log.h"
1414

1515
#include <QDataStream>
@@ -28,8 +28,7 @@ LayerPackager::LayerPackager()
2828
// maybe refactor on later
2929
auto ret = this->initWorkDir();
3030
if (!ret) {
31-
qCritical() << "init work dir failed";
32-
Q_ASSERT(false);
31+
LogE("init work dir failed");
3332
}
3433
}
3534

@@ -48,16 +47,15 @@ utils::error::Result<void> LayerPackager::initWorkDir()
4847
// 优先使用环境变量LINGLONG_TMPDIR指定的目录,默认为/var/tmp,避免/tmp是tmpfs内存不足
4948
auto uuid = QUuid::createUuid().toString(QUuid::Id128);
5049
auto dirName = "linglong-layer-workdir-" + uuid.toStdString();
51-
auto tmpDir = utils::command::getEnv("LINGLONG_TMPDIR");
52-
auto dirPath = std::filesystem::path(tmpDir.value_or("/var/tmp")) / dirName;
50+
auto *tmpDir = std::getenv("LINGLONG_TMPDIR");
51+
auto dirPath = std::filesystem::path(tmpDir ? tmpDir : "/var/tmp") / dirName;
5352
auto ret = this->mkdirDir(dirPath);
5453
if (!ret.has_value()) {
5554
// 如果/var/tmp目录无权限创建,则使用临时目录
5655
dirPath = std::filesystem::temp_directory_path() / dirName;
5756
ret = this->mkdirDir(dirPath);
5857
if (!ret) {
59-
qCritical() << "failed to set work dir" << ret.error().message();
60-
Q_ASSERT(false);
58+
LogE("failed to set work dir: {}", ret.error());
6159
}
6260
}
6361
this->workDir = dirPath;
@@ -84,16 +82,15 @@ utils::error::Result<void> LayerPackager::mkdirDir(const std::string &path) noex
8482
LayerPackager::~LayerPackager()
8583
{
8684
if (this->isMounted) {
87-
auto ret = utils::command::Cmd("fusermount")
85+
auto ret = utils::Cmd("fusermount")
8886
.exec({ "-z", "-u", (this->workDir / "unpack").string().c_str() });
8987
if (!ret) {
90-
qWarning() << "failed to umount " << (this->workDir / "unpack").c_str()
91-
<< ", please umount it manually";
88+
LogW("failed to umount {}, please umount it manually",
89+
(this->workDir / "unpack").string());
9290
}
9391
}
9492
if (!std::filesystem::remove_all(this->workDir)) {
9593
LogE("failed to remove {}", this->workDir);
96-
Q_ASSERT(false);
9794
}
9895
}
9996

@@ -151,23 +148,21 @@ LayerPackager::pack(const LayerDir &dir, const QString &layerFilePath) const
151148

152149
// compress data with erofs
153150
const auto &compressedFilePath = this->workDir / "tmp.erofs";
154-
const auto &ignoreRegex = QString{ "--exclude-regex=minified*" };
155151
// 使用-b统一指定block size为4096(2^12), 避免不同系统的兼容问题
156152
// loongarch64默认使用(16384)2^14, 在x86和arm64不受支持, 会导致无法推包
157-
auto ret = utils::command::Cmd("mkfs.erofs")
158-
.exec({ "-z" + compressor,
159-
"-b4096",
160-
compressedFilePath.string().c_str(),
161-
ignoreRegex,
162-
dir.absolutePath() });
153+
auto ret = utils::Cmd("mkfs.erofs")
154+
.exec(std::vector<std::string>{ "-z" + compressor.toStdString(),
155+
"-b4096",
156+
compressedFilePath.string(),
157+
"--exclude-regex=minified*",
158+
dir.absolutePath().toStdString() });
163159
if (!ret) {
164160
return LINGLONG_ERR(ret);
165161
}
166162

167-
ret = utils::command::Cmd("sh").exec(
168-
{ "-c", QString("cat %1 >> %2").arg(compressedFilePath.string().c_str(), layerFilePath) });
169-
if (!ret) {
170-
LINGLONG_ERR(ret);
163+
auto res = utils::concatFile(compressedFilePath, layerFilePath.toStdString());
164+
if (!res) {
165+
return LINGLONG_ERR(res);
171166
}
172167

173168
auto result = LayerFile::New(layerFilePath);
@@ -242,8 +237,10 @@ utils::error::Result<LayerDir> LayerPackager::unpack(LayerFile &file)
242237
}
243238
fuseOffset = "0";
244239
}
245-
auto ret = utils::command::Cmd("erofsfuse")
246-
.exec({ "--offset=" + fuseOffset, fdPath, unpackDir.absolutePath() });
240+
auto ret = utils::Cmd("erofsfuse")
241+
.exec({ "--offset=" + fuseOffset.toStdString(),
242+
fdPath.toStdString(),
243+
unpackDir.absolutePath().toStdString() });
247244
if (!ret) {
248245
return LINGLONG_ERR(ret);
249246
}
@@ -252,15 +249,16 @@ utils::error::Result<LayerDir> LayerPackager::unpack(LayerFile &file)
252249
}
253250
// 判断fsck.erofs命令是否存在,fsck.erofs是erofs-utils的命令,可用于解压erofs文件
254251
// 在旧版本中fsck.erofs不支持offset参数,所以需要提前将erofs文件复制到临时目录
255-
auto erofsFscExistsRet = utils::command::Cmd("fsck.erofs").exists();
252+
auto erofsFscExistsRet = utils::Cmd("fsck.erofs").exists();
256253
if (erofsFscExistsRet) {
257254
fdPath = (this->workDir / "layer.erofs").string().c_str();
258255
auto ret = this->copyFile(file, fdPath.toStdString(), *offset);
259256
if (!ret) {
260257
return LINGLONG_ERR(ret);
261258
}
262-
auto cmdRet = utils::command::Cmd("fsck.erofs")
263-
.exec({ "--extract=" + unpackDir.absolutePath(), fdPath });
259+
auto cmdRet =
260+
utils::Cmd("fsck.erofs")
261+
.exec({ "--extract=" + unpackDir.absolutePath().toStdString(), fdPath.toStdString() });
264262
if (!cmdRet) {
265263
return LINGLONG_ERR(cmdRet);
266264
}
@@ -278,7 +276,7 @@ void LayerPackager::setCompressor(const QString &compressor) noexcept
278276

279277
utils::error::Result<bool> LayerPackager::checkErofsFuseExists() const
280278
{
281-
return utils::command::Cmd("erofsfuse").exists();
279+
return utils::Cmd("erofsfuse").exists();
282280
}
283281

284282
} // namespace linglong::package

0 commit comments

Comments
 (0)