parent
f415963f24
commit
e687608175
@ -1,5 +1,4 @@
|
||||
#!/bin/bash
|
||||
loadkeys "$(cat /dev/shm/fixconkeys-layout)"
|
||||
setupcon --save-only
|
||||
update-initramfs -c -k all
|
||||
rm /usr/libexec/fixconkeys-part2
|
||||
|
@ -1,52 +1,143 @@
|
||||
#ifndef PACKAGESELECTVIEWSTEP_H
|
||||
#define PACKAGESELECTVIEWSTEP_H
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
#include <QMap>
|
||||
#include "DllMacro.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include "ui_pkgselect.h"
|
||||
|
||||
namespace Ui {
|
||||
class pkgselect;
|
||||
}
|
||||
|
||||
class QCheckBox;
|
||||
|
||||
/**
|
||||
* @class PackageSelectViewStep
|
||||
* @brief A Calamares view step for selecting and customizing packages during installation.
|
||||
*
|
||||
* This class provides a user interface for selecting additional packages to install,
|
||||
* managing installation modes, and handling network availability scenarios.
|
||||
*/
|
||||
class PLUGINDLLEXPORT PackageSelectViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new PackageSelectViewStep object.
|
||||
* @param parent The parent QObject.
|
||||
*/
|
||||
explicit PackageSelectViewStep(QObject* parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Destroys the PackageSelectViewStep object.
|
||||
*/
|
||||
~PackageSelectViewStep() override;
|
||||
|
||||
/**
|
||||
* @brief Returns the display name of the step.
|
||||
* @return The pretty name as a QString.
|
||||
*/
|
||||
QString prettyName() const override;
|
||||
|
||||
/**
|
||||
* @brief Returns the widget associated with this step.
|
||||
* @return A pointer to the QWidget.
|
||||
*/
|
||||
QWidget* widget() override;
|
||||
|
||||
/**
|
||||
* @brief Returns the list of jobs to execute for this step.
|
||||
* @return An empty Calamares::JobList.
|
||||
*/
|
||||
Calamares::JobList jobs() const override;
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the "Next" button is enabled.
|
||||
* @return Always returns true.
|
||||
*/
|
||||
bool isNextEnabled() const override;
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the "Back" button is enabled.
|
||||
* @return Always returns true.
|
||||
*/
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the step is at the beginning.
|
||||
* @return Always returns true.
|
||||
*/
|
||||
bool isAtBeginning() const override;
|
||||
|
||||
/**
|
||||
* @brief Indicates whether the step is at the end.
|
||||
* @return Always returns true.
|
||||
*/
|
||||
bool isAtEnd() const override;
|
||||
|
||||
/**
|
||||
* @brief Activates the step, setting up the UI based on network availability and configuration.
|
||||
*/
|
||||
void onActivate() override;
|
||||
|
||||
/**
|
||||
* @brief Handles actions to perform when leaving the step, such as storing selected packages.
|
||||
*/
|
||||
void onLeave() override;
|
||||
|
||||
/**
|
||||
* @brief Sets the configuration map for the step.
|
||||
* @param configurationMap The QVariantMap containing configuration data.
|
||||
*/
|
||||
void setConfigurationMap(const QVariantMap& configurationMap) override;
|
||||
|
||||
/**
|
||||
* @brief Retrieves the current package selections.
|
||||
* @return A QVariantMap of package selections.
|
||||
*/
|
||||
QVariantMap packageSelections() const { return m_packageSelections; }
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* @brief Slot to handle checkbox toggle events.
|
||||
* @param checked The new checked state of the checkbox.
|
||||
*/
|
||||
void updatePackageSelections(bool checked);
|
||||
|
||||
signals:
|
||||
/**
|
||||
* @brief Signal emitted when package selections change.
|
||||
*/
|
||||
void packageSelectionsChanged();
|
||||
|
||||
private:
|
||||
QVariantMap m_packageSelections;
|
||||
Ui::pkgselect *ui;
|
||||
QWidget* m_widget;
|
||||
/**
|
||||
* @brief Retrieves the checkbox associated with a given package ID.
|
||||
* @param id The package ID.
|
||||
* @return A pointer to the QCheckBox, or nullptr if not found.
|
||||
*/
|
||||
QCheckBox* getCheckboxById(const QString& id) const;
|
||||
|
||||
/**
|
||||
* @brief Checks if a given key exists in package selections and is set to true.
|
||||
* @param key The key to check.
|
||||
* @return True if the key exists and is true, otherwise false.
|
||||
*/
|
||||
bool exists_and_true(const QString& key) const;
|
||||
|
||||
QVariantMap m_packageSelections; ///< Stores the state of package selections.
|
||||
Ui::pkgselect* ui; ///< Pointer to the UI class.
|
||||
QWidget* m_widget; ///< Pointer to the main widget of the step.
|
||||
QVariantMap m_configurationMap; ///< Stores configuration data.
|
||||
|
||||
QMap<QString, QCheckBox*> m_packageCheckBoxes; ///< Maps package IDs to their corresponding checkboxes.
|
||||
bool m_connectionsMade; ///< Flag to ensure signal connections are made only once.
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION(PackageSelectViewStepFactory)
|
||||
|
||||
#endif
|
||||
#endif // PACKAGESELECTVIEWSTEP_H
|
||||
|
@ -0,0 +1,55 @@
|
||||
---
|
||||
packages:
|
||||
additional_packages:
|
||||
- id: "element-desktop"
|
||||
name: "Element"
|
||||
description: "Matrix-based end-to-end encrypted messenger and secure collaboration app."
|
||||
snap: true
|
||||
- id: "thunderbird"
|
||||
name: "Thunderbird"
|
||||
description: "Email, newsfeed, chat, and calendaring client."
|
||||
snap: true
|
||||
- id: "virt-manager"
|
||||
name: "Virtual Machine Manager"
|
||||
description: "Desktop user interface for managing virtual machines through libvirt."
|
||||
snap: false
|
||||
- id: "krita"
|
||||
name: "Krita"
|
||||
description: "Graphics editor designed primarily for digital art and 2D animation."
|
||||
snap: true
|
||||
minimal_remove_packages:
|
||||
- "snapd"
|
||||
- "lubuntu-snap-installation-monitor"
|
||||
- "vlc"
|
||||
- "plasma-discover"
|
||||
- "transmission-qt"
|
||||
- "quassel"
|
||||
- "2048-qt"
|
||||
- "featherpad"
|
||||
- "noblenote"
|
||||
- "kcalc"
|
||||
- "qps"
|
||||
- "zsync"
|
||||
- "partitionmanager"
|
||||
- "qapt-deb-installer"
|
||||
- "picom"
|
||||
- "qlipper"
|
||||
- "qtpass"
|
||||
- "libreoffice*"
|
||||
installer_remove_packages:
|
||||
- "^live-*"
|
||||
- calamares-settings-lubuntu
|
||||
- calamares
|
||||
- zram-config
|
||||
- cifs-utils
|
||||
- lubuntu-installer-prompt
|
||||
regular_install_packages:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
||||
refresh_snaps:
|
||||
- "firefox"
|
||||
- "firmware-updater"
|
@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
include(FeatureSummary)
|
||||
|
||||
set( CMAKE_CXX_STANDARD 20 )
|
||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
||||
|
||||
set( CALAMARES_VERSION_REQUIRED 3.3.9 )
|
||||
|
||||
find_package(ECM "6.0.0" NO_MODULE)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH})
|
||||
include(KDEInstallDirs)
|
||||
find_package(KF6 REQUIRED COMPONENTS CoreAddons)
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} NO_CMAKE_PACKAGE_REGISTRY)
|
||||
if (NOT TARGET Calamares::calamares OR NOT TARGET Calamares::calamaresui)
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} REQUIRED)
|
||||
endif()
|
||||
|
||||
message(STATUS "Found Calamares version ${Calamares_VERSION}")
|
||||
message(STATUS " libraries ${Calamares_LIB_DIRS}")
|
||||
message(STATUS "")
|
||||
|
||||
calamares_add_plugin( pkgselectprocess
|
||||
TYPE job
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
PackageSelectProcess.cpp
|
||||
SHARED_LIB
|
||||
NO_CONFIG
|
||||
)
|
@ -0,0 +1,390 @@
|
||||
#include "PackageSelectProcess.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
#include <QRegularExpression>
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION(PackageSelectProcessFactory, registerPlugin<PackageSelectProcess>();)
|
||||
|
||||
PackageSelectProcess::PackageSelectProcess(QObject* parent)
|
||||
: Calamares::CppJob(parent),
|
||||
m_prettyStatus(tr("Preparing to install selected packages..."))
|
||||
{
|
||||
}
|
||||
|
||||
QString PackageSelectProcess::prettyName() const
|
||||
{
|
||||
return tr("Installing selected packages");
|
||||
}
|
||||
|
||||
QString PackageSelectProcess::prettyStatusMessage() const
|
||||
{
|
||||
return m_prettyStatus;
|
||||
}
|
||||
|
||||
void PackageSelectProcess::setConfigurationMap(const QVariantMap& configurationMap)
|
||||
{
|
||||
m_configurationMap = configurationMap;
|
||||
}
|
||||
|
||||
Calamares::JobResult PackageSelectProcess::runAptCommand(const QString& command,
|
||||
const QString& rootMountPoint,
|
||||
double startProgress,
|
||||
double endProgress,
|
||||
bool verboseProgress)
|
||||
{
|
||||
QProcess aptProcess(this);
|
||||
aptProcess.setProgram("/usr/sbin/chroot");
|
||||
aptProcess.setArguments({ rootMountPoint, "/bin/bash", "-c", command });
|
||||
aptProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
constexpr int MAX_LINES = 5000;
|
||||
double progressRange = endProgress - startProgress;
|
||||
double progressPerLine = progressRange / static_cast<double>(MAX_LINES);
|
||||
int lineCount = 0;
|
||||
|
||||
QString commandHRPrefix;
|
||||
if (command.contains("install")) {
|
||||
commandHRPrefix = tr("Installing packages: ");
|
||||
} else if (command.contains("full-upgrade")) {
|
||||
commandHRPrefix = tr("Upgrading installed system: ");
|
||||
} else if (command.contains("autoremove")) {
|
||||
commandHRPrefix = tr("Cleaning up packages: ");
|
||||
}
|
||||
|
||||
QRegularExpression getRegex(R"(Get:\d+\s+[^ ]+\s+[^ ]+\s+(.+?)\s+\S+\s+(\S+)\s+\[(.*?)\])");
|
||||
|
||||
connect(&aptProcess, &QProcess::readyReadStandardOutput, this,
|
||||
[this, &aptProcess, &lineCount, progressPerLine, startProgress, endProgress, verboseProgress, commandHRPrefix, getRegex]() mutable {
|
||||
while (aptProcess.canReadLine()) {
|
||||
QString line = QString::fromUtf8(aptProcess.readLine()).trimmed();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (verboseProgress && !line.contains("Running in chroot, ignoring command") &&
|
||||
!line.contains("Waiting until unit") && !line.contains("Stopping snap") &&
|
||||
!line.contains("/dev/pts")) {
|
||||
|
||||
// Process "Get:" lines to show download information
|
||||
if (line.startsWith("Get:")) {
|
||||
QRegularExpressionMatch match = getRegex.match(line);
|
||||
if (match.hasMatch()) {
|
||||
QString packageName = match.captured(1);
|
||||
QString packageVersion = match.captured(2);
|
||||
QString packageSize = match.captured(3);
|
||||
line = tr("Downloading %1 %2 (%3)").arg(packageName, packageVersion, packageSize);
|
||||
}
|
||||
}
|
||||
|
||||
m_prettyStatus = commandHRPrefix + line;
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
qDebug() << m_prettyStatus;
|
||||
}
|
||||
|
||||
lineCount++;
|
||||
double currentProgress = startProgress + (lineCount * progressPerLine);
|
||||
currentProgress = qBound(startProgress, currentProgress, endProgress);
|
||||
emit progress(currentProgress);
|
||||
}
|
||||
});
|
||||
|
||||
aptProcess.start();
|
||||
if (!aptProcess.waitForStarted()) {
|
||||
qWarning() << "Failed to start apt command:" << aptProcess.errorString();
|
||||
return Calamares::JobResult::error(tr("Apt command failed"),
|
||||
tr("Failed to start apt command: %1").arg(aptProcess.errorString()));
|
||||
}
|
||||
|
||||
while (!aptProcess.waitForFinished(100)) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
if (aptProcess.exitStatus() != QProcess::NormalExit || aptProcess.exitCode() != 0) {
|
||||
QString errorOutput = QString::fromUtf8(aptProcess.readAllStandardError()).trimmed();
|
||||
qWarning() << "Apt command error:" << errorOutput;
|
||||
return Calamares::JobResult::error(tr("Apt command failed"),
|
||||
tr("Failed to execute apt command: %1").arg(errorOutput));
|
||||
}
|
||||
|
||||
emit progress(endProgress);
|
||||
m_prettyStatus = tr("Command executed successfully.");
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
Calamares::JobResult PackageSelectProcess::runSnapCommand(const QStringList& snapPackages,
|
||||
const QString& rootMountPoint,
|
||||
double startProgress,
|
||||
double endProgress)
|
||||
{
|
||||
const QString seedDirectory = QDir::cleanPath(rootMountPoint + "/var/lib/snapd/seed");
|
||||
QDir dir(seedDirectory);
|
||||
if (!dir.exists() && !dir.mkpath(".")) {
|
||||
return Calamares::JobResult::error(tr("Snap installation failed"),
|
||||
tr("Failed to create seed directory: %1").arg(seedDirectory));
|
||||
}
|
||||
|
||||
QStringList snapCommandArgs = { "--seed", seedDirectory };
|
||||
snapCommandArgs += snapPackages;
|
||||
|
||||
qDebug() << "Executing Snap Command:" << snapCommandArgs.join(" ");
|
||||
|
||||
QProcess snapProcess(this);
|
||||
snapProcess.setProgram("/usr/bin/snapd-seed-glue");
|
||||
snapProcess.setArguments(snapCommandArgs);
|
||||
snapProcess.setProcessChannelMode(QProcess::MergedChannels);
|
||||
|
||||
QString currentDescription;
|
||||
|
||||
connect(&snapProcess, &QProcess::readyReadStandardOutput, this,
|
||||
[&snapProcess, this, ¤tDescription, startProgress, endProgress]( ) {
|
||||
while (snapProcess.canReadLine()) {
|
||||
QString line = QString::fromUtf8(snapProcess.readLine()).trimmed();
|
||||
if (line.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QStringList parts = line.split("\t");
|
||||
if (parts.size() != 2) {
|
||||
qWarning() << "Unexpected output format from snap-seed-glue:" << line;
|
||||
continue;
|
||||
}
|
||||
|
||||
bool ok = false;
|
||||
double percentage = parts[0].toDouble(&ok);
|
||||
const QString& description = parts[1];
|
||||
|
||||
if (!ok) {
|
||||
qWarning() << "Failed to parse percentage from line:" << line;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (description != currentDescription) {
|
||||
m_prettyStatus = description;
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
currentDescription = description;
|
||||
qDebug() << description;
|
||||
}
|
||||
|
||||
double scaledProgress = startProgress + (percentage / 100.0) * (endProgress - startProgress);
|
||||
emit progress(scaledProgress);
|
||||
}
|
||||
});
|
||||
|
||||
m_prettyStatus = tr("Installing snap packages...");
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
emit progress(startProgress);
|
||||
|
||||
snapProcess.start();
|
||||
if (!snapProcess.waitForStarted()) {
|
||||
qWarning() << "Failed to start snap installation process:" << snapProcess.errorString();
|
||||
return Calamares::JobResult::error(tr("Snap installation failed"),
|
||||
tr("Failed to start snap installation process: %1").arg(snapProcess.errorString()));
|
||||
}
|
||||
|
||||
while (!snapProcess.waitForFinished(100)) {
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
if (snapProcess.exitStatus() != QProcess::NormalExit || snapProcess.exitCode() != 0) {
|
||||
QString errorOutput = QString::fromUtf8(snapProcess.readAllStandardError()).trimmed();
|
||||
qWarning() << "Snap installation error:" << errorOutput;
|
||||
return Calamares::JobResult::error(tr("Snap installation failed"),
|
||||
tr("Failed to install snap packages: %1").arg(errorOutput));
|
||||
}
|
||||
|
||||
emit progress(endProgress);
|
||||
m_prettyStatus = tr("Snap packages installed successfully.");
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
Calamares::JobResult PackageSelectProcess::exec()
|
||||
{
|
||||
auto gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if (!gs || !gs->contains("installation_data")) {
|
||||
return Calamares::JobResult::error(tr("No installation data found."),
|
||||
tr("Installation data is missing from global storage."));
|
||||
}
|
||||
|
||||
const QVariantMap installationData = gs->value("installation_data").toMap();
|
||||
const QString installationMode = installationData.value("installation_mode").toString();
|
||||
const bool downloadUpdates = installationData.value("download_updates").toBool();
|
||||
const QVariantList packagesToInstall = installationData.value("packages_to_install").toList();
|
||||
const QVariantList packagesToRemove = installationData.value("packages_to_remove").toList();
|
||||
const QVariantList presentSnaps = installationData.value("present_snaps").toList();
|
||||
|
||||
// Handle default value for rootMountPoint
|
||||
QString rootMountPoint = "/";
|
||||
if (gs->contains("rootMountPoint")) {
|
||||
rootMountPoint = gs->value("rootMountPoint").toString();
|
||||
}
|
||||
|
||||
static const QMap<QString, QVector<ProgressAllocation>> allocationMap = {
|
||||
{ "minimal", { {0.0, 1.0} } },
|
||||
{ "normal", { {0.0, 0.4}, {0.4, 1.0} } },
|
||||
{ "full", { {0.0, 0.25}, {0.25, 1.0} } }
|
||||
};
|
||||
|
||||
const QVector<ProgressAllocation> allocations = allocationMap.value(installationMode, { {0.0, 1.0} });
|
||||
|
||||
// Run apt update
|
||||
const double aptRange = allocations[0].end - allocations[0].start;
|
||||
const double updateStart = allocations[0].start;
|
||||
const double updateEnd = updateStart + 0.1 * aptRange;
|
||||
|
||||
m_prettyStatus = tr("Updating apt cache");
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
emit progress(updateStart);
|
||||
|
||||
Calamares::JobResult updateResult = runAptCommand("DEBIAN_FRONTEND=noninteractive apt-get update",
|
||||
rootMountPoint,
|
||||
updateStart,
|
||||
updateEnd,
|
||||
false);
|
||||
if (!updateResult) { // Using operator bool() to check for errors
|
||||
return std::move(updateResult); // Move to avoid copy
|
||||
}
|
||||
|
||||
QStringList debPackages;
|
||||
for (const QVariant& var : packagesToInstall) {
|
||||
const QVariantMap pkg = var.toMap();
|
||||
if (!pkg.value("snap").toBool()) {
|
||||
debPackages << pkg.value("id").toString();
|
||||
}
|
||||
}
|
||||
|
||||
double installStart;
|
||||
double installEnd;
|
||||
if (downloadUpdates) {
|
||||
const double upgradeStart = updateEnd;
|
||||
const double upgradeEnd = upgradeStart + 0.25 * aptRange;
|
||||
|
||||
Calamares::JobResult upgradeResult = runAptCommand(
|
||||
"DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confnew' full-upgrade",
|
||||
rootMountPoint,
|
||||
upgradeStart,
|
||||
upgradeEnd,
|
||||
true
|
||||
);
|
||||
if (!upgradeResult) { // Using operator bool() to check for errors
|
||||
return std::move(upgradeResult); // Move to avoid copy
|
||||
}
|
||||
|
||||
installStart = upgradeEnd;
|
||||
installEnd = installStart + 0.25 * aptRange;
|
||||
}
|
||||
else {
|
||||
installStart = updateEnd;
|
||||
installEnd = installStart + 0.5 * aptRange;
|
||||
installEnd = qMin(installEnd, allocations[0].end);
|
||||
}
|
||||
|
||||
qDebug() << "Progress range: installStart:" << installStart << "installEnd:" << installEnd;
|
||||
|
||||
if (!debPackages.isEmpty()) {
|
||||
const QString packageList = debPackages.join(" -e ");
|
||||
const QString installCommand = QString(
|
||||
"DEBIAN_FRONTEND=noninteractive apt-get -y install $(apt-cache --no-generate pkgnames %1 | grep -Fx -e %2)"
|
||||
).arg(debPackages.join(" ")).arg(packageList);
|
||||
|
||||
Calamares::JobResult installResult = runAptCommand(installCommand,
|
||||
rootMountPoint,
|
||||
installStart,
|
||||
installEnd,
|
||||
true);
|
||||
if (!installResult) { // Using operator bool() to check for errors
|
||||
return std::move(installResult); // Move to avoid copy
|
||||
}
|
||||
}
|
||||
else {
|
||||
qDebug() << "No packages to install.";
|
||||
}
|
||||
|
||||
QStringList removeDebPackages;
|
||||
for (const QVariant& var : packagesToRemove) {
|
||||
removeDebPackages << var.toString();
|
||||
}
|
||||
|
||||
const double removeStart = installEnd;
|
||||
const double removeEnd = removeStart + 0.2 * aptRange;
|
||||
|
||||
if (!removeDebPackages.isEmpty()) {
|
||||
const QString removeCommand = QString("DEBIAN_FRONTEND=noninteractive apt-get -y --purge remove %1")
|
||||
.arg(removeDebPackages.join(" "));
|
||||
Calamares::JobResult removeResult = runAptCommand(removeCommand,
|
||||
rootMountPoint,
|
||||
removeStart,
|
||||
removeEnd,
|
||||
true);
|
||||
if (!removeResult) { // Using operator bool() to check for errors
|
||||
return std::move(removeResult); // Move to avoid copy
|
||||
}
|
||||
}
|
||||
|
||||
const double autoremoveStart = removeEnd;
|
||||
const double autoremoveEnd = autoremoveStart + 0.2 * aptRange;
|
||||
|
||||
Calamares::JobResult autoremoveResult = runAptCommand("DEBIAN_FRONTEND=noninteractive apt-get -y autoremove",
|
||||
rootMountPoint,
|
||||
autoremoveStart,
|
||||
autoremoveEnd,
|
||||
true);
|
||||
if (!autoremoveResult) { // Using operator bool() to check for errors
|
||||
return std::move(autoremoveResult); // Move to avoid copy
|
||||
}
|
||||
|
||||
// Handle snap packages
|
||||
if (installationMode != "minimal") {
|
||||
QStringList snapPackages;
|
||||
QStringList presentSnapsList;
|
||||
// Convert QVariantList to QStringList
|
||||
for (const QVariant& var : presentSnaps) {
|
||||
presentSnapsList << var.toString();
|
||||
}
|
||||
|
||||
for (const QVariant& var : packagesToInstall) {
|
||||
const QVariantMap pkg = var.toMap();
|
||||
if (pkg.value("snap").toBool()) {
|
||||
snapPackages << pkg.value("id").toString();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList finalSnapPackages;
|
||||
|
||||
if (!snapPackages.isEmpty() && !presentSnapsList.isEmpty()) {
|
||||
finalSnapPackages = presentSnapsList + snapPackages;
|
||||
}
|
||||
else if (!snapPackages.isEmpty()) {
|
||||
finalSnapPackages = snapPackages;
|
||||
}
|
||||
else if (!presentSnapsList.isEmpty() && downloadUpdates) {
|
||||
finalSnapPackages = presentSnapsList;
|
||||
}
|
||||
|
||||
if (!finalSnapPackages.isEmpty()) {
|
||||
double snapStart = allocations.size() > 1 ? allocations[1].start : allocations[0].end;
|
||||
double snapEnd = allocations.size() > 1 ? allocations[1].end : allocations[0].end;
|
||||
|
||||
Calamares::JobResult snapResult = runSnapCommand(finalSnapPackages,
|
||||
rootMountPoint,
|
||||
snapStart,
|
||||
snapEnd);
|
||||
if (!snapResult) { // Using operator bool() to check for errors
|
||||
return std::move(snapResult); // Move to avoid copy
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emit progress(1.0);
|
||||
m_prettyStatus = tr("All selected packages installed successfully.");
|
||||
emit prettyStatusMessageChanged(m_prettyStatus);
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
#ifndef PACKAGESELECTPROCESS_H
|
||||
#define PACKAGESELECTPROCESS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
#include "CppJob.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class QProcess;
|
||||
|
||||
class PLUGINDLLEXPORT PackageSelectProcess : public Calamares::CppJob
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PackageSelectProcess(QObject* parent = nullptr);
|
||||
~PackageSelectProcess() override = default;
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyStatusMessage() const override;
|
||||
|
||||
Calamares::JobResult exec() override;
|
||||
|
||||
void setConfigurationMap(const QVariantMap& configurationMap) override;
|
||||
|
||||
signals:
|
||||
void prettyStatusMessageChanged(const QString&);
|
||||
|
||||
private:
|
||||
struct ProgressAllocation
|
||||
{
|
||||
double start;
|
||||
double end;
|
||||
};
|
||||
|
||||
Calamares::JobResult runAptCommand(const QString& command,
|
||||
const QString& rootMountPoint,
|
||||
double startProgress,
|
||||
double endProgress,
|
||||
bool verboseProgress);
|
||||
Calamares::JobResult runSnapCommand(const QStringList& snapPackages,
|
||||
const QString& rootMountPoint,
|
||||
double startProgress,
|
||||
double endProgress);
|
||||
|
||||
QVariantMap m_configurationMap;
|
||||
QString m_prettyStatus;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION(PackageSelectProcessFactory)
|
||||
|
||||
#endif // PACKAGESELECTPROCESS_H
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
type: "job"
|
||||
name: "pkgselectprocess"
|
||||
interface: "qtplugin"
|
||||
load: "libcalamares_job_pkgselectprocess.so"
|
||||
noconfig: true
|
||||
weight: 12
|
@ -1,16 +0,0 @@
|
||||
update_db: true
|
||||
backend: apt
|
||||
operations:
|
||||
- remove:
|
||||
- "^live-*"
|
||||
- calamares-settings-kubuntu
|
||||
- calamares
|
||||
- cifs-utils
|
||||
- kubuntu-installer-prompt
|
||||
- try_install:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
@ -0,0 +1,53 @@
|
||||
---
|
||||
packages:
|
||||
additional_packages:
|
||||
- id: "element-desktop"
|
||||
name: "Element"
|
||||
description: "Matrix-based end-to-end encrypted messenger and secure collaboration app."
|
||||
snap: true
|
||||
- id: "virt-manager"
|
||||
name: "Virtual Machine Manager"
|
||||
description: "Desktop user interface for managing virtual machines through libvirt."
|
||||
snap: false
|
||||
- id: "krita"
|
||||
name: "Krita"
|
||||
description: "Graphics editor designed primarily for digital art and 2D animation."
|
||||
snap: true
|
||||
minimal_remove_packages:
|
||||
- kmahjongg
|
||||
- kmines
|
||||
- kpat
|
||||
- ksudoku
|
||||
- skanlite
|
||||
- skanpage
|
||||
- okular
|
||||
- "libreoffice*"
|
||||
- kdeconnect
|
||||
- krdc
|
||||
- konversation
|
||||
- neochat
|
||||
- elisa
|
||||
- haruna
|
||||
- vim
|
||||
- snapd
|
||||
- partitionmanager
|
||||
- usb-creator*
|
||||
- plasma-welcome
|
||||
- kde-config-tablet
|
||||
installer_remove_packages:
|
||||
- "^live-*"
|
||||
- calamares-settings-kubuntu
|
||||
- calamares
|
||||
- cifs-utils
|
||||
- kubuntu-installer-prompt
|
||||
regular_install_packages:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
||||
refresh_snaps:
|
||||
- "firefox"
|
||||
- "thunderbird"
|
||||
- "firmware-updater"
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
dontChroot: false
|
||||
timeout: 10800
|
||||
"packages.minimalButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y --purge remove kmahjongg kmines kpat ksudoku skanlite skanpage okular libreoffice* kdeconnect krdc konversation neochat elisa haruna vim snapd partitionmanager usb-creator* plasma-welcome kde-config-tablet plasma-welcome"
|
||||
- "apt-get -y autoremove"
|
||||
"packages.partyButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install ubuntu-restricted-addons unrar"
|
||||
"packages.updatesButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confnew' full-upgrade"
|
||||
"packages.virtmanagerButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install virt-manager"
|
@ -1,9 +0,0 @@
|
||||
---
|
||||
dontChroot: true
|
||||
timeout: 10800
|
||||
"packages.elementButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed element-desktop"
|
||||
"packages.kritaButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed krita"
|
||||
"packages.thunderbirdButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed thunderbird"
|
@ -1,17 +0,0 @@
|
||||
update_db: true
|
||||
backend: apt
|
||||
operations:
|
||||
- remove:
|
||||
- "^live-*"
|
||||
- calamares-settings-lubuntu
|
||||
- calamares
|
||||
- zram-config
|
||||
- cifs-utils
|
||||
- lubuntu-installer-prompt
|
||||
- try_install:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
@ -0,0 +1,55 @@
|
||||
---
|
||||
packages:
|
||||
additional_packages:
|
||||
- id: "element-desktop"
|
||||
name: "Element"
|
||||
description: "Matrix-based end-to-end encrypted messenger and secure collaboration app."
|
||||
snap: true
|
||||
- id: "thunderbird"
|
||||
name: "Thunderbird"
|
||||
description: "Email, newsfeed, chat, and calendaring client."
|
||||
snap: true
|
||||
- id: "virt-manager"
|
||||
name: "Virtual Machine Manager"
|
||||
description: "Desktop user interface for managing virtual machines through libvirt."
|
||||
snap: false
|
||||
- id: "krita"
|
||||
name: "Krita"
|
||||
description: "Graphics editor designed primarily for digital art and 2D animation."
|
||||
snap: true
|
||||
minimal_remove_packages:
|
||||
- snapd
|
||||
- snapd-installation-monitor
|
||||
- vlc
|
||||
- plasma-discover
|
||||
- transmission-qt
|
||||
- quassel
|
||||
- 2048-qt
|
||||
- featherpad
|
||||
- noblenote
|
||||
- kcalc
|
||||
- qps
|
||||
- zsync
|
||||
- partitionmanager
|
||||
- qapt-deb-installer
|
||||
- picom
|
||||
- qlipper
|
||||
- qtpass
|
||||
- "libreoffice*"
|
||||
installer_remove_packages:
|
||||
- "^live-*"
|
||||
- calamares-settings-lubuntu
|
||||
- calamares
|
||||
- zram-config
|
||||
- cifs-utils
|
||||
- lubuntu-installer-prompt
|
||||
regular_install_packages:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
||||
refresh_snaps:
|
||||
- "firefox"
|
||||
- "firmware-updater"
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
dontChroot: false
|
||||
timeout: 10800
|
||||
"packages.minimalButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y --purge remove snapd lubuntu-snap-installation-monitor vlc plasma-discover transmission-qt quassel 2048-qt featherpad noblenote kcalc qps zsync partitionmanager qapt-deb-installer picom qlipper qtpass libreoffice*"
|
||||
- "apt-get -y autoremove"
|
||||
"packages.partyButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install ubuntu-restricted-addons unrar"
|
||||
"packages.updatesButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confnew' full-upgrade"
|
||||
"packages.virtmanagerButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install virt-manager"
|
@ -1,9 +0,0 @@
|
||||
---
|
||||
dontChroot: true
|
||||
timeout: 10800
|
||||
"packages.elementButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed element-desktop"
|
||||
"packages.kritaButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed krita"
|
||||
"packages.thunderbirdButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed thunderbird"
|
@ -1,15 +0,0 @@
|
||||
update_db: true
|
||||
backend: apt
|
||||
operations:
|
||||
- remove:
|
||||
- "^live-*"
|
||||
- calamares-settings-ubuntu-unity
|
||||
- calamares
|
||||
- cifs-utils
|
||||
- try_install:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
@ -0,0 +1,52 @@
|
||||
---
|
||||
packages:
|
||||
additional_packages:
|
||||
- id: "element-desktop"
|
||||
name: "Element"
|
||||
description: "Matrix-based end-to-end encrypted messenger and secure collaboration app."
|
||||
snap: true
|
||||
- id: "thunderbird"
|
||||
name: "Thunderbird"
|
||||
description: "Email, newsfeed, chat, and calendaring client."
|
||||
snap: true
|
||||
- id: "virt-manager"
|
||||
name: "Virtual Machine Manager"
|
||||
description: "Desktop user interface for managing virtual machines through libvirt."
|
||||
snap: false
|
||||
- id: "krita"
|
||||
name: "Krita"
|
||||
description: "Graphics editor designed primarily for digital art and 2D animation."
|
||||
snap: true
|
||||
minimal_remove_packages:
|
||||
- snapd aisleriot
|
||||
- atril
|
||||
- cheese
|
||||
- simple-scan
|
||||
- gdebi
|
||||
- gparted
|
||||
- "*kvantum*"
|
||||
- "libreoffice*"
|
||||
- gnome-mahjongg
|
||||
- gnome-mines
|
||||
- remmina
|
||||
- rhythmbox
|
||||
- shotwell
|
||||
- gnome-sudoku
|
||||
- synaptic
|
||||
- transmission-gtk
|
||||
- vlc
|
||||
- stacer
|
||||
installer_remove_packages:
|
||||
- "^live-*"
|
||||
- calamares-settings-ubuntu-unity
|
||||
- calamares
|
||||
- cifs-utils
|
||||
regular_install_packages:
|
||||
- language-pack-$LOCALE
|
||||
- language-pack-gnome-$LOCALE
|
||||
- language-pack-kde-$LOCALE
|
||||
- hunspell-$LOCALE
|
||||
- libreoffice-help-$LOCALE
|
||||
- libreoffice-l10n-$LOCALE
|
||||
refresh_snaps:
|
||||
- "firefox"
|
@ -1,19 +0,0 @@
|
||||
---
|
||||
dontChroot: false
|
||||
timeout: 10800
|
||||
"packages.minimalButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y --purge remove snapd aisleriot atril cheese simple-scan gdebi gparted *kvantum* libreoffice* gnome-mahjongg gnome-mines remmina rhythmbox shotwell gnome-sudoku synaptic transmission-gtk vlc stacer"
|
||||
- "apt-get -y autoremove"
|
||||
"packages.partyButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install ubuntu-restricted-addons unrar"
|
||||
"packages.updatesButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y -o Dpkg::Options::='--force-confnew' full-upgrade"
|
||||
"packages.virtmanagerButton":
|
||||
true:
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get update"
|
||||
- "DEBIAN_FRONTEND=noninteractive apt-get -y install virt-manager"
|
@ -1,9 +0,0 @@
|
||||
---
|
||||
dontChroot: true
|
||||
timeout: 10800
|
||||
"packages.elementButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed element-desktop"
|
||||
"packages.kritaButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed krita"
|
||||
"packages.thunderbirdButton":
|
||||
true: "snap-seed-glue --seed ${ROOT}/var/lib/snapd/seed thunderbird"
|
Loading…
Reference in new issue