Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.11.4)

project(
linglong
VERSION 1.11.2
VERSION 1.11.3
DESCRIPTION "a container based application package manager for Linux desktop"
HOMEPAGE_URL "https://github.com/OpenAtom-Linyaps/linyaps"
LANGUAGES CXX C)
Expand Down
37 changes: 7 additions & 30 deletions apps/ll-cli/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
#include <QtGlobal>

#include <algorithm>
#include <cstddef>

Check warning on line 32 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <cstddef> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <functional>

Check warning on line 33 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <functional> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <memory>

Check warning on line 34 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <memory> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <string_view>

Check warning on line 35 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <string_view> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <thread>

Check warning on line 36 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <thread> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <fcntl.h>

Check warning on line 38 in apps/ll-cli/src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <fcntl.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <unistd.h>
#include <wordexp.h>

Expand Down Expand Up @@ -67,37 +68,13 @@
std::vector<std::string> transformOldExec(int argc, char **argv) noexcept
{
std::vector<std::string> res;
std::reverse_copy(argv + 1, argv + argc, std::back_inserter(res));
if (std::find(res.rbegin(), res.rend(), "run") == res.rend()) {
return res;
}

auto exec = std::find(res.rbegin(), res.rend(), "--exec");
if (exec == res.rend()) {
return res;
}

if ((exec + 1) == res.rend() || (exec + 2) != res.rend()) {
*exec = "--";
qDebug() << "replace `--exec` with `--`";
return res;
}

wordexp_t words;
auto _ = linglong::utils::finally::finally([&]() {
wordfree(&words);
});

if (auto ret = wordexp((exec + 1)->c_str(), &words, 0); ret != 0) {
qCritical() << "wordexp on" << (exec + 1)->c_str() << "failed with" << ret
<< "transform old exec arguments failed.";
return res;
}

auto it = res.erase(res.rend().base(), exec.base());
res.emplace(it, "--");
for (decltype(words.we_wordc) i = 0; i < words.we_wordc; ++i) {
res.emplace(res.begin(), words.we_wordv[i]);
for (int i = argc - 1; i > 0; --i) {
if (std::string_view(argv[i]) == "--exec") {
res.emplace_back("--");
} else {
res.emplace_back(argv[i]);
}
}

return res;
Expand Down
3 changes: 1 addition & 2 deletions apps/ll-driver-detect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ pfl_add_executable(
./src/dbus_notifier.cpp
LINK_LIBRARIES
PRIVATE
CLI11::CLI11
linglong::utils)
linglong::linglong)
41 changes: 36 additions & 5 deletions apps/ll-driver-detect/src/driver_detection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@

#include "driver_detection_manager.h"

#include "linglong/utils/cmd.h"

Check warning on line 7 in apps/ll-driver-detect/src/driver_detection_manager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/utils/cmd.h" not found.
#include "linglong/utils/log/log.h"

Check warning on line 8 in apps/ll-driver-detect/src/driver_detection_manager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "linglong/utils/log/log.h" not found.
#include "nvidia_driver_detector.h"

namespace linglong::driver::detect {

DriverDetectionManager::DriverDetectionManager()
{
registerDetectors();

Check warning on line 15 in apps/ll-driver-detect/src/driver_detection_manager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Virtual function 'registerDetectors' is called from constructor 'DriverDetectionManager()' at line 15. Dynamic binding is not used.
}

utils::error::Result<DriverDetectionResult> DriverDetectionManager::detectAllDrivers()
utils::error::Result<std::vector<GraphicsDriverInfo>>
DriverDetectionManager::detectAvailableDrivers()

Check warning on line 19 in apps/ll-driver-detect/src/driver_detection_manager.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

The function 'detectAvailableDrivers' is never used.
{
DriverDetectionResult result;
std::vector<GraphicsDriverInfo> detectedDrivers;

for (const auto &detector : detectors_) {
auto detectionResult = detector->detect();
Expand All @@ -27,13 +29,13 @@
continue;
}

result.detectedDrivers.emplace_back(*detectionResult);
detectedDrivers.emplace_back(*detectionResult);
LogD("Detected driver: {} version: {}",
detectionResult->packageName,
detectionResult->version);
detectionResult->packageVersion);
}

return result;
return detectedDrivers;
}

void DriverDetectionManager::registerDetectors()
Expand All @@ -46,4 +48,33 @@
LogD("Registered {} driver detectors", detectors_.size());
}

linglong::utils::error::Result<void>
DriverDetectionManager::installDriverPackage(const std::vector<GraphicsDriverInfo> &drivers)
{
LINGLONG_TRACE("installDriverPackage")

try {
for (const auto &info : drivers) {
LogD("Processing driver: Identify={}, Version={}, Package={}",
info.identify,
info.packageVersion,
info.packageName);

// Execute ll-cli install command to install the package
auto packageRef = info.packageName + "/" + info.packageVersion;
auto ret = linglong::utils::Cmd("ll-cli").exec(
{ "install", packageRef, "--repo", info.repoName });
if (!ret) {
return LINGLONG_ERR("Installation command failed: " + ret.error().message());
}

LogD("Driver package installation command executed successfully: {}", *ret);
}

return LINGLONG_OK;
} catch (const std::exception &e) {
return LINGLONG_ERR("Failed to install driver package: " + std::string(e.what()));
}
}

} // namespace linglong::driver::detect
17 changes: 2 additions & 15 deletions apps/ll-driver-detect/src/driver_detection_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@

namespace linglong::driver::detect {

// Result of driver detection for all available drivers
struct DriverDetectionResult
{
std::vector<GraphicsDriverInfo> detectedDrivers;

bool hasAvailableDrivers() const
{
return std::any_of(detectedDrivers.begin(), detectedDrivers.end(), [](const auto &driver) {
return !driver.isInstalled;
});
}
};

// Manager class that coordinates detection of multiple graphics drivers
class DriverDetectionManager
{
Expand All @@ -33,12 +20,12 @@ class DriverDetectionManager

// Detect all available graphics drivers on the system
// Returns all detected drivers, or empty vector if none found
utils::error::Result<DriverDetectionResult> detectAllDrivers();
utils::error::Result<std::vector<GraphicsDriverInfo>> detectAvailableDrivers();
linglong::utils::error::Result<void> installDriverPackage(const std::vector<GraphicsDriverInfo> &drivers);

protected:
// Register all available driver detectors
virtual void registerDetectors();

std::vector<std::unique_ptr<DriverDetector>> detectors_;
};

Expand Down
7 changes: 5 additions & 2 deletions apps/ll-driver-detect/src/driver_detector.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ namespace linglong::driver::detect {
struct GraphicsDriverInfo
{
std::string identify;
std::string version;
std::string packageName;
bool isInstalled = false;
std::string packageVersion;
std::string repoName{ "stable" };
};

class DriverDetector
Expand All @@ -29,6 +29,9 @@ class DriverDetector
// Check if the driver package is installed
virtual utils::error::Result<bool> checkPackageInstalled(const std::string &packageName) = 0;

// Check if the driver package can upgraded
virtual utils::error::Result<bool> checkPackageUpgradable(const std::string &packageName) = 0;

// Get the Identify of driver this detector handles
virtual std::string getDriverIdentify() const = 0;
};
Expand Down
58 changes: 11 additions & 47 deletions apps/ll-driver-detect/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include "driver_detection_config.h"
#include "driver_detection_manager.h"
#include "driver_detector.h"
#include "linglong/utils/cmd.h"
#include "linglong/utils/global/initialize.h"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The header linglong/utils/global/initialize.h is included twice in this file (here and on line 14). To keep the code clean, one of these redundant includes should be removed.

#include "linglong/utils/error/error.h"
#include "linglong/utils/gettext.h"
#include "linglong/utils/global/initialize.h"
Expand Down Expand Up @@ -86,41 +86,6 @@ linglong::utils::error::Result<DriverDetectionConfigManager> setupConfigManager(
return configManager;
}

linglong::utils::error::Result<void>
installDriverPackage(const std::vector<GraphicsDriverInfo> &drivers)
{
LINGLONG_TRACE("installDriverPackage")

try {
for (const auto &driverInfo : drivers) {
LogD("Processing driver: Identify={}, Version={}, Package={}, Installed={}",
driverInfo.identify,
driverInfo.version,
driverInfo.packageName,
driverInfo.isInstalled);

if (driverInfo.isInstalled) {
LogD("Driver package is already installed: {}", driverInfo.packageName);
continue;
}

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

LogD("Driver package installation command executed successfully: {}", *ret);
}

return LINGLONG_OK;
} catch (const std::exception &e) {
return LINGLONG_ERR("Failed to install driver package: " + std::string(e.what()));
}

return LINGLONG_OK;
}

} // namespace

int main(int argc, char *argv[])
Expand Down Expand Up @@ -191,7 +156,7 @@ int main(int argc, char *argv[])
DriverDetectionManager detectionManager;

// Run driver detection and handling for all available drivers
auto result = detectionManager.detectAllDrivers();
auto result = detectionManager.detectAvailableDrivers();

if (!result) {
LogF("Driver detection failed: {}", result.error().message());
Expand All @@ -201,8 +166,8 @@ int main(int argc, char *argv[])

const auto &detectionResult = *result;

if (!detectionResult.hasAvailableDrivers()) {
std::cout << "No available graphics drivers detected or already installed" << std::endl;
if (detectionResult.size() == 0) {
LogD("No graphics drivers detected that require installation or upgrade");
return 0;
}

Expand All @@ -211,22 +176,21 @@ int main(int argc, char *argv[])
"will be performed."
<< std::endl;
std::cout << "Detected drivers:" << std::endl;
for (const auto &driverInfo : detectionResult.detectedDrivers) {
for (const auto &info : detectionResult) {
std::cout << "----------------------------------------" << std::endl;
std::cout << " Identify: " << driverInfo.identify << std::endl;
std::cout << " Version: " << driverInfo.version << std::endl;
std::cout << " Package: " << driverInfo.packageName << std::endl;
std::cout << " Installed: " << (driverInfo.isInstalled ? "Yes" : "No") << std::endl;
std::cout << " Identify: " << info.identify << std::endl;
std::cout << " Version: " << info.packageVersion << std::endl;
std::cout << " Package: " << info.packageName << std::endl;
std::cout << "----------------------------------------" << std::endl;
}
return 0;
}

LogD("Detected {} graphics driver(s)", detectionResult.detectedDrivers.size());
LogD("Detected {} graphics driver(s)", detectionResult.size());

if (options.installOnly) {
std::cout << "Install-only: installing detected drivers without notifications" << std::endl;
auto installResult = installDriverPackage(detectionResult.detectedDrivers);
auto installResult = detectionManager.installDriverPackage(detectionResult);
if (!installResult) {
LogW("Failed to install driver package {}: {}",
options.packageName,
Expand Down Expand Up @@ -270,7 +234,7 @@ int main(int argc, char *argv[])
if (response.action == kActionInstallNow && response.success) {
LogD("User chose to install graphics driver");

auto installResult = installDriverPackage(detectionResult.detectedDrivers);
auto installResult = detectionManager.installDriverPackage(detectionResult);
if (!installResult) {
LogW("Failed to install driver package: {}", installResult.error().message());
return 1;
Expand Down
Loading