From 6e8779cbce44e282f3f9d8de09bd75a3b37495ae Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 4 Dec 2021 08:53:15 -0600 Subject: [PATCH 001/168] [mount] Ensure path is available when creating nested btrfs subvolumes --- src/modules/mount/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index f186b0d26..a3318d1a0 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -193,6 +193,7 @@ def mount_partition(root_mount_point, partition, partitions): for s in btrfs_subvolumes: if not s["subvolume"]: continue + os.makedirs(root_mount_point + os.path.dirname(s["subvolume"]), exist_ok=True) subprocess.check_call(["btrfs", "subvolume", "create", root_mount_point + s["subvolume"]]) if s["mountPoint"] == "/": From 1d96c5af4615d17fdc744538bcf31b62d8f04ea2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 5 Dec 2021 01:32:51 +0100 Subject: [PATCH 002/168] [partition] Table type 'none' is a late addition. --- src/modules/partition/gui/DeviceInfoWidget.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/partition/gui/DeviceInfoWidget.cpp b/src/modules/partition/gui/DeviceInfoWidget.cpp index 05a8c4b63..39d9413e1 100644 --- a/src/modules/partition/gui/DeviceInfoWidget.cpp +++ b/src/modules/partition/gui/DeviceInfoWidget.cpp @@ -100,7 +100,9 @@ DeviceInfoWidget::retranslateUi() "that makes a file accessible as a block device. " "This kind of setup usually only contains a single filesystem." ); break; +#if defined( WITH_KPMCORE42API ) case PartitionTable::none: +#endif case PartitionTable::unknownTableType: typeString = " ? "; toolTipString = tr( "This installer cannot detect a partition table on the " From 6bf0da7230260ddcf3f6afd6ec5820da87bb466c Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Sun, 5 Dec 2021 04:50:13 +0400 Subject: [PATCH 003/168] [libcalamaresui] Initial rework of error dialog --- src/libcalamaresui/CMakeLists.txt | 3 + src/libcalamaresui/ViewManager.cpp | 47 ++----- .../utils/ErrorDialog/ErrorDialog.cpp | 89 +++++++++++++ .../utils/ErrorDialog/ErrorDialog.h | 57 +++++++++ .../utils/ErrorDialog/ErrorDialog.ui | 120 ++++++++++++++++++ 5 files changed, 282 insertions(+), 34 deletions(-) create mode 100644 src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp create mode 100644 src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h create mode 100644 src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index a704b7484..e745681f3 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -20,6 +20,7 @@ set( calamaresui_SOURCES utils/CalamaresUtilsGui.cpp utils/ImageRegistry.cpp utils/Paste.cpp + utils/ErrorDialog/ErrorDialog.cpp viewpages/BlankViewStep.cpp viewpages/ExecutionViewStep.cpp @@ -75,6 +76,8 @@ calamares_add_library( calamaresui Qt5::Svg RESOURCES libcalamaresui.qrc EXPORT Calamares + UI + utils/ErrorDialog/ErrorDialog.ui VERSION ${CALAMARES_VERSION_SHORT} ) target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp ) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 57570ad64..ee521a02c 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -25,6 +25,7 @@ #include "viewpages/ExecutionViewStep.h" #include "viewpages/ViewStep.h" #include "widgets/TranslationFix.h" +#include "utils/ErrorDialog/ErrorDialog.h" #include #include @@ -32,6 +33,7 @@ #include #include #include +#include #define UPDATE_BUTTON_PROPERTY( name, value ) \ do \ @@ -159,44 +161,21 @@ ViewManager::onInstallationFailed( const QString& message, const QString& detail cDebug() << Logger::SubEntry << "- details:" << Logger::NoQuote << details; QString heading - = Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" ); - QString pasteMsg = tr( "Would you like to paste the install log to the web?" ); - QString text = "

" + message + "

"; - if ( !details.isEmpty() ) - { - text += "

" - + CalamaresUtils::truncateMultiLine( details, CalamaresUtils::LinesStartEnd { 6, 2 } ) - .replace( '\n', QStringLiteral( "
" ) ) - + "

"; - } - if ( shouldOfferWebPaste ) - { - text += "

" + pasteMsg + "

"; - } + = Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" ); - QMessageBox* msgBox = new QMessageBox(); - msgBox->setIcon( QMessageBox::Critical ); - msgBox->setWindowTitle( tr( "Error" ) ); - msgBox->setText( "" + heading + "" ); - msgBox->setInformativeText( text ); - if ( shouldOfferWebPaste ) - { - msgBox->setStandardButtons( QMessageBox::Yes | QMessageBox::No ); - msgBox->setDefaultButton( QMessageBox::No ); - } - else - { - msgBox->setStandardButtons( QMessageBox::Close ); - msgBox->setDefaultButton( QMessageBox::Close ); - } - Calamares::fixButtonLabels( msgBox ); - msgBox->show(); + ErrorDialog* errorDialog = new ErrorDialog(); + errorDialog->setWindowTitle( tr( "Error" ) ); + errorDialog->setHeading( "" + heading + "" ); + errorDialog->setInformativeText( message ); + errorDialog->setShouldOfferWebPaste(shouldOfferWebPaste); + errorDialog->setDetails(details); + errorDialog->show(); cDebug() << "Calamares will quit when the dialog closes."; - connect( msgBox, &QMessageBox::buttonClicked, [msgBox]( QAbstractButton* button ) { - if ( msgBox->buttonRole( button ) == QMessageBox::ButtonRole::YesRole ) + connect( errorDialog, &QDialog::finished, [errorDialog]( int result ) { + if ( result == QDialog::Accepted && errorDialog->shouldOfferWebPaste() ) { - CalamaresUtils::Paste::doLogUploadUI( msgBox ); + CalamaresUtils::Paste::doLogUploadUI( errorDialog ); } QApplication::quit(); } ); diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp new file mode 100644 index 000000000..080ff2115 --- /dev/null +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp @@ -0,0 +1,89 @@ +#include "ErrorDialog.h" +#include "ui_ErrorDialog.h" + +#include +#include + +namespace Calamares { + + +ErrorDialog::ErrorDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::ErrorDialog) +{ + ui->setupUi(this); + ui->iconLabel->setPixmap(QIcon::fromTheme("dialog-error").pixmap(64)); + ui->detailsWidget->hide(); + ui->offerWebPasteLabel->hide(); +} + +ErrorDialog::~ErrorDialog() +{ + delete ui; +} + + +QString ErrorDialog::heading() const +{ + return ui->headingLabel->text(); +} + +QString ErrorDialog::informativeText() const +{ + return ui->informativeTextLabel->text(); +} + +QString ErrorDialog::details() const +{ + return ui->detailsBrowser->toPlainText(); +} + +void ErrorDialog::setHeading(const QString &newHeading) +{ + if (ui->headingLabel->text() == newHeading) + return; + ui->headingLabel->setText(newHeading); + emit headingChanged(); +} + +void ErrorDialog::setInformativeText(const QString &newInformativeText) +{ + if (ui->informativeTextLabel->text() == newInformativeText) + return; + ui->informativeTextLabel->setText(newInformativeText); + emit informativeTextChanged(); +} + +void ErrorDialog::setDetails(const QString &newDetails) +{ + if (ui->detailsBrowser->toPlainText() == newDetails) + return; + ui->detailsBrowser->setPlainText(newDetails); + + ui->detailsWidget->setVisible(!ui->detailsBrowser->toPlainText().trimmed().isEmpty()); + + emit detailsChanged(); +} + +bool ErrorDialog::shouldOfferWebPaste() const +{ + return m_shouldOfferWebPaste; +} + +void ErrorDialog::setShouldOfferWebPaste(bool newShouldOfferWebPaste) +{ + if (m_shouldOfferWebPaste == newShouldOfferWebPaste) + return; + m_shouldOfferWebPaste = newShouldOfferWebPaste; + + ui->offerWebPasteLabel->setVisible(m_shouldOfferWebPaste); + + ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste + ? (QDialogButtonBox::Yes | QDialogButtonBox::No) + : QDialogButtonBox::Close ); + + + emit shouldOfferWebPasteChanged(); +} + +} // namespace Calamares diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h new file mode 100644 index 000000000..8962c3e99 --- /dev/null +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h @@ -0,0 +1,57 @@ +#ifndef ERRORDIALOG_H +#define ERRORDIALOG_H + +#include + + +namespace Ui { +class ErrorDialog; +} +class QDialogButtonBox; +namespace Calamares +{ +class ErrorDialog : public QDialog +{ + Q_OBJECT + + Q_PROPERTY(QString heading READ heading WRITE setHeading NOTIFY headingChanged) + Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged) + Q_PROPERTY(QString details READ details WRITE setDetails NOTIFY detailsChanged) + Q_PROPERTY(bool shouldOfferWebPaste READ shouldOfferWebPaste WRITE setShouldOfferWebPaste NOTIFY shouldOfferWebPasteChanged) + +public: + explicit ErrorDialog(QWidget *parent = nullptr); + ~ErrorDialog(); + + QString heading() const; + + QString informativeText() const; + + QString details() const; + + void setHeading(const QString &newHeading); + + void setInformativeText(const QString &newInformativeText); + + void setDetails(const QString &newDetails); + + bool shouldOfferWebPaste() const; + void setShouldOfferWebPaste(bool newShouldOfferWebPaste); + +signals: + void headingChanged(); + + void informativeTextChanged(); + + void detailsChanged(); + + void shouldOfferWebPasteChanged(); + +private: + Ui::ErrorDialog *ui; + bool m_shouldOfferWebPaste; +}; + +}; // namespace Calamares + +#endif // ERRORDIALOG_H diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui new file mode 100644 index 000000000..2632af617 --- /dev/null +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui @@ -0,0 +1,120 @@ + + + ErrorDialog + + + + 0 + 0 + 425 + 262 + + + + Dialog + + + + + + + 0 + 0 + + + + + + + + + + + + + + Details: + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close + + + + + + + Would you like to paste the install log to the web? + + + + + + + + + buttonBox + accepted() + ErrorDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + ErrorDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + From c834a5066d079bd8f554bab3fc463c0f32cdfb73 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 5 Dec 2021 02:26:23 +0100 Subject: [PATCH 004/168] [umount] Make it much more clear that the logfiles-thing is going away. --- CHANGES-3.2 | 6 ++++++ src/modules/umount/main.py | 1 + src/modules/umount/umount.conf | 18 +++++++++++------- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index b658191fb..566a61ed9 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -13,6 +13,9 @@ This release contains contributions from (alphabetically by first name): - Artem Grinev - Evan James +Distributions are **specifically** reminded to update the *umount* module +configuration (and to use *preservefiles* if needed). + ## Core ## - Errors (e.g. when an installation fails for whatever reason) are displayed in a dialog with a scrollable details panel, rather than growing up @@ -21,6 +24,9 @@ This release contains contributions from (alphabetically by first name): ## Modules ## - *partition* now supports "deep" btrfs subvolume names, e.g. a separate subvolume for `/usr/local`. (Thanks Evan) + - The *umount* module now warns if the "preserve log file" feature is used. + This has been deprecated for a long time: use the *preservefiles* module + instead. A future release will turn this into an error. # 3.2.48 (2021-12-03) # diff --git a/src/modules/umount/main.py b/src/modules/umount/main.py index 77ea91e34..5fdb36014 100644 --- a/src/modules/umount/main.py +++ b/src/modules/umount/main.py @@ -80,6 +80,7 @@ def run(): if(libcalamares.job.configuration and "srcLog" in libcalamares.job.configuration and "destLog" in libcalamares.job.configuration): + libcalamares.utils.warning("Log-file preserving is **deprecated** in the *umount* module") log_source = libcalamares.job.configuration["srcLog"] log_destination = libcalamares.job.configuration["destLog"] # Relocate log_destination into target system diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index b6d86e353..062f7ac4b 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -10,16 +10,20 @@ # The "copy log files" functionality is deprecated; use the *preservefiles* # module instead, which is more flexible. # -# This module has two configuration keys: -# srcLog location in the live system where the log is -# destLog location in the target system to copy the log # --- -# example when using the normal Calamares log: -srcLog: "/root/.cache/calamares/session.log" -destLog: "/var/log/Calamares.log" - +# This is a **deprecated** example. Use the *preservefiles* module +# instead, where the equivalent configuration is this: +# +# files: +# - from: log +# dest: /var/log/installation.log +# +# Note that the "equivalent configuration" always finds the log, +# and is not dependent on specific user names or the vagaries of +# polkit configuration -- so it is a **better** "equivalent". +# # example when using a log created by `sudo calamares -d`: #srcLog: "/home/live/installation.log" #destLog: "/var/log/installation.log" From e8936392e373b6bc1ab93e5c3693152d388ff23c Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 5 Dec 2021 13:17:23 -0600 Subject: [PATCH 005/168] [luksopenswaphookcfg] Add support unlocking swap with root on a btrfs subvol --- src/modules/luksopenswaphookcfg/main.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/modules/luksopenswaphookcfg/main.py b/src/modules/luksopenswaphookcfg/main.py index ec09a631b..aaac8a31a 100644 --- a/src/modules/luksopenswaphookcfg/main.py +++ b/src/modules/luksopenswaphookcfg/main.py @@ -64,6 +64,11 @@ def write_openswap_conf(partitions, root_mount_point, openswap_conf_path): elif lines[i].startswith("keyfile_filename"): lines[i] = "keyfile_filename=crypto_keyfile.bin" + elif lines[i].startswith("#keyfile_device_mount_options"): + if libcalamares.globalstorage.contains("btrfsRootSubvolume"): + btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume") + lines[i] = "keyfile_device_mount_options=--options=subvol=" + btrfs_root_subvolume.lstrip("/") + with open(os.path.join(root_mount_point, openswap_conf_path), 'w') as openswap_file: openswap_file.write("\n".join(lines) + "\n") @@ -84,11 +89,11 @@ def run(): if not partitions: libcalamares.utils.warning("partitions is empty, {!s}".format(partitions)) return (_("Configuration Error"), - _("No partitions are defined for
{!s}
to use." ).format("luksopenswaphookcfg")) + _("No partitions are defined for
{!s}
to use.").format("luksopenswaphookcfg")) if not root_mount_point: libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point)) return (_("Configuration Error"), - _("No root mount point is given for
{!s}
to use." ).format("luksopenswaphookcfg")) + _("No root mount point is given for
{!s}
to use.").format("luksopenswaphookcfg")) openswap_conf_path = openswap_conf_path.lstrip('/') From 32c5e18db0e75833e9ad599694edc0d040c9ae22 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 02:26:13 +0400 Subject: [PATCH 006/168] [libcalamaresui] Add QDialogButtonBox translation fix --- src/libcalamaresui/widgets/TranslationFix.cpp | 35 +++++++++++++------ src/libcalamaresui/widgets/TranslationFix.h | 3 ++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/libcalamaresui/widgets/TranslationFix.cpp b/src/libcalamaresui/widgets/TranslationFix.cpp index 1262fceb5..b73bd0e16 100644 --- a/src/libcalamaresui/widgets/TranslationFix.cpp +++ b/src/libcalamaresui/widgets/TranslationFix.cpp @@ -10,21 +10,16 @@ #include "TranslationFix.h" #include +#include #include #include +#include namespace Calamares { -void -fixButtonLabels( QMessageBox* box ) -{ - if ( !box ) - { - return; - } - - static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = { +//Using QMessageBox's StandardButton enum here but according to headers they should be kept in-sync between multiple classes. +static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = { { QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) }, { QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) }, { QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) }, @@ -32,9 +27,17 @@ fixButtonLabels( QMessageBox* box ) { QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) }, }; +template +void fixButtonLabels ( TButtonBox* box ) +{ + if ( !box ) + { + return; + } + for ( auto [ sb, label ] : maps ) { - auto* button = box->button( sb ); + auto* button = box->button( static_cast(int(sb)) ); if ( button ) { button->setText( QCoreApplication::translate( "StandardButtons", label ) ); @@ -42,4 +45,16 @@ fixButtonLabels( QMessageBox* box ) } } +void +fixButtonLabels( QMessageBox* box ) +{ + fixButtonLabels(box); +} + +void +fixButtonLabels(QDialogButtonBox *box) +{ + fixButtonLabels(box); +} + } // namespace Calamares diff --git a/src/libcalamaresui/widgets/TranslationFix.h b/src/libcalamaresui/widgets/TranslationFix.h index 107dad67d..89ee9a51a 100644 --- a/src/libcalamaresui/widgets/TranslationFix.h +++ b/src/libcalamaresui/widgets/TranslationFix.h @@ -13,6 +13,7 @@ #include "DllMacro.h" class QMessageBox; +class QDialogButtonBox; namespace Calamares { @@ -26,6 +27,8 @@ namespace Calamares * guess the context. */ void UIDLLEXPORT fixButtonLabels( QMessageBox* ); + +void UIDLLEXPORT fixButtonLabels( QDialogButtonBox* ); } // namespace Calamares #endif From bfa7b9a7927b05ad2fcabc3ce460d640bc786d97 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 02:27:18 +0400 Subject: [PATCH 007/168] [libcalamaresui] Use translation fix for Error Dialog --- src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp index 080ff2115..29da42e4d 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp @@ -3,6 +3,7 @@ #include #include +#include "widgets/TranslationFix.h" namespace Calamares { @@ -81,7 +82,8 @@ void ErrorDialog::setShouldOfferWebPaste(bool newShouldOfferWebPaste) ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? (QDialogButtonBox::Yes | QDialogButtonBox::No) : QDialogButtonBox::Close ); - + + fixButtonLabels(ui->buttonBox); emit shouldOfferWebPasteChanged(); } From 2dd77ee828f5df31460535abc85ef9c2489287d1 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 02:31:05 +0400 Subject: [PATCH 008/168] [libcalamaresui] Initialize Error Dialog field --- src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h index 8962c3e99..4196f6a7f 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h @@ -49,7 +49,7 @@ signals: private: Ui::ErrorDialog *ui; - bool m_shouldOfferWebPaste; + bool m_shouldOfferWebPaste = false; }; }; // namespace Calamares From 2f2a418cc42fa6b9bf3e2c68ab5f569e06e21e32 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 02:37:11 +0400 Subject: [PATCH 009/168] [libcalamaresui] Run clang-format --- src/libcalamaresui/ViewManager.cpp | 27 +++--- .../utils/ErrorDialog/ErrorDialog.cpp | 86 ++++++++++--------- .../utils/ErrorDialog/ErrorDialog.h | 56 ++++++------ 3 files changed, 91 insertions(+), 78 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index ee521a02c..87024ea6b 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -17,6 +17,7 @@ #include "JobQueue.h" #include "Settings.h" +#include "utils/ErrorDialog/ErrorDialog.h" #include "utils/Logger.h" #include "utils/Paste.h" #include "utils/Retranslator.h" @@ -25,15 +26,14 @@ #include "viewpages/ExecutionViewStep.h" #include "viewpages/ViewStep.h" #include "widgets/TranslationFix.h" -#include "utils/ErrorDialog/ErrorDialog.h" #include #include #include +#include #include #include #include -#include #define UPDATE_BUTTON_PROPERTY( name, value ) \ do \ @@ -161,24 +161,27 @@ ViewManager::onInstallationFailed( const QString& message, const QString& detail cDebug() << Logger::SubEntry << "- details:" << Logger::NoQuote << details; QString heading - = Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" ); + = Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" ); ErrorDialog* errorDialog = new ErrorDialog(); errorDialog->setWindowTitle( tr( "Error" ) ); errorDialog->setHeading( "" + heading + "" ); errorDialog->setInformativeText( message ); - errorDialog->setShouldOfferWebPaste(shouldOfferWebPaste); - errorDialog->setDetails(details); + errorDialog->setShouldOfferWebPaste( shouldOfferWebPaste ); + errorDialog->setDetails( details ); errorDialog->show(); cDebug() << "Calamares will quit when the dialog closes."; - connect( errorDialog, &QDialog::finished, [errorDialog]( int result ) { - if ( result == QDialog::Accepted && errorDialog->shouldOfferWebPaste() ) - { - CalamaresUtils::Paste::doLogUploadUI( errorDialog ); - } - QApplication::quit(); - } ); + connect( errorDialog, + &QDialog::finished, + [ errorDialog ]( int result ) + { + if ( result == QDialog::Accepted && errorDialog->shouldOfferWebPaste() ) + { + CalamaresUtils::Paste::doLogUploadUI( errorDialog ); + } + QApplication::quit(); + } ); } diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp index 29da42e4d..ca88031f6 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp @@ -1,19 +1,20 @@ #include "ErrorDialog.h" #include "ui_ErrorDialog.h" -#include -#include #include "widgets/TranslationFix.h" +#include +#include -namespace Calamares { - - -ErrorDialog::ErrorDialog(QWidget *parent) : - QDialog(parent), - ui(new Ui::ErrorDialog) +namespace Calamares { - ui->setupUi(this); - ui->iconLabel->setPixmap(QIcon::fromTheme("dialog-error").pixmap(64)); + + +ErrorDialog::ErrorDialog( QWidget* parent ) + : QDialog( parent ) + , ui( new Ui::ErrorDialog ) +{ + ui->setupUi( this ); + ui->iconLabel->setPixmap( QIcon::fromTheme( "dialog-error" ).pixmap( 64 ) ); ui->detailsWidget->hide(); ui->offerWebPasteLabel->hide(); } @@ -24,68 +25,75 @@ ErrorDialog::~ErrorDialog() } -QString ErrorDialog::heading() const +QString +ErrorDialog::heading() const { return ui->headingLabel->text(); } -QString ErrorDialog::informativeText() const +QString +ErrorDialog::informativeText() const { return ui->informativeTextLabel->text(); } -QString ErrorDialog::details() const +QString +ErrorDialog::details() const { return ui->detailsBrowser->toPlainText(); } -void ErrorDialog::setHeading(const QString &newHeading) +void +ErrorDialog::setHeading( const QString& newHeading ) { - if (ui->headingLabel->text() == newHeading) + if ( ui->headingLabel->text() == newHeading ) return; - ui->headingLabel->setText(newHeading); + ui->headingLabel->setText( newHeading ); emit headingChanged(); } -void ErrorDialog::setInformativeText(const QString &newInformativeText) +void +ErrorDialog::setInformativeText( const QString& newInformativeText ) { - if (ui->informativeTextLabel->text() == newInformativeText) + if ( ui->informativeTextLabel->text() == newInformativeText ) return; - ui->informativeTextLabel->setText(newInformativeText); + ui->informativeTextLabel->setText( newInformativeText ); emit informativeTextChanged(); } -void ErrorDialog::setDetails(const QString &newDetails) +void +ErrorDialog::setDetails( const QString& newDetails ) { - if (ui->detailsBrowser->toPlainText() == newDetails) - return; - ui->detailsBrowser->setPlainText(newDetails); - - ui->detailsWidget->setVisible(!ui->detailsBrowser->toPlainText().trimmed().isEmpty()); - + if ( ui->detailsBrowser->toPlainText() == newDetails ) + return; + ui->detailsBrowser->setPlainText( newDetails ); + + ui->detailsWidget->setVisible( !ui->detailsBrowser->toPlainText().trimmed().isEmpty() ); + emit detailsChanged(); } -bool ErrorDialog::shouldOfferWebPaste() const +bool +ErrorDialog::shouldOfferWebPaste() const { return m_shouldOfferWebPaste; } -void ErrorDialog::setShouldOfferWebPaste(bool newShouldOfferWebPaste) +void +ErrorDialog::setShouldOfferWebPaste( bool newShouldOfferWebPaste ) { - if (m_shouldOfferWebPaste == newShouldOfferWebPaste) + if ( m_shouldOfferWebPaste == newShouldOfferWebPaste ) return; m_shouldOfferWebPaste = newShouldOfferWebPaste; - - ui->offerWebPasteLabel->setVisible(m_shouldOfferWebPaste); - - ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste - ? (QDialogButtonBox::Yes | QDialogButtonBox::No) - : QDialogButtonBox::Close ); - - fixButtonLabels(ui->buttonBox); - + + ui->offerWebPasteLabel->setVisible( m_shouldOfferWebPaste ); + + ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? ( QDialogButtonBox::Yes | QDialogButtonBox::No ) + : QDialogButtonBox::Close ); + + fixButtonLabels( ui->buttonBox ); + emit shouldOfferWebPasteChanged(); } -} // namespace Calamares +} // namespace Calamares diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h index 4196f6a7f..0c700f8d3 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h @@ -4,7 +4,8 @@ #include -namespace Ui { +namespace Ui +{ class ErrorDialog; } class QDialogButtonBox; @@ -13,45 +14,46 @@ namespace Calamares class ErrorDialog : public QDialog { Q_OBJECT - - Q_PROPERTY(QString heading READ heading WRITE setHeading NOTIFY headingChanged) - Q_PROPERTY(QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged) - Q_PROPERTY(QString details READ details WRITE setDetails NOTIFY detailsChanged) - Q_PROPERTY(bool shouldOfferWebPaste READ shouldOfferWebPaste WRITE setShouldOfferWebPaste NOTIFY shouldOfferWebPasteChanged) - + + Q_PROPERTY( QString heading READ heading WRITE setHeading NOTIFY headingChanged ) + Q_PROPERTY( QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged ) + Q_PROPERTY( QString details READ details WRITE setDetails NOTIFY detailsChanged ) + Q_PROPERTY( bool shouldOfferWebPaste READ shouldOfferWebPaste WRITE setShouldOfferWebPaste NOTIFY + shouldOfferWebPasteChanged ) + public: - explicit ErrorDialog(QWidget *parent = nullptr); + explicit ErrorDialog( QWidget* parent = nullptr ); ~ErrorDialog(); - + QString heading() const; - + QString informativeText() const; - + QString details() const; - - void setHeading(const QString &newHeading); - - void setInformativeText(const QString &newInformativeText); - - void setDetails(const QString &newDetails); - + + void setHeading( const QString& newHeading ); + + void setInformativeText( const QString& newInformativeText ); + + void setDetails( const QString& newDetails ); + bool shouldOfferWebPaste() const; - void setShouldOfferWebPaste(bool newShouldOfferWebPaste); - + void setShouldOfferWebPaste( bool newShouldOfferWebPaste ); + signals: void headingChanged(); - + void informativeTextChanged(); - + void detailsChanged(); - + void shouldOfferWebPasteChanged(); - + private: - Ui::ErrorDialog *ui; + Ui::ErrorDialog* ui; bool m_shouldOfferWebPaste = false; }; -}; // namespace Calamares +}; // namespace Calamares -#endif // ERRORDIALOG_H +#endif // ERRORDIALOG_H From d9f7726f7db3db97955fed876d37a80af7006a96 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 02:41:17 +0400 Subject: [PATCH 010/168] [libcalamaresui] Add SPDX-header for Error Dialog files --- src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp | 9 +++++++++ src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp index ca88031f6..4ffe20384 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp @@ -1,3 +1,12 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Artem Grinev + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + #include "ErrorDialog.h" #include "ui_ErrorDialog.h" diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h index 0c700f8d3..a0126c2ce 100644 --- a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h +++ b/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h @@ -1,3 +1,12 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Artem Grinev + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + #ifndef ERRORDIALOG_H #define ERRORDIALOG_H From aa332477fd1858603f528a5f036925624446249a Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Mon, 6 Dec 2021 03:11:16 +0400 Subject: [PATCH 011/168] [libcalamaresui] Run clang-format on TranslationFix.cpp --- src/libcalamaresui/widgets/TranslationFix.cpp | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/libcalamaresui/widgets/TranslationFix.cpp b/src/libcalamaresui/widgets/TranslationFix.cpp index b73bd0e16..dbfd0bd83 100644 --- a/src/libcalamaresui/widgets/TranslationFix.cpp +++ b/src/libcalamaresui/widgets/TranslationFix.cpp @@ -10,34 +10,35 @@ #include "TranslationFix.h" #include -#include #include -#include #include +#include +#include namespace Calamares { //Using QMessageBox's StandardButton enum here but according to headers they should be kept in-sync between multiple classes. static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = { - { QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) }, - { QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) }, - { QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) }, - { QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) }, - { QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) }, - }; + { QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) }, + { QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) }, + { QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) }, + { QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) }, + { QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) }, +}; -template -void fixButtonLabels ( TButtonBox* box ) +template < typename TButtonBox > +void +fixButtonLabels( TButtonBox* box ) { if ( !box ) { return; } - + for ( auto [ sb, label ] : maps ) { - auto* button = box->button( static_cast(int(sb)) ); + auto* button = box->button( static_cast< typename TButtonBox::StandardButton >( int( sb ) ) ); if ( button ) { button->setText( QCoreApplication::translate( "StandardButtons", label ) ); @@ -48,13 +49,13 @@ void fixButtonLabels ( TButtonBox* box ) void fixButtonLabels( QMessageBox* box ) { - fixButtonLabels(box); + fixButtonLabels< QMessageBox >( box ); } void -fixButtonLabels(QDialogButtonBox *box) +fixButtonLabels( QDialogButtonBox* box ) { - fixButtonLabels(box); + fixButtonLabels< QDialogButtonBox >( box ); } } // namespace Calamares From b8c02587ae6accef5f85c06c49bc3e00d3cfccdf Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 10:29:16 +0100 Subject: [PATCH 012/168] Changes: post-release housekeeping --- CHANGES-3.2 | 13 +++++++++++++ CMakeLists.txt | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index baaf261d4..81fd55343 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,6 +7,19 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. +# 3.2.49 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - Evan James + +## Core ## + - No core changes yet + +## Modules ## + - *partition* now supports "deep" btrfs subvolume names, e.g. a + separate subvolume for `/usr/local`. (Thanks Evan) + + # 3.2.48 (2021-12-03) # This release contains contributions from (alphabetically by first name): diff --git a/CMakeLists.txt b/CMakeLists.txt index c998d43d0..1a55eae1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.48 + VERSION 3.2.49 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 6e08da6c8d4bcf7608e6b61dc170d06e0b3246f7 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 4 Dec 2021 09:10:49 -0600 Subject: [PATCH 013/168] [bootloader] Fix error with systemd-boot when path exists in the ESP --- src/modules/bootloader/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index 25c7e0d9b..0182d1110 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -224,7 +224,7 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker # Copy kernel and initramfs to a subdirectory of /efi partition files_dir = os.path.join(install_path + efi_dir, entry_name) - os.mkdir(files_dir) + os.makedirs(files_dir, exist_ok=True) kernel_path = install_path + kernel kernel_name = os.path.basename(kernel_path) From baf8297cc4eeb6f5aba774a61dea10673bab2d15 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Dec 2021 12:11:33 +0100 Subject: [PATCH 014/168] [libcalamares] Reading a file from target system --- .../utils/CalamaresUtilsSystem.cpp | 24 +++++++++++++++++++ src/libcalamares/utils/CalamaresUtilsSystem.h | 18 ++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index b290b62c5..301d20b33 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -147,6 +147,30 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write return CreationResult( QFileInfo( f ).canonicalFilePath() ); } +QStringList +System::readTargetFile( const QString& path ) const +{ + const QString completePath = targetPath( path ); + if ( completePath.isEmpty() ) + { + return QStringList(); + } + + QFile f( completePath ); + if ( !f.open( QIODevice::ReadOnly ) ) + { + return QStringList(); + } + + QTextStream in( &f ); + QStringList l; + while ( !f.atEnd() ) + { + l << in.readLine(); + } + return l; +} + void System::removeTargetFile( const QString& path ) const { diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.h b/src/libcalamares/utils/CalamaresUtilsSystem.h index e11ecae05..1bb5629d1 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.h +++ b/src/libcalamares/utils/CalamaresUtilsSystem.h @@ -287,6 +287,24 @@ public: */ DLLEXPORT void removeTargetFile( const QString& path ) const; + /** @brief Reads a file from the target system. + * + * @param path Path to the file; this is interpreted from the root of + * the target system (@see targetPath()). + * + * Does no error checking, and returns an empty list if the file does + * not exist. + * + * NOTE: This function is now basically the same as QFile::readAll(), + * splitting into lines, but Calamares may need to change + * permissions or raise privileges to actually read the file, + * which is why there is an API. + * + * NOTE: Since this buffers the whole file in memory, reading big files + * is not recommended. + */ + DLLEXPORT QStringList readTargetFile( const QString& path ) const; + /** @brief Ensure that the directory @p path exists * * @param path a full pathname to a desired directory. From 6ef7acc1080d577359f2f5e26436a93221fee546 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Dec 2021 13:22:18 +0100 Subject: [PATCH 015/168] [libcalamares] Add minor tests for new readTargetFile --- src/libcalamares/utils/Tests.cpp | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/src/libcalamares/utils/Tests.cpp b/src/libcalamares/utils/Tests.cpp index 12b72cb4c..8fd11cd87 100644 --- a/src/libcalamares/utils/Tests.cpp +++ b/src/libcalamares/utils/Tests.cpp @@ -76,6 +76,9 @@ private Q_SLOTS: void testCalculateWorkingDirectory(); void testRunnerOutput(); + /** @section Test file-functions */ + void testReadWriteFile(); + private: void recursiveCompareMap( const QVariantMap& a, const QVariantMap& b, int depth ); }; @@ -950,6 +953,84 @@ LibCalamaresTests::testRunnerOutput() } +CalamaresUtils::System* +file_setup( const QTemporaryDir& tempRoot ) +{ + CalamaresUtils::System* ss = CalamaresUtils::System::instance(); + if ( !ss ) + { + ss = new CalamaresUtils::System( true ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs ) + { + cDebug() << "Creating new JobQueue"; + (void)new Calamares::JobQueue(); + gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + } + if ( gs ) + { + // Working with a rootMountPoint set + gs->insert( "rootMountPoint", tempRoot.path() ); + } + return ss; +} + +void +LibCalamaresTests::testReadWriteFile() +{ + static const QByteArray otherContents( "derp\n" ); + + QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + auto* ss = file_setup( tempRoot ); + + QVERIFY( ss ); + { + auto fullPath = ss->createTargetFile( "test0", QByteArray(), CalamaresUtils::System::WriteMode::Overwrite ); + QVERIFY( fullPath ); + QVERIFY( !fullPath.path().isEmpty() ); + + QFileInfo fi( fullPath.path() ); + QVERIFY( fi.exists() ); + QVERIFY( fi.isFile() ); + QCOMPARE( fi.size(), 0 ); + } + // It won't overwrite unless you ask for it + { + auto fullPath = ss->createTargetFile( "test0", otherContents ); + QVERIFY( !fullPath ); // Failed, because it won't overwrite + QCOMPARE( fullPath.code(), decltype(fullPath)::Code::AlreadyExists ); + QVERIFY( fullPath.path().isEmpty() ); // Because it wasn't written + + QFileInfo fi( tempRoot.filePath( "test0" ) ); // Compute the name some other way + QVERIFY( fi.exists() ); + QVERIFY( fi.isFile() ); + QCOMPARE( fi.size(), 0 ); + } + // But it will if you say so explicitly + { + auto fullPath = ss->createTargetFile( "test0", otherContents, CalamaresUtils::System::WriteMode::Overwrite ); + QVERIFY( fullPath ); + QVERIFY( !fullPath.path().isEmpty() ); + + QFileInfo fi( fullPath.path() ); + QVERIFY( fi.exists() ); + QVERIFY( fi.isFile() ); + QCOMPARE( fi.size(), 5 ); + } + + // Now it's been written, we can read it, too + { + auto contents = ss->readTargetFile( "test0" ); + QVERIFY( !contents.isEmpty() ); + QCOMPARE( contents.count(), 1 ); + QCOMPARE( contents[ 0 ], QStringLiteral( "derp" ) ); // No trailing \n + } +} + + QTEST_GUILESS_MAIN( LibCalamaresTests ) #include "utils/moc-warnings.h" From 890c17cd71b2126e0a20f42fa9025b0f6358f62b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 12:29:03 +0100 Subject: [PATCH 016/168] [libcalamares] Expand error-logging when creating files --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 301d20b33..9a4ba990f 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -115,12 +115,14 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write QString completePath = targetPath( path ); if ( completePath.isEmpty() ) { + cWarning() << "No target path for" << path; return CreationResult( CreationResult::Code::Invalid ); } QFile f( completePath ); if ( ( mode == WriteMode::KeepExisting ) && f.exists() ) { + cWarning() << "Target file" << completePath << "already exists"; return CreationResult( CreationResult::Code::AlreadyExists ); } @@ -133,13 +135,16 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write if ( !f.open( m ) ) { + cWarning() << "Could not open target file" << completePath; return CreationResult( CreationResult::Code::Failed ); } - if ( f.write( contents ) != contents.size() ) + auto written = f.write( contents ); + if ( written != contents.size() ) { f.close(); f.remove(); + cWarning() << "Short write (" << written << "out of" << contents.size() << "bytes) to" << completePath; return CreationResult( CreationResult::Code::Failed ); } From d89553a7773b0a5b2f362fd903de191f246ddff2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 14:44:38 +0100 Subject: [PATCH 017/168] [partition] Avoid problems with MessageAndPath in containers (drop const) --- src/modules/partition/jobs/ClearMountsJob.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index 831a1e868..2f5a8bd36 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -243,14 +243,8 @@ public: } private: -#if ( QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 ) ) - // TODO: 3.3 remove because newer Qt does support constness const char* m_message = nullptr; QString m_path; -#else - const char* const m_message = nullptr; - QString const m_path; -#endif }; STATICTEST inline QDebug& From 149f3ff3fe18a239e6c71bc93c0f570f0358bc07 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 14:52:33 +0100 Subject: [PATCH 018/168] [partition] Reduce warnings about shadowed variables --- .../partition/jobs/CreatePartitionJob.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/modules/partition/jobs/CreatePartitionJob.cpp b/src/modules/partition/jobs/CreatePartitionJob.cpp index 83ebc0509..3e51ed598 100644 --- a/src/modules/partition/jobs/CreatePartitionJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionJob.cpp @@ -60,24 +60,24 @@ createZfs( Partition* partition, Device* device ) // Now we need to do some things that would normally be done by kpmcore // First we get the device node from the output and set it as the partition path - QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) ); - QRegularExpressionMatch rem = re.match( r.getOutput() ); - QString deviceNode; - if ( rem.hasMatch() ) { - if ( partition->devicePath().back().isDigit() ) + QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) ); + QRegularExpressionMatch rem = re.match( r.getOutput() ); + + if ( rem.hasMatch() ) { - deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 ); - } - else - { - deviceNode = partition->devicePath() + rem.captured( 1 ); + if ( partition->devicePath().back().isDigit() ) + { + deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 ); + } + else + { + deviceNode = partition->devicePath() + rem.captured( 1 ); + } } + partition->setPartitionPath( deviceNode ); } - - partition->setPartitionPath( deviceNode ); - // If it is a gpt device, set the partition UUID if ( device->partitionTable()->type() == PartitionTable::gpt && partition->uuid().isEmpty() ) { From eb2cf60466fb9dbab07742b2bda249a4e359b614 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 10:57:06 +0100 Subject: [PATCH 019/168] CI: support FreeBSD when pulling translations --- ci/txpull.sh | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/ci/txpull.sh b/ci/txpull.sh index f68814560..1c5c11a45 100755 --- a/ci/txpull.sh +++ b/ci/txpull.sh @@ -116,6 +116,19 @@ git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true # PO-Created line). This applies only to modules which use po-files. git diff --numstat src/modules | awk '($1==1 && $2==1){print $3}' | xargs git checkout -- +# sed either wants -i'' (GNU sed) or -i '' (BSD sed) to +# replace in a file, with no backup extension. Define +# a `reinplace` command to deal with the difference. +if test FreeBSD = `uname` ; then + reinplace() { + sed -i '' "$@" + } +else + reinplace() { + sed -i'' "$@" + } +fi + # Go through the Python modules; those with a lang/ subdir have their # own complete gettext-based setup. for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do @@ -125,7 +138,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do if [ -d ${MODULE_DIR}/lang ]; then # Convert PO files to MO files for POFILE in $(find ${MODULE_DIR} -name "*.po") ; do - sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE + reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE # msgfmt -o ${POFILE%.po}.mo $POFILE done git add --verbose ${MODULE_DIR}/lang/* @@ -135,7 +148,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do done for POFILE in $(find lang -name "python.po") ; do - sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE + reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE # msgfmt -o ${POFILE%.po}.mo $POFILE done git add --verbose lang/python* From 13196ed2e2f2913375f6e64ad65750dfd6ca2316 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 11:04:19 +0100 Subject: [PATCH 020/168] CI: sort .desktop entries for i18n The ordering of entries jumps around sometimes when reading from Transifex (this might be Python unordered dictionaries, or based on translation statistics -- I can't tell). Force an order by sorting on language code and key-name so they all end up grouped by language code, sorted Name Icon GenericName Comment. Although this shuffles some more entries now, longer-term it will reduce churn in the .desktop file. --- ci/txpull.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/ci/txpull.sh b/ci/txpull.sh index 1c5c11a45..a6e4127af 100755 --- a/ci/txpull.sh +++ b/ci/txpull.sh @@ -108,6 +108,21 @@ awk ' skip=0; print $0; }}' < calamares.desktop > calamares.desktop.new mv calamares.desktop.new calamares.desktop +# Now group translated key-names (Name, Icon, Description, ..) by sorted +# language key rather than random-ish language-key order (which shuffles +# entries around). +# +# First, the non-translated lines +grep -v '\[.*\]=' calamares.desktop > calamares.desktop.new +# The translated lines: +# - replace (the first) [] by | so we have a consistent field separator +# - sort based on field 2, then 1 (language code, then reversed key-name) +# - replace the first | by [, the first (remaining) | by ] +# Effectively this puts the fields in this order: Name, Icon, Generic Name, +# Comment -- within each language key. This keeps churn down since the +# language codes and key-names are constant. +grep '\[.*\]=' calamares.desktop | sed -e 's/\[/|/' -e 's/\]/|/' | sort -t '|' -k 2,2 -k 1,1r | sed -e 's/|/\[/' | sed -e 's/|/\]/' >> calamares.desktop.new +mv calamares.desktop.new calamares.desktop git add --verbose calamares.desktop git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true From 8e4c9b8bd60d60d9ec8bf949d666bcdf5d20d6c4 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 7 Dec 2021 10:58:18 +0100 Subject: [PATCH 021/168] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_sv.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lang/calamares_sv.ts b/lang/calamares_sv.ts index 5fdcce0eb..64946e710 100644 --- a/lang/calamares_sv.ts +++ b/lang/calamares_sv.ts @@ -688,17 +688,17 @@ Alla ändringar kommer att gå förlorade. Successfully unmounted %1. - + Framgångsrikt avmonterade %1. Successfully disabled swap %1. - + Framgångsrikt inaktiverade swap %1. Successfully cleared swap %1. - + Framgångsrikt rensade swap %1. @@ -708,7 +708,7 @@ Alla ändringar kommer att gå förlorade. Successfully disabled volume group %1. - + Framgångsrikt inaktiverade volymgrupp %1. From c8ea3bccf72bea180b62e724a962d39ebc233eca Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 7 Dec 2021 10:58:18 +0100 Subject: [PATCH 022/168] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/calamares.desktop b/calamares.desktop index bfe3955b1..48d0df26d 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -98,10 +98,6 @@ Name[hr]=Instaliraj sustav Icon[hr]=calamares GenericName[hr]=Instalacija sustava Comment[hr]=Calamares — Instalacija sustava -Name[ie]=Installar li sistema -Icon[ie]=calamares -GenericName[ie]=Installator del sistema -Comment[ie]=Calamares — Installator del sistema Name[hu]=Rendszer telepítése Icon[hu]=calamares GenericName[hu]=Rendszertelepítő @@ -114,10 +110,6 @@ Name[is]=Setja upp kerfið Icon[is]=calamares GenericName[is]=Kerfis uppsetning Comment[is]=Calamares — Kerfis uppsetning -Name[cs_CZ]=Nainstalovat systém -Icon[cs_CZ]=calamares -GenericName[cs_CZ]=Instalátor systému -Comment[cs_CZ]=Calamares – instalátor operačních systémů Name[ja]=システムをインストール Icon[ja]=calamares GenericName[ja]=システムインストーラー @@ -158,6 +150,14 @@ Name[pl]=Zainstaluj system Icon[pl]=calamares GenericName[pl]=Instalator systemu Comment[pl]=Calamares — Instalator systemu +Name[ie]=Installar li sistema +Icon[ie]=calamares +GenericName[ie]=Installator del sistema +Comment[ie]=Calamares — Installator del sistema +Name[cs_CZ]=Nainstalovat systém +Icon[cs_CZ]=calamares +GenericName[cs_CZ]=Instalátor systému +Comment[cs_CZ]=Calamares – instalátor operačních systémů Name[pt_BR]=Sistema de Instalação Icon[pt_BR]=calamares GenericName[pt_BR]=Instalador de Sistema @@ -174,11 +174,6 @@ Name[si]=පද්ධතිය ස්ථාපනය කරන්න Icon[si]=කැලමරේස් GenericName[si]=පද්ධති ස්ථාපකය Comment[si]=Calamares - පද්ධති ස්ථාපකය -Name[sk]=Inštalovať systém -Icon[sk]=calamares -GenericName[sk]=Inštalátor systému -Comment[sk]=Calamares — Inštalátor systému -Name[sl]=Namesti sistem Name[sq]=Instalo Sistemin Icon[sq]=calamares GenericName[sq]=Instalues Sistemi @@ -187,11 +182,16 @@ Name[fi_FI]=Asenna järjestelmä Icon[fi_FI]=calamares GenericName[fi_FI]=Järjestelmän asennusohjelma Comment[fi_FI]=Calamares — Järjestelmän asentaja -Name[sr@latin]=Instaliraj sistem Name[sr]=Инсталирај систем Icon[sr]=calamares GenericName[sr]=Инсталатер система Comment[sr]=Каламарес — инсталатер система +Name[sr@latin]=Instaliraj sistem +Name[sk]=Inštalovať systém +Icon[sk]=calamares +GenericName[sk]=Inštalátor systému +Comment[sk]=Calamares — Inštalátor systému +Name[sl]=Namesti sistem Name[sv]=Installera system Icon[sv]=calamares GenericName[sv]=Systeminstallerare From d2ac201b982d272da2ce9220277e74e9155a1f5b Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 7 Dec 2021 11:05:37 +0100 Subject: [PATCH 023/168] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 108 +++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/calamares.desktop b/calamares.desktop index 48d0df26d..4db300495 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -21,10 +21,18 @@ Name[as]=চিছটেম ইনস্তল কৰক Icon[as]=কেলামাৰেচ GenericName[as]=চিছটেম ইনস্তলাৰ Comment[as]=কেলামাৰেচ — চিছটেম​ ইনস্তলাৰ +Name[ast]=Instalar el sistema +Icon[ast]=calamares +GenericName[ast]=Instalador del sistema +Comment[ast]=Calamares — Instalador del sistema Name[az]=Sistemi Quraşdırmaq Icon[az]=calamares GenericName[az]=Sistem Quraşdırıcısı Comment[az]=Calamares Sistem Quraşdırıcısı +Name[az_AZ]=Sistemi quraşdırmaq +Icon[az_AZ]=calamares +GenericName[az_AZ]=Sistem quraşdırcısı +Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı Name[be]=Усталяваць сістэму Icon[be]=calamares GenericName[be]=Усталёўшчык сістэмы @@ -41,6 +49,10 @@ Name[ca]=Instal·la el sistema Icon[ca]=calamares GenericName[ca]=Instal·lador de sistema Comment[ca]=Calamares — Instal·lador de sistema +Name[cs_CZ]=Nainstalovat systém +Icon[cs_CZ]=calamares +GenericName[cs_CZ]=Instalátor systému +Comment[cs_CZ]=Calamares – instalátor operačních systémů Name[da]=Installér system Icon[da]=calamares GenericName[da]=Systeminstallationsprogram @@ -57,10 +69,19 @@ Name[en_GB]=Install System Icon[en_GB]=calamares GenericName[en_GB]=System Installer Comment[en_GB]=Calamares — System Installer +Name[eo]=Instali Sistemo +Icon[eo]=calamares +GenericName[eo]=Sistema Instalilo +Comment[eo]=Calamares — Sistema Instalilo Name[es]=Instalar Sistema Icon[es]=calamares GenericName[es]=Instalador del Sistema Comment[es]=Calamares — Instalador del Sistema +Name[es_MX]=Instalar el Sistema +Icon[es_MX]=calamares +GenericName[es_MX]=Instalador del sistema +Comment[es_MX]=Calamares - Instalador del sistema +Name[es_PR]=Instalar el sistema Name[et]=Paigalda süsteem Icon[et]=calamares GenericName[et]=Süsteemipaigaldaja @@ -73,7 +94,10 @@ Name[fa]=نصب سامانه Icon[fa]=کالامارس GenericName[fa]=نصب‌کننده سامانه Comment[fa]=کالامارس — نصب‌کننده سامانه -Name[es_PR]=Instalar el sistema +Name[fi_FI]=Asenna järjestelmä +Icon[fi_FI]=calamares +GenericName[fi_FI]=Järjestelmän asennusohjelma +Comment[fi_FI]=Calamares — Järjestelmän asentaja Name[fr]=Installer le système Icon[fr]=calamares GenericName[fr]=Installateur système @@ -106,10 +130,18 @@ Name[id]=Instal Sistem Icon[id]=calamares GenericName[id]=Pemasang Comment[id]=Calamares — Pemasang Sistem +Name[ie]=Installar li sistema +Icon[ie]=calamares +GenericName[ie]=Installator del sistema +Comment[ie]=Calamares — Installator del sistema Name[is]=Setja upp kerfið Icon[is]=calamares GenericName[is]=Kerfis uppsetning Comment[is]=Calamares — Kerfis uppsetning +Name[it_IT]=Installa il sistema +Icon[it_IT]=calamares +GenericName[it_IT]=Programma d'installazione del sistema +Comment[it_IT]=Calamares — Programma d'installazione del sistema Name[ja]=システムをインストール Icon[ja]=calamares GenericName[ja]=システムインストーラー @@ -122,10 +154,6 @@ Name[lt]=Įdiegti Sistemą Icon[lt]=calamares GenericName[lt]=Sistemos diegimas į kompiuterį Comment[lt]=Calamares — Sistemos diegimo programa -Name[it_IT]=Installa il sistema -Icon[it_IT]=calamares -GenericName[it_IT]=Programma d'installazione del sistema -Comment[it_IT]=Calamares — Programma d'installazione del sistema Name[mk]=Инсталирај го системот Icon[mk]=calamares GenericName[mk]=Системен Инсталер @@ -138,30 +166,26 @@ Name[nb]=Installer System Icon[nb]=calamares GenericName[nb]=Systeminstallatør Comment[nb]=Calamares-systeminstallatør +Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस् +Icon[ne_NP]=Calamares +GenericName[ne_NP]=सिस्टम इन्स्टलर +Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर Name[nl]=Installeer systeem Icon[nl]=calamares GenericName[nl]=Installatieprogramma Comment[nl]=Calamares — Installatieprogramma -Name[az_AZ]=Sistemi quraşdırmaq -Icon[az_AZ]=calamares -GenericName[az_AZ]=Sistem quraşdırcısı -Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı Name[pl]=Zainstaluj system Icon[pl]=calamares GenericName[pl]=Instalator systemu Comment[pl]=Calamares — Instalator systemu -Name[ie]=Installar li sistema -Icon[ie]=calamares -GenericName[ie]=Installator del sistema -Comment[ie]=Calamares — Installator del sistema -Name[cs_CZ]=Nainstalovat systém -Icon[cs_CZ]=calamares -GenericName[cs_CZ]=Instalátor systému -Comment[cs_CZ]=Calamares – instalátor operačních systémů Name[pt_BR]=Sistema de Instalação Icon[pt_BR]=calamares GenericName[pt_BR]=Instalador de Sistema Comment[pt_BR]=Calamares — Instalador de Sistema +Name[pt_PT]=Instalar Sistema +Icon[pt_PT]=calamares +GenericName[pt_PT]=Instalador de Sistema +Comment[pt_PT]=Instalador de Sistema - Calamares Name[ro]=Instalează sistemul Icon[ro]=calamares GenericName[ro]=Instalator de sistem @@ -174,24 +198,20 @@ Name[si]=පද්ධතිය ස්ථාපනය කරන්න Icon[si]=කැලමරේස් GenericName[si]=පද්ධති ස්ථාපකය Comment[si]=Calamares - පද්ධති ස්ථාපකය -Name[sq]=Instalo Sistemin -Icon[sq]=calamares -GenericName[sq]=Instalues Sistemi -Comment[sq]=Calamares — Instalues Sistemi -Name[fi_FI]=Asenna järjestelmä -Icon[fi_FI]=calamares -GenericName[fi_FI]=Järjestelmän asennusohjelma -Comment[fi_FI]=Calamares — Järjestelmän asentaja -Name[sr]=Инсталирај систем -Icon[sr]=calamares -GenericName[sr]=Инсталатер система -Comment[sr]=Каламарес — инсталатер система -Name[sr@latin]=Instaliraj sistem Name[sk]=Inštalovať systém Icon[sk]=calamares GenericName[sk]=Inštalátor systému Comment[sk]=Calamares — Inštalátor systému Name[sl]=Namesti sistem +Name[sq]=Instalo Sistemin +Icon[sq]=calamares +GenericName[sq]=Instalues Sistemi +Comment[sq]=Calamares — Instalues Sistemi +Name[sr]=Инсталирај систем +Icon[sr]=calamares +GenericName[sr]=Инсталатер система +Comment[sr]=Каламарес — инсталатер система +Name[sr@latin]=Instaliraj sistem Name[sv]=Installera system Icon[sv]=calamares GenericName[sv]=Systeminstallerare @@ -201,6 +221,10 @@ Icon[tg]=calamares GenericName[tg]=Насбкунандаи низомӣ Comment[tg]=Calamares — Насбкунандаи низомӣ Name[th]=ติดตั้งระบบ +Name[tr_TR]=Sistemi Yükle +Icon[tr_TR]=calamares +GenericName[tr_TR]=Sistem Yükleyici +Comment[tr_TR]=Calamares — Sistem Yükleyici Name[uk]=Встановити Систему Icon[uk]=calamares GenericName[uk]=Встановлювач системи @@ -217,27 +241,3 @@ Name[zh_TW]=安裝系統 Icon[zh_TW]=calamares GenericName[zh_TW]=系統安裝程式 Comment[zh_TW]=Calamares ── 系統安裝程式 -Name[ast]=Instalar el sistema -Icon[ast]=calamares -GenericName[ast]=Instalador del sistema -Comment[ast]=Calamares — Instalador del sistema -Name[eo]=Instali Sistemo -Icon[eo]=calamares -GenericName[eo]=Sistema Instalilo -Comment[eo]=Calamares — Sistema Instalilo -Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस् -Icon[ne_NP]=Calamares -GenericName[ne_NP]=सिस्टम इन्स्टलर -Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर -Name[es_MX]=Instalar el Sistema -Icon[es_MX]=calamares -GenericName[es_MX]=Instalador del sistema -Comment[es_MX]=Calamares - Instalador del sistema -Name[pt_PT]=Instalar Sistema -Icon[pt_PT]=calamares -GenericName[pt_PT]=Instalador de Sistema -Comment[pt_PT]=Instalador de Sistema - Calamares -Name[tr_TR]=Sistemi Yükle -Icon[tr_TR]=calamares -GenericName[tr_TR]=Sistem Yükleyici -Comment[tr_TR]=Calamares — Sistem Yükleyici From dc11dd2203fda01e1f78e2c29225a885c2bc7449 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:24:41 +0100 Subject: [PATCH 024/168] [libcalamaresui] Move ErrorDialog to the widgets/ part --- src/libcalamaresui/CMakeLists.txt | 6 +++--- .../{utils/ErrorDialog => widgets}/ErrorDialog.cpp | 0 .../{utils/ErrorDialog => widgets}/ErrorDialog.h | 0 .../{utils/ErrorDialog => widgets}/ErrorDialog.ui | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename src/libcalamaresui/{utils/ErrorDialog => widgets}/ErrorDialog.cpp (100%) rename src/libcalamaresui/{utils/ErrorDialog => widgets}/ErrorDialog.h (100%) rename src/libcalamaresui/{utils/ErrorDialog => widgets}/ErrorDialog.ui (100%) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index e745681f3..ab0ad963a 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -20,7 +20,6 @@ set( calamaresui_SOURCES utils/CalamaresUtilsGui.cpp utils/ImageRegistry.cpp utils/Paste.cpp - utils/ErrorDialog/ErrorDialog.cpp viewpages/BlankViewStep.cpp viewpages/ExecutionViewStep.cpp @@ -28,6 +27,7 @@ set( calamaresui_SOURCES viewpages/ViewStep.cpp widgets/ClickableLabel.cpp + widgets/ErrorDialog.cpp widgets/FixedAspectRatioLabel.cpp widgets/PrettyRadioButton.cpp widgets/TranslationFix.cpp @@ -76,8 +76,8 @@ calamares_add_library( calamaresui Qt5::Svg RESOURCES libcalamaresui.qrc EXPORT Calamares - UI - utils/ErrorDialog/ErrorDialog.ui + UI + utils/ErrorDialog/ErrorDialog.ui VERSION ${CALAMARES_VERSION_SHORT} ) target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp ) diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp b/src/libcalamaresui/widgets/ErrorDialog.cpp similarity index 100% rename from src/libcalamaresui/utils/ErrorDialog/ErrorDialog.cpp rename to src/libcalamaresui/widgets/ErrorDialog.cpp diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h b/src/libcalamaresui/widgets/ErrorDialog.h similarity index 100% rename from src/libcalamaresui/utils/ErrorDialog/ErrorDialog.h rename to src/libcalamaresui/widgets/ErrorDialog.h diff --git a/src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui b/src/libcalamaresui/widgets/ErrorDialog.ui similarity index 100% rename from src/libcalamaresui/utils/ErrorDialog/ErrorDialog.ui rename to src/libcalamaresui/widgets/ErrorDialog.ui From 49890acd041594dc5b736aea137a95873d76b595 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:39:50 +0100 Subject: [PATCH 025/168] [libcalamaresui] Fix build after move --- src/libcalamaresui/ViewManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 87024ea6b..e61859a13 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -17,7 +17,6 @@ #include "JobQueue.h" #include "Settings.h" -#include "utils/ErrorDialog/ErrorDialog.h" #include "utils/Logger.h" #include "utils/Paste.h" #include "utils/Retranslator.h" @@ -25,6 +24,7 @@ #include "viewpages/BlankViewStep.h" #include "viewpages/ExecutionViewStep.h" #include "viewpages/ViewStep.h" +#include "widgets/ErrorDialog.h" #include "widgets/TranslationFix.h" #include From ca7f28848827ea60f64a2882719826e52b0933bc Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:40:05 +0100 Subject: [PATCH 026/168] [libcalamaresui] APIDOX for ErrorDialog --- src/libcalamaresui/widgets/ErrorDialog.h | 43 ++++++++++++++++-------- 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/libcalamaresui/widgets/ErrorDialog.h b/src/libcalamaresui/widgets/ErrorDialog.h index a0126c2ce..c4949a89c 100644 --- a/src/libcalamaresui/widgets/ErrorDialog.h +++ b/src/libcalamaresui/widgets/ErrorDialog.h @@ -7,17 +7,16 @@ * */ -#ifndef ERRORDIALOG_H -#define ERRORDIALOG_H +#ifndef LIBCALAMARESUI_ERRORDIALOG_H +#define LIBCALAMARESUI_ERRORDIALOG_H #include - namespace Ui { class ErrorDialog; } -class QDialogButtonBox; + namespace Calamares { class ErrorDialog : public QDialog @@ -32,30 +31,46 @@ class ErrorDialog : public QDialog public: explicit ErrorDialog( QWidget* parent = nullptr ); - ~ErrorDialog(); + ~ErrorDialog() override; + /** @brief The heading (title) of the error dialog + * + * This is a short (one-line) title. It is human-readable, so should + * be translated at the time it is set. + */ QString heading() const; - - QString informativeText() const; - - QString details() const; - void setHeading( const QString& newHeading ); + /** @brief The description of the problem + * + * Longer, human-readable, description of the problem. This text + * is word-wrapped as necessary. + */ + QString informativeText() const; void setInformativeText( const QString& newInformativeText ); + /** @brief Details of the problem + * + * This is generally command-output; it might not be translated + * when set. It should be considered "background to the informative + * text", or maybe "the reasons". Write the informative text for + * the end-user. + */ + QString details() const; void setDetails( const QString& newDetails ); + /** @brief Enable web-paste button + * + * The web-paste button can be configured at a global level, + * but each individual error dialog can be set separately. + */ bool shouldOfferWebPaste() const; void setShouldOfferWebPaste( bool newShouldOfferWebPaste ); signals: void headingChanged(); - void informativeTextChanged(); - void detailsChanged(); - void shouldOfferWebPasteChanged(); private: @@ -65,4 +80,4 @@ private: }; // namespace Calamares -#endif // ERRORDIALOG_H +#endif // LIBCALAMARESUI_ERRORDIALOG_H From 2f9edb3e08019ed7db413daeffe79066822c8543 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:44:19 +0100 Subject: [PATCH 027/168] [libcalamaresui] Code style --- src/libcalamaresui/widgets/ErrorDialog.cpp | 52 +++++++++++----------- 1 file changed, 25 insertions(+), 27 deletions(-) diff --git a/src/libcalamaresui/widgets/ErrorDialog.cpp b/src/libcalamaresui/widgets/ErrorDialog.cpp index 4ffe20384..8c682f964 100644 --- a/src/libcalamaresui/widgets/ErrorDialog.cpp +++ b/src/libcalamaresui/widgets/ErrorDialog.cpp @@ -17,7 +17,6 @@ namespace Calamares { - ErrorDialog::ErrorDialog( QWidget* parent ) : QDialog( parent ) , ui( new Ui::ErrorDialog ) @@ -33,7 +32,6 @@ ErrorDialog::~ErrorDialog() delete ui; } - QString ErrorDialog::heading() const { @@ -55,31 +53,32 @@ ErrorDialog::details() const void ErrorDialog::setHeading( const QString& newHeading ) { - if ( ui->headingLabel->text() == newHeading ) - return; - ui->headingLabel->setText( newHeading ); - emit headingChanged(); + if ( ui->headingLabel->text() != newHeading ) + { + ui->headingLabel->setText( newHeading ); + emit headingChanged(); + } } void ErrorDialog::setInformativeText( const QString& newInformativeText ) { - if ( ui->informativeTextLabel->text() == newInformativeText ) - return; - ui->informativeTextLabel->setText( newInformativeText ); - emit informativeTextChanged(); + if ( ui->informativeTextLabel->text() != newInformativeText ) + { + ui->informativeTextLabel->setText( newInformativeText ); + emit informativeTextChanged(); + } } void ErrorDialog::setDetails( const QString& newDetails ) { - if ( ui->detailsBrowser->toPlainText() == newDetails ) - return; - ui->detailsBrowser->setPlainText( newDetails ); - - ui->detailsWidget->setVisible( !ui->detailsBrowser->toPlainText().trimmed().isEmpty() ); - - emit detailsChanged(); + if ( ui->detailsBrowser->toPlainText() != newDetails ) + { + ui->detailsBrowser->setPlainText( newDetails ); + ui->detailsWidget->setVisible( !ui->detailsBrowser->toPlainText().trimmed().isEmpty() ); + emit detailsChanged(); + } } bool @@ -91,18 +90,17 @@ ErrorDialog::shouldOfferWebPaste() const void ErrorDialog::setShouldOfferWebPaste( bool newShouldOfferWebPaste ) { - if ( m_shouldOfferWebPaste == newShouldOfferWebPaste ) - return; - m_shouldOfferWebPaste = newShouldOfferWebPaste; + if ( m_shouldOfferWebPaste != newShouldOfferWebPaste ) + { + m_shouldOfferWebPaste = newShouldOfferWebPaste; - ui->offerWebPasteLabel->setVisible( m_shouldOfferWebPaste ); + ui->offerWebPasteLabel->setVisible( m_shouldOfferWebPaste ); + ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? ( QDialogButtonBox::Yes | QDialogButtonBox::No ) + : QDialogButtonBox::Close ); + fixButtonLabels( ui->buttonBox ); - ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? ( QDialogButtonBox::Yes | QDialogButtonBox::No ) - : QDialogButtonBox::Close ); - - fixButtonLabels( ui->buttonBox ); - - emit shouldOfferWebPasteChanged(); + emit shouldOfferWebPasteChanged(); + } } } // namespace Calamares From 3234de5753faaed5760a2354fbaa5e09614de3c3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:48:17 +0100 Subject: [PATCH 028/168] [libcalamaresui] Make web-paste decision more readable --- src/libcalamaresui/ViewManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index e61859a13..5d4109ca2 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -152,9 +152,9 @@ ViewManager::insertViewStep( int before, ViewStep* step ) void ViewManager::onInstallationFailed( const QString& message, const QString& details ) { - bool shouldOfferWebPaste = std::get< 0 >( Calamares::Branding::instance()->uploadServer() ) - != Calamares::Branding::UploadServerType::None - and std::get< 2 >( Calamares::Branding::instance()->uploadServer() ) != 0; + const auto webPaste = Calamares::Branding::instance()->uploadServer(); + bool shouldOfferWebPaste + = std::get< 0 >( webPaste ) != Calamares::Branding::UploadServerType::None and std::get< 2 >( webPaste ) != 0; cError() << "Installation failed:" << message; cDebug() << Logger::SubEntry << "- message:" << message; From b07c9bb4af8f202a741286d2068e7e116a332c48 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:53:43 +0100 Subject: [PATCH 029/168] [libcalamaresui] Use meaningful type for Upload info - use a struct with named fields instead of a tuple - offer an operator bool() for the logic of does-it-make-sense-to-upload --- src/libcalamaresui/Branding.cpp | 7 ++++--- src/libcalamaresui/Branding.h | 9 ++++++++- src/libcalamaresui/ViewManager.cpp | 4 +--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp index 5894c723d..b723f5dc7 100644 --- a/src/libcalamaresui/Branding.cpp +++ b/src/libcalamaresui/Branding.cpp @@ -162,14 +162,15 @@ uploadServerFromMap( const QVariantMap& map ) if ( typestring.isEmpty() || urlstring.isEmpty() ) { - return Branding::UploadServerInfo( Branding::UploadServerType::None, QUrl(), 0 ); + return Branding::UploadServerInfo { Branding::UploadServerType::None, QUrl(), 0 }; } bool bogus = false; // we don't care about type-name lookup success here - return Branding::UploadServerInfo( + return Branding::UploadServerInfo { names.find( typestring, bogus ), QUrl( urlstring, QUrl::ParsingMode::StrictMode ), - sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1 ); + sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1 + }; } /** @brief Load the @p map with strings from @p config diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index ba49f87c3..899b14c78 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -227,7 +227,14 @@ public: * is irrelevant and usually empty), the URL for the upload and the size limit of upload * in bytes (for configuration value < 0, it serves -1, which stands for having no limit). */ - using UploadServerInfo = std::tuple< UploadServerType, QUrl, qint64 >; + struct UploadServerInfo + { + UploadServerType type; + QUrl url; + qint64 size; + + operator bool() const { return type != Calamares::Branding::UploadServerType::None && size != 0; } + }; UploadServerInfo uploadServer() const { return m_uploadServer; } /** diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 5d4109ca2..0c0e324a1 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -152,9 +152,7 @@ ViewManager::insertViewStep( int before, ViewStep* step ) void ViewManager::onInstallationFailed( const QString& message, const QString& details ) { - const auto webPaste = Calamares::Branding::instance()->uploadServer(); - bool shouldOfferWebPaste - = std::get< 0 >( webPaste ) != Calamares::Branding::UploadServerType::None and std::get< 2 >( webPaste ) != 0; + bool shouldOfferWebPaste = bool( Calamares::Branding::instance()->uploadServer() ); cError() << "Installation failed:" << message; cDebug() << Logger::SubEntry << "- message:" << message; From 3030a710cce93646f558be27355a04b57c440443 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 12:58:22 +0100 Subject: [PATCH 030/168] [libcalamaresui] Simplify --- src/libcalamaresui/ViewManager.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 0c0e324a1..44afafb15 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -152,8 +152,6 @@ ViewManager::insertViewStep( int before, ViewStep* step ) void ViewManager::onInstallationFailed( const QString& message, const QString& details ) { - bool shouldOfferWebPaste = bool( Calamares::Branding::instance()->uploadServer() ); - cError() << "Installation failed:" << message; cDebug() << Logger::SubEntry << "- message:" << message; cDebug() << Logger::SubEntry << "- details:" << Logger::NoQuote << details; @@ -165,7 +163,7 @@ ViewManager::onInstallationFailed( const QString& message, const QString& detail errorDialog->setWindowTitle( tr( "Error" ) ); errorDialog->setHeading( "" + heading + "" ); errorDialog->setInformativeText( message ); - errorDialog->setShouldOfferWebPaste( shouldOfferWebPaste ); + errorDialog->setShouldOfferWebPaste( Calamares::Branding::instance()->uploadServer() ); errorDialog->setDetails( details ); errorDialog->show(); From 8b804c4ae04bf2844a05c8ff679acfafae47c098 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 14:15:43 +0100 Subject: [PATCH 031/168] [libcalamaresui] Improve icon+heading layout - Icon was too wide, heading and message placed off to the side --- src/libcalamaresui/widgets/ErrorDialog.ui | 87 +++++++++++++---------- 1 file changed, 50 insertions(+), 37 deletions(-) diff --git a/src/libcalamaresui/widgets/ErrorDialog.ui b/src/libcalamaresui/widgets/ErrorDialog.ui index 2632af617..cb480034e 100644 --- a/src/libcalamaresui/widgets/ErrorDialog.ui +++ b/src/libcalamaresui/widgets/ErrorDialog.ui @@ -11,25 +11,25 @@ - Dialog + Dialog - - - - - 0 - 0 - - - - - - - - + + + + + + 0 + 0 + + + + + + + @@ -43,27 +43,17 @@ - - - - - 0 - 0 - + + + + - + Would you like to paste the install log to the web? - - - - - - - - + Qt::Horizontal @@ -73,12 +63,35 @@ - - - - Would you like to paste the install log to the web? - - + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + From c2e63f4a6bad3dae76d72690e721950eb793177b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 14:20:31 +0100 Subject: [PATCH 032/168] [libcalamaresui] Don't bother tagging nonexistent 3rdparty sources --- src/libcalamaresui/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index e745681f3..c5101cb61 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -40,8 +40,6 @@ set( calamaresui_SOURCES # Don't warn about third-party sources mark_thirdparty_code( - ${CMAKE_SOURCE_DIR}/3rdparty/qjsonitem.cpp - ${CMAKE_SOURCE_DIR}/3rdparty/qjsonmodel.cpp ${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp ) @@ -76,8 +74,8 @@ calamares_add_library( calamaresui Qt5::Svg RESOURCES libcalamaresui.qrc EXPORT Calamares - UI - utils/ErrorDialog/ErrorDialog.ui + UI + utils/ErrorDialog/ErrorDialog.ui VERSION ${CALAMARES_VERSION_SHORT} ) target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp ) From 0b6239a9961ba32560cbf6c931ef553b9cb0b15c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 14:28:43 +0100 Subject: [PATCH 033/168] [libcalamaresui] Warnings-- : we know TCP ports are 16 bit --- src/libcalamaresui/utils/Paste.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libcalamaresui/utils/Paste.cpp b/src/libcalamaresui/utils/Paste.cpp index 519dc0133..d782d138e 100644 --- a/src/libcalamaresui/utils/Paste.cpp +++ b/src/libcalamaresui/utils/Paste.cpp @@ -69,7 +69,8 @@ STATICTEST QString ficheLogUpload( const QByteArray& pasteData, const QUrl& serverUrl, QObject* parent ) { QTcpSocket* socket = new QTcpSocket( parent ); - socket->connectToHost( serverUrl.host(), serverUrl.port() ); + // 16 bits of port-number + socket->connectToHost( serverUrl.host(), quint16( serverUrl.port() ) ); if ( !socket->waitForConnected() ) { From 32da51b44cae6fe560f860172da574aeda6ad661 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 14:48:14 +0100 Subject: [PATCH 034/168] [libcalamares] Avoid warnings in Boost::Python macros --- src/libcalamares/PythonJob.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index 291adbc54..b1373f5f3 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -23,6 +23,11 @@ static const char* s_preScript = nullptr; namespace bp = boost::python; +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" +#endif + BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, CalamaresPython::mount, 2, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, CalamaresPython::target_env_call, 1, 3 ); BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_list_overloads, CalamaresPython::target_env_call, 1, 3 ); @@ -42,6 +47,10 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_process_output_overloads, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( host_env_process_output_overloads, CalamaresPython::host_env_process_output, 1, 4 ); +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + BOOST_PYTHON_MODULE( libcalamares ) { bp::object package = bp::scope(); From eda85c176afe2781bc9ef0d5566d3d1fd7cc26f3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:01:29 +0100 Subject: [PATCH 035/168] [tracking] Avoid unused-deprecated-methods warnings - these are internal classes, with no real Qt machinery; remove the Q_OBJECT macros. - replace the tr() calls with calls with an explicit context, so that translations do not change. --- src/modules/tracking/TrackingJobs.cpp | 54 +++++++++++++++------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 5e3cd12b5..7430bd57b 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -19,6 +19,8 @@ #include +#include + #include @@ -37,7 +39,6 @@ namespace */ class TrackingInstallJob : public Calamares::Job { - Q_OBJECT public: TrackingInstallJob( const QString& url ); ~TrackingInstallJob() override; @@ -58,7 +59,6 @@ private: */ class TrackingMachineUpdateManagerJob : public Calamares::Job { - Q_OBJECT public: ~TrackingMachineUpdateManagerJob() override; @@ -75,7 +75,6 @@ public: */ class TrackingKUserFeedbackJob : public Calamares::Job { - Q_OBJECT public: TrackingKUserFeedbackJob( const QString& username, const QStringList& areas ); ~TrackingKUserFeedbackJob() override; @@ -99,13 +98,13 @@ TrackingInstallJob::~TrackingInstallJob() {} QString TrackingInstallJob::prettyName() const { - return tr( "Installation feedback" ); + return QCoreApplication::translate( "TrackingInstallJob", "Installation feedback" ); } QString TrackingInstallJob::prettyStatusMessage() const { - return tr( "Sending installation feedback." ); + return QCoreApplication::translate( "TrackingInstallJob", "Sending installation feedback." ); } Calamares::JobResult @@ -122,8 +121,9 @@ TrackingInstallJob::exec() if ( result.status == RequestStatus::Timeout ) { cWarning() << "install-tracking request timed out."; - return Calamares::JobResult::error( tr( "Internal error in install-tracking." ), - tr( "HTTP request timed out." ) ); + return Calamares::JobResult::error( + QCoreApplication::translate( "TrackingInstallJob", "Internal error in install-tracking." ), + QCoreApplication::translate( "TrackingInstallJob", "HTTP request timed out." ) ); } return Calamares::JobResult::ok(); } @@ -133,13 +133,13 @@ TrackingMachineUpdateManagerJob::~TrackingMachineUpdateManagerJob() {} QString TrackingMachineUpdateManagerJob::prettyName() const { - return tr( "Machine feedback" ); + return QCoreApplication::translate( "TrackingMachineUpdateManagerJob", "Machine feedback" ); } QString TrackingMachineUpdateManagerJob::prettyStatusMessage() const { - return tr( "Configuring machine feedback." ); + return QCoreApplication::translate( "TrackingMachineUpdateManagerJob", "Configuring machine feedback." ); } Calamares::JobResult @@ -162,14 +162,20 @@ TrackingMachineUpdateManagerJob::exec() else if ( r > 0 ) { return Calamares::JobResult::error( - tr( "Error in machine feedback configuration." ), - tr( "Could not configure machine feedback correctly, script error %1." ).arg( r ) ); + QCoreApplication::translate( "TrackingMachineUpdateManagerJob", + "Error in machine feedback configuration." ), + QCoreApplication::translate( "TrackingMachineUpdateManagerJob", + "Could not configure machine feedback correctly, script error %1." ) + .arg( r ) ); } else { return Calamares::JobResult::error( - tr( "Error in machine feedback configuration." ), - tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) ); + QCoreApplication::translate( "TrackingMachineUpdateManagerJob", + "Error in machine feedback configuration." ), + QCoreApplication::translate( "TrackingMachineUpdateManagerJob", + "Could not configure machine feedback correctly, Calamares error %1." ) + .arg( r ) ); } } @@ -184,13 +190,13 @@ TrackingKUserFeedbackJob::~TrackingKUserFeedbackJob() {} QString TrackingKUserFeedbackJob::prettyName() const { - return tr( "KDE user feedback" ); + return QCoreApplication::translate( "TrackingKUserFeedbackJob", "KDE user feedback" ); } QString TrackingKUserFeedbackJob::prettyStatusMessage() const { - return tr( "Configuring KDE user feedback." ); + return QCoreApplication::translate( "TrackingKUserFeedbackJob", "Configuring KDE user feedback." ); } Calamares::JobResult @@ -212,21 +218,25 @@ FeedbackLevel=16 if ( r > 0 ) { return Calamares::JobResult::error( - tr( "Error in KDE user feedback configuration." ), - tr( "Could not configure KDE user feedback correctly, script error %1." ).arg( r ) ); + QCoreApplication::translate( "TrackingKUserFeedbackJob", "Error in KDE user feedback configuration." ), + QCoreApplication::translate( "TrackingKUserFeedbackJob", + "Could not configure KDE user feedback correctly, script error %1." ) + .arg( r ) ); } else if ( r < 0 ) { return Calamares::JobResult::error( - tr( "Error in KDE user feedback configuration." ), - tr( "Could not configure KDE user feedback correctly, Calamares error %1." ).arg( r ) ); + QCoreApplication::translate( "TrackingKUserFeedbackJob", "Error in KDE user feedback configuration." ), + QCoreApplication::translate( "TrackingKUserFeedbackJob", + "Could not configure KDE user feedback correctly, Calamares error %1." ) + .arg( r ) ); } } return Calamares::JobResult::ok(); } -} // namespace +} // namespace void addJob( Calamares::JobList& list, InstallTrackingConfig* config ) @@ -290,7 +300,3 @@ addJob( Calamares::JobList& list, UserTrackingConfig* config ) } } } - -#include "utils/moc-warnings.h" - -#include "TrackingJobs.moc" From 5b0511035164e17c2da787f1183370b4892a8bac Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:29:02 +0100 Subject: [PATCH 036/168] [partition] Add convenience function formatByteSize We want to use the KPMCore function consistently, but Calamares uses a qint64 most of the time. Centralize the cast to double in one place in the code. --- src/modules/partition/core/SizeUtils.h | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/modules/partition/core/SizeUtils.h diff --git a/src/modules/partition/core/SizeUtils.h b/src/modules/partition/core/SizeUtils.h new file mode 100644 index 000000000..d474656c9 --- /dev/null +++ b/src/modules/partition/core/SizeUtils.h @@ -0,0 +1,27 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#ifndef PARTITION_CORE_SIZEUTILS_H +#define PARTITION_CORE_SIZEUTILS_H + +#include + +/** @brief Helper function for printing sizes consistently. + * + * Most of Calamares uses a qint64 for partition sizes, so use that + * parameter type. However, the human-visible formatting doesn't need + * to bother with one-byte accuracy (and anyway, a double has at least 50 bits + * at which point we're printing giga (or gibi) bytes). + */ +static inline QString formatByteSize( qint64 sizeValue ) +{ + return Capacity::formatByteSize( static_cast< double >( sizeValue ) ); +} + +#endif // PARTITION_CORE_SIZEUTILS_H From bb3f4442f5f5e203a3c0ce673cd362aadb02882c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:30:21 +0100 Subject: [PATCH 037/168] [partition] Warnings-reduction - use consistent size-formatting - needs an out-of-line virtual function --- src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp | 7 ++++--- src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp index 1e8a9e573..8eeafcbf4 100644 --- a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.cpp @@ -9,11 +9,10 @@ #include "ListPhysicalVolumeWidgetItem.h" -#include +#include "core/SizeUtils.h" ListPhysicalVolumeWidgetItem::ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked ) - : QListWidgetItem( - QString( "%1 | %2" ).arg( partition->deviceNode(), Capacity::formatByteSize( partition->capacity() ) ) ) + : QListWidgetItem( QString( "%1 | %2" ).arg( partition->deviceNode(), formatByteSize( partition->capacity() ) ) ) , m_partition( partition ) { setToolTip( partition->deviceNode() ); @@ -26,3 +25,5 @@ ListPhysicalVolumeWidgetItem::partition() const { return m_partition; } + +ListPhysicalVolumeWidgetItem::~ListPhysicalVolumeWidgetItem() {} diff --git a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h index 6e0b1c85a..5d7fdcb76 100644 --- a/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h +++ b/src/modules/partition/gui/ListPhysicalVolumeWidgetItem.h @@ -18,6 +18,7 @@ class ListPhysicalVolumeWidgetItem : public QListWidgetItem { public: ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked ); + ~ListPhysicalVolumeWidgetItem() override; const Partition* partition() const; From 09a03fbbc0356f1fdd24de28715f4b8dc183d236 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:31:49 +0100 Subject: [PATCH 038/168] [partition] Warnings--: we don't care about one-byte-in-10^12 --- src/modules/partition/gui/ReplaceWidget.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 94f527646..2e5675a11 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -212,7 +212,8 @@ ReplaceWidget::onPartitionSelected() } } - if ( partition->capacity() < requiredSpaceB ) + // The loss of precision is ok; we're not going to fall over from a single byte + if ( static_cast< double >( partition->capacity() ) < requiredSpaceB ) { updateStatus( CalamaresUtils::Fail, tr( "%4

" From 6e715205d785f63a997d48aaa59d9be6de44705b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:36:11 +0100 Subject: [PATCH 039/168] [partition] Warnings-- by calling formatting consistently --- src/modules/partition/core/DeviceModel.cpp | 8 +++----- src/modules/partition/core/PartitionModel.cpp | 10 ++++------ src/modules/partition/gui/PartitionLabelsView.cpp | 5 ++--- src/modules/partition/gui/VolumeGroupBaseDialog.cpp | 7 +++---- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 33aae20c0..25bdbff6c 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -8,9 +8,10 @@ * Calamares is Free Software: see the License-Identifier above. * */ -#include "core/DeviceModel.h" +#include "DeviceModel.h" #include "core/PartitionModel.h" +#include "core/SizeUtils.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" @@ -18,9 +19,6 @@ // KPMcore #include -// KF5 -#include - #include #include @@ -83,7 +81,7 @@ DeviceModel::data( const QModelIndex& index, int role ) const //: device[name] - size[number] (device-node[name]) return tr( "%1 - %2 (%3)" ) .arg( device->name() ) - .arg( KFormat().formatByteSize( device->capacity() ) ) + .arg( formatByteSize( device->capacity() ) ) .arg( device->deviceNode() ); } else diff --git a/src/modules/partition/core/PartitionModel.cpp b/src/modules/partition/core/PartitionModel.cpp index e310eee5e..19dbcd076 100644 --- a/src/modules/partition/core/PartitionModel.cpp +++ b/src/modules/partition/core/PartitionModel.cpp @@ -8,11 +8,12 @@ * */ -#include "core/PartitionModel.h" +#include "PartitionModel.h" #include "core/ColorUtils.h" #include "core/KPMHelpers.h" #include "core/PartitionInfo.h" +#include "core/SizeUtils.h" #include "partition/FileSystem.h" #include "partition/PartitionQuery.h" @@ -24,9 +25,6 @@ #include #include -// KF5 -#include - // Qt #include @@ -178,7 +176,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const if ( col == SizeColumn ) { qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize(); - return KFormat().formatByteSize( size ); + return formatByteSize( size ); } cDebug() << "Unknown column" << col; return QVariant(); @@ -210,7 +208,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const QString prettyFileSystem = CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() ); qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize(); - QString prettySize = KFormat().formatByteSize( size ); + QString prettySize = formatByteSize( size ); return QVariant( name + " " + prettyFileSystem + " " + prettySize ); } case SizeRole: diff --git a/src/modules/partition/gui/PartitionLabelsView.cpp b/src/modules/partition/gui/PartitionLabelsView.cpp index 5803d59a2..e73d7f4af 100644 --- a/src/modules/partition/gui/PartitionLabelsView.cpp +++ b/src/modules/partition/gui/PartitionLabelsView.cpp @@ -12,6 +12,7 @@ #include "core/ColorUtils.h" #include "core/PartitionModel.h" +#include "core/SizeUtils.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Logger.h" @@ -20,8 +21,6 @@ #include #include -#include - // Qt #include #include @@ -39,7 +38,7 @@ static QStringList buildUnknownDisklabelTexts( Device* dev ) { QStringList texts = { QObject::tr( "Unpartitioned space or unknown partition table" ), - KFormat().formatByteSize( dev->totalLogical() * dev->logicalSize() ) }; + formatByteSize( dev->totalLogical() * dev->logicalSize() ) }; return texts; } diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index 6277c30e5..48b44f68d 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -10,10 +10,9 @@ #include "VolumeGroupBaseDialog.h" #include "ui_VolumeGroupBaseDialog.h" +#include "core/SizeUtils.h" #include "gui/ListPhysicalVolumeWidgetItem.h" -#include - #include #include #include @@ -100,7 +99,7 @@ VolumeGroupBaseDialog::setUsedSizeValue( qint64 usedSize ) { m_usedSizeValue = usedSize; - ui->usedSize->setText( Capacity::formatByteSize( m_usedSizeValue ) ); + ui->usedSize->setText( formatByteSize( m_usedSizeValue ) ); } void @@ -121,7 +120,7 @@ VolumeGroupBaseDialog::updateTotalSize() % ( ui->peSize->value() * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB ) ); } - ui->totalSize->setText( Capacity::formatByteSize( m_totalSizeValue ) ); + ui->totalSize->setText( formatByteSize( m_totalSizeValue ) ); updateTotalSectors(); } From 4611545f93a2aafe8aea927a547c0df59c1f804c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:42:14 +0100 Subject: [PATCH 040/168] [libcalamares] Warnings-- on switch() - some switch statements handle a bunch of items explicitly, then default the rest. Clang complains about that. Turn off the warning for these specific switches, since there's dozens of values that simply do not need to be handled. --- src/libcalamares/PythonHelper.cpp | 8 ++++++++ src/libcalamares/partition/FileSystem.cpp | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/libcalamares/PythonHelper.cpp b/src/libcalamares/PythonHelper.cpp index d6e61b3aa..ca004ab5f 100644 --- a/src/libcalamares/PythonHelper.cpp +++ b/src/libcalamares/PythonHelper.cpp @@ -26,6 +26,11 @@ namespace CalamaresPython boost::python::object variantToPyObject( const QVariant& variant ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" +#endif + // 49 enumeration values not handled switch ( variant.type() ) { case QVariant::Map: @@ -62,6 +67,9 @@ variantToPyObject( const QVariant& variant ) default: return bp::object(); } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } diff --git a/src/libcalamares/partition/FileSystem.cpp b/src/libcalamares/partition/FileSystem.cpp index ad4df31ed..0dcd6fd32 100644 --- a/src/libcalamares/partition/FileSystem.cpp +++ b/src/libcalamares/partition/FileSystem.cpp @@ -22,6 +22,11 @@ namespace Partition QString prettyNameForFileSystemType( FileSystem::Type t ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" +#endif + // 13 enumeration values not handled switch ( t ) { case FileSystem::Unknown: @@ -60,11 +65,19 @@ prettyNameForFileSystemType( FileSystem::Type t ) default: return FileSystem::nameForType( t ); } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } QString untranslatedFS( FileSystem::Type t ) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wswitch-enum" +#endif + // 34 enumeration values not handled switch ( t ) { case FileSystem::Type::ReiserFS: @@ -72,6 +85,9 @@ untranslatedFS( FileSystem::Type t ) default: return FileSystem::nameForType( t, { QStringLiteral( "C" ) } ); } +#ifdef __clang__ +#pragma clang diagnostic pop +#endif } } // namespace Partition From 09f47b576285001ca2fabb7e034d66b5a5404b91 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 15:51:45 +0100 Subject: [PATCH 041/168] [partition] Build tests with consistent flags (in particular, KPMCore4-API flags) --- src/modules/partition/tests/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index 2839270fb..da017d96f 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -61,6 +61,7 @@ calamares_add_test( SOURCES ${PartitionModule_SOURCE_DIR}/jobs/AutoMountManagementJob.cpp AutoMountTests.cpp + DEFINITIONS ${_partition_defs} ) calamares_add_test( @@ -70,4 +71,5 @@ calamares_add_test( ${PartitionModule_SOURCE_DIR}/core/DeviceList.cpp LIBRARIES kpmcore + DEFINITIONS ${_partition_defs} ) From 1197d8c750ad20bedf7d3a9ed3c55c77ec7bf13a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 7 Dec 2021 18:19:32 +0100 Subject: [PATCH 042/168] [interactiveterminal] Warnings-- with KF5 5.86-or-later --- .../InteractiveTerminalPage.cpp | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/modules/interactiveterminal/InteractiveTerminalPage.cpp b/src/modules/interactiveterminal/InteractiveTerminalPage.cpp index afd39936b..ea30c21ef 100644 --- a/src/modules/interactiveterminal/InteractiveTerminalPage.cpp +++ b/src/modules/interactiveterminal/InteractiveTerminalPage.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -41,8 +42,10 @@ InteractiveTerminalPage::InteractiveTerminalPage( QWidget* parent ) void InteractiveTerminalPage::errorKonsoleNotInstalled() { - QMessageBox mb(QMessageBox::Critical, - tr( "Konsole not installed" ), tr( "Please install KDE Konsole and try again!" ), QMessageBox::Ok ); + QMessageBox mb( QMessageBox::Critical, + tr( "Konsole not installed" ), + tr( "Please install KDE Konsole and try again!" ), + QMessageBox::Ok ); Calamares::fixButtonLabels( &mb ); mb.exec(); } @@ -54,20 +57,30 @@ InteractiveTerminalPage::onActivate() { return; } - // For whatever reason, instead of simply linking against a library we - // need to do a runtime query to KService just to get a sodding terminal - // widget. + +#if KCOREADDONS_VERSION_MAJOR != 5 +#error Incompatible with not-KF5 +#endif +#if KCOREADDONS_VERSION_MINOR >= 86 + // 5.86 deprecated a bunch of KService and PluginFactory and related methods + auto md = KPluginMetaData::findPluginById( QString(), "konsolepart" ); + if ( !md.isValid() ) + { + errorKonsoleNotInstalled(); + return; + } + auto* p = KPluginFactory::instantiatePlugin< KParts::ReadOnlyPart >( md, this ).plugin; +#else KService::Ptr service = KService::serviceByDesktopName( "konsolepart" ); if ( !service ) { - // And all of this hoping the Konsole application is installed. If not, - // tough cookies. errorKonsoleNotInstalled(); return; } // Create one instance of konsolepart. KParts::ReadOnlyPart* p = service->createInstance< KParts::ReadOnlyPart >( this, this, {} ); +#endif if ( !p ) { // One more opportunity for the loading operation to fail. @@ -91,7 +104,6 @@ InteractiveTerminalPage::onActivate() m_termHostWidget = p->widget(); m_layout->addWidget( m_termHostWidget ); - cDebug() << "Part widget ought to be" << m_termHostWidget->metaObject()->className(); t->showShellInDir( QDir::home().path() ); t->sendInput( QString( "%1\n" ).arg( m_command ) ); From 13700b18c8ecf5f7ee44e266ef5b45e0eb750243 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 00:06:17 +0100 Subject: [PATCH 043/168] [partition] Warnings-- - remove superfluous `break` - massage types around partition sizes --- src/modules/partition/PartitionViewStep.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/modules/partition/PartitionViewStep.cpp b/src/modules/partition/PartitionViewStep.cpp index a6b5e1dd8..18f10d629 100644 --- a/src/modules/partition/PartitionViewStep.cpp +++ b/src/modules/partition/PartitionViewStep.cpp @@ -146,15 +146,12 @@ modeDescription( Config::InstallChoice choice ) case Config::InstallChoice::Alongside: return QCoreApplication::translate( context, "Install %1 alongside another operating system." ) .arg( branding->shortVersionedName() ); - break; case Config::InstallChoice::Erase: return QCoreApplication::translate( context, "Erase disk and install %1." ) .arg( branding->shortVersionedName() ); - break; case Config::InstallChoice::Replace: return QCoreApplication::translate( context, "Replace a partition with %1." ) .arg( branding->shortVersionedName() ); - break; case Config::InstallChoice::NoChoice: case Config::InstallChoice::Manual: return QCoreApplication::translate( context, "Manual partitioning." ); @@ -187,21 +184,18 @@ diskDescription( int listLength, const PartitionCoreModule::SummaryInfo& info, C .arg( branding->shortVersionedName() ) .arg( info.deviceNode ) .arg( info.deviceName ); - break; case Config::Erase: return QCoreApplication::translate( context, "Erase disk %2 (%3) and install %1." ) .arg( branding->shortVersionedName() ) .arg( info.deviceNode ) .arg( info.deviceName ); - break; case Config::Replace: return QCoreApplication::translate( context, "Replace a partition on disk %2 (%3) with %1." ) .arg( branding->shortVersionedName() ) .arg( info.deviceNode ) .arg( info.deviceName ); - break; case Config::NoChoice: case Config::Manual: return QCoreApplication::translate( @@ -558,7 +552,7 @@ PartitionViewStep::onLeave() if ( !okSize ) { cDebug() << o << "ESP too small"; - const auto atLeastBytes = PartUtils::efiFilesystemMinimumSize(); + const qint64 atLeastBytes = static_cast< qint64 >( PartUtils::efiFilesystemMinimumSize() ); const auto atLeastMiB = CalamaresUtils::BytesToMiB( atLeastBytes ); description.append( ' ' ); description.append( tr( "The filesystem must be at least %1 MiB in size." ).arg( atLeastMiB ) ); From e8ca298712461c694269300422964905ed944af1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 00:15:01 +0100 Subject: [PATCH 044/168] [partition] Reduce warnings --- src/modules/partition/core/PartUtils.cpp | 8 ++++++-- src/modules/partition/core/PartitionActions.cpp | 6 +++--- src/modules/partition/core/PartitionLayout.cpp | 3 +++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 507330a80..cb7c8a01d 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -451,6 +451,8 @@ isEfiFilesystemSuitableType( const Partition* candidate ) { auto type = candidate->fileSystem().type(); + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" ) switch ( type ) { case FileSystem::Type::Fat32: @@ -465,6 +467,7 @@ isEfiFilesystemSuitableType( const Partition* candidate ) cWarning() << "EFI boot partition must be FAT32"; return false; } + QT_WARNING_POP } bool @@ -526,14 +529,15 @@ efiFilesystemMinimumSize() { using CalamaresUtils::Units::operator""_MiB; - auto uefisys_part_sizeB = 300_MiB; + size_t uefisys_part_sizeB = 300_MiB; // The default can be overridden; the key used here comes // from the partition module Config.cpp auto* gs = Calamares::JobQueue::instance()->globalStorage(); if ( gs->contains( "efiSystemPartitionSize_i" ) ) { - uefisys_part_sizeB = gs->value( "efiSystemPartitionSize_i" ).toLongLong(); + qint64 v = gs->value( "efiSystemPartitionSize_i" ).toLongLong(); + uefisys_part_sizeB = v > 0 ? static_cast< size_t >( v ) : 0; } // There is a lower limit of what can be configured if ( uefisys_part_sizeB < 32_MiB ) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 8514bbe2c..8226499b4 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -71,15 +71,15 @@ swapSuggestion( const qint64 availableSpaceB, Config::SwapChoice swap ) // Allow for a fudge factor - suggestedSwapSizeB *= overestimationFactor; + suggestedSwapSizeB = qRound( suggestedSwapSizeB * overestimationFactor ); // don't use more than 10% of available space if ( !ensureSuspendToDisk ) { - suggestedSwapSizeB = qMin( suggestedSwapSizeB, qint64( 0.10 * availableSpaceB ) ); + suggestedSwapSizeB = qMin( suggestedSwapSizeB, availableSpaceB / 10 /* 10% is 0.1 */ ); } - cDebug() << "Suggested swap size:" << suggestedSwapSizeB / 1024. / 1024. / 1024. << "GiB"; + cDebug() << "Suggested swap size:" << CalamaresUtils::BytesToGiB( suggestedSwapSizeB ) << "GiB"; return suggestedSwapSizeB; } diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index f60952643..3813207ef 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -141,6 +141,8 @@ void PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType ) { using FileSystem = FileSystem::Type; + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" ) switch ( defaultFsType ) { case FileSystem::Unknown: @@ -196,6 +198,7 @@ PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType ) << "Using ext4 instead."; defaultFsType = FileSystem::Ext4; } + QT_WARNING_POP m_defaultFsType = defaultFsType; } From f0eb7ffbda5f6844c864ee0d5269a54445bbab6e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 00:59:20 +0100 Subject: [PATCH 045/168] [partition Untangle, Warnings-- The translations apply to labels and a tooltip, which depends on the partition-table type. Move the strings together and make the whole range of the switch explicitly. --- .../partition/gui/DeviceInfoWidget.cpp | 83 ++++++++++--------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/src/modules/partition/gui/DeviceInfoWidget.cpp b/src/modules/partition/gui/DeviceInfoWidget.cpp index bbc8ce74c..05a8c4b63 100644 --- a/src/modules/partition/gui/DeviceInfoWidget.cpp +++ b/src/modules/partition/gui/DeviceInfoWidget.cpp @@ -68,7 +68,8 @@ DeviceInfoWidget::setPartitionTableType( PartitionTable::TableType type ) void DeviceInfoWidget::retranslateUi() { - QString typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper(); + QString typeString; + QString toolTipString; // fix up if the name shouldn't be uppercase: switch ( m_tableType ) @@ -76,38 +77,32 @@ DeviceInfoWidget::retranslateUi() case PartitionTable::msdos: case PartitionTable::msdos_sectorbased: typeString = "MBR"; + toolTipString += tr( "

This partition table type is only advisable on older " + "systems which start from a BIOS boot " + "environment. GPT is recommended in most other cases.

" + "Warning: the MBR partition table " + "is an obsolete MS-DOS era standard.
" + "Only 4 primary partitions may be created, and of " + "those 4, one can be an extended partition, which " + "may in turn contain many logical partitions." ); + break; + case PartitionTable::gpt: + // TypeString is ok + toolTipString += tr( "

This is the recommended partition table type for modern " + "systems which start from an EFI boot " + "environment." ); break; case PartitionTable::loop: typeString = "loop"; - break; - case PartitionTable::mac: - typeString = "Mac"; - break; - case PartitionTable::amiga: - typeString = "Amiga"; - break; - case PartitionTable::sun: - typeString = "Sun"; - break; - case PartitionTable::unknownTableType: - typeString = " ? "; - } - - - QString toolTipString = tr( "This device has a %1 partition " - "table." ) - .arg( typeString ); - - switch ( m_tableType ) - { - case PartitionTable::loop: toolTipString = tr( "This is a loop " "device.

" "It is a pseudo-device with no partition table " "that makes a file accessible as a block device. " "This kind of setup usually only contains a single filesystem." ); break; + case PartitionTable::none: case PartitionTable::unknownTableType: + typeString = " ? "; toolTipString = tr( "This installer cannot detect a partition table on the " "selected storage device.

" "The device either has no partition " @@ -117,21 +112,35 @@ DeviceInfoWidget::retranslateUi() "either automatically, or through the manual partitioning " "page." ); break; - case PartitionTable::gpt: - toolTipString += tr( "

This is the recommended partition table type for modern " - "systems which start from an EFI boot " - "environment." ); + // The next ones need to have the name adjusted, but the default tooltip is OK + case PartitionTable::mac: + typeString = "Mac"; break; - case PartitionTable::msdos: - case PartitionTable::msdos_sectorbased: - toolTipString += tr( "

This partition table type is only advisable on older " - "systems which start from a BIOS boot " - "environment. GPT is recommended in most other cases.

" - "Warning: the MBR partition table " - "is an obsolete MS-DOS era standard.
" - "Only 4 primary partitions may be created, and of " - "those 4, one can be an extended partition, which " - "may in turn contain many logical partitions." ); + case PartitionTable::amiga: + typeString = "Amiga"; + break; + case PartitionTable::sun: + typeString = "Sun"; + break; + // Peculiar tables, do nothing and use default type and tooltip strings + case PartitionTable::aix: + case PartitionTable::bsd: + case PartitionTable::dasd: + case PartitionTable::dvh: + case PartitionTable::pc98: + case PartitionTable::vmd: + break; + } + + if ( typeString.isEmpty() ) + { + typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper(); + } + if ( toolTipString.isEmpty() ) + { + toolTipString = tr( "This device has a %1 partition " + "table." ) + .arg( typeString ); } m_ptLabel->setText( typeString ); From 043bdc36d683e6619acc336879d7c102c2a0485b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 01:02:27 +0100 Subject: [PATCH 046/168] Changes: document contributors --- CHANGES-3.2 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 81fd55343..b658191fb 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -10,10 +10,13 @@ website will have to do for older versions. # 3.2.49 (unreleased) # This release contains contributions from (alphabetically by first name): + - Artem Grinev - Evan James ## Core ## - - No core changes yet + - Errors (e.g. when an installation fails for whatever reason) are displayed + in a dialog with a scrollable details panel, rather than growing up + to the size of the screen. (Thanks Artem) ## Modules ## - *partition* now supports "deep" btrfs subvolume names, e.g. a From bb948c47dc447c0a01c9d2ecbadeb3aa060bdb77 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 13:06:53 +0100 Subject: [PATCH 047/168] [fstab] Cut the example btrfs flags to 'defaults' Testing shows that the flags can influence -- maybe cause -- data corruption when noatime is set. FIXES #1846 --- src/modules/fstab/fstab.conf | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index c05f1929a..560aa0073 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -18,10 +18,16 @@ # # btrfs_swap options are used when a swapfile is chosen with a btrfs root # the options are applied to the subvolume which holds the swap partition +# +# The settings shown here apply only the btrfs defaults; these +# are generally the right ones. Commented-out lines show other +# options wich **might** be applicable for specific situations. mountOptions: default: defaults,noatime - btrfs: defaults,noatime,autodefrag,compress=zstd - btrfs_swap: defaults,noatime + # btrfs: defaults,noatime,autodefrag,compress=zstd + btrfs: defaults + # btrfs_swap: defaults,noatime + btrfs_swap: defaults # Mount options to use for the EFI System Partition. If not defined, the # *mountOptions* for *vfat* are used, or if that is not set either, From bc2713ccbbb857ece8329b1b0eb0ef68e17e4d50 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 14:08:37 +0100 Subject: [PATCH 048/168] [libcalamares] Add string functions for lstrip() and rstrip()-like --- src/libcalamares/utils/String.cpp | 21 ++++++++++ src/libcalamares/utils/String.h | 13 ++++++ src/libcalamares/utils/Tests.cpp | 68 +++++++++++++++++++++++++++++-- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/utils/String.cpp b/src/libcalamares/utils/String.cpp index 615d30309..c88c23693 100644 --- a/src/libcalamares/utils/String.cpp +++ b/src/libcalamares/utils/String.cpp @@ -224,5 +224,26 @@ truncateMultiLine( const QString& string, CalamaresUtils::LinesStartEnd lines, C return front + back.right( chars.total / 2 ); } +void +removeLeading( QString& string, QChar c ) +{ + int count = 0; + while ( string.length() > count && string[ count ] == c ) + { + count++; + } + string.remove( 0, count ); +} + +void +removeTrailing( QString& string, QChar c ) +{ + int lastIndex = string.length(); + while ( lastIndex > 0 && string[ lastIndex - 1 ] == c ) + { + lastIndex--; + } + string.remove( lastIndex, string.length() ); +} } // namespace CalamaresUtils diff --git a/src/libcalamares/utils/String.h b/src/libcalamares/utils/String.h index e08255f86..1adc2336a 100644 --- a/src/libcalamares/utils/String.h +++ b/src/libcalamares/utils/String.h @@ -100,6 +100,19 @@ DLLEXPORT QString truncateMultiLine( const QString& string, LinesStartEnd lines = LinesStartEnd { 3, 5 }, CharCount chars = CharCount { 812 } ); +/** @brief Remove all @p c at the beginning of @p string + * + * Modifies the @p string in-place. If @p c is not the first character + * of @p string, the string is left unchanged; otherwise the first character + * is removed and the process repeats. + */ +DLLEXPORT void removeLeading( QString& string, QChar c ); +/** @brief Remove all @p c at the end of @p string + * + * Like removeLeading(), but at the end of the string. + */ +DLLEXPORT void removeTrailing( QString& string, QChar c ); + } // namespace CalamaresUtils #endif diff --git a/src/libcalamares/utils/Tests.cpp b/src/libcalamares/utils/Tests.cpp index 8fd11cd87..3dde75338 100644 --- a/src/libcalamares/utils/Tests.cpp +++ b/src/libcalamares/utils/Tests.cpp @@ -70,6 +70,10 @@ private Q_SLOTS: void testStringTruncation(); void testStringTruncationShorter(); void testStringTruncationDegenerate(); + void testStringRemoveLeading_data(); + void testStringRemoveLeading(); + void testStringRemoveTrailing_data(); + void testStringRemoveTrailing(); /** @section Test Runner directory-manipulation. */ void testRunnerDirs(); @@ -754,6 +758,64 @@ LibCalamaresTests::testStringTruncationDegenerate() } } +void +LibCalamaresTests::testStringRemoveLeading_data() +{ + QTest::addColumn< QString >( "string" ); + QTest::addColumn< char >( "c" ); + QTest::addColumn< QString >( "result" ); + + QTest::newRow( "empty" ) << QString() << '/' << QString(); + QTest::newRow( "one-slash" ) << QStringLiteral( "/tmp" ) << '/' << QStringLiteral( "tmp" ); + QTest::newRow( "two-slash" ) << QStringLiteral( "//tmp" ) << '/' << QStringLiteral( "tmp" ); + QTest::newRow( "multi-slash" ) << QStringLiteral( "/tmp/p" ) << '/' << QStringLiteral( "tmp/p" ); + QTest::newRow( "later-slash" ) << QStringLiteral( "@/tmp" ) << '/' << QStringLiteral( "@/tmp" ); + QTest::newRow( "all-one-slash" ) << QStringLiteral( "/" ) << '/' << QString(); + QTest::newRow( "all-many-slash" ) << QStringLiteral( "////////////////////" ) << '/' << QString(); + QTest::newRow( "trailing" ) << QStringLiteral( "tmp/" ) << '/' << QStringLiteral( "tmp/" ); +} + +void +LibCalamaresTests::testStringRemoveLeading() +{ + QFETCH( QString, string ); + QFETCH( char, c ); + QFETCH( QString, result ); + + const QString initial = string; + CalamaresUtils::removeLeading( string, c ); + QCOMPARE( string, result ); +} + +void +LibCalamaresTests::testStringRemoveTrailing_data() +{ + QTest::addColumn< QString >( "string" ); + QTest::addColumn< char >( "c" ); + QTest::addColumn< QString >( "result" ); + + QTest::newRow( "empty" ) << QString() << '/' << QString(); + QTest::newRow( "one-slash" ) << QStringLiteral( "/tmp" ) << '/' << QStringLiteral( "/tmp" ); + QTest::newRow( "two-slash" ) << QStringLiteral( "//tmp" ) << '/' << QStringLiteral( "//tmp" ); + QTest::newRow( "multi-slash" ) << QStringLiteral( "/tmp//p/" ) << '/' << QStringLiteral( "/tmp//p" ); + QTest::newRow( "later-slash" ) << QStringLiteral( "@/tmp/@" ) << '/' << QStringLiteral( "@/tmp/@" ); + QTest::newRow( "later-slash2" ) << QStringLiteral( "@/tmp/@//" ) << '/' << QStringLiteral( "@/tmp/@" ); + QTest::newRow( "all-one-slash" ) << QStringLiteral( "/" ) << '/' << QString(); + QTest::newRow( "all-many-slash" ) << QStringLiteral( "////////////////////" ) << '/' << QString(); + QTest::newRow( "trailing" ) << QStringLiteral( "tmp/" ) << '/' << QStringLiteral( "tmp" ); +} + +void +LibCalamaresTests::testStringRemoveTrailing() +{ + QFETCH( QString, string ); + QFETCH( char, c ); + QFETCH( QString, result ); + + const QString initial = string; + CalamaresUtils::removeTrailing( string, c ); + QCOMPARE( string, result ); +} static QString dirname( const QTemporaryDir& d ) @@ -1001,10 +1063,10 @@ LibCalamaresTests::testReadWriteFile() { auto fullPath = ss->createTargetFile( "test0", otherContents ); QVERIFY( !fullPath ); // Failed, because it won't overwrite - QCOMPARE( fullPath.code(), decltype(fullPath)::Code::AlreadyExists ); - QVERIFY( fullPath.path().isEmpty() ); // Because it wasn't written + QCOMPARE( fullPath.code(), decltype( fullPath )::Code::AlreadyExists ); + QVERIFY( fullPath.path().isEmpty() ); // Because it wasn't written - QFileInfo fi( tempRoot.filePath( "test0" ) ); // Compute the name some other way + QFileInfo fi( tempRoot.filePath( "test0" ) ); // Compute the name some other way QVERIFY( fi.exists() ); QVERIFY( fi.isFile() ); QCOMPARE( fi.size(), 0 ); From 5ca029df255cdc01ccbe599480e3f89ebd89e060 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 30 Nov 2021 16:02:59 +0100 Subject: [PATCH 049/168] [luksopenswaphookcfg] Start a C++ port - this module needs work to handle BTRFS special-cases *anyway* - limited in scope, few options: port it while doing the special-cases So far, this is just a C++ stub. SEE #1659 #1644 --- .../luksopenswaphookcfg/CMakeLists.txt | 21 +++++++ src/modules/luksopenswaphookcfg/LOSHJob.cpp | 62 +++++++++++++++++++ src/modules/luksopenswaphookcfg/Tests.cpp | 38 ++++++++++++ src/modules/luksopenswaphookcfg/module.desc | 7 --- 4 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 src/modules/luksopenswaphookcfg/CMakeLists.txt create mode 100644 src/modules/luksopenswaphookcfg/LOSHJob.cpp create mode 100644 src/modules/luksopenswaphookcfg/Tests.cpp delete mode 100644 src/modules/luksopenswaphookcfg/module.desc diff --git a/src/modules/luksopenswaphookcfg/CMakeLists.txt b/src/modules/luksopenswaphookcfg/CMakeLists.txt new file mode 100644 index 000000000..64b6c58bc --- /dev/null +++ b/src/modules/luksopenswaphookcfg/CMakeLists.txt @@ -0,0 +1,21 @@ +# === This file is part of Calamares - === +# +# SPDX-FileCopyrightText: 2021 Adriaan de Groot +# SPDX-License-Identifier: BSD-2-Clause +# + +# Because LUKS Open Swap Hook (Job) is such a mouthful, we'll +# use LOSH all over the place as a shorthand. +calamares_add_plugin( luksopenswaphook + TYPE job + EXPORT_MACRO PLUGINDLLEXPORT_PRO + SOURCES + LOSHJob.cpp + SHARED_LIB +) + +calamares_add_test( + luksopenswaphooktest + SOURCES + Tests.cpp +) diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp new file mode 100644 index 000000000..e05b24108 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -0,0 +1,62 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "CppJob.h" +#include "DllMacro.h" +#include "utils/Permissions.h" +#include "utils/PluginFactory.h" + +#include +#include +#include + +class PLUGINDLLEXPORT LOSHJob : public Calamares::CppJob +{ + Q_OBJECT + +public: + explicit LOSHJob( QObject* parent = nullptr ); + ~LOSHJob() override; + + QString prettyName() const override; + + Calamares::JobResult exec() override; + + void setConfigurationMap( const QVariantMap& configurationMap ) override; + +private: +}; + +LOSHJob::LOSHJob( QObject* parent ) + : Calamares::CppJob( parent ) +{ +} + +QString +LOSHJob::prettyName() const +{ + return tr( "Configuring encrypted swap." ); +} + + +Calamares::JobResult +LOSHJob::exec() +{ + return Calamares::JobResult::ok(); +} + +void +LOSHJob::setConfigurationMap( const QVariantMap& configurationMap ) +{ +} + +CALAMARES_PLUGIN_FACTORY_DECLARATION( LOSHJobFactory ) +CALAMARES_PLUGIN_FACTORY_DEFINITION( LOSHJobFactory, registerPlugin< LOSHJob >(); ) + +#include "utils/moc-warnings.h" + +#include "LOSHJob.moc" diff --git a/src/modules/luksopenswaphookcfg/Tests.cpp b/src/modules/luksopenswaphookcfg/Tests.cpp new file mode 100644 index 000000000..233701746 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/Tests.cpp @@ -0,0 +1,38 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "utils/Logger.h" + +#include + +// LOSH = LUKS Open Swap Hook (Job) + +class LOSHTests : public QObject +{ + Q_OBJECT +public: + LOSHTests(); + ~LOSHTests() override {} + +private Q_SLOTS: + void initTestCase(); + + void testTrue(); +}; + +LOSHTests::LOSHTests() {} + +void +LOSHTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); + cDebug() << "LOSH test started."; +} + +#include "utils/moc-warnings.h" + +#include "Tests.moc" diff --git a/src/modules/luksopenswaphookcfg/module.desc b/src/modules/luksopenswaphookcfg/module.desc deleted file mode 100644 index 919a92792..000000000 --- a/src/modules/luksopenswaphookcfg/module.desc +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-FileCopyrightText: no -# SPDX-License-Identifier: CC0-1.0 ---- -type: "job" -name: "luksopenswaphookcfg" -interface: "python" -script: "main.py" From 7ea21663cacf8f8e40a184db304d3dddbf9ce04e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Dec 2021 13:28:16 +0100 Subject: [PATCH 050/168] [luksopenswaphookcfg] Partial implementation in C++ - Futz a bit with the string replacements -- do not assume # will introduce a comment half-way through a line. --- .../luksopenswaphookcfg/CMakeLists.txt | 1 + src/modules/luksopenswaphookcfg/LOSHInfo.h | 62 ++++++ src/modules/luksopenswaphookcfg/LOSHJob.cpp | 106 ++++++++--- src/modules/luksopenswaphookcfg/LOSHJob.h | 37 ++++ src/modules/luksopenswaphookcfg/Tests.cpp | 180 +++++++++++++++++- 5 files changed, 361 insertions(+), 25 deletions(-) create mode 100644 src/modules/luksopenswaphookcfg/LOSHInfo.h create mode 100644 src/modules/luksopenswaphookcfg/LOSHJob.h diff --git a/src/modules/luksopenswaphookcfg/CMakeLists.txt b/src/modules/luksopenswaphookcfg/CMakeLists.txt index 64b6c58bc..6d80df815 100644 --- a/src/modules/luksopenswaphookcfg/CMakeLists.txt +++ b/src/modules/luksopenswaphookcfg/CMakeLists.txt @@ -17,5 +17,6 @@ calamares_add_plugin( luksopenswaphook calamares_add_test( luksopenswaphooktest SOURCES + LOSHJob.cpp Tests.cpp ) diff --git a/src/modules/luksopenswaphookcfg/LOSHInfo.h b/src/modules/luksopenswaphookcfg/LOSHInfo.h new file mode 100644 index 000000000..94ccba379 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHInfo.h @@ -0,0 +1,62 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef LUKSOPENSWAPHOOKCFG_LOSHINFO_H +#define LUKSOPENSWAPHOOKCFG_LOSHINFO_H + +#include + +/** @brief Information needed to create a suitable config file + * + * The LUKS swap configuration has a handful of keys that need to + * be written to the config file. This struct holds those keys + * and can find the key values from Global Storage (where the + * *partition* module sets them). + */ +struct LOSHInfo +{ + // Member names copied from Python code + QString swap_outer_uuid; + QString swap_mapper_name; + QString mountable_keyfile_device; + QString swap_device_path; + + bool isValid() const { return !swap_device_path.isEmpty(); } + + /** @brief Helper method for doing key-value replacements + * + * Given a named @p key (e.g. "duck", or "swap_device"), returns the + * value set for that key. Invalid keys (e.g. "duck") return an empty string. + */ + QString replacementFor( const QString& key ) const + { + if ( key == QStringLiteral( "swap_device" ) ) + { + return swap_device_path; + } + if ( key == QStringLiteral( "crypt_swap_name" ) ) + { + return swap_mapper_name; + } + if ( key == QStringLiteral( "keyfile_device" ) ) + { + return mountable_keyfile_device; + } + if ( key == QStringLiteral( "keyfile_filename" ) ) + { + return QStringLiteral( "crypto_keyfile.bin" ); + } + return QString(); + } + + /** @brief Creates a struct from information already set in GS + * + * TODO: implement this in LOSHJob.cpp + */ + static LOSHInfo fromGlobalStorage() { return LOSHInfo {}; } +}; + +#endif diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp index e05b24108..986213cf5 100644 --- a/src/modules/luksopenswaphookcfg/LOSHJob.cpp +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -4,59 +4,117 @@ * SPDX-License-Identifier: GPL-3.0-or-later * */ +#include "LOSHJob.h" -#include "CppJob.h" -#include "DllMacro.h" +#include "LOSHInfo.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" #include "utils/Permissions.h" #include "utils/PluginFactory.h" +#include "utils/Variant.h" #include #include #include -class PLUGINDLLEXPORT LOSHJob : public Calamares::CppJob -{ - Q_OBJECT - -public: - explicit LOSHJob( QObject* parent = nullptr ); - ~LOSHJob() override; - - QString prettyName() const override; - - Calamares::JobResult exec() override; - - void setConfigurationMap( const QVariantMap& configurationMap ) override; - -private: -}; - LOSHJob::LOSHJob( QObject* parent ) : Calamares::CppJob( parent ) { } +LOSHJob::~LOSHJob() {} + + QString LOSHJob::prettyName() const { return tr( "Configuring encrypted swap." ); } +STATICTEST QString +get_assignment_part( const QString& line ) +{ + static QRegularExpression re( "^[# \\t]*([A-Za-z_]+)[ \\t]*=" ); + auto m = re.match( line ); + if ( m.hasMatch() ) + { + return m.captured( 1 ); + } + return QString(); +} + +/** Writes the config file at @p path + * + * NOTE: @p path is relative to the target system, not an absolute path. + */ +STATICTEST void +write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info ) +{ + if ( info.isValid() ) + { + for ( auto& line : contents ) + { + const QString key = get_assignment_part( line ); + QString replacement = info.replacementFor( key ); + if ( !replacement.isEmpty() ) + { + line.clear(); + line.append( QStringLiteral( "%1=%2" ).arg( key, replacement ) ); + } + } + cDebug() << "Writing" << contents.length() << "line configuration to" << path; + // \n between each two lines, and a \n at the end + CalamaresUtils::System::instance()->createTargetFile( + path, contents.join( '\n' ).append( '\n' ).toUtf8(), CalamaresUtils::System::WriteMode::Overwrite ); + } + else + { + cDebug() << "Will not write an invalid configuration to" << path; + } +} Calamares::JobResult LOSHJob::exec() { + const auto* sys = CalamaresUtils::System::instance(); + if ( !sys ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No target system available." ), Calamares::JobResult::InvalidConfiguration ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs || gs->value( "rootMountPoint" ).toString().isEmpty() ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No rootMountPoint is set." ), Calamares::JobResult::InvalidConfiguration ); + } + if ( m_configFilePath.isEmpty() ) + { + return Calamares::JobResult::internalError( + "LuksOpenSwapHook", tr( "No configFilePath is set." ), Calamares::JobResult::InvalidConfiguration ); + } + + QStringList contents = sys->readTargetFile( m_configFilePath ); + if ( contents.isEmpty() ) + { + contents << QStringLiteral( "# swap_device=" ) << QStringLiteral( "# crypt_swap_name=" ) + << QStringLiteral( "# keyfile_device=" ) << QStringLiteral( "# keyfile_filename=" ); + } + + write_openswap_conf( m_configFilePath, contents, LOSHInfo::fromGlobalStorage() ); return Calamares::JobResult::ok(); } void LOSHJob::setConfigurationMap( const QVariantMap& configurationMap ) { + m_configFilePath = CalamaresUtils::getString( + configurationMap, QStringLiteral( "configFilePath" ), QStringLiteral( "/etc/openswap.conf" ) ); } -CALAMARES_PLUGIN_FACTORY_DECLARATION( LOSHJobFactory ) CALAMARES_PLUGIN_FACTORY_DEFINITION( LOSHJobFactory, registerPlugin< LOSHJob >(); ) - -#include "utils/moc-warnings.h" - -#include "LOSHJob.moc" diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.h b/src/modules/luksopenswaphookcfg/LOSHJob.h new file mode 100644 index 000000000..4a435a935 --- /dev/null +++ b/src/modules/luksopenswaphookcfg/LOSHJob.h @@ -0,0 +1,37 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef LUKSOPENSWAPHOOKCFG_LOSHJOB_H +#define LUKSOPENSWAPHOOKCFG_LOSHJOB_H + +#include "CppJob.h" +#include "DllMacro.h" +#include "utils/PluginFactory.h" + +#include +#include + +class PLUGINDLLEXPORT LOSHJob : public Calamares::CppJob +{ + Q_OBJECT + +public: + explicit LOSHJob( QObject* parent = nullptr ); + ~LOSHJob() override; + + QString prettyName() const override; + + Calamares::JobResult exec() override; + + void setConfigurationMap( const QVariantMap& configurationMap ) override; + +private: + QString m_configFilePath; +}; + +CALAMARES_PLUGIN_FACTORY_DECLARATION( LOSHJobFactory ) + +#endif diff --git a/src/modules/luksopenswaphookcfg/Tests.cpp b/src/modules/luksopenswaphookcfg/Tests.cpp index 233701746..0cb79d7b9 100644 --- a/src/modules/luksopenswaphookcfg/Tests.cpp +++ b/src/modules/luksopenswaphookcfg/Tests.cpp @@ -5,12 +5,22 @@ * */ +#include "LOSHInfo.h" +#include "LOSHJob.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include // LOSH = LUKS Open Swap Hook (Job) +// Implementation details +extern QString get_assignment_part( const QString& line ); +extern void write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info ); + class LOSHTests : public QObject { Q_OBJECT @@ -21,7 +31,12 @@ public: private Q_SLOTS: void initTestCase(); - void testTrue(); + void testAssignmentExtraction_data(); + void testAssignmentExtraction(); + + void testLOSHInfo(); + void testConfigWriting(); + void testJob(); }; LOSHTests::LOSHTests() {} @@ -33,6 +48,169 @@ LOSHTests::initTestCase() cDebug() << "LOSH test started."; } + +void +LOSHTests::testAssignmentExtraction_data() +{ + QTest::addColumn< QString >( "line" ); + QTest::addColumn< QString >( "match" ); + + QTest::newRow( "empty" ) << QString() << QString(); + QTest::newRow( "comment-only1" ) << QStringLiteral( "# " ) << QString(); + QTest::newRow( "comment-only2" ) << QStringLiteral( "###" ) << QString(); + QTest::newRow( "comment-only3" ) << QStringLiteral( "# # #" ) << QString(); + + QTest::newRow( "comment-text" ) << QStringLiteral( "# NOTE:" ) << QString(); + QTest::newRow( "comment-story" ) << QStringLiteral( "# This is a shell comment" ) << QString(); + // We look for assignments, but only for single-words + QTest::newRow( "comment-space-eq" ) << QStringLiteral( "# Check that a = b" ) << QString(); + + + QTest::newRow( "assignment1" ) << QStringLiteral( "a=1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment2" ) << QStringLiteral( "a = 1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment3" ) << QStringLiteral( "# a=1" ) << QStringLiteral( "a" ); + QTest::newRow( "assignment4" ) << QStringLiteral( "cows = 12" ) << QStringLiteral( "cows" ); + QTest::newRow( "assignment5" ) << QStringLiteral( "# # cows=1" ) << QStringLiteral( "cows" ); + QTest::newRow( "assignment6" ) << QStringLiteral( "# moose='cool' # not cows" ) << QStringLiteral( "moose" ); + QTest::newRow( "assignment7" ) << QStringLiteral( " moose=cows=42" ) << QStringLiteral( "moose" ); +} + +void +LOSHTests::testAssignmentExtraction() +{ + QFETCH( QString, line ); + QFETCH( QString, match ); + + QCOMPARE( get_assignment_part( line ), match ); +} + +static CalamaresUtils::System* +file_setup( const QTemporaryDir& tempRoot ) +{ + CalamaresUtils::System* ss = CalamaresUtils::System::instance(); + if ( !ss ) + { + ss = new CalamaresUtils::System( true ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs ) + { + cDebug() << "Creating new JobQueue"; + (void)new Calamares::JobQueue(); + gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + } + if ( gs ) + { + // Working with a rootMountPoint set + gs->insert( "rootMountPoint", tempRoot.path() ); + } + return ss; +} + +static void +make_valid_loshinfo( LOSHInfo& i ) +{ + i.swap_outer_uuid = QStringLiteral( "UUID-0000" ); + i.swap_mapper_name = QStringLiteral( "/dev/mapper/0000" ); + i.swap_device_path = QStringLiteral( "/dev/sda0" ); + i.mountable_keyfile_device = QStringLiteral( "/dev/ada0p0s0" ); +} + +void +LOSHTests::testLOSHInfo() +{ + LOSHInfo i {}; + QVERIFY( !i.isValid() ); + + make_valid_loshinfo( i ); + QVERIFY( i.isValid() ); + QCOMPARE( i.replacementFor( QStringLiteral( "swap_device" ) ), QStringLiteral( "/dev/sda0" ) ); + QCOMPARE( i.replacementFor( QStringLiteral( "duck" ) ), QString() ); +} + + +void +LOSHTests::testConfigWriting() +{ + QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + QVERIFY( tempRoot.isValid() ); + auto* ss = file_setup( tempRoot ); + QVERIFY( ss ); + QVERIFY( Calamares::JobQueue::instance()->globalStorage() ); + QVERIFY( QFile::exists( tempRoot.path() ) ); + QVERIFY( QFileInfo(tempRoot.path()).isDir() ); + + const QString targetFilePath = QStringLiteral( "losh.conf" ); + const QString filePath = tempRoot.filePath( targetFilePath ); + QStringList contents { QStringLiteral( "# Calamares demo" ), + QStringLiteral( "# swap_device=a thing" ), + QStringLiteral( "# duck duck swap_device=another" ) }; + + // When the information is invalid, file contents are unchanged, + // and no file is written either. + LOSHInfo i {}; + QVERIFY( !i.isValid() ); + QVERIFY( !QFile::exists( filePath ) ); + write_openswap_conf( targetFilePath, contents, i ); // Invalid i + QVERIFY( !QFile::exists( filePath ) ); + QCOMPARE( contents.length(), 3 ); + QCOMPARE( contents.at( 1 ).left( 4 ), QStringLiteral( "# s" ) ); + + // Can we write there at all? + QFile derp(filePath); + QVERIFY(derp.open(QIODevice::WriteOnly)); + QVERIFY(derp.write("xx", 2)); + derp.close(); + QVERIFY(QFile::exists(filePath)); + QVERIFY(QFile::remove(filePath)); + + // Once the information is valid, though, the file is written + make_valid_loshinfo( i ); + QVERIFY( i.isValid() ); + QVERIFY( !QFile::exists( filePath ) ); + write_openswap_conf( targetFilePath, contents, i ); // Now it is valid + QVERIFY( QFile::exists( filePath ) ); + QCOMPARE( contents.length(), 3 ); + QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/sda0" ) ); // expected key value + QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/sda0" ) ); // expected line + + // readLine() returns with newlines-added + QFile f( filePath ); + QVERIFY( f.open( QIODevice::ReadOnly ) ); + QCOMPARE( f.readLine(), QStringLiteral( "# Calamares demo\n" ) ); + QCOMPARE( f.readLine(), QStringLiteral( "swap_device=/dev/sda0\n" ) ); + QCOMPARE( f.readLine(), QStringLiteral( "# duck duck swap_device=another\n" ) ); + QCOMPARE( f.readLine(), QString() ); + QVERIFY( f.atEnd() ); + + // Note how the contents is updated on every write_openswap_conf() + i.swap_device_path = QStringLiteral( "/dev/zram/0.zram" ); + write_openswap_conf( targetFilePath, contents, i ); // Still valid + QCOMPARE( contents.length(), 3 ); + QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/zram/0.zram" ) ); // expected key value + QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/zram/0.zram" ) ); // expected line +} + + +void LOSHTests::testJob() +{ + QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); + QVERIFY( tempRoot.isValid() ); + auto* ss = file_setup( tempRoot ); + QVERIFY( ss ); + + LOSHJob j; + j.setConfigurationMap(QVariantMap()); + auto jobresult = j.exec(); + QVERIFY(jobresult); + QVERIFY( QFile::exists( tempRoot.filePath( "etc/openswap.conf" ) ) ); +} + + +QTEST_GUILESS_MAIN( LOSHTests ) + #include "utils/moc-warnings.h" #include "Tests.moc" From 45d6eb36fb4396af7360acef427cfad6ff6f8c23 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 11:21:27 +0100 Subject: [PATCH 051/168] [luksopenswaphookcfg] Extend info with btrfs subvol This is a C++-ification of e8936392 from dalto8 . Add a line for options to the empty-file-fallback. --- src/modules/luksopenswaphookcfg/LOSHInfo.h | 5 +++++ src/modules/luksopenswaphookcfg/LOSHJob.cpp | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/luksopenswaphookcfg/LOSHInfo.h b/src/modules/luksopenswaphookcfg/LOSHInfo.h index 94ccba379..470b5a0cc 100644 --- a/src/modules/luksopenswaphookcfg/LOSHInfo.h +++ b/src/modules/luksopenswaphookcfg/LOSHInfo.h @@ -23,6 +23,7 @@ struct LOSHInfo QString swap_mapper_name; QString mountable_keyfile_device; QString swap_device_path; + QString keyfile_device_mount_options; bool isValid() const { return !swap_device_path.isEmpty(); } @@ -49,6 +50,10 @@ struct LOSHInfo { return QStringLiteral( "crypto_keyfile.bin" ); } + if ( key == QStringLiteral( "keyfile_device_mount_options" ) ) + { + return keyfile_device_mount_options; + } return QString(); } diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp index 986213cf5..a5e5a183a 100644 --- a/src/modules/luksopenswaphookcfg/LOSHJob.cpp +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -103,7 +103,8 @@ LOSHJob::exec() if ( contents.isEmpty() ) { contents << QStringLiteral( "# swap_device=" ) << QStringLiteral( "# crypt_swap_name=" ) - << QStringLiteral( "# keyfile_device=" ) << QStringLiteral( "# keyfile_filename=" ); + << QStringLiteral( "# keyfile_device=" ) << QStringLiteral( "# keyfile_filename=" ) + << QStringLiteral( "# keyfile_device_mount_options" ); } write_openswap_conf( m_configFilePath, contents, LOSHInfo::fromGlobalStorage() ); From 2c20a00cc366a6e4a3c9ca953bbec8ec12ed988d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Dec 2021 19:49:48 +0100 Subject: [PATCH 052/168] [luksopenswaphookcfg] Read GS for finding LUKS config --- src/modules/luksopenswaphookcfg/LOSHInfo.h | 3 +- src/modules/luksopenswaphookcfg/LOSHJob.cpp | 59 +++++++++++++++++++++ src/modules/luksopenswaphookcfg/Tests.cpp | 51 ++++++++++++++---- 3 files changed, 101 insertions(+), 12 deletions(-) diff --git a/src/modules/luksopenswaphookcfg/LOSHInfo.h b/src/modules/luksopenswaphookcfg/LOSHInfo.h index 470b5a0cc..1a87f4e61 100644 --- a/src/modules/luksopenswaphookcfg/LOSHInfo.h +++ b/src/modules/luksopenswaphookcfg/LOSHInfo.h @@ -59,9 +59,8 @@ struct LOSHInfo /** @brief Creates a struct from information already set in GS * - * TODO: implement this in LOSHJob.cpp */ - static LOSHInfo fromGlobalStorage() { return LOSHInfo {}; } + static LOSHInfo fromGlobalStorage(); }; #endif diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp index a5e5a183a..916ffcb8b 100644 --- a/src/modules/luksopenswaphookcfg/LOSHJob.cpp +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -14,6 +14,7 @@ #include "utils/Logger.h" #include "utils/Permissions.h" #include "utils/PluginFactory.h" +#include "utils/String.h" #include "utils/Variant.h" #include @@ -118,4 +119,62 @@ LOSHJob::setConfigurationMap( const QVariantMap& configurationMap ) configurationMap, QStringLiteral( "configFilePath" ), QStringLiteral( "/etc/openswap.conf" ) ); } +STATICTEST void +globalStoragePartitionInfo( Calamares::GlobalStorage* gs, LOSHInfo& info ) +{ + if ( !gs ) + { + return; + } + QVariantList l = gs->value( "partitions" ).toList(); + if ( l.isEmpty() ) + { + return; + } + + for ( const auto& pv : l ) + { + const QVariantMap partition = pv.toMap(); + if ( !partition.isEmpty() ) + { + QString mountPoint = partition.value( "mountPoint" ).toString(); + QString fileSystem = partition.value( "fs" ).toString(); + QString luksMapperName = partition.value( "luksMapperName" ).toString(); + // if partition["fs"] == "linuxswap" and "luksMapperName" in partition: + if ( fileSystem == QStringLiteral( "linuxswap" ) && !luksMapperName.isEmpty() ) + { + info.swap_outer_uuid = partition.value( "luksUuid" ).toString(); + info.swap_mapper_name = luksMapperName; + } + else if ( mountPoint == QStringLiteral( "/" ) && !luksMapperName.isEmpty() ) + { + + info.mountable_keyfile_device = QStringLiteral( "/dev/mapper/" ) + luksMapperName; + } + } + } + + if ( !info.mountable_keyfile_device.isEmpty() && !info.swap_outer_uuid.isEmpty() ) + { + info.swap_device_path = QStringLiteral( "/dev/disk/by-uuid/" ) + info.swap_outer_uuid; + } + + QString btrfsRootSubvolume = gs->value( "btrfsRootSubvolume" ).toString(); + if ( !btrfsRootSubvolume.isEmpty() ) + { + CalamaresUtils::removeLeading( btrfsRootSubvolume, '/' ); + info.keyfile_device_mount_options + = QStringLiteral( "keyfile_device_mount_options=--options=subvol=" ) + btrfsRootSubvolume; + } +} + +LOSHInfo +LOSHInfo::fromGlobalStorage() +{ + LOSHInfo i {}; + globalStoragePartitionInfo( + Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr, i ); + return i; +} + CALAMARES_PLUGIN_FACTORY_DEFINITION( LOSHJobFactory, registerPlugin< LOSHJob >(); ) diff --git a/src/modules/luksopenswaphookcfg/Tests.cpp b/src/modules/luksopenswaphookcfg/Tests.cpp index 0cb79d7b9..7ec623eaa 100644 --- a/src/modules/luksopenswaphookcfg/Tests.cpp +++ b/src/modules/luksopenswaphookcfg/Tests.cpp @@ -140,7 +140,7 @@ LOSHTests::testConfigWriting() QVERIFY( ss ); QVERIFY( Calamares::JobQueue::instance()->globalStorage() ); QVERIFY( QFile::exists( tempRoot.path() ) ); - QVERIFY( QFileInfo(tempRoot.path()).isDir() ); + QVERIFY( QFileInfo( tempRoot.path() ).isDir() ); const QString targetFilePath = QStringLiteral( "losh.conf" ); const QString filePath = tempRoot.filePath( targetFilePath ); @@ -159,12 +159,12 @@ LOSHTests::testConfigWriting() QCOMPARE( contents.at( 1 ).left( 4 ), QStringLiteral( "# s" ) ); // Can we write there at all? - QFile derp(filePath); - QVERIFY(derp.open(QIODevice::WriteOnly)); - QVERIFY(derp.write("xx", 2)); + QFile derp( filePath ); + QVERIFY( derp.open( QIODevice::WriteOnly ) ); + QVERIFY( derp.write( "xx", 2 ) ); derp.close(); - QVERIFY(QFile::exists(filePath)); - QVERIFY(QFile::remove(filePath)); + QVERIFY( QFile::exists( filePath ) ); + QVERIFY( QFile::remove( filePath ) ); // Once the information is valid, though, the file is written make_valid_loshinfo( i ); @@ -194,18 +194,49 @@ LOSHTests::testConfigWriting() } -void LOSHTests::testJob() +void +LOSHTests::testJob() { QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) ); QVERIFY( tempRoot.isValid() ); auto* ss = file_setup( tempRoot ); QVERIFY( ss ); + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + QVERIFY( gs ); + + { + QDir d( tempRoot.path() ); + d.mkdir( "etc" ); + } + + QVERIFY( !LOSHInfo::fromGlobalStorage().isValid() ); + QVariantList outerPartition; + QVariantMap innerPartition; + innerPartition.insert( "mountPoint", "/" ); + innerPartition.insert( "fs", "ext4" ); + innerPartition.insert( "luksMapperName", "root" ); + innerPartition.insert( "luksUUID", "0000" ); + outerPartition.append( innerPartition ); + innerPartition.remove( "mountPoint" ); + innerPartition.insert( "fs", "linuxswap" ); + innerPartition.insert( "luksMapperName", "swap" ); + innerPartition.insert( "luksUuid", "0001" ); + outerPartition.append( innerPartition ); + gs->insert( "partitions", outerPartition ); + QVERIFY( LOSHInfo::fromGlobalStorage().isValid() ); LOSHJob j; - j.setConfigurationMap(QVariantMap()); + j.setConfigurationMap( QVariantMap() ); auto jobresult = j.exec(); - QVERIFY(jobresult); - QVERIFY( QFile::exists( tempRoot.filePath( "etc/openswap.conf" ) ) ); + QVERIFY( jobresult ); + + { + QFile f( tempRoot.filePath( "etc/openswap.conf" ) ); + QVERIFY( f.exists() ); + QVERIFY( f.open( QIODevice::ReadOnly ) ); + cDebug() << f.readAll(); + } } From 046a228d62dc2623384056ecd610dd5f53355b92 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 14:25:03 +0100 Subject: [PATCH 053/168] [luksopenswaphookcfg] Expand tests with lines more-closely tailored to the actual file-format --- src/modules/luksopenswaphookcfg/Tests.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/luksopenswaphookcfg/Tests.cpp b/src/modules/luksopenswaphookcfg/Tests.cpp index 7ec623eaa..840bd9355 100644 --- a/src/modules/luksopenswaphookcfg/Tests.cpp +++ b/src/modules/luksopenswaphookcfg/Tests.cpp @@ -73,6 +73,12 @@ LOSHTests::testAssignmentExtraction_data() QTest::newRow( "assignment5" ) << QStringLiteral( "# # cows=1" ) << QStringLiteral( "cows" ); QTest::newRow( "assignment6" ) << QStringLiteral( "# moose='cool' # not cows" ) << QStringLiteral( "moose" ); QTest::newRow( "assignment7" ) << QStringLiteral( " moose=cows=42" ) << QStringLiteral( "moose" ); + QTest::newRow( "assignment8" ) << QStringLiteral( "#swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); + QTest::newRow( "assignment9" ) << QStringLiteral( "# swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); + QTest::newRow( "assignment10" ) << QStringLiteral( "swap_device=/dev/something" ) + << QStringLiteral( "swap_device" ); } void From 3870851074fff8c1b9d775627dac09180ac452be Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 14:35:52 +0100 Subject: [PATCH 054/168] [luksopenswaphookcfg] Remove Python implementation --- src/modules/luksopenswaphookcfg/main.py | 100 ------------------------ 1 file changed, 100 deletions(-) delete mode 100644 src/modules/luksopenswaphookcfg/main.py diff --git a/src/modules/luksopenswaphookcfg/main.py b/src/modules/luksopenswaphookcfg/main.py deleted file mode 100644 index aaac8a31a..000000000 --- a/src/modules/luksopenswaphookcfg/main.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# === This file is part of Calamares - === -# -# SPDX-FileCopyrightText: 2016 Teo Mrnjavac -# SPDX-FileCopyrightText: 2017 Alf Gaida -# SPDX-FileCopyrightText: 2019 Adriaan de Groot -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Calamares is Free Software: see the License-Identifier above. -# - -import libcalamares -import os.path - - -import gettext -_ = gettext.translation("calamares-python", - localedir=libcalamares.utils.gettext_path(), - languages=libcalamares.utils.gettext_languages(), - fallback=True).gettext - - -def pretty_name(): - return _("Configuring encrypted swap.") - - -def write_openswap_conf(partitions, root_mount_point, openswap_conf_path): - swap_outer_uuid = "" - swap_mapper_name = "" - mountable_keyfile_device = "" - - for partition in partitions: - if partition["fs"] == "linuxswap" and "luksMapperName" in partition: - swap_outer_uuid = partition["luksUuid"] - swap_mapper_name = partition["luksMapperName"] - - elif partition["mountPoint"] == "/" and "luksMapperName" in partition: - mountable_keyfile_device = ( - "/dev/mapper/{!s}".format(partition["luksMapperName"]) - ) - - if not mountable_keyfile_device or not swap_outer_uuid: - return None - - swap_device_path = "/dev/disk/by-uuid/{!s}".format(swap_outer_uuid) - - lines = [] - with open(os.path.join(root_mount_point, - openswap_conf_path), 'r') as openswap_file: - lines = [x.strip() for x in openswap_file.readlines()] - - for i in range(len(lines)): - if lines[i].startswith("swap_device"): - lines[i] = "swap_device={!s}".format(swap_device_path) - - elif lines[i].startswith("crypt_swap_name"): - lines[i] = "crypt_swap_name={!s}".format(swap_mapper_name) - - elif lines[i].startswith("keyfile_device"): - lines[i] = "keyfile_device={!s}".format(mountable_keyfile_device) - - elif lines[i].startswith("keyfile_filename"): - lines[i] = "keyfile_filename=crypto_keyfile.bin" - - elif lines[i].startswith("#keyfile_device_mount_options"): - if libcalamares.globalstorage.contains("btrfsRootSubvolume"): - btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume") - lines[i] = "keyfile_device_mount_options=--options=subvol=" + btrfs_root_subvolume.lstrip("/") - - with open(os.path.join(root_mount_point, - openswap_conf_path), 'w') as openswap_file: - openswap_file.write("\n".join(lines) + "\n") - - return None - - -def run(): - """ - This module sets up the openswap hook for a resumable encrypted swap. - :return: - """ - - root_mount_point = libcalamares.globalstorage.value("rootMountPoint") - openswap_conf_path = libcalamares.job.configuration["configFilePath"] - partitions = libcalamares.globalstorage.value("partitions") - - if not partitions: - libcalamares.utils.warning("partitions is empty, {!s}".format(partitions)) - return (_("Configuration Error"), - _("No partitions are defined for
{!s}
to use.").format("luksopenswaphookcfg")) - if not root_mount_point: - libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point)) - return (_("Configuration Error"), - _("No root mount point is given for
{!s}
to use.").format("luksopenswaphookcfg")) - - openswap_conf_path = openswap_conf_path.lstrip('/') - - return write_openswap_conf(partitions, root_mount_point, openswap_conf_path) From b4afedc79e49fc678ba23d5d93a18756a89c2593 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 10 Dec 2021 15:46:11 +0100 Subject: [PATCH 055/168] Changes: pre-release housekeeping --- CHANGES-3.2 | 4 +++- CMakeLists.txt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 566a61ed9..cb342ed53 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,7 +7,7 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.49 (unreleased) # +# 3.2.49 (2021-12-10) # This release contains contributions from (alphabetically by first name): - Artem Grinev @@ -22,6 +22,8 @@ configuration (and to use *preservefiles* if needed). to the size of the screen. (Thanks Artem) ## Modules ## + - *bootloader* better supports multiple installations of the same OS. + - *mount* supports btrfs subvolumes on subdirectories of / now. - *partition* now supports "deep" btrfs subvolume names, e.g. a separate subvolume for `/usr/local`. (Thanks Evan) - The *umount* module now warns if the "preserve log file" feature is used. diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a55eae1c..03dfdad22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ project( CALAMARES LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 3cdb019de7f2ad6c5cfa92a39a70212a3a3ec42a Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 10 Dec 2021 15:55:58 +0100 Subject: [PATCH 056/168] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_sv.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/calamares_sv.ts b/lang/calamares_sv.ts index 64946e710..bd6add603 100644 --- a/lang/calamares_sv.ts +++ b/lang/calamares_sv.ts @@ -703,7 +703,7 @@ Alla ändringar kommer att gå förlorade. Successfully closed mapper device %1. - + Framgångsrikt stängde krypterad enhet %1. From 7ac42b5f4060f97dc560891d4a3178feb7c41362 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 10 Dec 2021 16:44:01 +0100 Subject: [PATCH 057/168] [umount] Tests don't like an empty config - modules with no configuration should be marked 'noconfig', but umount is special: it has no **useful** configuration (maybe no **non-deprecated** configuration), but isn't marked 'noconfig' **yet**. --- src/modules/umount/umount.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 062f7ac4b..7c11f4db6 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -27,3 +27,4 @@ # example when using a log created by `sudo calamares -d`: #srcLog: "/home/live/installation.log" #destLog: "/var/log/installation.log" +srcLog: "/bogus/just/do/not/use/this/anymore.txt" From adaed528183fb4f245c374cd5b535b850ae10944 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 10 Dec 2021 17:01:42 +0100 Subject: [PATCH 058/168] Changes: post-release housekeeping --- CHANGES-3.2 | 12 ++++++++++++ CMakeLists.txt | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index cb342ed53..5f032ab58 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,6 +7,18 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. +# 3.2.50 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - No external contributors yet + +## Core ## + - No core changes yet + +## Modules ## + - No module changes yet + + # 3.2.49 (2021-12-10) # This release contains contributions from (alphabetically by first name): diff --git a/CMakeLists.txt b/CMakeLists.txt index 03dfdad22..15f40803e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.49 + VERSION 3.2.50 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 03da766b396d57d6dc050ee1c5c25e5d1a73f862 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 13:19:08 +0100 Subject: [PATCH 059/168] [partition] Keep 64-bit integers for swap sizes FIXES #1849 --- src/modules/partition/core/PartitionActions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 8226499b4..a56446a39 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -71,7 +71,7 @@ swapSuggestion( const qint64 availableSpaceB, Config::SwapChoice swap ) // Allow for a fudge factor - suggestedSwapSizeB = qRound( suggestedSwapSizeB * overestimationFactor ); + suggestedSwapSizeB = qRound64( suggestedSwapSizeB * overestimationFactor ); // don't use more than 10% of available space if ( !ensureSuspendToDisk ) From db86c2463858efae726178860183c2d8dfb5ded0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 13:23:23 +0100 Subject: [PATCH 060/168] Changes: pre-hotfix-release housekeeping --- CHANGES-3.2 | 12 +++--------- CMakeLists.txt | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 5f032ab58..bd04ee64c 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,16 +7,10 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.50 (unreleased) # +# 3.2.49.1 (2021-12-11) # -This release contains contributions from (alphabetically by first name): - - No external contributors yet - -## Core ## - - No core changes yet - -## Modules ## - - No module changes yet +This is a hot-fix release, to fix a regression in the calculation of +swap-size. Reported by EndeavourOS (Joe Kamprad) and Xero Linux. # 3.2.49 (2021-12-10) # diff --git a/CMakeLists.txt b/CMakeLists.txt index 15f40803e..5ad72ae47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.50 + VERSION 3.2.49.1 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 1a1c1eb6dde4d3980cbc1f7774ed4fb012bc2759 Mon Sep 17 00:00:00 2001 From: Artem Grinev Date: Sat, 11 Dec 2021 13:30:17 +0000 Subject: [PATCH 061/168] [fstab] Remove additional ssd options for btrfs --- src/modules/fstab/fstab.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index 7110c5a5f..1e87acddc 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -55,7 +55,7 @@ efiMountOptions: umask=0077 # The standard configuration applies asynchronous discard support and ssd optimizations to btrfs # and does nothing for other filesystems. ssdExtraMountOptions: - btrfs: discard=async,ssd,commit=120 + btrfs: discard=async # Additional options added to each line in /etc/crypttab crypttabOptions: luks From 132ebd2c2dfbab92c2b4b1d8e072f51f79ebc025 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 15:12:51 +0100 Subject: [PATCH 062/168] [networkcfg] NetworkManager files are UTF-8 encoded The filenames don't matter, but the contents of the file are also UTF-8, and depending on the default encoding of the Python interpreter, this can fail on non-ASCII characters in the file. Set the encoding explicitly while reading and writing the NetworkManager configuration files. FIXES #1848 --- src/modules/networkcfg/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/networkcfg/main.py b/src/modules/networkcfg/main.py index 0ee47c1aa..807fdf613 100644 --- a/src/modules/networkcfg/main.py +++ b/src/modules/networkcfg/main.py @@ -73,12 +73,12 @@ def replace_username(nm_config_filename, live_user, target_user): if not os.path.exists(nm_config_filename): return - with open(nm_config_filename, "r") as network_conf: + with open(nm_config_filename, "r", encoding="UTF-8") as network_conf: text = network_conf.readlines() live_permissions = 'permissions=user:{}:;'.format(live_user) target_permissions = 'permissions=user:{}:;\n'.format(target_user) - with open(nm_config_filename, "w") as network_conf: + with open(nm_config_filename, "w", encoding="UTF-8") as network_conf: for line in text: if live_permissions in line: line = target_permissions From 6261f8a5cb420e38521f2cb4aeb78009e1f79de7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 15:31:59 +0100 Subject: [PATCH 063/168] Changes: post-release housekeeping --- CHANGES-3.2 | 15 +++++++++++++++ CMakeLists.txt | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index bd04ee64c..cca35f9e7 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,6 +7,21 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. +# 3.2.50 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - No external contributors yet + +## Core ## + - No core changes yet + +## Modules ## + - *networkcfg* could fail to update the NetworkManager configuration + if the SSID or username contained non-ASCII characters **and** the + default Python text-file encoding was set to ASCII. The files are + now read and written in UTF-8, explicitly. #1848 + + # 3.2.49.1 (2021-12-11) # This is a hot-fix release, to fix a regression in the calculation of diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ad72ae47..15f40803e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.49.1 + VERSION 3.2.50 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 5b225cf960e9c948f590f3c3f4d8775ad073cdf5 Mon Sep 17 00:00:00 2001 From: arcolinuxz Date: Sat, 11 Dec 2021 18:11:45 +0100 Subject: [PATCH 064/168] [preservefiles] Put the logs in /var/log --- CHANGES-3.2 | 2 +- src/modules/preservefiles/preservefiles.conf | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index cca35f9e7..93231b57a 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -10,7 +10,7 @@ website will have to do for older versions. # 3.2.50 (unreleased) # This release contains contributions from (alphabetically by first name): - - No external contributors yet + - Erik Dubois ## Core ## - No core changes yet diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index 6af0872d7..d862e35e9 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -34,15 +34,13 @@ # - *log*, for the complete log file (up to the moment the preservefiles # module is run), # - *config*, for a JSON dump of the contents of global storage ---- files: - - /etc/oem-information - from: log - dest: /root/install.log - perm: root:wheel:644 + dest: /var/log/Calamares.log + perm: root:wheel:600 - from: config - dest: /root/install.json - perm: root:wheel:400 + dest: /var/log/Camamares-install.json + perm: root:wheel:600 # The *perm* key contains a default value to apply to all files listed # above that do not have a *perm* key of their own. If not set, From becb1d57103eb0f423404f6e91ac6c14f119ba4d Mon Sep 17 00:00:00 2001 From: Johannes Kamprad Date: Sun, 12 Dec 2021 01:22:22 +0100 Subject: [PATCH 065/168] Update preservefiles.conf --- src/modules/preservefiles/preservefiles.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index d862e35e9..1c23a93de 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -39,7 +39,7 @@ files: dest: /var/log/Calamares.log perm: root:wheel:600 - from: config - dest: /var/log/Camamares-install.json + dest: /var/log/Calamares-install.json perm: root:wheel:600 # The *perm* key contains a default value to apply to all files listed From b1ecbb4151f22a74be4b4997dbbafbc77ef8b9ba Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 12 Dec 2021 00:33:55 +0100 Subject: [PATCH 066/168] [preservefiles] Start cleanup of structure, polymorphism --- src/modules/preservefiles/PreserveFiles.cpp | 51 +++++++++++++++------ src/modules/preservefiles/PreserveFiles.h | 25 ++-------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/modules/preservefiles/PreserveFiles.cpp b/src/modules/preservefiles/PreserveFiles.cpp index b235aac93..d46563185 100644 --- a/src/modules/preservefiles/PreserveFiles.cpp +++ b/src/modules/preservefiles/PreserveFiles.cpp @@ -18,6 +18,30 @@ #include +enum class ItemType +{ + None, + Path, + Log, + Config +}; + +struct Item +{ + QString source; + QString dest; + CalamaresUtils::Permissions perm; + ItemType type; + + Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t ) + : source( src ) + , dest( d ) + , perm( std::move( p ) ) + , type( t ) + { + } +}; + using namespace CalamaresUtils::Units; QString @@ -113,7 +137,7 @@ copy_file( const QString& source, const QString& dest ) Calamares::JobResult PreserveFiles::exec() { - if ( m_items.isEmpty() ) + if ( m_items.empty() ) { return Calamares::JobResult::error( tr( "No files configured to save for later." ) ); } @@ -124,18 +148,18 @@ PreserveFiles::exec() prefix.append( '/' ); } - int count = 0; - for ( const auto& it : m_items ) + size_t count = 0; + for ( const auto& it : qAsConst( m_items ) ) { - QString source = it.source; - QString bare_dest = atReplacements( it.dest ); + QString source = it->source; + QString bare_dest = atReplacements( it->dest ); QString dest = prefix + bare_dest; - if ( it.type == ItemType::Log ) + if ( it->type == ItemType::Log ) { source = Logger::logFile(); } - if ( it.type == ItemType::Config ) + if ( it->type == ItemType::Config ) { if ( !Calamares::JobQueue::instance()->globalStorage()->saveJson( dest ) ) { @@ -154,9 +178,9 @@ PreserveFiles::exec() { if ( copy_file( source, dest ) ) { - if ( it.perm.isValid() ) + if ( it->perm.isValid() ) { - if ( !it.perm.apply( CalamaresUtils::System::instance()->targetPath( bare_dest ) ) ) + if ( !it->perm.apply( CalamaresUtils::System::instance()->targetPath( bare_dest ) ) ) { cWarning() << "Could not set attributes of" << bare_dest; } @@ -167,7 +191,7 @@ PreserveFiles::exec() } } - return count == m_items.count() + return count == m_items.size() ? Calamares::JobResult::ok() : Calamares::JobResult::error( tr( "Not all of the configured files could be preserved." ) ); } @@ -202,8 +226,8 @@ PreserveFiles::setConfigurationMap( const QVariantMap& configurationMap ) { QString filename = li.toString(); if ( !filename.isEmpty() ) - m_items.append( - Item { filename, filename, CalamaresUtils::Permissions( defaultPermissions ), ItemType::Path } ); + m_items.push_back( std::make_unique< Item >( + filename, filename, CalamaresUtils::Permissions( defaultPermissions ), ItemType::Path ) ); else { cDebug() << "Empty filename for preservefiles, item" << c; @@ -231,7 +255,8 @@ PreserveFiles::setConfigurationMap( const QVariantMap& configurationMap ) } else { - m_items.append( Item { QString(), dest, CalamaresUtils::Permissions( perm ), t } ); + m_items.push_back( + std::make_unique< Item >( QString(), dest, CalamaresUtils::Permissions( perm ), t ) ); } } else diff --git a/src/modules/preservefiles/PreserveFiles.h b/src/modules/preservefiles/PreserveFiles.h index 7a0aab34d..a54005254 100644 --- a/src/modules/preservefiles/PreserveFiles.h +++ b/src/modules/preservefiles/PreserveFiles.h @@ -13,31 +13,16 @@ #include "utils/Permissions.h" #include "utils/PluginFactory.h" -#include -#include -#include +#include +#include + +struct Item; class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob { Q_OBJECT - enum class ItemType - { - None, - Path, - Log, - Config - }; - - struct Item - { - QString source; - QString dest; - CalamaresUtils::Permissions perm; - ItemType type; - }; - - using ItemList = QList< Item >; + using ItemList = std::vector< std::unique_ptr< Item > >; public: explicit PreserveFiles( QObject* parent = nullptr ); From 238672ef78a43e4261bedf2ac419c3f0ac606952 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 13:00:28 +0100 Subject: [PATCH 067/168] [preservefiles] Split file-items into separate header Put the Item class in a separate header; give it functionality to create itself from Variants (e.g. from the configuration data) and to run itself (do whatever the item is supposed to do). This makes the polymorphic approach unnecessary: we just have items that are sufficiently smart. This moves do-a-thing to the Item, while the Job now has one job: be a loop around creating Items and running items. --- src/modules/preservefiles/CMakeLists.txt | 1 + src/modules/preservefiles/Item.cpp | 160 +++++++++++++++++ src/modules/preservefiles/Item.h | 72 ++++++++ src/modules/preservefiles/PreserveFiles.cpp | 184 ++------------------ src/modules/preservefiles/PreserveFiles.h | 8 +- 5 files changed, 249 insertions(+), 176 deletions(-) create mode 100644 src/modules/preservefiles/Item.cpp create mode 100644 src/modules/preservefiles/Item.h diff --git a/src/modules/preservefiles/CMakeLists.txt b/src/modules/preservefiles/CMakeLists.txt index 820c50a2b..e5cbe819c 100644 --- a/src/modules/preservefiles/CMakeLists.txt +++ b/src/modules/preservefiles/CMakeLists.txt @@ -9,6 +9,7 @@ calamares_add_plugin( preservefiles TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES + Item.cpp PreserveFiles.cpp # REQUIRES mount # To set the rootMountPoint SHARED_LIB diff --git a/src/modules/preservefiles/Item.cpp b/src/modules/preservefiles/Item.cpp new file mode 100644 index 000000000..bc2357876 --- /dev/null +++ b/src/modules/preservefiles/Item.cpp @@ -0,0 +1,160 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2018, 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ + +#include "Item.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" +#include "utils/Units.h" + +#include + +using namespace CalamaresUtils::Units; + +static bool +copy_file( const QString& source, const QString& dest ) +{ + QFile sourcef( source ); + if ( !sourcef.open( QFile::ReadOnly ) ) + { + cWarning() << "Could not read" << source; + return false; + } + + QFile destf( dest ); + if ( !destf.open( QFile::WriteOnly ) ) + { + sourcef.close(); + cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source; + return false; + } + + QByteArray b; + do + { + b = sourcef.read( 1_MiB ); + destf.write( b ); + } while ( b.count() > 0 ); + + sourcef.close(); + destf.close(); + + return true; +} + +Item +Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& defaultPermissions ) +{ + if ( v.type() == QVariant::String ) + { + QString filename = v.toString(); + if ( !filename.isEmpty() ) + { + return { filename, filename, defaultPermissions, ItemType::Path }; + } + else + { + cWarning() << "Empty filename for preservefiles, item" << v; + return {}; + } + } + else if ( v.type() == QVariant::Map ) + { + const auto map = v.toMap(); + + CalamaresUtils::Permissions perm( defaultPermissions ); + ItemType t = ItemType::None; + + { + QString perm_string = map[ "perm" ].toString(); + if ( !perm_string.isEmpty() ) + { + perm = CalamaresUtils::Permissions( perm_string ); + } + } + + { + QString from = map[ "from" ].toString(); + t = ( from == "log" ) ? ItemType::Log : ( from == "config" ) ? ItemType::Config : ItemType::None; + + if ( t == ItemType::None && !map[ "src" ].toString().isEmpty() ) + { + t = ItemType::Path; + } + } + + QString dest = map[ "dest" ].toString(); + if ( dest.isEmpty() ) + { + cWarning() << "Empty dest for preservefiles, item" << v; + return {}; + } + + switch ( t ) + { + case ItemType::Config: + return { QString(), dest, perm, t }; + case ItemType::Log: + return { QString(), dest, perm, t }; + case ItemType::Path: + return { map[ "src" ].toString(), dest, perm, t }; + case ItemType::None: + cWarning() << "Invalid type for preservefiles, item" << v; + return {}; + } + } + else + { + cWarning() << "Invalid type for preservefiles, item" << v; + return {}; + } +} + + +bool +Item::exec( const std::function< QString( QString ) >& replacements ) const +{ + QString expanded_dest = replacements( dest ); + QString full_dest = CalamaresUtils::System::instance()->targetPath( expanded_dest ); + + bool success = false; + switch ( type ) + { + case ItemType::None: + cWarning() << "Invalid item for preservefiles skipped."; + return false; + case ItemType::Config: + if ( !( success = Calamares::JobQueue::instance()->globalStorage()->saveJson( full_dest ) ) ) + { + cWarning() << "Could not write a JSON dump of global storage to" << full_dest; + } + break; + case ItemType::Log: + if ( !( success = copy_file( Logger::logFile(), full_dest ) ) ) + { + cWarning() << "Could not preserve log file to" << full_dest; + } + break; + case ItemType::Path: + if ( !( success = copy_file( source, full_dest ) ) ) + { + cWarning() << "Could not preserve" << source << "to" << full_dest; + } + break; + } + if ( !success ) + { + CalamaresUtils::System::instance()->removeTargetFile( expanded_dest ); + return false; + } + else + { + return perm.apply( full_dest ); + } +} diff --git a/src/modules/preservefiles/Item.h b/src/modules/preservefiles/Item.h new file mode 100644 index 000000000..cd15e2042 --- /dev/null +++ b/src/modules/preservefiles/Item.h @@ -0,0 +1,72 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2018, 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + */ +#ifndef PRESERVEFILES_ITEM_H +#define PRESERVEFILES_ITEM_H + +#include "utils/Permissions.h" + +#include +#include + +#include + +enum class ItemType +{ + None, + Path, + Log, + Config +}; + +/** @brief Represents one item to copy + * + * All item types need a destination (to place the data), this is + * intepreted within the target system. All items need a permission, + * which is applied to the data once written. + * + * The source may be a path, but not all types need a source. + */ +class Item +{ + QString source; + QString dest; + CalamaresUtils::Permissions perm; + ItemType type; + +public: + Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t ) + : source( src ) + , dest( d ) + , perm( std::move( p ) ) + , type( t ) + { + } + + Item() + : type( ItemType::None ) + { + } + + operator bool() const { return type != ItemType::None; } + + bool exec( const std::function< QString( QString ) >& replacements ) const; + + + /** @brief Create an Item -- or one of its subclasses -- from @p v + * + * Depending on the structure and contents of @p v, a pointer + * to an Item is returned. If @p v cannot be interpreted meaningfully, + * then a nullptr is returned. + * + * When the entry contains a *perm* key, use that permission, otherwise + * apply @p defaultPermissions to the item. + */ + static Item fromVariant( const QVariant& v, const CalamaresUtils::Permissions& defaultPermissions ); +}; + + +#endif diff --git a/src/modules/preservefiles/PreserveFiles.cpp b/src/modules/preservefiles/PreserveFiles.cpp index d46563185..4adde85bb 100644 --- a/src/modules/preservefiles/PreserveFiles.cpp +++ b/src/modules/preservefiles/PreserveFiles.cpp @@ -7,70 +7,20 @@ #include "PreserveFiles.h" +#include "Item.h" + #include "CalamaresVersion.h" #include "GlobalStorage.h" #include "JobQueue.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/CommandList.h" #include "utils/Logger.h" -#include "utils/Permissions.h" #include "utils/Units.h" #include -enum class ItemType -{ - None, - Path, - Log, - Config -}; - -struct Item -{ - QString source; - QString dest; - CalamaresUtils::Permissions perm; - ItemType type; - - Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t ) - : source( src ) - , dest( d ) - , perm( std::move( p ) ) - , type( t ) - { - } -}; - using namespace CalamaresUtils::Units; -QString -targetPrefix() -{ - if ( CalamaresUtils::System::instance()->doChroot() ) - { - Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - if ( gs && gs->contains( "rootMountPoint" ) ) - { - QString r = gs->value( "rootMountPoint" ).toString(); - if ( !r.isEmpty() ) - { - return r; - } - else - { - cDebug() << "RootMountPoint is empty"; - } - } - else - { - cDebug() << "No rootMountPoint defined, preserving files to '/'"; - } - } - - return QLatin1String( "/" ); -} - QString atReplacements( QString s ) { @@ -103,37 +53,6 @@ PreserveFiles::prettyName() const return tr( "Saving files for later ..." ); } -static bool -copy_file( const QString& source, const QString& dest ) -{ - QFile sourcef( source ); - if ( !sourcef.open( QFile::ReadOnly ) ) - { - cWarning() << "Could not read" << source; - return false; - } - - QFile destf( dest ); - if ( !destf.open( QFile::WriteOnly ) ) - { - sourcef.close(); - cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source; - return false; - } - - QByteArray b; - do - { - b = sourcef.read( 1_MiB ); - destf.write( b ); - } while ( b.count() > 0 ); - - sourcef.close(); - destf.close(); - - return true; -} - Calamares::JobResult PreserveFiles::exec() { @@ -142,52 +61,20 @@ PreserveFiles::exec() return Calamares::JobResult::error( tr( "No files configured to save for later." ) ); } - QString prefix = targetPrefix(); - if ( !prefix.endsWith( '/' ) ) - { - prefix.append( '/' ); - } - - size_t count = 0; + int count = 0; for ( const auto& it : qAsConst( m_items ) ) { - QString source = it->source; - QString bare_dest = atReplacements( it->dest ); - QString dest = prefix + bare_dest; - - if ( it->type == ItemType::Log ) + if ( !it ) { - source = Logger::logFile(); + // Invalid entries are nullptr, ignore them but count as a success + // because they shouldn't block the installation. There are + // warnings in the log showing what the configuration problem is. + ++count; + continue; } - if ( it->type == ItemType::Config ) + if ( it.exec( atReplacements ) ) { - if ( !Calamares::JobQueue::instance()->globalStorage()->saveJson( dest ) ) - { - cWarning() << "Could not write a JSON dump of global storage to" << dest; - } - else - { - ++count; - } - } - else if ( source.isEmpty() ) - { - cWarning() << "Skipping unnamed source file for" << dest; - } - else - { - if ( copy_file( source, dest ) ) - { - if ( it->perm.isValid() ) - { - if ( !it->perm.apply( CalamaresUtils::System::instance()->targetPath( bare_dest ) ) ) - { - cWarning() << "Could not set attributes of" << bare_dest; - } - } - - ++count; - } + ++count; } } @@ -217,54 +104,11 @@ PreserveFiles::setConfigurationMap( const QVariantMap& configurationMap ) { defaultPermissions = QStringLiteral( "root:root:0400" ); } + CalamaresUtils::Permissions perm( defaultPermissions ); - QVariantList l = files.toList(); - unsigned int c = 0; - for ( const auto& li : l ) + for ( const auto& li : files.toList() ) { - if ( li.type() == QVariant::String ) - { - QString filename = li.toString(); - if ( !filename.isEmpty() ) - m_items.push_back( std::make_unique< Item >( - filename, filename, CalamaresUtils::Permissions( defaultPermissions ), ItemType::Path ) ); - else - { - cDebug() << "Empty filename for preservefiles, item" << c; - } - } - else if ( li.type() == QVariant::Map ) - { - const auto map = li.toMap(); - QString dest = map[ "dest" ].toString(); - QString from = map[ "from" ].toString(); - ItemType t = ( from == "log" ) ? ItemType::Log : ( from == "config" ) ? ItemType::Config : ItemType::None; - QString perm = map[ "perm" ].toString(); - if ( perm.isEmpty() ) - { - perm = defaultPermissions; - } - - if ( dest.isEmpty() ) - { - cDebug() << "Empty dest for preservefiles, item" << c; - } - else if ( t == ItemType::None ) - { - cDebug() << "Invalid type for preservefiles, item" << c; - } - else - { - m_items.push_back( - std::make_unique< Item >( QString(), dest, CalamaresUtils::Permissions( perm ), t ) ); - } - } - else - { - cDebug() << "Invalid type for preservefiles, item" << c; - } - - ++c; + m_items.push_back( Item::fromVariant( li, perm ) ); } } diff --git a/src/modules/preservefiles/PreserveFiles.h b/src/modules/preservefiles/PreserveFiles.h index a54005254..dfd2804e3 100644 --- a/src/modules/preservefiles/PreserveFiles.h +++ b/src/modules/preservefiles/PreserveFiles.h @@ -10,19 +10,15 @@ #include "CppJob.h" #include "DllMacro.h" -#include "utils/Permissions.h" #include "utils/PluginFactory.h" -#include -#include - -struct Item; +class Item; class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob { Q_OBJECT - using ItemList = std::vector< std::unique_ptr< Item > >; + using ItemList = QList< Item >; public: explicit PreserveFiles( QObject* parent = nullptr ); From 90f6ea1fc834eeb6d3ccde7539b1f9ce0830e273 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 14:51:42 +0100 Subject: [PATCH 068/168] [preservefiles] polish the documentation --- src/modules/preservefiles/preservefiles.conf | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index 1c23a93de..2853ac037 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -11,8 +11,9 @@ # is true, then these items are ignored (since the destination is the same # as the source). # - a map with a *dest* key. The *dest* value is a path interpreted in the -# target system (if dontChroot is true, in the host system). Relative paths -# are not recommended. There are three possible other keys in the map: +# target system (if the global *dontChroot* is true, then the host is the +# target as well). Relative paths are not recommended. There are three +# possible other keys in the map: # - *from*, which must have one of the values, below; it is used to # preserve files whose pathname is known to Calamares internally. # - *src*, to refer to a path interpreted in the host system. Relative @@ -23,17 +24,23 @@ # by owner). If set, the file's ownership and permissions are set to # those values within the target system; if not set, no permissions # are changed. -# Only one of the two source keys (either *from* or *src*) may be set. +# Exactly one of the two source keys (either *from* or *src*) must be set. # -# The target filename is modified as follows: -# - `@@ROOT@@` is replaced by the path to the target root (may be /) +# The target path (*dest*) is modified as follows: +# - `@@ROOT@@` is replaced by the path to the target root (may be /). +# There is never any reason to use this, since the *dest* is already +# interpreted in the target system. # - `@@USER@@` is replaced by the username entered by on the user # page (may be empty, for instance if no user page is enabled) # # Special values for the key *from* are: # - *log*, for the complete log file (up to the moment the preservefiles # module is run), -# - *config*, for a JSON dump of the contents of global storage +# - *config*, for a JSON dump of the contents of global storage. +# Note that this may contain sensitive information, and should be +# given restrictive permissions. +# +# files: - from: log dest: /var/log/Calamares.log From 8b5e49d9806b2c9fbfc5149a7e0107bceabfa40b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 15:04:23 +0100 Subject: [PATCH 069/168] [preservefiles] Add (stub) tests --- src/modules/preservefiles/CMakeLists.txt | 9 ++- src/modules/preservefiles/Tests.cpp | 70 ++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 src/modules/preservefiles/Tests.cpp diff --git a/src/modules/preservefiles/CMakeLists.txt b/src/modules/preservefiles/CMakeLists.txt index e5cbe819c..5df637321 100644 --- a/src/modules/preservefiles/CMakeLists.txt +++ b/src/modules/preservefiles/CMakeLists.txt @@ -3,8 +3,6 @@ # SPDX-FileCopyrightText: 2020 Adriaan de Groot # SPDX-License-Identifier: BSD-2-Clause # -include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ) - calamares_add_plugin( preservefiles TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO @@ -15,3 +13,10 @@ calamares_add_plugin( preservefiles SHARED_LIB EMERGENCY ) + +calamares_add_test( + preservefilestest + SOURCES + Item.cpp + Tests.cpp +) diff --git a/src/modules/preservefiles/Tests.cpp b/src/modules/preservefiles/Tests.cpp new file mode 100644 index 000000000..3bf4aa833 --- /dev/null +++ b/src/modules/preservefiles/Tests.cpp @@ -0,0 +1,70 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "Item.h" + +#include "Settings.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" +#include "utils/Yaml.h" + +#include + +class PreserveFilesTests : public QObject +{ + Q_OBJECT +public: + PreserveFilesTests(); + ~PreserveFilesTests() override {} + +private Q_SLOTS: + void initTestCase(); + + /* + void testOneUrl(); + void testUrls_data(); + void testUrls(); + + void testBadConfigDoesNotResetUrls(); + */ + void testTrue(); +}; + +PreserveFilesTests::PreserveFilesTests() {} + +void +PreserveFilesTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); + cDebug() << "PreserveFiles test started."; + + // Ensure we have a system object, expect it to be a "bogus" one + CalamaresUtils::System* system = CalamaresUtils::System::instance(); + QVERIFY( system ); + cDebug() << Logger::SubEntry << "System @" << Logger::Pointer( system ); + + const auto* settings = Calamares::Settings::instance(); + if ( !settings ) + { + (void)new Calamares::Settings( true ); + } +} + +void +PreserveFilesTests::testTrue() +{ + QVERIFY( true ); +} + + +QTEST_GUILESS_MAIN( PreserveFilesTests ) + +#include "utils/moc-warnings.h" + +#include "Tests.moc" From a1b7ba0dc59cd0d70146cc7872808f68209f7c1e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 15:44:07 +0100 Subject: [PATCH 070/168] [preservefiles] Accessor for item-type (needed for tests) --- src/modules/preservefiles/Item.cpp | 2 +- src/modules/preservefiles/Item.h | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/modules/preservefiles/Item.cpp b/src/modules/preservefiles/Item.cpp index bc2357876..335110b75 100644 --- a/src/modules/preservefiles/Item.cpp +++ b/src/modules/preservefiles/Item.cpp @@ -124,7 +124,7 @@ Item::exec( const std::function< QString( QString ) >& replacements ) const QString full_dest = CalamaresUtils::System::instance()->targetPath( expanded_dest ); bool success = false; - switch ( type ) + switch ( m_type ) { case ItemType::None: cWarning() << "Invalid item for preservefiles skipped."; diff --git a/src/modules/preservefiles/Item.h b/src/modules/preservefiles/Item.h index cd15e2042..9bd8f9613 100644 --- a/src/modules/preservefiles/Item.h +++ b/src/modules/preservefiles/Item.h @@ -35,23 +35,24 @@ class Item QString source; QString dest; CalamaresUtils::Permissions perm; - ItemType type; + ItemType m_type; public: Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t ) : source( src ) , dest( d ) , perm( std::move( p ) ) - , type( t ) + , m_type( t ) { } Item() - : type( ItemType::None ) + : m_type( ItemType::None ) { } - operator bool() const { return type != ItemType::None; } + operator bool() const { return m_type != ItemType::None; } + ItemType type() const { return m_type; } bool exec( const std::function< QString( QString ) >& replacements ) const; From 3be52f8b37b841bcf420626cfcfed931b9175747 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 15:44:32 +0100 Subject: [PATCH 071/168] [preservefiles] Expand tests with reading some existing config-items --- src/modules/preservefiles/Tests.cpp | 43 ++++++++++++++----- src/modules/preservefiles/tests/1a-log.conf | 7 +++ .../preservefiles/tests/1b-config.conf | 6 +++ src/modules/preservefiles/tests/1c-src.conf | 6 +++ .../preservefiles/tests/1d-filename.conf | 6 +++ src/modules/preservefiles/tests/1e-empty.conf | 3 ++ src/modules/preservefiles/tests/1f-bad.conf | 4 ++ 7 files changed, 65 insertions(+), 10 deletions(-) create mode 100644 src/modules/preservefiles/tests/1a-log.conf create mode 100644 src/modules/preservefiles/tests/1b-config.conf create mode 100644 src/modules/preservefiles/tests/1c-src.conf create mode 100644 src/modules/preservefiles/tests/1d-filename.conf create mode 100644 src/modules/preservefiles/tests/1e-empty.conf create mode 100644 src/modules/preservefiles/tests/1f-bad.conf diff --git a/src/modules/preservefiles/Tests.cpp b/src/modules/preservefiles/Tests.cpp index 3bf4aa833..57cefcf9d 100644 --- a/src/modules/preservefiles/Tests.cpp +++ b/src/modules/preservefiles/Tests.cpp @@ -12,6 +12,7 @@ #include "Settings.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" +#include "utils/NamedEnum.h" #include "utils/Yaml.h" #include @@ -26,14 +27,8 @@ public: private Q_SLOTS: void initTestCase(); - /* - void testOneUrl(); - void testUrls_data(); - void testUrls(); - - void testBadConfigDoesNotResetUrls(); - */ - void testTrue(); + void testItems_data(); + void testItems(); }; PreserveFilesTests::PreserveFilesTests() {} @@ -57,11 +52,39 @@ PreserveFilesTests::initTestCase() } void -PreserveFilesTests::testTrue() +PreserveFilesTests::testItems_data() { - QVERIFY( true ); + QTest::addColumn< QString >( "filename" ); + QTest::addColumn< bool >( "ok" ); + QTest::addColumn< int >( "type_i" ); + + QTest::newRow( "log " ) << QString( "1a-log.conf" ) << true << smash( ItemType::Log ); + QTest::newRow( "config " ) << QString( "1b-config.conf" ) << true << smash( ItemType::Config ); + QTest::newRow( "src " ) << QString( "1c-src.conf" ) << true << smash( ItemType::Path ); + QTest::newRow( "filename" ) << QString( "1d-filename.conf" ) << true << smash( ItemType::Path ); + QTest::newRow( "empty " ) << QString( "1e-empty.conf" ) << false << smash( ItemType::None ); + QTest::newRow( "bad " ) << QString( "1f-bad.conf" ) << false << smash( ItemType::None ); } +void +PreserveFilesTests::testItems() +{ + QFETCH( QString, filename ); + QFETCH( bool, ok ); + QFETCH( int, type_i ); + + QFile fi( QString( "%1/tests/%2" ).arg( BUILD_AS_TEST, filename ) ); + QVERIFY( fi.exists() ); + + bool config_file_ok = false; + const auto map = CalamaresUtils::loadYaml( fi, &config_file_ok ); + QVERIFY( config_file_ok ); + + CalamaresUtils::Permissions perm( QStringLiteral( "adridg:adridg:0750" ) ); + auto i = Item::fromVariant( map[ "item" ], perm ); + QCOMPARE( bool( i ), ok ); + QCOMPARE( smash( i.type() ), type_i ); +} QTEST_GUILESS_MAIN( PreserveFilesTests ) diff --git a/src/modules/preservefiles/tests/1a-log.conf b/src/modules/preservefiles/tests/1a-log.conf new file mode 100644 index 000000000..d589d4dfb --- /dev/null +++ b/src/modules/preservefiles/tests/1a-log.conf @@ -0,0 +1,7 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +# +item: + from: log + dest: /var/log/Calamares.log + perm: root:wheel:601 diff --git a/src/modules/preservefiles/tests/1b-config.conf b/src/modules/preservefiles/tests/1b-config.conf new file mode 100644 index 000000000..409dc89d9 --- /dev/null +++ b/src/modules/preservefiles/tests/1b-config.conf @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +item: + from: config + dest: /var/log/Calamares-install.json + perm: root:wheel:600 diff --git a/src/modules/preservefiles/tests/1c-src.conf b/src/modules/preservefiles/tests/1c-src.conf new file mode 100644 index 000000000..130ddd06f --- /dev/null +++ b/src/modules/preservefiles/tests/1c-src.conf @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +item: + src: /root/.cache/calamares/session.log + dest: /var/log/Calamares.log + perm: root:wheel:600 diff --git a/src/modules/preservefiles/tests/1d-filename.conf b/src/modules/preservefiles/tests/1d-filename.conf new file mode 100644 index 000000000..130ddd06f --- /dev/null +++ b/src/modules/preservefiles/tests/1d-filename.conf @@ -0,0 +1,6 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +item: + src: /root/.cache/calamares/session.log + dest: /var/log/Calamares.log + perm: root:wheel:600 diff --git a/src/modules/preservefiles/tests/1e-empty.conf b/src/modules/preservefiles/tests/1e-empty.conf new file mode 100644 index 000000000..183d4e456 --- /dev/null +++ b/src/modules/preservefiles/tests/1e-empty.conf @@ -0,0 +1,3 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +item: [] diff --git a/src/modules/preservefiles/tests/1f-bad.conf b/src/modules/preservefiles/tests/1f-bad.conf new file mode 100644 index 000000000..b2c008955 --- /dev/null +++ b/src/modules/preservefiles/tests/1f-bad.conf @@ -0,0 +1,4 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +item: + bop: 1 From 445ed870ccf5be0237b29ea83da708487b702ea3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 15:53:15 +0100 Subject: [PATCH 072/168] [preservefiles] Simplify code to help gcc warnings --- src/modules/preservefiles/Item.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/modules/preservefiles/Item.cpp b/src/modules/preservefiles/Item.cpp index 335110b75..4354c2e08 100644 --- a/src/modules/preservefiles/Item.cpp +++ b/src/modules/preservefiles/Item.cpp @@ -109,11 +109,8 @@ Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& default return {}; } } - else - { - cWarning() << "Invalid type for preservefiles, item" << v; - return {}; - } + cWarning() << "Invalid type for preservefiles, item" << v; + return {}; } From 778c2855f41d6d544d196c6ff60ed9ce40ff19f0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 16:34:38 +0100 Subject: [PATCH 073/168] [preservefiles] Introduce the notion of optionally-preserved files --- src/modules/preservefiles/Item.cpp | 10 +++--- src/modules/preservefiles/Item.h | 7 ++-- src/modules/preservefiles/PreserveFiles.cpp | 4 ++- src/modules/preservefiles/preservefiles.conf | 35 +++++++++++++------- 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/modules/preservefiles/Item.cpp b/src/modules/preservefiles/Item.cpp index 4354c2e08..2ae929e67 100644 --- a/src/modules/preservefiles/Item.cpp +++ b/src/modules/preservefiles/Item.cpp @@ -12,6 +12,7 @@ #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include "utils/Units.h" +#include "utils/Variant.h" #include @@ -56,7 +57,7 @@ Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& default QString filename = v.toString(); if ( !filename.isEmpty() ) { - return { filename, filename, defaultPermissions, ItemType::Path }; + return { filename, filename, defaultPermissions, ItemType::Path, false }; } else { @@ -70,6 +71,7 @@ Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& default CalamaresUtils::Permissions perm( defaultPermissions ); ItemType t = ItemType::None; + bool optional = CalamaresUtils::getBool( map, "optional", false ); { QString perm_string = map[ "perm" ].toString(); @@ -99,11 +101,11 @@ Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& default switch ( t ) { case ItemType::Config: - return { QString(), dest, perm, t }; + return { QString(), dest, perm, t, optional }; case ItemType::Log: - return { QString(), dest, perm, t }; + return { QString(), dest, perm, t, optional }; case ItemType::Path: - return { map[ "src" ].toString(), dest, perm, t }; + return { map[ "src" ].toString(), dest, perm, t, optional }; case ItemType::None: cWarning() << "Invalid type for preservefiles, item" << v; return {}; diff --git a/src/modules/preservefiles/Item.h b/src/modules/preservefiles/Item.h index 9bd8f9613..896b9471f 100644 --- a/src/modules/preservefiles/Item.h +++ b/src/modules/preservefiles/Item.h @@ -35,14 +35,16 @@ class Item QString source; QString dest; CalamaresUtils::Permissions perm; - ItemType m_type; + ItemType m_type = ItemType::None; + bool m_optional = false; public: - Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t ) + Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t, bool optional ) : source( src ) , dest( d ) , perm( std::move( p ) ) , m_type( t ) + , m_optional( optional ) { } @@ -53,6 +55,7 @@ public: operator bool() const { return m_type != ItemType::None; } ItemType type() const { return m_type; } + bool isOptional() const { return m_optional; } bool exec( const std::function< QString( QString ) >& replacements ) const; diff --git a/src/modules/preservefiles/PreserveFiles.cpp b/src/modules/preservefiles/PreserveFiles.cpp index 4adde85bb..f904ded8c 100644 --- a/src/modules/preservefiles/PreserveFiles.cpp +++ b/src/modules/preservefiles/PreserveFiles.cpp @@ -72,7 +72,9 @@ PreserveFiles::exec() ++count; continue; } - if ( it.exec( atReplacements ) ) + // Try to preserve the file. If it's marked as optional, count it + // as a success regardless. + if ( it.exec( atReplacements ) || it.isOptional() ) { ++count; } diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index 2853ac037..4fb393b2e 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -7,24 +7,38 @@ # the list should have one of these forms: # # - an absolute path (probably within the host system). This will be preserved -# as the same path within the target system (chroot). If, globally, dontChroot -# is true, then these items are ignored (since the destination is the same -# as the source). +# as the same path within the target system (chroot). If, globally, +# *dontChroot* is true, then these items will be ignored (since the +# destination is the same as the source). # - a map with a *dest* key. The *dest* value is a path interpreted in the # target system (if the global *dontChroot* is true, then the host is the -# target as well). Relative paths are not recommended. There are three -# possible other keys in the map: +# target as well). Relative paths are not recommended. There are two +# ways to select the source data for the file: # - *from*, which must have one of the values, below; it is used to # preserve files whose pathname is known to Calamares internally. # - *src*, to refer to a path interpreted in the host system. Relative # paths are not recommended, and are interpreted relative to where # Calamares is being run. +# Exactly one of the two source keys (either *from* or *src*) must be set. +# +# Special values for the key *from* are: +# - *log*, for the complete log file (up to the moment the preservefiles +# module is run), +# - *config*, for a JSON dump of the contents of global storage. +# Note that this may contain sensitive information, and should be +# given restrictive permissions. +# +# A map with a *dest* key can have these additional fields: # - *perm*, is a colon-separated tuple of :: # where is in octal (e.g. 4777 for wide-open, 0400 for read-only # by owner). If set, the file's ownership and permissions are set to # those values within the target system; if not set, no permissions # are changed. -# Exactly one of the two source keys (either *from* or *src*) must be set. +# - *optional*, is a boolean; if this is set to `true` then failure to +# preserve the file will **not** be counted as a failure of the +# module, and installation will proceed. Set this for files that might +# not exist in the host system (e.g. nvidia configuration files that +# are created in some boot scenarios and not in others). # # The target path (*dest*) is modified as follows: # - `@@ROOT@@` is replaced by the path to the target root (may be /). @@ -33,12 +47,6 @@ # - `@@USER@@` is replaced by the username entered by on the user # page (may be empty, for instance if no user page is enabled) # -# Special values for the key *from* are: -# - *log*, for the complete log file (up to the moment the preservefiles -# module is run), -# - *config*, for a JSON dump of the contents of global storage. -# Note that this may contain sensitive information, and should be -# given restrictive permissions. # # files: @@ -48,6 +56,9 @@ files: - from: config dest: /var/log/Calamares-install.json perm: root:wheel:600 +# - src: /var/log/nvidia.conf +# dest: /var/log/Calamares-nvidia.conf +# optional: true # The *perm* key contains a default value to apply to all files listed # above that do not have a *perm* key of their own. If not set, From d3ed5663d08a8d76054f67e9fa57a72a7eda24dd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 13 Dec 2021 16:56:07 +0100 Subject: [PATCH 074/168] [preservefiles] Add a schema-file --- .../preservefiles/preservefiles.schema.yaml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/modules/preservefiles/preservefiles.schema.yaml diff --git a/src/modules/preservefiles/preservefiles.schema.yaml b/src/modules/preservefiles/preservefiles.schema.yaml new file mode 100644 index 000000000..65067ea97 --- /dev/null +++ b/src/modules/preservefiles/preservefiles.schema.yaml @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2020 Adriaan de Groot +# SPDX-License-Identifier: GPL-3.0-or-later +--- +$schema: https://json-schema.org/schema# +$id: https://calamares.io/schemas/preservefiles +additionalProperties: false +type: object +properties: + # TODO: it's a particularly-formatted string + perm: { type: string } + files: + type: array + items: + # There are three entries here because: string, or an entry with + # a src (but no from) or an entry with from (but no src). + anyOf: + - type: string + - type: object + properties: + dest: { type: string } + src: { type: string } + # TODO: it's a particularly-formatted string + perm: { type: string } + optional: { type: boolean } + required: [ dest ] + additionalProperties: false + - type: object + properties: + dest: { type: string } + from: { type: string, enum: [config, log] } + # TODO: it's a particularly-formatted string + perm: { type: string } + optional: { type: boolean } + required: [ dest ] + additionalProperties: false + +required: [ files ] From dc7a1e43b73af5ab216df977ed518fd63f252585 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 16:19:28 +0100 Subject: [PATCH 075/168] [partition] Add helper for running a KPMCore operation Most *partition* module jobs run an operation and turn that into a JobResult -- ok if it succeeds, and with the report text otherwise. Factor it out into a separate method that can be used as shorthand. --- src/modules/partition/core/KPMHelpers.cpp | 15 +++++++++++++++ src/modules/partition/core/KPMHelpers.h | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index ed105e28b..46efeb392 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -127,4 +127,19 @@ clonePartition( Device* device, Partition* partition ) partition->activeFlags() ); } +Calamares::JobResult +execute( Operation& operation, const QString& failureMessage ) +{ + operation.setStatus( Operation::StatusRunning ); + + Report report( nullptr ); + if ( operation.execute( report ) ) + { + return Calamares::JobResult::ok(); + } + + return Calamares::JobResult::error( failureMessage, report.toText() ); +} + + } // namespace KPMHelpers diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index 89a019f6c..1d40dd363 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -11,11 +11,13 @@ #ifndef KPMHELPERS_H #define KPMHELPERS_H -// KPMcore +#include "Job.h" + #include #include +#include +#include -// Qt #include #include @@ -72,6 +74,14 @@ Partition* createNewEncryptedPartition( PartitionNode* parent, Partition* clonePartition( Device* device, Partition* partition ); +/** @brief Return a result for an @p operation + * + * Executes the operation, and if successful, returns a success result. + * Otherwise returns an error using @p failureMessage as the primary part + * of the error, and details obtained from the operation. + */ +Calamares::JobResult execute( Operation& operation, const QString& failureMessage ); + } // namespace KPMHelpers #endif /* KPMHELPERS_H */ From 8bb2c5fc6b64af01bbbc7af44ac01b676acbd450 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 16:28:13 +0100 Subject: [PATCH 076/168] [partition] Use convenience-method for running operation --- .../partition/jobs/CreatePartitionJob.cpp | 14 ++++---------- .../partition/jobs/DeletePartitionJob.cpp | 18 ++++++------------ 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/modules/partition/jobs/CreatePartitionJob.cpp b/src/modules/partition/jobs/CreatePartitionJob.cpp index 3e51ed598..248104226 100644 --- a/src/modules/partition/jobs/CreatePartitionJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionJob.cpp @@ -11,7 +11,9 @@ #include "CreatePartitionJob.h" +#include "core/KPMHelpers.h" #include "core/PartitionInfo.h" + #include "partition/FileSystem.h" #include "partition/PartitionQuery.h" #include "utils/CalamaresUtilsSystem.h" @@ -273,17 +275,9 @@ CreatePartitionJob::exec() return createZfs( m_partition, m_device ); } - Report report( nullptr ); NewOperation op( *m_device, m_partition ); - op.setStatus( Operation::StatusRunning ); - - QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( + op, tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ) ); } void diff --git a/src/modules/partition/jobs/DeletePartitionJob.cpp b/src/modules/partition/jobs/DeletePartitionJob.cpp index a678b5e90..e573d1d3c 100644 --- a/src/modules/partition/jobs/DeletePartitionJob.cpp +++ b/src/modules/partition/jobs/DeletePartitionJob.cpp @@ -10,9 +10,11 @@ */ #include "DeletePartitionJob.h" + +#include "core/KPMHelpers.h" + #include "utils/CalamaresUtilsSystem.h" -// KPMcore #include #include #include @@ -45,7 +47,7 @@ removePartition( Partition* partition ) auto r = CalamaresUtils::System::instance()->runCommand( { "sfdisk", "--delete", "--force", partition->devicePath(), QString::number( partition->number() ) }, std::chrono::seconds( 5 ) ); - if ( r.getExitCode() !=0 || r.getOutput().contains("failed") ) + if ( r.getExitCode() != 0 || r.getOutput().contains( "failed" ) ) { return Calamares::JobResult::error( QCoreApplication::translate( DeletePartitionJob::staticMetaObject.className(), "Deletion Failed" ), @@ -96,17 +98,9 @@ DeletePartitionJob::exec() return removePartition( m_partition ); } - Report report( nullptr ); DeleteOperation op( *m_device, m_partition ); - op.setStatus( Operation::StatusRunning ); - - QString message = tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( op, + tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() ) ); } void From 1356012fb468c46159baf5699aa6537c7c818b08 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 21:35:09 +0100 Subject: [PATCH 077/168] [partition] With rvalue, code becomes even more compact --- src/modules/partition/core/KPMHelpers.cpp | 2 +- src/modules/partition/core/KPMHelpers.h | 2 +- src/modules/partition/jobs/CreatePartitionJob.cpp | 4 ++-- src/modules/partition/jobs/DeletePartitionJob.cpp | 3 +-- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index 46efeb392..f836d271d 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -128,7 +128,7 @@ clonePartition( Device* device, Partition* partition ) } Calamares::JobResult -execute( Operation& operation, const QString& failureMessage ) +execute( Operation&& operation, const QString& failureMessage ) { operation.setStatus( Operation::StatusRunning ); diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index 1d40dd363..fe4d24f14 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -80,7 +80,7 @@ Partition* clonePartition( Device* device, Partition* partition ); * Otherwise returns an error using @p failureMessage as the primary part * of the error, and details obtained from the operation. */ -Calamares::JobResult execute( Operation& operation, const QString& failureMessage ); +Calamares::JobResult execute( Operation&& operation, const QString& failureMessage ); } // namespace KPMHelpers diff --git a/src/modules/partition/jobs/CreatePartitionJob.cpp b/src/modules/partition/jobs/CreatePartitionJob.cpp index 248104226..fe7c6f350 100644 --- a/src/modules/partition/jobs/CreatePartitionJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionJob.cpp @@ -275,9 +275,9 @@ CreatePartitionJob::exec() return createZfs( m_partition, m_device ); } - NewOperation op( *m_device, m_partition ); return KPMHelpers::execute( - op, tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ) ); + NewOperation( *m_device, m_partition ), + tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ) ); } void diff --git a/src/modules/partition/jobs/DeletePartitionJob.cpp b/src/modules/partition/jobs/DeletePartitionJob.cpp index e573d1d3c..d61bb955e 100644 --- a/src/modules/partition/jobs/DeletePartitionJob.cpp +++ b/src/modules/partition/jobs/DeletePartitionJob.cpp @@ -98,8 +98,7 @@ DeletePartitionJob::exec() return removePartition( m_partition ); } - DeleteOperation op( *m_device, m_partition ); - return KPMHelpers::execute( op, + return KPMHelpers::execute( DeleteOperation( *m_device, m_partition ), tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() ) ); } From b8ce21d572f39c0622749c079e7d6125fd7e9ef3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:03:26 +0100 Subject: [PATCH 078/168] [partition] Use convenience function for running operations --- .../jobs/CreatePartitionTableJob.cpp | 17 +++++------------ .../partition/jobs/CreateVolumeGroupJob.cpp | 18 ++++-------------- .../partition/jobs/FormatPartitionJob.cpp | 18 +++++------------- .../partition/jobs/RemoveVolumeGroupJob.cpp | 18 +++++------------- .../partition/jobs/ResizeVolumeGroupJob.cpp | 19 +++++-------------- 5 files changed, 24 insertions(+), 66 deletions(-) diff --git a/src/modules/partition/jobs/CreatePartitionTableJob.cpp b/src/modules/partition/jobs/CreatePartitionTableJob.cpp index 118ec8823..3908ccc81 100644 --- a/src/modules/partition/jobs/CreatePartitionTableJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionTableJob.cpp @@ -14,7 +14,8 @@ #include "partition/PartitionIterator.h" #include "utils/Logger.h" -// KPMcore +#include "core/KPMHelpers.h" + #include #include #include @@ -63,8 +64,6 @@ CreatePartitionTableJob::prettyStatusMessage() const Calamares::JobResult CreatePartitionTableJob::exec() { - Report report( nullptr ); - QString message = tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() ); PartitionTable* table = m_device->partitionTable(); @@ -91,15 +90,9 @@ CreatePartitionTableJob::exec() cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mount.readAllStandardOutput(); } - CreatePartitionTableOperation op( *m_device, table ); - op.setStatus( Operation::StatusRunning ); - - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( + CreatePartitionTableOperation( *m_device, table ), + tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() ) ); } void diff --git a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp index 36d79b7b7..683913b7f 100644 --- a/src/modules/partition/jobs/CreateVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/CreateVolumeGroupJob.cpp @@ -9,7 +9,8 @@ #include "CreateVolumeGroupJob.h" -// KPMcore +#include "core/KPMHelpers.h" + #include #include #include @@ -46,19 +47,8 @@ CreateVolumeGroupJob::prettyStatusMessage() const Calamares::JobResult CreateVolumeGroupJob::exec() { - Report report( nullptr ); - - CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize ); - - op.setStatus( Operation::StatusRunning ); - - QString message = tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( CreateVolumeGroupOperation( m_vgName, m_pvList, m_peSize ), + tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName ) ); } void diff --git a/src/modules/partition/jobs/FormatPartitionJob.cpp b/src/modules/partition/jobs/FormatPartitionJob.cpp index 4dadacf9c..1ccc6e617 100644 --- a/src/modules/partition/jobs/FormatPartitionJob.cpp +++ b/src/modules/partition/jobs/FormatPartitionJob.cpp @@ -11,6 +11,8 @@ #include "FormatPartitionJob.h" +#include "core/KPMHelpers.h" + #include "partition/FileSystem.h" #include "utils/Logger.h" @@ -65,17 +67,7 @@ FormatPartitionJob::prettyStatusMessage() const Calamares::JobResult FormatPartitionJob::exec() { - Report report( nullptr ); // Root of the report tree, no parent - CreateFileSystemOperation op( *m_device, *m_partition, m_partition->fileSystem().type() ); - op.setStatus( Operation::StatusRunning ); - - QString message = tr( "The installer failed to format partition %1 on disk '%2'." ) - .arg( m_partition->partitionPath(), m_device->name() ); - - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( CreateFileSystemOperation( *m_device, *m_partition, m_partition->fileSystem().type() ), + tr( "The installer failed to format partition %1 on disk '%2'." ) + .arg( m_partition->partitionPath(), m_device->name() ) ); } diff --git a/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp index 3c4e7b036..227351064 100644 --- a/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/RemoveVolumeGroupJob.cpp @@ -9,6 +9,8 @@ #include "RemoveVolumeGroupJob.h" +#include "core/KPMHelpers.h" + #include #include #include @@ -39,17 +41,7 @@ RemoveVolumeGroupJob::prettyStatusMessage() const Calamares::JobResult RemoveVolumeGroupJob::exec() { - Report report( nullptr ); - - RemoveVolumeGroupOperation op( *m_device ); - - op.setStatus( Operation::OperationStatus::StatusRunning ); - - QString message = tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( + RemoveVolumeGroupOperation( *m_device ), + tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() ) ); } diff --git a/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp index 1aa4541b8..f7a21d80d 100644 --- a/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/ResizeVolumeGroupJob.cpp @@ -9,7 +9,8 @@ #include "ResizeVolumeGroupJob.h" -// KPMcore +#include "core/KPMHelpers.h" + #include #include #include @@ -51,19 +52,9 @@ ResizeVolumeGroupJob::prettyStatusMessage() const Calamares::JobResult ResizeVolumeGroupJob::exec() { - Report report( nullptr ); - - ResizeVolumeGroupOperation op( *m_device, m_partitionList ); - - op.setStatus( Operation::OperationStatus::StatusRunning ); - - QString message = tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( message, report.toText() ); + return KPMHelpers::execute( + ResizeVolumeGroupOperation( *m_device, m_partitionList ), + tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() ) ); } QString From c5573a1997a2cb92f2bfccbe8fdf7ddc568d1ee5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:19:01 +0100 Subject: [PATCH 079/168] [partition] Add non-const lvalue overload for execute() --- src/modules/partition/core/KPMHelpers.cpp | 2 +- src/modules/partition/core/KPMHelpers.h | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index f836d271d..46efeb392 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -128,7 +128,7 @@ clonePartition( Device* device, Partition* partition ) } Calamares::JobResult -execute( Operation&& operation, const QString& failureMessage ) +execute( Operation& operation, const QString& failureMessage ) { operation.setStatus( Operation::StatusRunning ); diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index fe4d24f14..2f867bc25 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -80,7 +80,17 @@ Partition* clonePartition( Device* device, Partition* partition ); * Otherwise returns an error using @p failureMessage as the primary part * of the error, and details obtained from the operation. */ -Calamares::JobResult execute( Operation&& operation, const QString& failureMessage ); +Calamares::JobResult execute( Operation& operation, const QString& failureMessage ); +/** @brief Return a result for an @p operation + * + * It's acceptable to use an rvalue: the operation-running is the effect + * you're interested in, rather than keeping the temporary around. + */ +static inline Calamares::JobResult +execute( Operation&& operation, const QString& failureMessage ) +{ + return execute( operation, failureMessage ); +} } // namespace KPMHelpers From 668058472404a183eb535f83a2724a5f9c369377 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:25:21 +0100 Subject: [PATCH 080/168] [partition] Use convenience function execute() This job needs the lvalue-overload of execute() because it needs to call a method on the operation after execute() finishes successfully. --- .../partition/jobs/DeactivateVolumeGroupJob.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp index 92086015d..65920a84e 100644 --- a/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp +++ b/src/modules/partition/jobs/DeactivateVolumeGroupJob.cpp @@ -9,6 +9,8 @@ #include "DeactivateVolumeGroupJob.h" +#include "core/KPMHelpers.h" + #include #include #include @@ -39,18 +41,12 @@ DeactivateVolumeGroupJob::prettyStatusMessage() const Calamares::JobResult DeactivateVolumeGroupJob::exec() { - Report report( nullptr ); - DeactivateVolumeGroupOperation op( *m_device ); - - op.setStatus( Operation::OperationStatus::StatusRunning ); - - QString message = tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() ); - if ( op.execute( report ) ) + auto r = KPMHelpers::execute( + op, tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() ) ); + if ( r ) { op.preview(); - return Calamares::JobResult::ok(); } - - return Calamares::JobResult::error( message, report.toText() ); + return r; } From fdf0f208f08de8d39c7f24ca7b406006bb5c686a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:26:12 +0100 Subject: [PATCH 081/168] [partition] Use lvalue-overload of execute() convenience - These jobs may take a long time, and report progress; we need the operation around to be able to connect the signals and slots --- .../partition/jobs/ResizePartitionJob.cpp | 20 +++++++------------ .../partition/jobs/SetPartitionFlagsJob.cpp | 15 ++++---------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/src/modules/partition/jobs/ResizePartitionJob.cpp b/src/modules/partition/jobs/ResizePartitionJob.cpp index 87b87c1c0..fe1ceca4c 100644 --- a/src/modules/partition/jobs/ResizePartitionJob.cpp +++ b/src/modules/partition/jobs/ResizePartitionJob.cpp @@ -11,9 +11,10 @@ #include "ResizePartitionJob.h" +#include "core/KPMHelpers.h" + #include "utils/Units.h" -// KPMcore #include #include #include @@ -66,23 +67,16 @@ ResizePartitionJob::prettyStatusMessage() const Calamares::JobResult ResizePartitionJob::exec() { - Report report( nullptr ); // Restore partition sectors that were modified for preview m_partition->setFirstSector( m_oldFirstSector ); m_partition->setLastSector( m_oldLastSector ); + ResizeOperation op( *m_device, *m_partition, m_newFirstSector, m_newLastSector ); - op.setStatus( Operation::StatusRunning ); connect( &op, &Operation::progress, this, &ResizePartitionJob::iprogress ); - - QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." ) - .arg( m_partition->partitionPath() ) - .arg( m_device->name() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( errorMessage, report.toText() ); + return KPMHelpers::execute( op, + tr( "The installer failed to resize partition %1 on disk '%2'." ) + .arg( m_partition->partitionPath() ) + .arg( m_device->name() ) ); } void diff --git a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp index de77d86f8..507773288 100644 --- a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp +++ b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp @@ -13,6 +13,8 @@ #include "SetPartitionFlagsJob.h" +#include "core/KPMHelpers.h" + #include "partition/FileSystem.h" #include "utils/Logger.h" #include "utils/Units.h" @@ -148,17 +150,8 @@ SetPartFlagsJob::exec() cDebug() << "Setting flags on" << m_device->deviceNode() << "partition" << partition()->deviceNode() << Logger::DebugList( flagsList ); - Report report( nullptr ); SetPartFlagsOperation op( *m_device, *partition(), m_flags ); - op.setStatus( Operation::StatusRunning ); connect( &op, &Operation::progress, this, &SetPartFlagsJob::iprogress ); - - QString errorMessage - = tr( "The installer failed to set flags on partition %1." ).arg( m_partition->partitionPath() ); - if ( op.execute( report ) ) - { - return Calamares::JobResult::ok(); - } - - return Calamares::JobResult::error( errorMessage, report.toText() ); + return KPMHelpers::execute( + op, tr( "The installer failed to set flags on partition %1." ).arg( m_partition->partitionPath() ) ); } From 07354a26a99b73f8c5ce542992361928b9adc158 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:35:34 +0100 Subject: [PATCH 082/168] [partition] Simplify debug calls to executables - Use the Calamares support-functions for running lsblk and mount (these might need to have privilege support if Cala is not running as root, so this is future-proofing) --- .../partition/jobs/CreatePartitionTableJob.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/modules/partition/jobs/CreatePartitionTableJob.cpp b/src/modules/partition/jobs/CreatePartitionTableJob.cpp index 3908ccc81..3b9415d1a 100644 --- a/src/modules/partition/jobs/CreatePartitionTableJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionTableJob.cpp @@ -12,6 +12,7 @@ #include "CreatePartitionTableJob.h" #include "partition/PartitionIterator.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include "core/KPMHelpers.h" @@ -75,19 +76,11 @@ CreatePartitionTableJob::exec() cDebug() << Logger::SubEntry << ( ( *it ) ? ( *it )->deviceNode() : QString( "" ) ); } - QProcess lsblk; - lsblk.setProgram( "lsblk" ); - lsblk.setProcessChannelMode( QProcess::MergedChannels ); - lsblk.start(); - lsblk.waitForFinished(); - cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblk.readAllStandardOutput(); + auto lsblkResult = CalamaresUtils::System::runCommand( { "lsblk" }, std::chrono::seconds( 30 ) ); + cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblkResult.getOutput(); - QProcess mount; - mount.setProgram( "mount" ); // Debug output only, not mounting something - mount.setProcessChannelMode( QProcess::MergedChannels ); - mount.start(); - mount.waitForFinished(); - cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mount.readAllStandardOutput(); + auto mountResult = CalamaresUtils::System::runCommand( { "mount" }, std::chrono::seconds( 30 ) ); + cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mountResult.getOutput(); } return KPMHelpers::execute( From f04394d0147fab83b92923bb490723eba82625ab Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 11 Dec 2021 23:44:23 +0100 Subject: [PATCH 083/168] [partition] Improve rendering of KPMCore errors --- src/modules/partition/core/KPMHelpers.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index 46efeb392..d5086ef21 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -15,8 +15,8 @@ #include "partition/PartitionIterator.h" #include "utils/Logger.h" +#include "utils/String.h" -// KPMcore #include #include #include @@ -138,7 +138,11 @@ execute( Operation& operation, const QString& failureMessage ) return Calamares::JobResult::ok(); } - return Calamares::JobResult::error( failureMessage, report.toText() ); + // Remove the === lines from the report by trimming them to empty + QStringList l = report.toText().split( '\n' ); + std::for_each( l.begin(), l.end(), []( QString& s ) { CalamaresUtils::removeLeading( s, '=' ); } ); + + return Calamares::JobResult::error( failureMessage, l.join( '\n' ) ); } From 587a18a6fae7a34edd4a95ad79f69ad21dc8d1a7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 14 Dec 2021 12:50:27 +0100 Subject: [PATCH 084/168] [partition] Use runCommand() for future-proofing --- src/modules/partition/core/DeviceList.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/modules/partition/core/DeviceList.cpp b/src/modules/partition/core/DeviceList.cpp index c7de12e88..423c3b4ee 100644 --- a/src/modules/partition/core/DeviceList.cpp +++ b/src/modules/partition/core/DeviceList.cpp @@ -11,6 +11,7 @@ #include "DeviceList.h" #include "partition/PartitionIterator.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include @@ -43,11 +44,9 @@ hasRootPartition( Device* device ) static bool blkIdCheckIso9660( const QString& path ) { - QProcess blkid; - blkid.start( "blkid", { path } ); - blkid.waitForFinished(); - QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() ); - return output.contains( "iso9660" ); + // If blkid fails, there's no output, but we don't care + auto r = CalamaresUtils::System::runCommand( { "blkid", path }, std::chrono::seconds( 30 ) ); + return r.getOutput().contains( "iso9660" ); } static bool From be18e51bc967b12c7659b65ed0f4760452ee9524 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Sat, 18 Dec 2021 00:38:06 +0100 Subject: [PATCH 085/168] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_en_GB.ts | 2 +- lang/calamares_hi.ts | 10 +- lang/calamares_id.ts | 68 +- lang/calamares_ro.ts | 2 +- lang/calamares_ta_IN.ts | 4377 +++++++++++++++++++++++++++++++++++++++ lang/calamares_vi.ts | 12 +- 6 files changed, 4424 insertions(+), 47 deletions(-) create mode 100644 lang/calamares_ta_IN.ts diff --git a/lang/calamares_en_GB.ts b/lang/calamares_en_GB.ts index 3578d4554..b8ddc023f 100644 --- a/lang/calamares_en_GB.ts +++ b/lang/calamares_en_GB.ts @@ -1989,7 +1989,7 @@ The installer will quit and all changes will be lost. Configuration Error - + Configuration Error diff --git a/lang/calamares_hi.ts b/lang/calamares_hi.ts index 7f20e8bcd..16eee77b5 100644 --- a/lang/calamares_hi.ts +++ b/lang/calamares_hi.ts @@ -689,27 +689,27 @@ The installer will quit and all changes will be lost. Successfully unmounted %1. - + %1 को माउंट से हटाना सफल। Successfully disabled swap %1. - + %1 स्वैप निष्क्रिय करना सफल। Successfully cleared swap %1. - + %1 स्वैप रिक्त करना सफल। Successfully closed mapper device %1. - + प्रतिचित्रण उपकरण %1 बंद करना सफल। Successfully disabled volume group %1. - + वॉल्यूम समूह %1 निष्क्रिय करना सफल। diff --git a/lang/calamares_id.ts b/lang/calamares_id.ts index d3a29ac42..a8b1d4cbf 100644 --- a/lang/calamares_id.ts +++ b/lang/calamares_id.ts @@ -6,7 +6,7 @@ Manage auto-mount settings - + Kelola pengaturan mount otomatis @@ -114,12 +114,12 @@ Uploads the session log to the configured pastebin. - + Unggah catatan sesi ke pastebin yang telah dikonfigurasi. Send Session Log - + Kirim Catatan Sesi @@ -165,7 +165,7 @@ Programmed job failure was explicitly requested. - + Kegagalan pekerjaan diprogram diminta secara eksplisit. @@ -189,7 +189,7 @@ Run command '%1' in target system. - Jalankan perintah '%1' di dalam sistem target. + Jalankan perintah '%1' pada sistem target. @@ -245,7 +245,7 @@ QML Step <i>%1</i>. - + QML Langkah <i>%1</i>. @@ -277,7 +277,7 @@ System-requirements checking is complete. - + Pengecekan kebutuhan sistem telah selesai. @@ -295,7 +295,7 @@ Would you like to paste the install log to the web? - Maukah anda untuk menempelkan log instalasi ke situs? + Maukah anda menempelkan log instalasi ke situs? @@ -429,7 +429,7 @@ Link copied to clipboard &Done - &Kelar + &Selesai @@ -1054,12 +1054,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Label for the filesystem - + Label untuk filesystem FS Label: - + Label FS: @@ -1418,12 +1418,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Label for the filesystem - + Label untuk filesystem FS Label: - + Label FS: @@ -1582,7 +1582,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Format partition %1 (file system: %2, size: %3 MiB) on %4. - + Format partisi %1 (file system: %2, ukuran %3 MiB) pada %4. @@ -1645,12 +1645,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. is running the installer as an administrator (root) - + menjalankan installer sebagai administrator (root) The setup program is not running with administrator rights. - + Installer tidak dijalankan dengan kewenangan administrator. @@ -1699,7 +1699,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Could not open file <code>%1</code>. - + Tidak dapat membuka berkas <code>%1</code>. @@ -1712,7 +1712,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Creating initramfs with mkinitcpio. - + Membuat initramfs menggunakan mkinitcpio. @@ -1720,7 +1720,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Creating initramfs. - + Membuat initramfs. @@ -2031,12 +2031,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Browser software - Peramban perangkat lunak + Perangkat lunak peramban Browser package - Peramban paket + Paket peramban @@ -2046,12 +2046,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Kernel - Inti + Kernel Services - Jasa + Servis @@ -2587,12 +2587,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan. Repeat Password - + Ulangi Kata Sandi When this box is checked, password-strength checking is done and you will not be able to use a weak password. - + Ketikan kotak ini dicentang, pengecekan kekuatan kata sandi akan dilakukan dan anda tidak akan dapat menggunakan kata sandi yang lemah. @@ -4252,7 +4252,7 @@ Keluaran: root is not allowed as username. - + root tidak boleh digunakan sebagai nama pengguna. @@ -4287,7 +4287,7 @@ Keluaran: Repeat Password - + Ulangi Kata Sandi @@ -4297,27 +4297,27 @@ Keluaran: Validate passwords quality - + Validasi kualitas kata sandi When this box is checked, password-strength checking is done and you will not be able to use a weak password. - + Ketikan kotak ini dicentang, pengecekan kekuatan kata sandi akan dilakukan dan anda tidak akan dapat menggunakan kata sandi yang lemah. Log in automatically without asking for the password - + Masuk ke dalam sesi secara otomatis tanpa menanyakan kata sandi Only letters, numbers, underscore and hyphen are allowed, minimal of two characters. - + Hanya huruf, angka, garis bawah, dan tanda hubung yang diperbolehkan, minimal dua karakter. Reuse user password as root password - + Gunakan kata sandi pengguna sebagai kata sandi root @@ -4332,12 +4332,12 @@ Keluaran: Root Password - + Kata Sandi Root Repeat Root Password - + Ulangi Kata Sandi diff --git a/lang/calamares_ro.ts b/lang/calamares_ro.ts index a6872e55b..39573886d 100644 --- a/lang/calamares_ro.ts +++ b/lang/calamares_ro.ts @@ -1991,7 +1991,7 @@ Programul de instalare va ieși, iar toate modificările vor fi pierdute. Configuration Error - + Eroare de configurare diff --git a/lang/calamares_ta_IN.ts b/lang/calamares_ta_IN.ts new file mode 100644 index 000000000..165321f17 --- /dev/null +++ b/lang/calamares_ta_IN.ts @@ -0,0 +1,4377 @@ + + + + + AutoMountManagementJob + + + Manage auto-mount settings + + + + + BootInfoWidget + + + The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. + + + + + This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. + + + + + This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. + + + + + BootLoaderModel + + + Master Boot Record of %1 + + + + + Boot Partition + இயக்கப் பகுதிப்பிரிப்பு + + + + System Partition + + + + + Do not install a boot loader + + + + + %1 (%2) + + + + + Calamares::BlankViewStep + + + Blank Page + + + + + Calamares::DebugWindow + + + Form + + + + + GlobalStorage + + + + + JobQueue + + + + + Modules + + + + + Type: + + + + + + none + + + + + Interface: + + + + + Crashes Calamares, so that Dr. Konqui can look at it. + + + + + Reloads the stylesheet from the branding directory. + + + + + Uploads the session log to the configured pastebin. + + + + + Send Session Log + + + + + Reload Stylesheet + + + + + Displays the tree of widget names in the log (for stylesheet debugging). + + + + + Widget Tree + + + + + Debug information + + + + + Calamares::ExecutionViewStep + + + Set up + + + + + Install + + + + + Calamares::FailJob + + + Job failed (%1) + + + + + Programmed job failure was explicitly requested. + + + + + Calamares::JobThread + + + Done + + + + + Calamares::NamedJob + + + Example job (%1) + + + + + Calamares::ProcessJob + + + Run command '%1' in target system. + + + + + Run command '%1'. + + + + + Running command %1 %2 + + + + + Calamares::PythonJob + + + Running %1 operation. + + + + + Bad working directory path + + + + + Working directory %1 for python job %2 is not readable. + + + + + Bad main script file + + + + + Main script file %1 for python job %2 is not readable. + + + + + Boost.Python error in job "%1". + + + + + Calamares::QmlViewStep + + + Loading ... + + + + + QML Step <i>%1</i>. + + + + + Loading failed. + + + + + Calamares::RequirementsChecker + + + Requirements checking for module <i>%1</i> is complete. + + + + + Waiting for %n module(s). + + + + + + + + (%n second(s)) + + + + + + + + System-requirements checking is complete. + + + + + Calamares::ViewManager + + + Setup Failed + + + + + Installation Failed + + + + + Would you like to paste the install log to the web? + + + + + Error + + + + + &Yes + + + + + &No + + + + + &Close + + + + + Install Log Paste URL + + + + + The upload was unsuccessful. No web-paste was done. + + + + + Install log posted to + +%1 + +Link copied to clipboard + + + + + Calamares Initialization Failed + + + + + %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. + + + + + <br/>The following modules could not be loaded: + + + + + Continue with setup? + + + + + Continue with installation? + + + + + The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> + + + + + The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> + + + + + &Set up now + + + + + &Install now + + + + + Go &back + + + + + &Set up + + + + + &Install + + + + + Setup is complete. Close the setup program. + + + + + The installation is complete. Close the installer. + + + + + Cancel setup without changing the system. + + + + + Cancel installation without changing the system. + + + + + &Next + + + + + &Back + + + + + &Done + + + + + &Cancel + + + + + Cancel setup? + + + + + Cancel installation? + + + + + Do you really want to cancel the current setup process? +The setup program will quit and all changes will be lost. + + + + + Do you really want to cancel the current install process? +The installer will quit and all changes will be lost. + + + + + CalamaresPython::Helper + + + Unknown exception type + + + + + unparseable Python error + + + + + unparseable Python traceback + + + + + Unfetchable Python error. + + + + + CalamaresWindow + + + %1 Setup Program + + + + + %1 Installer + + + + + ChangeFilesystemLabelJob + + + Set filesystem label on %1. + + + + + Set filesystem label <strong>%1</strong> to partition <strong>%2</strong>. + + + + + The installer failed to update partition table on disk '%1'. + + + + + CheckerContainer + + + Gathering system information... + + + + + ChoicePage + + + Form + + + + + Select storage de&vice: + + + + + + + + Current: + + + + + After: + + + + + <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. + + + + + Reuse %1 as home partition for %2. + + + + + <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> + + + + + %1 will be shrunk to %2MiB and a new %3MiB partition will be created for %4. + + + + + Boot loader location: + + + + + <strong>Select a partition to install on</strong> + + + + + An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. + + + + + The EFI system partition at %1 will be used for starting %2. + + + + + EFI system partition: + + + + + This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + + + + <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. + + + + + + + + <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. + + + + + + + + <strong>Replace a partition</strong><br/>Replaces a partition with %1. + + + + + This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device already has an operating system on it, but the partition table <strong>%1</strong> is different from the needed <strong>%2</strong>.<br/> + + + + + This storage device has one of its partitions <strong>mounted</strong>. + + + + + This storage device is a part of an <strong>inactive RAID</strong> device. + + + + + No Swap + + + + + Reuse Swap + + + + + Swap (no Hibernate) + + + + + Swap (with Hibernate) + + + + + Swap to file + + + + + ClearMountsJob + + + Successfully unmounted %1. + + + + + Successfully disabled swap %1. + + + + + Successfully cleared swap %1. + + + + + Successfully closed mapper device %1. + + + + + Successfully disabled volume group %1. + + + + + Clear mounts for partitioning operations on %1 + + + + + Clearing mounts for partitioning operations on %1. + + + + + Cleared all mounts for %1 + + + + + ClearTempMountsJob + + + Clear all temporary mounts. + + + + + Clearing all temporary mounts. + + + + + Cannot get list of temporary mounts. + + + + + Cleared all temporary mounts. + + + + + CommandList + + + + Could not run command. + + + + + The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. + + + + + The command needs to know the user's name, but no username is defined. + + + + + Config + + + Set keyboard model to %1.<br/> + + + + + Set keyboard layout to %1/%2. + + + + + Set timezone to %1/%2. + + + + + The system language will be set to %1. + + + + + The numbers and dates locale will be set to %1. + + + + + Network Installation. (Disabled: Incorrect configuration) + + + + + Network Installation. (Disabled: Received invalid groups data) + + + + + Network Installation. (Disabled: Internal error) + + + + + Network Installation. (Disabled: No package list) + + + + + Package selection + + + + + Network Installation. (Disabled: Unable to fetch package lists, check your network connection) + + + + + This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> + + + + + This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> + + + + + This computer does not satisfy some of the recommended requirements for setting up %1.<br/>Setup can continue, but some features might be disabled. + + + + + This computer does not satisfy some of the recommended requirements for installing %1.<br/>Installation can continue, but some features might be disabled. + + + + + This program will ask you some questions and set up %2 on your computer. + + + + + <h1>Welcome to the Calamares setup program for %1</h1> + + + + + <h1>Welcome to %1 setup</h1> + + + + + <h1>Welcome to the Calamares installer for %1</h1> + + + + + <h1>Welcome to the %1 installer</h1> + + + + + Your username is too long. + + + + + '%1' is not allowed as username. + + + + + Your username must start with a lowercase letter or underscore. + + + + + Only lowercase letters, numbers, underscore and hyphen are allowed. + + + + + Your hostname is too short. + + + + + Your hostname is too long. + + + + + '%1' is not allowed as hostname. + + + + + Only letters, numbers, underscore and hyphen are allowed. + + + + + Your passwords do not match! + + + + + OK! + + + + + Setup Failed + + + + + Installation Failed + + + + + The setup of %1 did not complete successfully. + + + + + The installation of %1 did not complete successfully. + + + + + Setup Complete + + + + + Installation Complete + + + + + The setup of %1 is complete. + + + + + The installation of %1 is complete. + + + + + Package Selection + + + + + Please pick a product from the list. The selected product will be installed. + + + + + Install option: <strong>%1</strong> + + + + + None + + + + + Summary + + + + + This is an overview of what will happen once you start the setup procedure. + + + + + This is an overview of what will happen once you start the install procedure. + + + + + ContextualProcessJob + + + Contextual Processes Job + + + + + CreatePartitionDialog + + + Create a Partition + + + + + Si&ze: + + + + + MiB + + + + + Partition &Type: + + + + + &Primary + + + + + E&xtended + + + + + Fi&le System: + + + + + LVM LV name + + + + + &Mount Point: + + + + + Flags: + + + + + Label for the filesystem + + + + + FS Label: + + + + + En&crypt + + + + + Logical + + + + + Primary + + + + + GPT + + + + + Mountpoint already in use. Please select another one. + + + + + CreatePartitionJob + + + Create new %1MiB partition on %3 (%2) with entries %4. + + + + + Create new %1MiB partition on %3 (%2). + + + + + Create new %2MiB partition on %4 (%3) with file system %1. + + + + + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2) with entries <em>%4</em>. + + + + + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2). + + + + + Create new <strong>%2MiB</strong> partition on <strong>%4</strong> (%3) with file system <strong>%1</strong>. + + + + + + Creating new %1 partition on %2. + + + + + The installer failed to create partition on disk '%1'. + + + + + CreatePartitionTableDialog + + + Create Partition Table + + + + + Creating a new partition table will delete all existing data on the disk. + + + + + What kind of partition table do you want to create? + + + + + Master Boot Record (MBR) + + + + + GUID Partition Table (GPT) + + + + + CreatePartitionTableJob + + + Create new %1 partition table on %2. + + + + + Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). + + + + + Creating new %1 partition table on %2. + + + + + The installer failed to create a partition table on %1. + + + + + CreateUserJob + + + Create user %1 + + + + + Create user <strong>%1</strong>. + + + + + Preserving home directory + + + + + + Creating user %1 + + + + + Configuring user %1 + + + + + Setting file permissions + + + + + CreateVolumeGroupDialog + + + Create Volume Group + + + + + CreateVolumeGroupJob + + + Create new volume group named %1. + + + + + Create new volume group named <strong>%1</strong>. + + + + + Creating new volume group named %1. + + + + + The installer failed to create a volume group named '%1'. + + + + + DeactivateVolumeGroupJob + + + + Deactivate volume group named %1. + + + + + Deactivate volume group named <strong>%1</strong>. + + + + + The installer failed to deactivate a volume group named %1. + + + + + DeletePartitionJob + + + Delete partition %1. + + + + + Delete partition <strong>%1</strong>. + + + + + Deleting partition %1. + + + + + The installer failed to delete partition %1. + + + + + DeviceInfoWidget + + + This device has a <strong>%1</strong> partition table. + + + + + This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. + + + + + This installer <strong>cannot detect a partition table</strong> on the selected storage device.<br><br>The device either has no partition table, or the partition table is corrupted or of an unknown type.<br>This installer can create a new partition table for you, either automatically, or through the manual partitioning page. + + + + + <br><br>This is the recommended partition table type for modern systems which start from an <strong>EFI</strong> boot environment. + + + + + <br><br>This partition table type is only advisable on older systems which start from a <strong>BIOS</strong> boot environment. GPT is recommended in most other cases.<br><br><strong>Warning:</strong> the MBR partition table is an obsolete MS-DOS era standard.<br>Only 4 <em>primary</em> partitions may be created, and of those 4, one can be an <em>extended</em> partition, which may in turn contain many <em>logical</em> partitions. + + + + + The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. + + + + + DeviceModel + + + %1 - %2 (%3) + device[name] - size[number] (device-node[name]) + + + + + %1 - (%2) + device[name] - (device-node[name]) + + + + + DracutLuksCfgJob + + + Write LUKS configuration for Dracut to %1 + + + + + Skip writing LUKS configuration for Dracut: "/" partition is not encrypted + + + + + Failed to open %1 + + + + + DummyCppJob + + + Dummy C++ Job + + + + + EditExistingPartitionDialog + + + Edit Existing Partition + + + + + Content: + + + + + &Keep + + + + + Format + + + + + Warning: Formatting the partition will erase all existing data. + + + + + &Mount Point: + + + + + Si&ze: + + + + + MiB + + + + + Fi&le System: + + + + + Flags: + + + + + Label for the filesystem + + + + + FS Label: + + + + + Mountpoint already in use. Please select another one. + + + + + EncryptWidget + + + Form + + + + + En&crypt system + + + + + Passphrase + + + + + Confirm passphrase + + + + + + Please enter the same passphrase in both boxes. + + + + + FillGlobalStorageJob + + + Set partition information + + + + + Install %1 on <strong>new</strong> %2 system partition with features <em>%3</em> + + + + + Install %1 on <strong>new</strong> %2 system partition. + + + + + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong> and features <em>%3</em>. + + + + + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>%3. + + + + + Install %2 on %3 system partition <strong>%1</strong> with features <em>%4</em>. + + + + + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong> and features <em>%4</em>. + + + + + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>%4. + + + + + Install %2 on %3 system partition <strong>%1</strong>. + + + + + Install boot loader on <strong>%1</strong>. + + + + + Setting up mount points. + + + + + FinishedPage + + + Form + + + + + &Restart now + + + + + <h1>All done.</h1><br/>%1 has been set up on your computer.<br/>You may now start using your new system. + + + + + <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> + + + + + <h1>All done.</h1><br/>%1 has been installed on your computer.<br/>You may now restart into your new system, or continue using the %2 Live environment. + + + + + <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the installer.</p></body></html> + + + + + <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. + + + + + <h1>Installation Failed</h1><br/>%1 has not been installed on your computer.<br/>The error message was: %2. + + + + + FinishedQmlViewStep + + + Finish + + + + + FinishedViewStep + + + Finish + + + + + FormatPartitionJob + + + Format partition %1 (file system: %2, size: %3 MiB) on %4. + + + + + Format <strong>%3MiB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. + + + + + Formatting partition %1 with file system %2. + + + + + The installer failed to format partition %1 on disk '%2'. + + + + + GeneralRequirements + + + has at least %1 GiB available drive space + + + + + There is not enough drive space. At least %1 GiB is required. + + + + + has at least %1 GiB working memory + + + + + The system does not have enough working memory. At least %1 GiB is required. + + + + + is plugged in to a power source + + + + + The system is not plugged in to a power source. + + + + + is connected to the Internet + + + + + The system is not connected to the Internet. + + + + + is running the installer as an administrator (root) + + + + + The setup program is not running with administrator rights. + + + + + The installer is not running with administrator rights. + + + + + has a screen large enough to show the whole installer + + + + + The screen is too small to display the setup program. + + + + + The screen is too small to display the installer. + + + + + HostInfoJob + + + Collecting information about your machine. + + + + + IDJob + + + + + + OEM Batch Identifier + + + + + Could not create directories <code>%1</code>. + + + + + Could not open file <code>%1</code>. + + + + + Could not write to file <code>%1</code>. + + + + + InitcpioJob + + + Creating initramfs with mkinitcpio. + + + + + InitramfsJob + + + Creating initramfs. + + + + + InteractiveTerminalPage + + + Konsole not installed + + + + + Please install KDE Konsole and try again! + + + + + Executing script: &nbsp;<code>%1</code> + + + + + InteractiveTerminalViewStep + + + Script + + + + + KeyboardQmlViewStep + + + Keyboard + + + + + KeyboardViewStep + + + Keyboard + + + + + LCLocaleDialog + + + System locale setting + + + + + The system locale setting affects the language and character set for some command line user interface elements.<br/>The current setting is <strong>%1</strong>. + + + + + &Cancel + + + + + &OK + + + + + LicensePage + + + Form + + + + + <h1>License Agreement</h1> + + + + + I accept the terms and conditions above. + + + + + Please review the End User License Agreements (EULAs). + + + + + This setup procedure will install proprietary software that is subject to licensing terms. + + + + + If you do not agree with the terms, the setup procedure cannot continue. + + + + + This setup procedure can install proprietary software that is subject to licensing terms in order to provide additional features and enhance the user experience. + + + + + If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. + + + + + LicenseViewStep + + + License + + + + + LicenseWidget + + + URL: %1 + + + + + <strong>%1 driver</strong><br/>by %2 + %1 is an untranslatable product name, example: Creative Audigy driver + + + + + <strong>%1 graphics driver</strong><br/><font color="Grey">by %2</font> + %1 is usually a vendor name, example: Nvidia graphics driver + + + + + <strong>%1 browser plugin</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1 codec</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1 package</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1</strong><br/><font color="Grey">by %2</font> + + + + + File: %1 + + + + + Hide license text + + + + + Show the license text + + + + + Open license agreement in browser. + + + + + LocalePage + + + Region: + + + + + Zone: + + + + + + &Change... + + + + + LocaleQmlViewStep + + + Location + + + + + LocaleTests + + + Quit + + + + + LocaleViewStep + + + Location + + + + + LuksBootKeyFileJob + + + Configuring LUKS key file. + + + + + + No partitions are defined. + + + + + + + Encrypted rootfs setup error + + + + + Root partition %1 is LUKS but no passphrase has been set. + + + + + Could not create LUKS key file for root partition %1. + + + + + Could not configure LUKS key file on partition %1. + + + + + MachineIdJob + + + Generate machine-id. + + + + + Configuration Error + + + + + No root mount point is set for MachineId. + + + + + Map + + + Timezone: %1 + + + + + Please select your preferred location on the map so the installer can suggest the locale + and timezone settings for you. You can fine-tune the suggested settings below. Search the map by dragging + to move and using the +/- buttons to zoom in/out or use mouse scrolling for zooming. + + + + + NetInstallViewStep + + + Package selection + + + + + Office software + + + + + Office package + + + + + Browser software + + + + + Browser package + + + + + Web browser + + + + + Kernel + + + + + Services + + + + + Login + + + + + Desktop + + + + + Applications + + + + + Communication + + + + + Development + + + + + Office + + + + + Multimedia + + + + + Internet + + + + + Theming + + + + + Gaming + + + + + Utilities + + + + + NotesQmlViewStep + + + Notes + + + + + OEMPage + + + Ba&tch: + + + + + <html><head/><body><p>Enter a batch-identifier here. This will be stored in the target system.</p></body></html> + + + + + <html><head/><body><h1>OEM Configuration</h1><p>Calamares will use OEM settings while configuring the target system.</p></body></html> + + + + + OEMViewStep + + + OEM Configuration + + + + + Set the OEM Batch Identifier to <code>%1</code>. + + + + + Offline + + + Select your preferred Region, or use the default settings. + + + + + + + Timezone: %1 + + + + + Select your preferred Zone within your Region. + + + + + Zones + + + + + You can fine-tune Language and Locale settings below. + + + + + PWQ + + + Password is too short + + + + + Password is too long + + + + + Password is too weak + + + + + Memory allocation error when setting '%1' + + + + + Memory allocation error + + + + + The password is the same as the old one + + + + + The password is a palindrome + + + + + The password differs with case changes only + + + + + The password is too similar to the old one + + + + + The password contains the user name in some form + + + + + The password contains words from the real name of the user in some form + + + + + The password contains forbidden words in some form + + + + + The password contains too few digits + + + + + The password contains too few uppercase letters + + + + + The password contains fewer than %n lowercase letters + + + + + + + + The password contains too few lowercase letters + + + + + The password contains too few non-alphanumeric characters + + + + + The password is too short + + + + + The password does not contain enough character classes + + + + + The password contains too many same characters consecutively + + + + + The password contains too many characters of the same class consecutively + + + + + The password contains fewer than %n digits + + + + + + + + The password contains fewer than %n uppercase letters + + + + + + + + The password contains fewer than %n non-alphanumeric characters + + + + + + + + The password is shorter than %n characters + + + + + + + + The password is a rotated version of the previous one + + + + + The password contains fewer than %n character classes + + + + + + + + The password contains more than %n same characters consecutively + + + + + + + + The password contains more than %n characters of the same class consecutively + + + + + + + + The password contains monotonic sequence longer than %n characters + + + + + + + + The password contains too long of a monotonic character sequence + + + + + No password supplied + + + + + Cannot obtain random numbers from the RNG device + + + + + Password generation failed - required entropy too low for settings + + + + + The password fails the dictionary check - %1 + + + + + The password fails the dictionary check + + + + + Unknown setting - %1 + + + + + Unknown setting + + + + + Bad integer value of setting - %1 + + + + + Bad integer value + + + + + Setting %1 is not of integer type + + + + + Setting is not of integer type + + + + + Setting %1 is not of string type + + + + + Setting is not of string type + + + + + Opening the configuration file failed + + + + + The configuration file is malformed + + + + + Fatal failure + + + + + Unknown error + + + + + Password is empty + + + + + PackageChooserPage + + + Form + + + + + Product Name + + + + + TextLabel + + + + + Long Product Description + + + + + Package Selection + + + + + Please pick a product from the list. The selected product will be installed. + + + + + PackageChooserQmlViewStep + + + Packages + + + + + PackageChooserViewStep + + + Packages + + + + + PackageModel + + + Name + + + + + Description + + + + + Page_Keyboard + + + Form + + + + + Keyboard Model: + + + + + Type here to test your keyboard + + + + + Page_UserSetup + + + Form + + + + + What is your name? + + + + + Your Full Name + + + + + What name do you want to use to log in? + + + + + login + + + + + What is the name of this computer? + + + + + <small>This name will be used if you make the computer visible to others on a network.</small> + + + + + Computer Name + + + + + Choose a password to keep your account safe. + + + + + + <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> + + + + + + Password + + + + + + Repeat Password + + + + + When this box is checked, password-strength checking is done and you will not be able to use a weak password. + + + + + Require strong passwords. + + + + + Log in automatically without asking for the password. + + + + + Use the same password for the administrator account. + + + + + Choose a password for the administrator account. + + + + + + <small>Enter the same password twice, so that it can be checked for typing errors.</small> + + + + + PartitionLabelsView + + + Root + + + + + Home + + + + + Boot + + + + + EFI system + + + + + Swap + + + + + New partition for %1 + + + + + New partition + + + + + %1 %2 + size[number] filesystem[name] + + + + + PartitionModel + + + + Free Space + + + + + + New partition + + + + + Name + + + + + File System + + + + + File System Label + + + + + Mount Point + + + + + Size + + + + + PartitionPage + + + Form + + + + + Storage de&vice: + + + + + &Revert All Changes + + + + + New Partition &Table + + + + + Cre&ate + + + + + &Edit + + + + + &Delete + + + + + New Volume Group + + + + + Resize Volume Group + + + + + Deactivate Volume Group + + + + + Remove Volume Group + + + + + I&nstall boot loader on: + + + + + Are you sure you want to create a new partition table on %1? + + + + + Can not create new partition + + + + + The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. + + + + + PartitionViewStep + + + Gathering system information... + + + + + Partitions + + + + + Current: + + + + + After: + + + + + No EFI system partition configured + + + + + EFI system partition configured incorrectly + + + + + An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem. + + + + + The filesystem must be mounted on <strong>%1</strong>. + + + + + The filesystem must have type FAT32. + + + + + The filesystem must be at least %1 MiB in size. + + + + + The filesystem must have flag <strong>%1</strong> set. + + + + + You can continue without setting up an EFI system partition but your system may fail to start. + + + + + Option to use GPT on BIOS + + + + + A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>bios_grub</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. + + + + + Boot partition not encrypted + + + + + A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window. + + + + + has at least one disk device available. + + + + + There are no partitions to install on. + + + + + PlasmaLnfJob + + + Plasma Look-and-Feel Job + + + + + + Could not select KDE Plasma Look-and-Feel package + + + + + PlasmaLnfPage + + + Form + + + + + Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is set up. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. + + + + + Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. + + + + + PlasmaLnfViewStep + + + Look-and-Feel + + + + + PreserveFiles + + + Saving files for later ... + + + + + No files configured to save for later. + + + + + Not all of the configured files could be preserved. + + + + + ProcessResult + + + +There was no output from the command. + + + + + +Output: + + + + + + External command crashed. + + + + + Command <i>%1</i> crashed. + + + + + External command failed to start. + + + + + Command <i>%1</i> failed to start. + + + + + Internal error when starting command. + + + + + Bad parameters for process job call. + + + + + External command failed to finish. + + + + + Command <i>%1</i> failed to finish in %2 seconds. + + + + + External command finished with errors. + + + + + Command <i>%1</i> finished with exit code %2. + + + + + QObject + + + %1 (%2) + + + + + unknown + + + + + extended + + + + + unformatted + + + + + swap + + + + + + Default + + + + + + + + File not found + + + + + Path <pre>%1</pre> must be an absolute path. + + + + + Directory not found + + + + + + Could not create new random file <pre>%1</pre>. + + + + + No product + + + + + No description provided. + + + + + (no mount point) + + + + + Unpartitioned space or unknown partition table + + + + + Recommended + + + <p>This computer does not satisfy some of the recommended requirements for setting up %1.<br/> + Setup can continue, but some features might be disabled.</p> + + + + + RemoveUserJob + + + Remove live user from target system + + + + + RemoveVolumeGroupJob + + + + Remove Volume Group named %1. + + + + + Remove Volume Group named <strong>%1</strong>. + + + + + The installer failed to remove a volume group named '%1'. + + + + + ReplaceWidget + + + Form + + + + + Select where to install %1.<br/><font color="red">Warning: </font>this will delete all files on the selected partition. + + + + + The selected item does not appear to be a valid partition. + + + + + %1 cannot be installed on empty space. Please select an existing partition. + + + + + %1 cannot be installed on an extended partition. Please select an existing primary or logical partition. + + + + + %1 cannot be installed on this partition. + + + + + Data partition (%1) + + + + + Unknown system partition (%1) + + + + + %1 system partition (%2) + + + + + <strong>%4</strong><br/><br/>The partition %1 is too small for %2. Please select a partition with capacity at least %3 GiB. + + + + + <strong>%2</strong><br/><br/>An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. + + + + + + + <strong>%3</strong><br/><br/>%1 will be installed on %2.<br/><font color="red">Warning: </font>all data on partition %2 will be lost. + + + + + The EFI system partition at %1 will be used for starting %2. + + + + + EFI system partition: + + + + + Requirements + + + <p>This computer does not satisfy the minimum requirements for installing %1.<br/> + Installation cannot continue.</p> + + + + + <p>This computer does not satisfy some of the recommended requirements for setting up %1.<br/> + Setup can continue, but some features might be disabled.</p> + + + + + ResizeFSJob + + + Resize Filesystem Job + + + + + Invalid configuration + + + + + The file-system resize job has an invalid configuration and will not run. + + + + + KPMCore not Available + + + + + Calamares cannot start KPMCore for the file-system resize job. + + + + + + + + + Resize Failed + + + + + The filesystem %1 could not be found in this system, and cannot be resized. + + + + + The device %1 could not be found in this system, and cannot be resized. + + + + + + The filesystem %1 cannot be resized. + + + + + + The device %1 cannot be resized. + + + + + The filesystem %1 must be resized, but cannot. + + + + + The device %1 must be resized, but cannot + + + + + ResizePartitionJob + + + Resize partition %1. + + + + + Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. + + + + + Resizing %2MiB partition %1 to %3MiB. + + + + + The installer failed to resize partition %1 on disk '%2'. + + + + + ResizeVolumeGroupDialog + + + Resize Volume Group + + + + + ResizeVolumeGroupJob + + + + Resize volume group named %1 from %2 to %3. + + + + + Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. + + + + + The installer failed to resize a volume group named '%1'. + + + + + ResultsListDialog + + + For best results, please ensure that this computer: + + + + + System requirements + + + + + ScanningDialog + + + Scanning storage devices... + + + + + Partitioning + + + + + SetHostNameJob + + + Set hostname %1 + + + + + Set hostname <strong>%1</strong>. + + + + + Setting hostname %1. + + + + + + Internal Error + + + + + + Cannot write hostname to target system + + + + + SetKeyboardLayoutJob + + + Set keyboard model to %1, layout to %2-%3 + + + + + Failed to write keyboard configuration for the virtual console. + + + + + + + Failed to write to %1 + + + + + Failed to write keyboard configuration for X11. + + + + + Failed to write keyboard configuration to existing /etc/default directory. + + + + + SetPartFlagsJob + + + Set flags on partition %1. + + + + + Set flags on %1MiB %2 partition. + + + + + Set flags on new partition. + + + + + Clear flags on partition <strong>%1</strong>. + + + + + Clear flags on %1MiB <strong>%2</strong> partition. + + + + + Clear flags on new partition. + + + + + Flag partition <strong>%1</strong> as <strong>%2</strong>. + + + + + Flag %1MiB <strong>%2</strong> partition as <strong>%3</strong>. + + + + + Flag new partition as <strong>%1</strong>. + + + + + Clearing flags on partition <strong>%1</strong>. + + + + + Clearing flags on %1MiB <strong>%2</strong> partition. + + + + + Clearing flags on new partition. + + + + + Setting flags <strong>%2</strong> on partition <strong>%1</strong>. + + + + + Setting flags <strong>%3</strong> on %1MiB <strong>%2</strong> partition. + + + + + Setting flags <strong>%1</strong> on new partition. + + + + + The installer failed to set flags on partition %1. + + + + + SetPasswordJob + + + Set password for user %1 + + + + + Setting password for user %1. + + + + + Bad destination system path. + + + + + rootMountPoint is %1 + + + + + Cannot disable root account. + + + + + passwd terminated with error code %1. + + + + + Cannot set password for user %1. + + + + + usermod terminated with error code %1. + + + + + SetTimezoneJob + + + Set timezone to %1/%2 + + + + + Cannot access selected timezone path. + + + + + Bad path: %1 + + + + + Cannot set timezone. + + + + + Link creation failed, target: %1; link name: %2 + + + + + Cannot set timezone, + + + + + Cannot open /etc/timezone for writing + + + + + SetupGroupsJob + + + Preparing groups. + + + + + + Could not create groups in target system + + + + + These groups are missing in the target system: %1 + + + + + SetupSudoJob + + + Configure <pre>sudo</pre> users. + + + + + Cannot chmod sudoers file. + + + + + Cannot create sudoers file for writing. + + + + + ShellProcessJob + + + Shell Processes Job + + + + + SlideCounter + + + %L1 / %L2 + slide counter, %1 of %2 (numeric) + + + + + StandardButtons + + + &OK + + + + + &Yes + + + + + &No + + + + + &Cancel + + + + + &Close + + + + + TrackingInstallJob + + + Installation feedback + + + + + Sending installation feedback. + + + + + Internal error in install-tracking. + + + + + HTTP request timed out. + + + + + TrackingKUserFeedbackJob + + + KDE user feedback + + + + + Configuring KDE user feedback. + + + + + + Error in KDE user feedback configuration. + + + + + Could not configure KDE user feedback correctly, script error %1. + + + + + Could not configure KDE user feedback correctly, Calamares error %1. + + + + + TrackingMachineUpdateManagerJob + + + Machine feedback + + + + + Configuring machine feedback. + + + + + + Error in machine feedback configuration. + + + + + Could not configure machine feedback correctly, script error %1. + + + + + Could not configure machine feedback correctly, Calamares error %1. + + + + + TrackingPage + + + Form + + + + + Placeholder + + + + + <html><head/><body><p>Click here to send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> + + + + + <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">Click here for more information about user feedback</span></a></p></body></html> + + + + + Tracking helps %1 to see how often it is installed, what hardware it is installed on and which applications are used. To see what will be sent, please click the help icon next to each area. + + + + + By selecting this you will send information about your installation and hardware. This information will only be sent <b>once</b> after the installation finishes. + + + + + By selecting this you will periodically send information about your <b>machine</b> installation, hardware and applications, to %1. + + + + + By selecting this you will regularly send information about your <b>user</b> installation, hardware, applications and application usage patterns, to %1. + + + + + TrackingViewStep + + + Feedback + + + + + UsersPage + + + <small>If more than one person will use this computer, you can create multiple accounts after setup.</small> + + + + + <small>If more than one person will use this computer, you can create multiple accounts after installation.</small> + + + + + UsersQmlViewStep + + + Users + + + + + UsersViewStep + + + Users + + + + + VariantModel + + + Key + Column header for key/value + + + + + Value + Column header for key/value + + + + + VolumeGroupBaseDialog + + + Create Volume Group + + + + + List of Physical Volumes + + + + + Volume Group Name: + + + + + Volume Group Type: + + + + + Physical Extent Size: + + + + + MiB + + + + + Total Size: + + + + + Used Size: + + + + + Total Sectors: + + + + + Quantity of LVs: + + + + + WelcomePage + + + Form + + + + + + Select application and system language + + + + + &About + + + + + Open donations website + + + + + &Donate + + + + + Open help and support website + + + + + &Support + + + + + Open issues and bug-tracking website + + + + + &Known issues + + + + + Open release notes website + + + + + &Release notes + + + + + <h1>Welcome to the Calamares setup program for %1.</h1> + + + + + <h1>Welcome to %1 setup.</h1> + + + + + <h1>Welcome to the Calamares installer for %1.</h1> + + + + + <h1>Welcome to the %1 installer.</h1> + + + + + %1 support + + + + + About %1 setup + + + + + About %1 installer + + + + + <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. + + + + + WelcomeQmlViewStep + + + Welcome + + + + + WelcomeViewStep + + + Welcome + + + + + about + + + <h1>%1</h1><br/> + <strong>%2<br/> + for %3</strong><br/><br/> + Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/> + Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/> + Thanks to <a href='https://calamares.io/team/'>the Calamares team</a> + and the <a href='https://www.transifex.com/calamares/calamares/'>Calamares + translators team</a>.<br/><br/> + <a href='https://calamares.io/'>Calamares</a> + development is sponsored by <br/> + <a href='http://www.blue-systems.com/'>Blue Systems</a> - + Liberating Software. + + + + + Back + + + + + calamares-sidebar + + + Show debug information + + + + + finishedq + + + Installation Completed + + + + + %1 has been installed on your computer.<br/> + You may now restart into your new system, or continue using the Live environment. + + + + + Close Installer + + + + + Restart System + + + + + <p>A full log of the install is available as installation.log in the home directory of the Live user.<br/> + This log is copied to /var/log/installation.log of the target system.</p> + + + + + i18n + + + <h1>Languages</h1> </br> + The system locale setting affects the language and character set for some command line user interface elements. The current setting is <strong>%1</strong>. + + + + + <h1>Locales</h1> </br> + The system locale setting affects the numbers and dates format. The current setting is <strong>%1</strong>. + + + + + Back + + + + + keyboardq + + + To activate keyboard preview, select a layout. + + + + + Keyboard Model: + + + + + Layouts + + + + + Type here to test your keyboard + + + + + Variants + + + + + localeq + + + Change + + + + + notesqml + + + <h3>%1</h3> + <p>These are example release notes.</p> + + + + + packagechooserq + + + LibreOffice is a powerful and free office suite, used by millions of people around the world. It includes several applications that make it the most versatile Free and Open Source office suite on the market.<br/> + Default option. + + + + + LibreOffice + + + + + If you don't want to install an office suite, just select No Office Suite. You can always add one (or more) later on your installed system as the need arrives. + + + + + No Office Suite + + + + + Create a minimal Desktop install, remove all extra applications and decide later on what you would like to add to your system. Examples of what won't be on such an install, there will be no Office Suite, no media players, no image viewer or print support. It will be just a desktop, file browser, package manager, text editor and simple web-browser. + + + + + Minimal Install + + + + + Please select an option for your install, or use the default: LibreOffice included. + + + + + release_notes + + + <h3>%1</h3> + <p>This an example QML file, showing options in RichText with Flickable content.</p> + + <p>QML with RichText can use HTML tags, Flickable content is useful for touchscreens.</p> + + <p><b>This is bold text</b></p> + <p><i>This is italic text</i></p> + <p><u>This is underlined text</u></p> + <p><center>This text will be center-aligned.</center></p> + <p><s>This is strikethrough</s></p> + + <p>Code example: + <code>ls -l /home</code></p> + + <p><b>Lists:</b></p> + <ul> + <li>Intel CPU systems</li> + <li>AMD CPU systems</li> + </ul> + + <p>The vertical scrollbar is adjustable, current width set to 10.</p> + + + + + Back + + + + + usersq + + + Pick your user name and credentials to login and perform admin tasks + + + + + What is your name? + + + + + Your Full Name + + + + + What name do you want to use to log in? + + + + + Login Name + + + + + If more than one person will use this computer, you can create multiple accounts after installation. + + + + + Only lowercase letters, numbers, underscore and hyphen are allowed. + + + + + root is not allowed as username. + + + + + What is the name of this computer? + + + + + Computer Name + + + + + This name will be used if you make the computer visible to others on a network. + + + + + localhost is not allowed as hostname. + + + + + Choose a password to keep your account safe. + + + + + Password + + + + + Repeat Password + + + + + Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals. + + + + + Validate passwords quality + + + + + When this box is checked, password-strength checking is done and you will not be able to use a weak password. + + + + + Log in automatically without asking for the password + + + + + Only letters, numbers, underscore and hyphen are allowed, minimal of two characters. + + + + + Reuse user password as root password + + + + + Use the same password for the administrator account. + + + + + Choose a root password to keep your account safe. + + + + + Root Password + + + + + Repeat Root Password + + + + + Enter the same password twice, so that it can be checked for typing errors. + + + + + welcomeq + + + <h3>Welcome to the %1 <quote>%2</quote> installer</h3> + <p>This program will ask you some questions and set up %1 on your computer.</p> + + + + + About + + + + + Support + + + + + Known issues + + + + + Release notes + + + + + Donate + + + + diff --git a/lang/calamares_vi.ts b/lang/calamares_vi.ts index 9e59b527d..14d93dade 100644 --- a/lang/calamares_vi.ts +++ b/lang/calamares_vi.ts @@ -6,7 +6,7 @@ Manage auto-mount settings - + Quản lý cài đặt tự động gắn kết(auto-mount) @@ -104,22 +104,22 @@ Crashes Calamares, so that Dr. Konqui can look at it. - + Gây crash Calamares, để Dr. Konqui có thể xem nó. Reloads the stylesheet from the branding directory. - + Tải lại stylesheet từ thư mục branding Uploads the session log to the configured pastebin. - + Đăng tải log của phiên này lên pastebin đã được cấu hình Send Session Log - + Gửi log của phiên này @@ -129,7 +129,7 @@ Displays the tree of widget names in the log (for stylesheet debugging). - + Hiễn thị cây của tên widget trong log(để gỡ lỗi stylesheet) From cfeba736d5042a2ac7177037e77c1fc10956b598 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Sat, 18 Dec 2021 00:38:13 +0100 Subject: [PATCH 086/168] i18n: [python] Automatic merge of Transifex translations --- lang/python/en_GB/LC_MESSAGES/python.po | 17 +- lang/python/hi/LC_MESSAGES/python.po | 4 +- lang/python/pl/LC_MESSAGES/python.po | 2 +- lang/python/ro/LC_MESSAGES/python.po | 11 +- lang/python/ta_IN/LC_MESSAGES/python.po | 387 ++++++++++++++++++++++++ lang/python/vi/LC_MESSAGES/python.po | 4 +- 6 files changed, 408 insertions(+), 17 deletions(-) create mode 100644 lang/python/ta_IN/LC_MESSAGES/python.po diff --git a/lang/python/en_GB/LC_MESSAGES/python.po b/lang/python/en_GB/LC_MESSAGES/python.po index 34fcd2d7a..c2d93d0f8 100644 --- a/lang/python/en_GB/LC_MESSAGES/python.po +++ b/lang/python/en_GB/LC_MESSAGES/python.po @@ -5,6 +5,7 @@ # # Translators: # Jason Collins , 2018 +# Karthik Balan, 2021 # #, fuzzy msgid "" @@ -13,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Jason Collins , 2018\n" +"Last-Translator: Karthik Balan, 2021\n" "Language-Team: English (United Kingdom) (https://www.transifex.com/calamares/teams/20061/en_GB/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -35,7 +36,7 @@ msgstr "" #: src/modules/luksopenswaphookcfg/main.py:86 #: src/modules/luksopenswaphookcfg/main.py:90 msgid "Configuration Error" -msgstr "" +msgstr "Configuration Error " #: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356 #: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145 @@ -61,7 +62,7 @@ msgstr "" #: src/modules/bootloader/main.py:508 msgid "Bootloader installation error" -msgstr "" +msgstr "Bootloader installation error" #: src/modules/bootloader/main.py:509 msgid "" @@ -91,7 +92,7 @@ msgstr "" #: src/modules/displaymanager/main.py:526 msgid "Cannot write KDM configuration file" -msgstr "" +msgstr "Cannot write KDM configuration file" #: src/modules/displaymanager/main.py:527 msgid "KDM config file {!s} does not exist" @@ -145,7 +146,7 @@ msgstr "" #: src/modules/services-openrc/main.py:29 msgid "Configure OpenRC services" -msgstr "" +msgstr "Configure OpenRC services" #: src/modules/services-openrc/main.py:57 msgid "Cannot add service {name!s} to run-level {level!s}." @@ -173,7 +174,7 @@ msgstr "" #: src/modules/services-openrc/main.py:101 msgid "Target runlevel does not exist" -msgstr "" +msgstr "Target runlevel does not exist" #: src/modules/services-openrc/main.py:102 msgid "" @@ -193,7 +194,7 @@ msgstr "" #: src/modules/networkcfg/main.py:29 msgid "Saving network configuration." -msgstr "" +msgstr "Saving network configuration " #: src/modules/packages/main.py:50 src/modules/packages/main.py:59 #: src/modules/packages/main.py:69 @@ -222,7 +223,7 @@ msgstr[1] "Removing %(num)d packages." #: src/modules/packages/main.py:638 src/modules/packages/main.py:650 #: src/modules/packages/main.py:678 msgid "Package Manager error" -msgstr "" +msgstr "Package Manager error" #: src/modules/packages/main.py:639 msgid "" diff --git a/lang/python/hi/LC_MESSAGES/python.po b/lang/python/hi/LC_MESSAGES/python.po index c80f08842..00914664c 100644 --- a/lang/python/hi/LC_MESSAGES/python.po +++ b/lang/python/hi/LC_MESSAGES/python.po @@ -319,7 +319,7 @@ msgstr "systemd लक्ष्य {name!s}सक्रिय क #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "" +msgstr "systemd टाइमर {name!s}सक्रिय करना विफल।" #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." @@ -399,6 +399,8 @@ msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." msgstr "" +"unsqaushfs खोजने में विफल, सुनिश्चित करें कि squashfs-tools पैकेज इंस्टॉल " +"है।" #: src/modules/unpackfs/main.py:479 msgid "The destination \"{}\" in the target system is not a directory" diff --git a/lang/python/pl/LC_MESSAGES/python.po b/lang/python/pl/LC_MESSAGES/python.po index ea9756e2b..7d4100a03 100644 --- a/lang/python/pl/LC_MESSAGES/python.po +++ b/lang/python/pl/LC_MESSAGES/python.po @@ -4,7 +4,7 @@ # FIRST AUTHOR , YEAR. # # Translators: -# Marcin Mikołajczak , 2017 +# marcin mikołajczak , 2017 # KagiSame, 2018 # Piotr Strębski , 2020 # Jacob B. , 2021 diff --git a/lang/python/ro/LC_MESSAGES/python.po b/lang/python/ro/LC_MESSAGES/python.po index ab6e35e7f..91be0dd5a 100644 --- a/lang/python/ro/LC_MESSAGES/python.po +++ b/lang/python/ro/LC_MESSAGES/python.po @@ -6,6 +6,7 @@ # Translators: # Jobava Jobava , 2018 # Sebastian Brici , 2018 +# Chele Ion , 2021 # #, fuzzy msgid "" @@ -14,7 +15,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Sebastian Brici , 2018\n" +"Last-Translator: Chele Ion , 2021\n" "Language-Team: Romanian (https://www.transifex.com/calamares/teams/20061/ro/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,7 +25,7 @@ msgstr "" #: src/modules/initramfscfg/main.py:32 msgid "Configuring initramfs." -msgstr "" +msgstr "Configurare initramfs" #: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 #: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361 @@ -36,21 +37,21 @@ msgstr "" #: src/modules/luksopenswaphookcfg/main.py:86 #: src/modules/luksopenswaphookcfg/main.py:90 msgid "Configuration Error" -msgstr "" +msgstr "Eroare de configurare" #: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356 #: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145 #: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73 #: src/modules/luksopenswaphookcfg/main.py:87 msgid "No partitions are defined for
{!s}
to use." -msgstr "" +msgstr "Nu sunt partiţii definite ca 1{!s}1 ." #: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362 #: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232 #: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77 #: src/modules/luksopenswaphookcfg/main.py:91 msgid "No root mount point is given for
{!s}
to use." -msgstr "" +msgstr "Nu este definită o partiţie rădăcină pentru 1{!s}1 ." #: src/modules/grubcfg/main.py:28 msgid "Configure GRUB." diff --git a/lang/python/ta_IN/LC_MESSAGES/python.po b/lang/python/ta_IN/LC_MESSAGES/python.po new file mode 100644 index 000000000..666703faf --- /dev/null +++ b/lang/python/ta_IN/LC_MESSAGES/python.po @@ -0,0 +1,387 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-11-02 15:45+0100\n" +"PO-Revision-Date: 2017-08-09 10:34+0000\n" +"Language-Team: Tamil (India) (https://www.transifex.com/calamares/teams/20061/ta_IN/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ta_IN\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/modules/initramfscfg/main.py:32 +msgid "Configuring initramfs." +msgstr "" + +#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 +#: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361 +#: src/modules/fstab/main.py:388 src/modules/networkcfg/main.py:105 +#: src/modules/initcpiocfg/main.py:227 src/modules/initcpiocfg/main.py:231 +#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:144 +#: src/modules/rawfs/main.py:164 src/modules/openrcdmcryptcfg/main.py:72 +#: src/modules/openrcdmcryptcfg/main.py:76 +#: src/modules/luksopenswaphookcfg/main.py:86 +#: src/modules/luksopenswaphookcfg/main.py:90 +msgid "Configuration Error" +msgstr "" + +#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356 +#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145 +#: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73 +#: src/modules/luksopenswaphookcfg/main.py:87 +msgid "No partitions are defined for
{!s}
to use." +msgstr "" + +#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362 +#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232 +#: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77 +#: src/modules/luksopenswaphookcfg/main.py:91 +msgid "No root mount point is given for
{!s}
to use." +msgstr "" + +#: src/modules/grubcfg/main.py:28 +msgid "Configure GRUB." +msgstr "" + +#: src/modules/bootloader/main.py:43 +msgid "Install bootloader." +msgstr "" + +#: src/modules/bootloader/main.py:508 +msgid "Bootloader installation error" +msgstr "" + +#: src/modules/bootloader/main.py:509 +msgid "" +"The bootloader could not be installed. The installation command " +"
{!s}
returned error code {!s}." +msgstr "" + +#: src/modules/fstab/main.py:29 +msgid "Writing fstab." +msgstr "" + +#: src/modules/fstab/main.py:389 +msgid "No
{!s}
configuration is given for
{!s}
to use." +msgstr "" + +#: src/modules/dracut/main.py:27 +msgid "Creating initramfs with dracut." +msgstr "" + +#: src/modules/dracut/main.py:49 +msgid "Failed to run dracut on the target" +msgstr "" + +#: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50 +msgid "The exit code was {}" +msgstr "" + +#: src/modules/displaymanager/main.py:526 +msgid "Cannot write KDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:527 +msgid "KDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:588 +msgid "Cannot write LXDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:589 +msgid "LXDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:672 +msgid "Cannot write LightDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:673 +msgid "LightDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:747 +msgid "Cannot configure LightDM" +msgstr "" + +#: src/modules/displaymanager/main.py:748 +msgid "No LightDM greeter installed." +msgstr "" + +#: src/modules/displaymanager/main.py:779 +msgid "Cannot write SLIM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:780 +msgid "SLIM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:906 +msgid "No display managers selected for the displaymanager module." +msgstr "" + +#: src/modules/displaymanager/main.py:907 +msgid "" +"The displaymanagers list is empty or undefined in both globalstorage and " +"displaymanager.conf." +msgstr "" + +#: src/modules/displaymanager/main.py:989 +msgid "Display manager configuration was incomplete" +msgstr "" + +#: src/modules/services-openrc/main.py:29 +msgid "Configure OpenRC services" +msgstr "" + +#: src/modules/services-openrc/main.py:57 +msgid "Cannot add service {name!s} to run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:59 +msgid "Cannot remove service {name!s} from run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:61 +msgid "" +"Unknown service-action {arg!s} for service {name!s} in run-" +"level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:93 +#: src/modules/services-systemd/main.py:59 +msgid "Cannot modify service" +msgstr "" + +#: src/modules/services-openrc/main.py:94 +msgid "" +"rc-update {arg!s} call in chroot returned error code {num!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:101 +msgid "Target runlevel does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:102 +msgid "" +"The path for runlevel {level!s} is {path!s}, which does not " +"exist." +msgstr "" + +#: src/modules/services-openrc/main.py:110 +msgid "Target service does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:111 +msgid "" +"The path for service {name!s} is {path!s}, which does not " +"exist." +msgstr "" + +#: src/modules/networkcfg/main.py:29 +msgid "Saving network configuration." +msgstr "" + +#: src/modules/packages/main.py:50 src/modules/packages/main.py:59 +#: src/modules/packages/main.py:69 +msgid "Install packages." +msgstr "" + +#: src/modules/packages/main.py:57 +#, python-format +msgid "Processing packages (%(count)d / %(total)d)" +msgstr "" + +#: src/modules/packages/main.py:62 +#, python-format +msgid "Installing one package." +msgid_plural "Installing %(num)d packages." +msgstr[0] "" +msgstr[1] "" + +#: src/modules/packages/main.py:65 +#, python-format +msgid "Removing one package." +msgid_plural "Removing %(num)d packages." +msgstr[0] "" +msgstr[1] "" + +#: src/modules/packages/main.py:638 src/modules/packages/main.py:650 +#: src/modules/packages/main.py:678 +msgid "Package Manager error" +msgstr "" + +#: src/modules/packages/main.py:639 +msgid "" +"The package manager could not prepare updates. The command
{!s}
" +"returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:651 +msgid "" +"The package manager could not update the system. The command
{!s}
" +" returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:679 +msgid "" +"The package manager could not make changes to the installed system. The " +"command
{!s}
returned error code {!s}." +msgstr "" + +#: src/modules/plymouthcfg/main.py:27 +msgid "Configure Plymouth theme" +msgstr "" + +#: src/modules/initcpiocfg/main.py:28 +msgid "Configuring mkinitcpio." +msgstr "" + +#: src/modules/localecfg/main.py:30 +msgid "Configuring locales." +msgstr "" + +#: src/modules/mount/main.py:30 +msgid "Mounting partitions." +msgstr "" + +#: src/modules/rawfs/main.py:26 +msgid "Installing data." +msgstr "" + +#: src/modules/dummypython/main.py:35 +msgid "Dummy python job." +msgstr "" + +#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 +#: src/modules/dummypython/main.py:94 +msgid "Dummy python step {}" +msgstr "" + +#: src/modules/hwclock/main.py:26 +msgid "Setting hardware clock." +msgstr "" + +#: src/modules/umount/main.py:31 +msgid "Unmount file systems." +msgstr "" + +#: src/modules/openrcdmcryptcfg/main.py:26 +msgid "Configuring OpenRC dmcrypt service." +msgstr "" + +#: src/modules/services-systemd/main.py:26 +msgid "Configure systemd services" +msgstr "" + +#: src/modules/services-systemd/main.py:60 +msgid "" +"systemctl {arg!s} call in chroot returned error code {num!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:63 +#: src/modules/services-systemd/main.py:69 +msgid "Cannot enable systemd service {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:65 +msgid "Cannot enable systemd target {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:67 +msgid "Cannot enable systemd timer {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:71 +msgid "Cannot disable systemd target {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:73 +msgid "Cannot mask systemd unit {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:75 +msgid "" +"Unknown systemd commands {command!s} and " +"{suffix!s} for unit {name!s}." +msgstr "" + +#: src/modules/mkinitfs/main.py:27 +msgid "Creating initramfs with mkinitfs." +msgstr "" + +#: src/modules/mkinitfs/main.py:49 +msgid "Failed to run mkinitfs on the target" +msgstr "" + +#: src/modules/unpackfs/main.py:34 +msgid "Filling up filesystems." +msgstr "" + +#: src/modules/unpackfs/main.py:254 +msgid "rsync failed with error code {}." +msgstr "" + +#: src/modules/unpackfs/main.py:299 +msgid "Unpacking image {}/{}, file {}/{}" +msgstr "" + +#: src/modules/unpackfs/main.py:314 +msgid "Starting to unpack {}" +msgstr "" + +#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:465 +msgid "Failed to unpack image \"{}\"" +msgstr "" + +#: src/modules/unpackfs/main.py:430 +msgid "No mount point for root partition" +msgstr "" + +#: src/modules/unpackfs/main.py:431 +msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" +msgstr "" + +#: src/modules/unpackfs/main.py:436 +msgid "Bad mount point for root partition" +msgstr "" + +#: src/modules/unpackfs/main.py:437 +msgid "rootMountPoint is \"{}\", which does not exist, doing nothing" +msgstr "" + +#: src/modules/unpackfs/main.py:453 src/modules/unpackfs/main.py:457 +#: src/modules/unpackfs/main.py:463 src/modules/unpackfs/main.py:478 +msgid "Bad unsquash configuration" +msgstr "" + +#: src/modules/unpackfs/main.py:454 +msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel" +msgstr "" + +#: src/modules/unpackfs/main.py:458 +msgid "The source filesystem \"{}\" does not exist" +msgstr "" + +#: src/modules/unpackfs/main.py:464 +msgid "" +"Failed to find unsquashfs, make sure you have the squashfs-tools package " +"installed." +msgstr "" + +#: src/modules/unpackfs/main.py:479 +msgid "The destination \"{}\" in the target system is not a directory" +msgstr "" + +#: src/modules/luksopenswaphookcfg/main.py:26 +msgid "Configuring encrypted swap." +msgstr "" diff --git a/lang/python/vi/LC_MESSAGES/python.po b/lang/python/vi/LC_MESSAGES/python.po index 900b99454..8948806ae 100644 --- a/lang/python/vi/LC_MESSAGES/python.po +++ b/lang/python/vi/LC_MESSAGES/python.po @@ -5,7 +5,7 @@ # # Translators: # T. Tran , 2020 -# Th1nhhdk, 2021 +# th1nhhdk , 2021 # #, fuzzy msgid "" @@ -14,7 +14,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Th1nhhdk, 2021\n" +"Last-Translator: th1nhhdk , 2021\n" "Language-Team: Vietnamese (https://www.transifex.com/calamares/teams/20061/vi/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From 0145f6fe7dceeecf5c28784c4412a9a7cad0fdf7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 18 Dec 2021 00:38:58 +0100 Subject: [PATCH 087/168] CMake: language stats --- CMakeLists.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15f40803e..c8b233f50 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,15 +135,15 @@ set( CALAMARES_DESCRIPTION_SUMMARY # NOTE: update these lines by running `txstats.py`, or for full automation # `txstats.py -e`. See also # -# Total 81 languages -set( _tx_complete az az_AZ ca de fa fi_FI he hr ja ko lt pt_PT si - sq tr_TR uk zh_TW ) -set( _tx_good as be ca@valencia cs_CZ da fr fur hi it_IT ml nl - pt_BR ru sk sv tg vi zh_CN ) +# Total 74 languages +set( _tx_complete az az_AZ ca de fa fi_FI he hi hr ja ko lt pt_BR + pt_PT si sq sv tr_TR uk zh_TW ) +set( _tx_good as be ca@valencia cs_CZ da fr fur it_IT ml nl ru sk + tg vi zh_CN ) set( _tx_ok ar ast bg bn el en_GB es es_MX et eu gl hu id is mr nb pl ro sl sr sr@latin th ) -set( _tx_incomplete en_HK en_IN eo es_PE es_PR fr_CH gu hi_IN id_ID - ie kk kn ko_KR lo lv mk ne ne_NP te te_IN ur zh zh_HK ) +set( _tx_incomplete eo es_PR gu ie kk kn lo lv mk ne ne_NP ta_IN te + ur zh zh_HK ) ### Required versions # From da72e815dc7fb1c63c2211612ca9824f4eb307ea Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 18 Dec 2021 00:43:30 +0100 Subject: [PATCH 088/168] [luksopenswaphookcfg] Fix build, missing include --- src/modules/luksopenswaphookcfg/LOSHJob.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/luksopenswaphookcfg/LOSHJob.cpp b/src/modules/luksopenswaphookcfg/LOSHJob.cpp index 916ffcb8b..42f160460 100644 --- a/src/modules/luksopenswaphookcfg/LOSHJob.cpp +++ b/src/modules/luksopenswaphookcfg/LOSHJob.cpp @@ -19,6 +19,7 @@ #include #include +#include #include LOSHJob::LOSHJob( QObject* parent ) From 728315d3cc1e91edb35945ac6209b3f45ab633b7 Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 19 Dec 2021 12:54:39 +0100 Subject: [PATCH 089/168] README, link to actual GPL 3.0 license fixing https://github.com/calamares/calamares/issues/1859 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fa2dfda7..c4c7a5e24 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Current issue](https://img.shields.io/badge/issue-in_progress-FE9B48)](https://github.com/calamares/calamares/labels/hacking%3A%20in-progress) [![GitHub release](https://img.shields.io/github/release/calamares/calamares.svg)](https://github.com/calamares/calamares/releases) [![GitHub Build Status](https://img.shields.io/github/workflow/status/calamares/calamares/ci?label=GH%20build)](https://github.com/calamares/calamares/actions?query=workflow%3Aci) -[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSE) +[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSES/LGPL-3.0-or-later.txt) | [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://www.transifex.com/projects/p/calamares/) | [Contribute](CONTRIBUTING.md) | [Matrix: #calamares:kde.org](https://webchat.kde.org/#/room/%23calamares:kde.org) | [IRC: Libera.Chat #calamares](https://kiwiirc.com/client/irc.libera.chat/#calamares) | [Wiki](https://github.com/calamares/calamares/wiki) | From f0aba5db965d178c97717c843f61e3a1ffc081b6 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 19 Dec 2021 15:29:42 -0600 Subject: [PATCH 090/168] Update modules readme for Python emergency modules support --- src/modules/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/README.md b/src/modules/README.md index 7b4d4b3a3..09696e66b 100644 --- a/src/modules/README.md +++ b/src/modules/README.md @@ -86,18 +86,18 @@ it needs those keys. ### Emergency Modules -Only C++ modules and job modules may be emergency modules. If, during an -*exec* step in the sequence, a module fails, installation as a whole fails -and the install is aborted. If there are emergency modules in the **same** -exec block, those will be executed before the installation is aborted. -Non-emergency modules are not executed. +If, during an *exec* step in the sequence, a module fails, installation as +a whole fails and the install is aborted. If there are emergency modules +in the **same** exec block, those will be executed before the installation +is aborted. Non-emergency modules are not executed. If an emergency-module fails while processing emergency-modules for another failed module, that failure is ignored and emergency-module processing continues. Use the EMERGENCY keyword in the CMake description of a C++ module -to generate a suitable `module.desc`. +to generate a suitable `module.desc`. For Python modules, manually add +`emergency: true` to `module.desc`. A module that is marked as an emergency module in its module.desc must **also** set the *emergency* key to *true* in its configuration file From 7864ab5cfaba8e59e35c65e7bec0953fc53c8d5b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Dec 2021 01:02:13 +0100 Subject: [PATCH 091/168] Docs: link to GPLv3+ --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4c7a5e24..3e79d9a72 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [![Current issue](https://img.shields.io/badge/issue-in_progress-FE9B48)](https://github.com/calamares/calamares/labels/hacking%3A%20in-progress) [![GitHub release](https://img.shields.io/github/release/calamares/calamares.svg)](https://github.com/calamares/calamares/releases) [![GitHub Build Status](https://img.shields.io/github/workflow/status/calamares/calamares/ci?label=GH%20build)](https://github.com/calamares/calamares/actions?query=workflow%3Aci) -[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSES/LGPL-3.0-or-later.txt) +[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSES/GPL-3.0-or-later.txt) | [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://www.transifex.com/projects/p/calamares/) | [Contribute](CONTRIBUTING.md) | [Matrix: #calamares:kde.org](https://webchat.kde.org/#/room/%23calamares:kde.org) | [IRC: Libera.Chat #calamares](https://kiwiirc.com/client/irc.libera.chat/#calamares) | [Wiki](https://github.com/calamares/calamares/wiki) | From 7cfa654a680497ca017e6eda81b81e529f1f7e9d Mon Sep 17 00:00:00 2001 From: demmm Date: Wed, 22 Dec 2021 22:17:13 +0100 Subject: [PATCH 092/168] [luksopenswaphookcfg] set plugin name according to module name either this, or have all distros adjust settings.conf from luksopenswaphookcfg to luksopenswaphook --- src/modules/luksopenswaphookcfg/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/luksopenswaphookcfg/CMakeLists.txt b/src/modules/luksopenswaphookcfg/CMakeLists.txt index 6d80df815..caede06a7 100644 --- a/src/modules/luksopenswaphookcfg/CMakeLists.txt +++ b/src/modules/luksopenswaphookcfg/CMakeLists.txt @@ -6,7 +6,7 @@ # Because LUKS Open Swap Hook (Job) is such a mouthful, we'll # use LOSH all over the place as a shorthand. -calamares_add_plugin( luksopenswaphook +calamares_add_plugin( luksopenswaphookcfg TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES From 4e61f2496068d5378f07bea3675da0f9ea754a5c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 14 Dec 2021 13:07:49 +0100 Subject: [PATCH 093/168] [partition] Tidy up iso9660 detection --- src/modules/partition/core/DeviceList.cpp | 25 ++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/modules/partition/core/DeviceList.cpp b/src/modules/partition/core/DeviceList.cpp index 423c3b4ee..adbbddd68 100644 --- a/src/modules/partition/core/DeviceList.cpp +++ b/src/modules/partition/core/DeviceList.cpp @@ -41,6 +41,10 @@ hasRootPartition( Device* device ) return false; } +/** @brief Check if @p path holds an iso9660 filesystem + * + * The @p path should point to a device; blkid is used to check the FS type. + */ static bool blkIdCheckIso9660( const QString& path ) { @@ -49,6 +53,18 @@ blkIdCheckIso9660( const QString& path ) return r.getOutput().contains( "iso9660" ); } +/// @brief Convenience to check if @p partition holds an iso9660 filesystem +static bool +blkIdCheckIso9660P( const Partition* partition ) +{ + return blkIdCheckIso9660( partition->partitionPath() ); +} + +/** @brief Check if the @p device is an iso9660 device + * + * An iso9660 device is **probably** a CD-ROM. If the device holds an + * iso9660 FS, or any of its partitions do, then we call it an iso9660 device. + */ static bool isIso9660( const Device* device ) { @@ -64,13 +80,8 @@ isIso9660( const Device* device ) if ( device->partitionTable() && !device->partitionTable()->children().isEmpty() ) { - for ( const Partition* partition : device->partitionTable()->children() ) - { - if ( blkIdCheckIso9660( partition->partitionPath() ) ) - { - return true; - } - } + const auto& p = device->partitionTable()->children(); + return std::any_of( p.cbegin(), p.cend(), blkIdCheckIso9660P ); } return false; } From 4fe5f1c06f641daf271b4294b6934de6e872ba6f Mon Sep 17 00:00:00 2001 From: dalto Date: Fri, 31 Dec 2021 08:06:13 -0600 Subject: [PATCH 094/168] [umount] Add support for umount to be an emergency module --- src/modules/umount/module.desc | 1 + src/modules/umount/umount.conf | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/modules/umount/module.desc b/src/modules/umount/module.desc index a1c189a62..1515e63df 100644 --- a/src/modules/umount/module.desc +++ b/src/modules/umount/module.desc @@ -5,3 +5,4 @@ type: "job" name: "umount" interface: "python" script: "main.py" +emergency: true \ No newline at end of file diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 7c11f4db6..04d68e477 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -28,3 +28,7 @@ #srcLog: "/home/live/installation.log" #destLog: "/var/log/installation.log" srcLog: "/bogus/just/do/not/use/this/anymore.txt" + +# Setting emergency to true will make it so this module is still run +# when a prior module fails +# emergency: true From c2ae5fad9638ce87b00200e58f67dd5c35ebc689 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 1 Jan 2022 10:05:00 -0600 Subject: [PATCH 095/168] [initcpio] Make implementation match config description and remove broken uname option --- src/modules/initcpio/InitcpioJob.cpp | 48 +++++++++++++--------------- src/modules/initcpio/initcpio.conf | 15 +++------ 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/src/modules/initcpio/InitcpioJob.cpp b/src/modules/initcpio/InitcpioJob.cpp index b96f3b316..5199f3e6a 100644 --- a/src/modules/initcpio/InitcpioJob.cpp +++ b/src/modules/initcpio/InitcpioJob.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * SPDX-FileCopyrightText: 2019 Adriaan de Groot + * SPDX-FileCopyrightText: 2022 Evan James * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. @@ -31,15 +32,22 @@ InitcpioJob::prettyName() const return tr( "Creating initramfs with mkinitcpio." ); } +/** @brief Sets conservative permissions on each initramfs + * + * Iterates over each initramfs contained directly in the directory @p d. + * For each initramfs found, the permissions are set to owner read/write only. + * + */ void fixPermissions( const QDir& d ) { - for ( const auto& fi : d.entryInfoList( { "initramfs*" }, QDir::Files ) ) + const auto initramList = d.entryInfoList( { "initramfs*" }, QDir::Files ); + for ( const auto& fi : initramList ) { QFile f( fi.absoluteFilePath() ); if ( f.exists() ) { - cDebug() << "initcpio fixing permissions for" << f.fileName(); + cDebug() << "initcpio setting permissions for" << f.fileName(); f.setPermissions( QFileDevice::ReadOwner | QFileDevice::WriteOwner ); } } @@ -63,9 +71,19 @@ InitcpioJob::exec() } } + // If the kernel option isn't set to a specific kernel, run mkinitcpio on all kernels + QStringList command = { "mkinitpio" }; + if ( m_kernel.isEmpty() || m_kernel == "all" ) + { + command.append( "-P" ); + } + else + { + command.append( { "-p", m_kernel } ); + } + cDebug() << "Updating initramfs with kernel" << m_kernel; - auto r = CalamaresUtils::System::instance()->targetEnvCommand( - { "mkinitcpio", "-p", m_kernel }, QString(), QString() /* no timeout , 0 */ ); + auto r = CalamaresUtils::System::instance()->targetEnvCommand( command, QString(), QString() /* no timeout , 0 */ ); return r.explainProcess( "mkinitcpio", std::chrono::seconds( 10 ) /* fake timeout */ ); } @@ -73,28 +91,6 @@ void InitcpioJob::setConfigurationMap( const QVariantMap& configurationMap ) { m_kernel = CalamaresUtils::getString( configurationMap, "kernel" ); - if ( m_kernel.isEmpty() ) - { - m_kernel = QStringLiteral( "all" ); - } - else if ( m_kernel == "$uname" ) - { - auto r = CalamaresUtils::System::runCommand( CalamaresUtils::System::RunLocation::RunInHost, - { "/bin/uname", "-r" }, - QString(), - QString(), - std::chrono::seconds( 3 ) ); - if ( r.getExitCode() == 0 ) - { - m_kernel = r.getOutput(); - cDebug() << "*initcpio* using running kernel" << m_kernel; - } - else - { - cWarning() << "*initcpio* could not determine running kernel, using 'all'." << Logger::Continuation - << r.getExitCode() << r.getOutput(); - } - } m_unsafe = CalamaresUtils::getBool( configurationMap, "be_unsafe", false ); } diff --git a/src/modules/initcpio/initcpio.conf b/src/modules/initcpio/initcpio.conf index 717a511df..f227d7034 100644 --- a/src/modules/initcpio/initcpio.conf +++ b/src/modules/initcpio/initcpio.conf @@ -5,19 +5,14 @@ --- # This key defines the kernel to be loaded. # It can have the following values: +# - the name of a single preset # - empty or unset, interpreted as "all" -# - the literal string "$uname" (without quotes, with dollar), -# which will use the output of `uname -r` to determine the -# running kernel, and use that. -# - any other string. +# - the literal string "all" # -# Whatever is set, that string is passed as *preset* argument to the -# `-p` option of *mkinitcpio*. Take care that both "$uname" operates -# in the host system, and might not be correct if the target system is -# updated (to a newer kernel) as part of the installation. +# If kernel is "all" or empty/unset then mkinitpio is called for all kernels. Otherwise +# it is called with a single prefix with the value contained in kernel # -# Note that "all" is probably not a good preset to use either. -kernel: linux312 +kernel: linux # Set this to true to turn off mitigations for lax file # permissions on initramfs (which, in turn, can compromise From 475c0d21a1008c56e154a62ee6fdb8e99186288a Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 1 Jan 2022 10:48:48 -0600 Subject: [PATCH 096/168] [initcpio] Spell mkinitcpio properly --- src/modules/initcpio/InitcpioJob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/initcpio/InitcpioJob.cpp b/src/modules/initcpio/InitcpioJob.cpp index 5199f3e6a..2f611173b 100644 --- a/src/modules/initcpio/InitcpioJob.cpp +++ b/src/modules/initcpio/InitcpioJob.cpp @@ -72,7 +72,7 @@ InitcpioJob::exec() } // If the kernel option isn't set to a specific kernel, run mkinitcpio on all kernels - QStringList command = { "mkinitpio" }; + QStringList command = { "mkinitcpio" }; if ( m_kernel.isEmpty() || m_kernel == "all" ) { command.append( "-P" ); From 3be6946d9320b1e51c52f8783141a0a0132cd967 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 1 Jan 2022 12:14:42 -0600 Subject: [PATCH 097/168] [initcpio] Minor documentation updates --- src/modules/initcpio/InitcpioJob.cpp | 2 +- src/modules/initcpio/initcpio.conf | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/modules/initcpio/InitcpioJob.cpp b/src/modules/initcpio/InitcpioJob.cpp index 2f611173b..df995ccbf 100644 --- a/src/modules/initcpio/InitcpioJob.cpp +++ b/src/modules/initcpio/InitcpioJob.cpp @@ -32,7 +32,7 @@ InitcpioJob::prettyName() const return tr( "Creating initramfs with mkinitcpio." ); } -/** @brief Sets conservative permissions on each initramfs +/** @brief Sets secure permissions on each initramfs * * Iterates over each initramfs contained directly in the directory @p d. * For each initramfs found, the permissions are set to owner read/write only. diff --git a/src/modules/initcpio/initcpio.conf b/src/modules/initcpio/initcpio.conf index f227d7034..d2a126864 100644 --- a/src/modules/initcpio/initcpio.conf +++ b/src/modules/initcpio/initcpio.conf @@ -5,16 +5,22 @@ --- # This key defines the kernel to be loaded. # It can have the following values: -# - the name of a single preset -# - empty or unset, interpreted as "all" +# - the name of a single mkinitcpio preset +# - empty or unset # - the literal string "all" # -# If kernel is "all" or empty/unset then mkinitpio is called for all kernels. Otherwise -# it is called with a single prefix with the value contained in kernel +# If kernel is set to "all" or empty/unset then mkinitpio is called for all +# kernels. Otherwise it is called with a single preset with the value +# contained in kernel. # kernel: linux # Set this to true to turn off mitigations for lax file # permissions on initramfs (which, in turn, can compromise # your LUKS encryption keys, CVS-2019-13179). +# +# If your initramfs are stored in the EFI partition or another non-POSIX +# filesystem, this has no effect as the file permissions cannot be changed. +# In this case, ensure the partition is mounted securely. +# be_unsafe: false From 626ab989494ded74c67d312b68b04f231a4afcdb Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 2 Jan 2022 08:41:47 -0600 Subject: [PATCH 098/168] [initramfs] Fix condition when call to uname fails --- src/modules/initramfs/InitramfsJob.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/initramfs/InitramfsJob.cpp b/src/modules/initramfs/InitramfsJob.cpp index 1b10a1a05..d83b4673c 100644 --- a/src/modules/initramfs/InitramfsJob.cpp +++ b/src/modules/initramfs/InitramfsJob.cpp @@ -81,6 +81,7 @@ InitramfsJob::setConfigurationMap( const QVariantMap& configurationMap ) } else { + m_kernel = QStringLiteral( "all" ); cWarning() << "*initramfs* could not determine running kernel, using 'all'." << Logger::Continuation << r.getExitCode() << r.getOutput(); } From e14fa5de75d745da86575ffb410d43d5e5464316 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 6 Jan 2022 23:51:18 +0100 Subject: [PATCH 099/168] [unpackfs] Improve error messages - the module is 'unpackfs', not 'unsquash' - add a warning + specific error if there is no unpack key in the config - the 'doing nothing' part isn't true: the module errors out instead of doing nothing. SEE #1870 --- src/modules/unpackfs/main.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/modules/unpackfs/main.py b/src/modules/unpackfs/main.py index 9f1bd822c..033073881 100644 --- a/src/modules/unpackfs/main.py +++ b/src/modules/unpackfs/main.py @@ -428,14 +428,16 @@ def run(): if not root_mount_point: libcalamares.utils.warning("No mount point for root partition") return (_("No mount point for root partition"), - _("globalstorage does not contain a \"rootMountPoint\" key, " - "doing nothing")) - + _("globalstorage does not contain a \"rootMountPoint\" key.")) if not os.path.exists(root_mount_point): libcalamares.utils.warning("Bad root mount point \"{}\"".format(root_mount_point)) return (_("Bad mount point for root partition"), - _("rootMountPoint is \"{}\", which does not " - "exist, doing nothing").format(root_mount_point)) + _("rootMountPoint is \"{}\", which does not exist.".format(root_mount_point))) + + if libcalamares.job.configuration.get("unpack", None) is None: + libcalamares.utils.warning("No *unpack* key in job configuration.") + return (_("Bad unpackfs configuration"), + _("There is no configuration information.")) supported_filesystems = get_supported_filesystems() @@ -450,17 +452,17 @@ def run(): if sourcefs not in supported_filesystems: libcalamares.utils.warning("The filesystem for \"{}\" ({}) is not supported by your current kernel".format(source, sourcefs)) libcalamares.utils.warning(" ... modprobe {} may solve the problem".format(sourcefs)) - return (_("Bad unsquash configuration"), + return (_("Bad unpackfs configuration"), _("The filesystem for \"{}\" ({}) is not supported by your current kernel").format(source, sourcefs)) if not os.path.exists(source): libcalamares.utils.warning("The source filesystem \"{}\" does not exist".format(source)) - return (_("Bad unsquash configuration"), + return (_("Bad unpackfs configuration"), _("The source filesystem \"{}\" does not exist").format(source)) if sourcefs == "squashfs": if shutil.which("unsquashfs") is None: libcalamares.utils.warning("Failed to find unsquashfs") - return (_("Bad unsquash configuration"), + return (_("Bad unpackfs configuration"), _("Failed to find unsquashfs, make sure you have the squashfs-tools package installed.") + " " + _("Failed to unpack image \"{}\"").format(source)) @@ -475,7 +477,7 @@ def run(): if not os.path.isdir(destination) and sourcefs != "file": libcalamares.utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination)) if is_first: - return (_("Bad unsquash configuration"), + return (_("Bad unpackfs configuration"), _("The destination \"{}\" in the target system is not a directory").format(destination)) else: libcalamares.utils.debug(".. assuming that the previous targets will create that directory.") From 1f9ae6cae61cdd7aaa4a0449bf57365ae0b9619a Mon Sep 17 00:00:00 2001 From: dalto Date: Fri, 7 Jan 2022 14:49:26 -0600 Subject: [PATCH 100/168] [initcpiocfg] Only add zfshook if zfs is enabled --- src/modules/initcpiocfg/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index 755039c0e..a821aee14 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -173,7 +173,8 @@ def find_initcpio_features(partitions, root_mount_point): if partition["fs"] == "btrfs": uses_btrfs = True - if partition["fs"] == "zfs": + # In addition to checking the filesystem, check to ensure that zfs is enabled + if partition["fs"] == "zfs" and libcalamares.globalstorage.contains("zfsPoolInfo"): uses_zfs = True if "lvm2" in partition["fs"]: From 94bca61491e04645d5083fa7cce84100b0d15169 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Jan 2022 11:16:42 +0100 Subject: [PATCH 101/168] Docs: be a little more explicit about emergency mode --- src/modules/README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/modules/README.md b/src/modules/README.md index 09696e66b..97a8556a1 100644 --- a/src/modules/README.md +++ b/src/modules/README.md @@ -67,7 +67,7 @@ Note that process modules are not recommended. Module descriptors **may** have the following keys: - *emergency* (a boolean value, set to true to mark the module - as an emergency module) + as an emergency module; see the section *Emergency Modules*, below) - *noconfig* (a boolean value, set to true to state that the module has no configuration file; defaults to false) - *requiredModules* (a list of modules which are required for this module @@ -102,8 +102,14 @@ to generate a suitable `module.desc`. For Python modules, manually add A module that is marked as an emergency module in its module.desc must **also** set the *emergency* key to *true* in its configuration file (see below). If it does not, the module is not considered to be an emergency -module after all (this is so that you can have modules that have several -instances, only some of which are actually needed for emergencies). +module after all. This is so that you can have modules that have several +instances, only some of which are actually needed for emergencies. + +In summary: +- in `module.desc`, write `emergency: true` to make it **possible** to + run the module in emergency mode, +- in `.conf`, write `emergency: true` to make that specific + module run in emergency mode. ### Module-specific configuration @@ -112,6 +118,10 @@ named `.conf`. If such a file is present in the module's directory, it can be shipped as a *default* configuration file. This only happens if the CMake-time option `INSTALL_CONFIG` is on. +The name of the configuration file for a given module can be +influenced by the `settings.conf` of the overall Calamares configuration. +By default, though, the module's own name is used. + Modules that have *noconfig* set to true will not attempt to read a configuration file, and will not warn that one is missing; conversely if *noconfig* is set to false (or is missing, since From f349a9c86447786064d6a7dbf19771bfcf820cdb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 12 Jan 2022 11:28:34 +0100 Subject: [PATCH 102/168] Changes: document new things --- CHANGES-3.2 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 52342e95b..0bcaf0285 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -10,12 +10,19 @@ website will have to do for older versions. # 3.2.50 (unreleased) # This release contains contributions from (alphabetically by first name): + - Anke Boersma - Erik Dubois + - Evan James + - Johannes Kamprad ## Core ## - No core changes yet ## Modules ## + - *initcpiocfg* mentioned a special kernel-name "all", which did not work, + and a special kernel-name "$uname" which cannot work. Fixed the former + and removed the "$uname" special key. (Thanks Evan) + - *luksswaphookcfg* has been converted to a C++ module. - *networkcfg* could fail to update the NetworkManager configuration if the SSID or username contained non-ASCII characters **and** the default Python text-file encoding was set to ASCII. The files are @@ -23,6 +30,8 @@ This release contains contributions from (alphabetically by first name): - *preservefiles* was missing some necessary features, needed for it to replace the deprecated log-file-saving functionality in the *umount* module. (Thanks Erik and Joe for testing) #1851 + - *umount* is now marked as an emergency module in the example configuration, + since it should **probably** be run as a cleanup. (Thanks Evan) # 3.2.49.1 (2021-12-11) # From 2eda55d3afb145e79f0c6b90d282a012cb0a9aea Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 15 Jan 2022 09:41:23 -0600 Subject: [PATCH 103/168] [packagechooser,netinstall] Add support for packagechooser to drive netinstall --- src/modules/netinstall/NetInstallPage.cpp | 16 ++++++++++ src/modules/netinstall/PackageModel.cpp | 35 +++++++++++++++++++++ src/modules/netinstall/PackageModel.h | 5 +++ src/modules/packagechooser/Config.cpp | 19 +++++++++++ src/modules/packagechooser/Config.h | 2 ++ src/modules/packagechooser/PackageModel.cpp | 25 ++++++++++++++- src/modules/packagechooser/PackageModel.h | 9 ++++++ 7 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index a1a86294e..75d7b660c 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -15,6 +15,7 @@ #include "PackageModel.h" #include "ui_page_netinst.h" +#include "GlobalStorage.h" #include "JobQueue.h" #include "network/Manager.h" @@ -62,4 +63,19 @@ void NetInstallPage::onActivate() { ui->groupswidget->setFocus(); + + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + if ( gs->contains( "NetinstallSelect" ) && gs->value( "NetinstallSelect" ).canConvert( QVariant::StringList ) ) + { + const QStringList selectNames = gs->value( "NetinstallSelect" ).toStringList(); + + static_cast< PackageModel* >( ui->groupswidget->model() )->setSelections( selectNames ); + } + + if ( gs->contains( "NetinstallAdd" ) && gs->value( "NetinstallAdd" ).canConvert( QVariant::List ) ) + { + const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); + + static_cast< PackageModel* >( ui->groupswidget->model() )->appendModelData( groups ); + } } diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index d4887b6c2..015b05303 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -170,6 +170,29 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c return QVariant(); } +void +PackageModel::setSelections( QStringList selectNames ) +{ + if ( m_rootItem ) + { + setSelections( selectNames, m_rootItem ); + } +} + +void +PackageModel::setSelections( QStringList selectNames, PackageTreeItem* item ) +{ + for ( int i = 0; i < item->childCount(); i++ ) + { + auto* child = item->child( i ); + setSelections( selectNames, child ); + } + if ( item->isGroup() && selectNames.contains( item->name() ) ) + { + item->setSelected( Qt::CheckState::Checked ); + } +} + PackageTreeItem::List PackageModel::getPackages() const { @@ -309,3 +332,15 @@ PackageModel::setupModelData( const QVariantList& l ) setupModelData( l, m_rootItem ); emit endResetModel(); } + + +void +PackageModel::appendModelData( const QVariantList& groupList ) +{ + if ( m_rootItem ) + { + emit beginResetModel(); + setupModelData( groupList, m_rootItem ); + emit endResetModel(); + } +} diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 998f42c38..fcdfe5daa 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -54,9 +54,14 @@ public: int rowCount( const QModelIndex& parent = QModelIndex() ) const override; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; + void setSelections( QStringList selectNames ); + void setSelections(QStringList selectNames, PackageTreeItem *item ); + PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; + void appendModelData( const QVariantList& groupList ); + private: friend class ItemTests; diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index 5c0db5d91..abf6a640e 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -55,6 +55,8 @@ PackageChooserMethodNames() { "custom", PackageChooserMethod::Legacy }, { "contextualprocess", PackageChooserMethod::Legacy }, { "packages", PackageChooserMethod::Packages }, + { "netinstall-add", PackageChooserMethod::NetAdd }, + { "netinstall-select", PackageChooserMethod::NetSelect }, }; return names; } @@ -121,6 +123,23 @@ Config::updateGlobalStorage( const QStringList& selected ) const CalamaresUtils::Packages::setGSPackageAdditions( Calamares::JobQueue::instance()->globalStorage(), m_defaultId, packageNames ); } + else if ( m_method == PackageChooserMethod::NetAdd ) + { + QVariantList netinstallDataList = m_model->getNetinstallDataForNames( selected ); + if ( netinstallDataList.isEmpty() ) + { + cWarning() << "No netinstall information found for " << selected; + } + else + { + Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallAdd", netinstallDataList ); + } + } + else if ( m_method == PackageChooserMethod::NetSelect ) + { + cDebug() << m_defaultId << "groups to select in netinstall" << selected; + Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallSelect", selected ); + } else { cWarning() << "Unknown packagechooser method" << smash( m_method ); diff --git a/src/modules/packagechooser/Config.h b/src/modules/packagechooser/Config.h index 32f1e8b57..76aa0c0f3 100644 --- a/src/modules/packagechooser/Config.h +++ b/src/modules/packagechooser/Config.h @@ -33,6 +33,8 @@ enum class PackageChooserMethod { Legacy, // use contextualprocess or other custom Packages, // use the packages module + NetAdd, // adds packages to the netinstall module + NetSelect, // makes selections in the netinstall module }; const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames(); diff --git a/src/modules/packagechooser/PackageModel.cpp b/src/modules/packagechooser/PackageModel.cpp index 8a0b13e51..f92b6893e 100644 --- a/src/modules/packagechooser/PackageModel.cpp +++ b/src/modules/packagechooser/PackageModel.cpp @@ -15,6 +15,14 @@ #include +static QVariantMap +getSubMap( const QVariantMap& map, const QString& key ) +{ + bool success; + + return CalamaresUtils::getSubMap( map, key, success ); +} + static QPixmap loadScreenshot( const QString& path ) { @@ -51,12 +59,13 @@ PackageItem::PackageItem( const QString& a_id, { } -PackageItem::PackageItem::PackageItem( const QVariantMap& item_map ) +PackageItem::PackageItem( const QVariantMap& item_map ) : id( CalamaresUtils::getString( item_map, "id" ) ) , name( CalamaresUtils::Locale::TranslatedString( item_map, "name" ) ) , description( CalamaresUtils::Locale::TranslatedString( item_map, "description" ) ) , screenshot( loadScreenshot( CalamaresUtils::getString( item_map, "screenshot" ) ) ) , packageNames( CalamaresUtils::getStringList( item_map, "packages" ) ) + , netinstallData( getSubMap( item_map, "netinstall" ) ) { if ( name.isEmpty() && id.isEmpty() ) { @@ -125,6 +134,20 @@ PackageListModel::getInstallPackagesForNames( const QStringList& ids ) const return l; } +QVariantList +PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const +{ + QVariantList l; + for ( const auto& p : qAsConst( m_packages ) ) + { + if ( ids.contains( p.id ) ) + { + l.append( p.netinstallData ); + } + } + return l; +} + int PackageListModel::rowCount( const QModelIndex& index ) const { diff --git a/src/modules/packagechooser/PackageModel.h b/src/modules/packagechooser/PackageModel.h index 71003197d..18682a121 100644 --- a/src/modules/packagechooser/PackageModel.h +++ b/src/modules/packagechooser/PackageModel.h @@ -26,6 +26,7 @@ struct PackageItem CalamaresUtils::Locale::TranslatedString description; QPixmap screenshot; QStringList packageNames; + QVariantMap netinstallData; /// @brief Create blank PackageItem PackageItem(); @@ -111,6 +112,14 @@ public: */ QStringList getInstallPackagesForNames( const QStringList& ids ) const; + /** @brief Does a name lookup (based on id) and returns the netinstall data + * + * If there is a package with an id in @p ids, returns their netinstall data + * + * returns a list of netinstall data or an emply list if none is found + */ + QVariantList getNetinstallDataForNames( const QStringList& ids ) const; + enum Roles : int { NameRole = Qt::DisplayRole, From b4ac6b73c8a188b00868bba4e0497fa2fc47fdfa Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 15 Jan 2022 11:13:17 -0600 Subject: [PATCH 104/168] [packagechooser,netinstall] Add documentation for packagechooser/netinstall integration --- src/modules/netinstall/NetInstallPage.cpp | 2 ++ src/modules/netinstall/PackageModel.cpp | 17 ++++++++++++++++- src/modules/packagechooser/PackageModel.cpp | 2 ++ src/modules/packagechooser/packagechooser.conf | 17 ++++++++++++++++- 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 75d7b660c..f897c0018 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -64,6 +64,7 @@ NetInstallPage::onActivate() { ui->groupswidget->setFocus(); + // The NetInstallSelect global sotrage value can be used to make additional items selected by default Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); if ( gs->contains( "NetinstallSelect" ) && gs->value( "NetinstallSelect" ).canConvert( QVariant::StringList ) ) { @@ -72,6 +73,7 @@ NetInstallPage::onActivate() static_cast< PackageModel* >( ui->groupswidget->model() )->setSelections( selectNames ); } + // If NetInstallAdd is found in global storage, add those items to the tree if ( gs->contains( "NetinstallAdd" ) && gs->value( "NetinstallAdd" ).canConvert( QVariant::List ) ) { const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 015b05303..9eafd898e 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -170,6 +170,15 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c return QVariant(); } +/** @brief Sets the checked flag on matching groups in the tree + * + * Recursively traverses the tree pointed to by m_rootItem and + * checks if a group name matches any of the items in @p selectNames. + * If a match is found, set check the box for that group and it's children. + * + * Individual packages will not be matched. + * + */ void PackageModel::setSelections( QStringList selectNames ) { @@ -333,7 +342,13 @@ PackageModel::setupModelData( const QVariantList& l ) emit endResetModel(); } - +/** @brief Appends groups to the tree + * + * Uses the data from @p groupList to add elements to the + * existing tree that m_rootItem points to. If m_rootItem + * is not valid, it does nothing + * + */ void PackageModel::appendModelData( const QVariantList& groupList ) { diff --git a/src/modules/packagechooser/PackageModel.cpp b/src/modules/packagechooser/PackageModel.cpp index f92b6893e..7b7cfc08f 100644 --- a/src/modules/packagechooser/PackageModel.cpp +++ b/src/modules/packagechooser/PackageModel.cpp @@ -15,6 +15,8 @@ #include +/** @brief A wrapper for CalamaresUtils::getSubMap that excludes the success param + */ static QVariantMap getSubMap( const QVariantMap& map, const QString& key ) { diff --git a/src/modules/packagechooser/packagechooser.conf b/src/modules/packagechooser/packagechooser.conf index bb982916e..ca458042b 100644 --- a/src/modules/packagechooser/packagechooser.conf +++ b/src/modules/packagechooser/packagechooser.conf @@ -33,6 +33,15 @@ mode: required # in the `exec` section. These package settings will then be handed # off to whatever package manager is configured there. # +# - "netinstall-select" +# When this is set, the id(s) selected are passed to the netinstall module. +# Any id that matches a group name in that module is set to checked +# +# - "netinstall-add" +# With this method, the packagechooser module is used to add groups to the +# netinstall module. For this to hav=e any effect. You must set netinstall, +# which is described below. +# # There is no need to put this module in the `exec` section. There # are no jobs that this module provides. You should put **other** # modules, either *contextualprocess* or *packages* or some custom @@ -101,13 +110,19 @@ labels: # an additional attempt is made to load the image from the **branding** # directory. # -# The following field is **optional** for an item: +# The following fields are **optional** for an item: # # - *packages* : # List of package names for the product. If using the *method* # "packages", consider this item mandatory (because otherwise # selecting the item would install no packages). # +# - *netinstall* : +# The data in this field should follow the format of a group +# from the netinstall module documented in +# src/modules/netinstall/netinstall.conf. This is only used +# when method is set to "netinstall-add" +# # # AppData Items # # # For data provided by AppData XML: the item has an *appdata* From 8eb7eb8b1f89032e9507110f12c9f136da1d3997 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 12:51:03 +0100 Subject: [PATCH 105/168] Changes: remind about *umount* replacement --- CHANGES-3.2 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 0bcaf0285..c1eb11caa 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -15,6 +15,10 @@ This release contains contributions from (alphabetically by first name): - Evan James - Johannes Kamprad +**Replacement notice:** The *umount* module will be replaced by a C++ +implementation in the next release. The "preserve log file" feature +will be removed in that release. Use the *preservefiles* module instead. + ## Core ## - No core changes yet From 4be932ff9d4daaabf91c1eebc9f46580ce945ea0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 13:42:36 +0100 Subject: [PATCH 106/168] [umount] Now mark deprecated use as an error --- src/modules/umount/main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/umount/main.py b/src/modules/umount/main.py index 5fdb36014..f7bb3ca5a 100644 --- a/src/modules/umount/main.py +++ b/src/modules/umount/main.py @@ -77,10 +77,13 @@ def run(): """ root_mount_point = libcalamares.globalstorage.value("rootMountPoint") + if(libcalamares.job.configuration and + "srcLog" in libcalamares.job.configuration or + "destLog" in libcalamares.job.configuration): + libcalamares.utils.error("Log-file preserving is **deprecated** in the *umount* module and removed in the next release") if(libcalamares.job.configuration and "srcLog" in libcalamares.job.configuration and "destLog" in libcalamares.job.configuration): - libcalamares.utils.warning("Log-file preserving is **deprecated** in the *umount* module") log_source = libcalamares.job.configuration["srcLog"] log_destination = libcalamares.job.configuration["destLog"] # Relocate log_destination into target system From e6813949aff5067b1b9514df26627d3b22e54a5d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 13:47:47 +0100 Subject: [PATCH 107/168] [libcalamares] Hook up Python's error() to error, rather than warning --- src/libcalamares/PythonJob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index b1373f5f3..ec17c31f3 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -100,7 +100,7 @@ BOOST_PYTHON_MODULE( libcalamares ) bp::args( "s" ), "Writes the given string to the Calamares warning stream." ); bp::def( - "error", &CalamaresPython::warning, bp::args( "s" ), "Writes the given string to the Calamares error stream." ); + "error", &CalamaresPython::error, bp::args( "s" ), "Writes the given string to the Calamares error stream." ); // .. YAML functions From fad23c9ac6d31fd558ca3ff310cb6e609be97273 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 17 Jan 2022 13:50:41 +0100 Subject: [PATCH 108/168] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_ja-Hira.ts | 4366 +++++++++++++++++++++++++++++++++++++ lang/calamares_pt_PT.ts | 4 +- lang/calamares_ro.ts | 8 +- lang/calamares_tg.ts | 2 +- lang/calamares_zh_CN.ts | 10 +- 5 files changed, 4378 insertions(+), 12 deletions(-) create mode 100644 lang/calamares_ja-Hira.ts diff --git a/lang/calamares_ja-Hira.ts b/lang/calamares_ja-Hira.ts new file mode 100644 index 000000000..ce8d59bf4 --- /dev/null +++ b/lang/calamares_ja-Hira.ts @@ -0,0 +1,4366 @@ + + + + + AutoMountManagementJob + + + Manage auto-mount settings + + + + + BootInfoWidget + + + The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. + + + + + This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. + + + + + This system was started with a <strong>BIOS</strong> boot environment.<br><br>To configure startup from a BIOS environment, this installer must install a boot loader, like <strong>GRUB</strong>, either at the beginning of a partition or on the <strong>Master Boot Record</strong> near the beginning of the partition table (preferred). This is automatic, unless you choose manual partitioning, in which case you must set it up on your own. + + + + + BootLoaderModel + + + Master Boot Record of %1 + + + + + Boot Partition + + + + + System Partition + + + + + Do not install a boot loader + + + + + %1 (%2) + + + + + Calamares::BlankViewStep + + + Blank Page + + + + + Calamares::DebugWindow + + + Form + + + + + GlobalStorage + + + + + JobQueue + + + + + Modules + + + + + Type: + + + + + + none + + + + + Interface: + + + + + Crashes Calamares, so that Dr. Konqui can look at it. + + + + + Reloads the stylesheet from the branding directory. + + + + + Uploads the session log to the configured pastebin. + + + + + Send Session Log + + + + + Reload Stylesheet + + + + + Displays the tree of widget names in the log (for stylesheet debugging). + + + + + Widget Tree + + + + + Debug information + + + + + Calamares::ExecutionViewStep + + + Set up + + + + + Install + + + + + Calamares::FailJob + + + Job failed (%1) + + + + + Programmed job failure was explicitly requested. + + + + + Calamares::JobThread + + + Done + + + + + Calamares::NamedJob + + + Example job (%1) + + + + + Calamares::ProcessJob + + + Run command '%1' in target system. + + + + + Run command '%1'. + + + + + Running command %1 %2 + + + + + Calamares::PythonJob + + + Running %1 operation. + + + + + Bad working directory path + + + + + Working directory %1 for python job %2 is not readable. + + + + + Bad main script file + + + + + Main script file %1 for python job %2 is not readable. + + + + + Boost.Python error in job "%1". + + + + + Calamares::QmlViewStep + + + Loading ... + + + + + QML Step <i>%1</i>. + + + + + Loading failed. + + + + + Calamares::RequirementsChecker + + + Requirements checking for module <i>%1</i> is complete. + + + + + Waiting for %n module(s). + + + + + + + (%n second(s)) + + + + + + + System-requirements checking is complete. + + + + + Calamares::ViewManager + + + Setup Failed + + + + + Installation Failed + + + + + Would you like to paste the install log to the web? + + + + + Error + + + + + &Yes + + + + + &No + + + + + &Close + + + + + Install Log Paste URL + + + + + The upload was unsuccessful. No web-paste was done. + + + + + Install log posted to + +%1 + +Link copied to clipboard + + + + + Calamares Initialization Failed + + + + + %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. + + + + + <br/>The following modules could not be loaded: + + + + + Continue with setup? + + + + + Continue with installation? + + + + + The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> + + + + + The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> + + + + + &Set up now + + + + + &Install now + + + + + Go &back + + + + + &Set up + + + + + &Install + + + + + Setup is complete. Close the setup program. + + + + + The installation is complete. Close the installer. + + + + + Cancel setup without changing the system. + + + + + Cancel installation without changing the system. + + + + + &Next + + + + + &Back + + + + + &Done + + + + + &Cancel + + + + + Cancel setup? + + + + + Cancel installation? + + + + + Do you really want to cancel the current setup process? +The setup program will quit and all changes will be lost. + + + + + Do you really want to cancel the current install process? +The installer will quit and all changes will be lost. + + + + + CalamaresPython::Helper + + + Unknown exception type + + + + + unparseable Python error + + + + + unparseable Python traceback + + + + + Unfetchable Python error. + + + + + CalamaresWindow + + + %1 Setup Program + + + + + %1 Installer + + + + + ChangeFilesystemLabelJob + + + Set filesystem label on %1. + + + + + Set filesystem label <strong>%1</strong> to partition <strong>%2</strong>. + + + + + The installer failed to update partition table on disk '%1'. + + + + + CheckerContainer + + + Gathering system information... + + + + + ChoicePage + + + Form + + + + + Select storage de&vice: + + + + + + + + Current: + + + + + After: + + + + + <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. + + + + + Reuse %1 as home partition for %2. + + + + + <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> + + + + + %1 will be shrunk to %2MiB and a new %3MiB partition will be created for %4. + + + + + Boot loader location: + + + + + <strong>Select a partition to install on</strong> + + + + + An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. + + + + + The EFI system partition at %1 will be used for starting %2. + + + + + EFI system partition: + + + + + This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + + + + <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. + + + + + + + + <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. + + + + + + + + <strong>Replace a partition</strong><br/>Replaces a partition with %1. + + + + + This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. + + + + + This storage device already has an operating system on it, but the partition table <strong>%1</strong> is different from the needed <strong>%2</strong>.<br/> + + + + + This storage device has one of its partitions <strong>mounted</strong>. + + + + + This storage device is a part of an <strong>inactive RAID</strong> device. + + + + + No Swap + + + + + Reuse Swap + + + + + Swap (no Hibernate) + + + + + Swap (with Hibernate) + + + + + Swap to file + + + + + ClearMountsJob + + + Successfully unmounted %1. + + + + + Successfully disabled swap %1. + + + + + Successfully cleared swap %1. + + + + + Successfully closed mapper device %1. + + + + + Successfully disabled volume group %1. + + + + + Clear mounts for partitioning operations on %1 + + + + + Clearing mounts for partitioning operations on %1. + + + + + Cleared all mounts for %1 + + + + + ClearTempMountsJob + + + Clear all temporary mounts. + + + + + Clearing all temporary mounts. + + + + + Cannot get list of temporary mounts. + + + + + Cleared all temporary mounts. + + + + + CommandList + + + + Could not run command. + + + + + The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. + + + + + The command needs to know the user's name, but no username is defined. + + + + + Config + + + Set keyboard model to %1.<br/> + + + + + Set keyboard layout to %1/%2. + + + + + Set timezone to %1/%2. + + + + + The system language will be set to %1. + + + + + The numbers and dates locale will be set to %1. + + + + + Network Installation. (Disabled: Incorrect configuration) + + + + + Network Installation. (Disabled: Received invalid groups data) + + + + + Network Installation. (Disabled: Internal error) + + + + + Network Installation. (Disabled: No package list) + + + + + Package selection + + + + + Network Installation. (Disabled: Unable to fetch package lists, check your network connection) + + + + + This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> + + + + + This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> + + + + + This computer does not satisfy some of the recommended requirements for setting up %1.<br/>Setup can continue, but some features might be disabled. + + + + + This computer does not satisfy some of the recommended requirements for installing %1.<br/>Installation can continue, but some features might be disabled. + + + + + This program will ask you some questions and set up %2 on your computer. + + + + + <h1>Welcome to the Calamares setup program for %1</h1> + + + + + <h1>Welcome to %1 setup</h1> + + + + + <h1>Welcome to the Calamares installer for %1</h1> + + + + + <h1>Welcome to the %1 installer</h1> + + + + + Your username is too long. + + + + + '%1' is not allowed as username. + + + + + Your username must start with a lowercase letter or underscore. + + + + + Only lowercase letters, numbers, underscore and hyphen are allowed. + + + + + Your hostname is too short. + + + + + Your hostname is too long. + + + + + '%1' is not allowed as hostname. + + + + + Only letters, numbers, underscore and hyphen are allowed. + + + + + Your passwords do not match! + + + + + OK! + + + + + Setup Failed + + + + + Installation Failed + + + + + The setup of %1 did not complete successfully. + + + + + The installation of %1 did not complete successfully. + + + + + Setup Complete + + + + + Installation Complete + + + + + The setup of %1 is complete. + + + + + The installation of %1 is complete. + + + + + Package Selection + + + + + Please pick a product from the list. The selected product will be installed. + + + + + Install option: <strong>%1</strong> + + + + + None + + + + + Summary + + + + + This is an overview of what will happen once you start the setup procedure. + + + + + This is an overview of what will happen once you start the install procedure. + + + + + ContextualProcessJob + + + Contextual Processes Job + + + + + CreatePartitionDialog + + + Create a Partition + + + + + Si&ze: + + + + + MiB + + + + + Partition &Type: + + + + + &Primary + + + + + E&xtended + + + + + Fi&le System: + + + + + LVM LV name + + + + + &Mount Point: + + + + + Flags: + + + + + Label for the filesystem + + + + + FS Label: + + + + + En&crypt + + + + + Logical + + + + + Primary + + + + + GPT + + + + + Mountpoint already in use. Please select another one. + + + + + CreatePartitionJob + + + Create new %1MiB partition on %3 (%2) with entries %4. + + + + + Create new %1MiB partition on %3 (%2). + + + + + Create new %2MiB partition on %4 (%3) with file system %1. + + + + + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2) with entries <em>%4</em>. + + + + + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2). + + + + + Create new <strong>%2MiB</strong> partition on <strong>%4</strong> (%3) with file system <strong>%1</strong>. + + + + + + Creating new %1 partition on %2. + + + + + The installer failed to create partition on disk '%1'. + + + + + CreatePartitionTableDialog + + + Create Partition Table + + + + + Creating a new partition table will delete all existing data on the disk. + + + + + What kind of partition table do you want to create? + + + + + Master Boot Record (MBR) + + + + + GUID Partition Table (GPT) + + + + + CreatePartitionTableJob + + + Create new %1 partition table on %2. + + + + + Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). + + + + + Creating new %1 partition table on %2. + + + + + The installer failed to create a partition table on %1. + + + + + CreateUserJob + + + Create user %1 + + + + + Create user <strong>%1</strong>. + + + + + Preserving home directory + + + + + + Creating user %1 + + + + + Configuring user %1 + + + + + Setting file permissions + + + + + CreateVolumeGroupDialog + + + Create Volume Group + + + + + CreateVolumeGroupJob + + + Create new volume group named %1. + + + + + Create new volume group named <strong>%1</strong>. + + + + + Creating new volume group named %1. + + + + + The installer failed to create a volume group named '%1'. + + + + + DeactivateVolumeGroupJob + + + + Deactivate volume group named %1. + + + + + Deactivate volume group named <strong>%1</strong>. + + + + + The installer failed to deactivate a volume group named %1. + + + + + DeletePartitionJob + + + Delete partition %1. + + + + + Delete partition <strong>%1</strong>. + + + + + Deleting partition %1. + + + + + The installer failed to delete partition %1. + + + + + DeviceInfoWidget + + + This device has a <strong>%1</strong> partition table. + + + + + This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. + + + + + This installer <strong>cannot detect a partition table</strong> on the selected storage device.<br><br>The device either has no partition table, or the partition table is corrupted or of an unknown type.<br>This installer can create a new partition table for you, either automatically, or through the manual partitioning page. + + + + + <br><br>This is the recommended partition table type for modern systems which start from an <strong>EFI</strong> boot environment. + + + + + <br><br>This partition table type is only advisable on older systems which start from a <strong>BIOS</strong> boot environment. GPT is recommended in most other cases.<br><br><strong>Warning:</strong> the MBR partition table is an obsolete MS-DOS era standard.<br>Only 4 <em>primary</em> partitions may be created, and of those 4, one can be an <em>extended</em> partition, which may in turn contain many <em>logical</em> partitions. + + + + + The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. + + + + + DeviceModel + + + %1 - %2 (%3) + device[name] - size[number] (device-node[name]) + + + + + %1 - (%2) + device[name] - (device-node[name]) + + + + + DracutLuksCfgJob + + + Write LUKS configuration for Dracut to %1 + + + + + Skip writing LUKS configuration for Dracut: "/" partition is not encrypted + + + + + Failed to open %1 + + + + + DummyCppJob + + + Dummy C++ Job + + + + + EditExistingPartitionDialog + + + Edit Existing Partition + + + + + Content: + + + + + &Keep + + + + + Format + + + + + Warning: Formatting the partition will erase all existing data. + + + + + &Mount Point: + + + + + Si&ze: + + + + + MiB + + + + + Fi&le System: + + + + + Flags: + + + + + Label for the filesystem + + + + + FS Label: + + + + + Mountpoint already in use. Please select another one. + + + + + EncryptWidget + + + Form + + + + + En&crypt system + + + + + Passphrase + + + + + Confirm passphrase + + + + + + Please enter the same passphrase in both boxes. + + + + + FillGlobalStorageJob + + + Set partition information + + + + + Install %1 on <strong>new</strong> %2 system partition with features <em>%3</em> + + + + + Install %1 on <strong>new</strong> %2 system partition. + + + + + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong> and features <em>%3</em>. + + + + + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>%3. + + + + + Install %2 on %3 system partition <strong>%1</strong> with features <em>%4</em>. + + + + + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong> and features <em>%4</em>. + + + + + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>%4. + + + + + Install %2 on %3 system partition <strong>%1</strong>. + + + + + Install boot loader on <strong>%1</strong>. + + + + + Setting up mount points. + + + + + FinishedPage + + + Form + + + + + &Restart now + + + + + <h1>All done.</h1><br/>%1 has been set up on your computer.<br/>You may now start using your new system. + + + + + <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> + + + + + <h1>All done.</h1><br/>%1 has been installed on your computer.<br/>You may now restart into your new system, or continue using the %2 Live environment. + + + + + <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the installer.</p></body></html> + + + + + <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. + + + + + <h1>Installation Failed</h1><br/>%1 has not been installed on your computer.<br/>The error message was: %2. + + + + + FinishedQmlViewStep + + + Finish + + + + + FinishedViewStep + + + Finish + + + + + FormatPartitionJob + + + Format partition %1 (file system: %2, size: %3 MiB) on %4. + + + + + Format <strong>%3MiB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. + + + + + Formatting partition %1 with file system %2. + + + + + The installer failed to format partition %1 on disk '%2'. + + + + + GeneralRequirements + + + has at least %1 GiB available drive space + + + + + There is not enough drive space. At least %1 GiB is required. + + + + + has at least %1 GiB working memory + + + + + The system does not have enough working memory. At least %1 GiB is required. + + + + + is plugged in to a power source + + + + + The system is not plugged in to a power source. + + + + + is connected to the Internet + + + + + The system is not connected to the Internet. + + + + + is running the installer as an administrator (root) + + + + + The setup program is not running with administrator rights. + + + + + The installer is not running with administrator rights. + + + + + has a screen large enough to show the whole installer + + + + + The screen is too small to display the setup program. + + + + + The screen is too small to display the installer. + + + + + HostInfoJob + + + Collecting information about your machine. + + + + + IDJob + + + + + + OEM Batch Identifier + + + + + Could not create directories <code>%1</code>. + + + + + Could not open file <code>%1</code>. + + + + + Could not write to file <code>%1</code>. + + + + + InitcpioJob + + + Creating initramfs with mkinitcpio. + + + + + InitramfsJob + + + Creating initramfs. + + + + + InteractiveTerminalPage + + + Konsole not installed + + + + + Please install KDE Konsole and try again! + + + + + Executing script: &nbsp;<code>%1</code> + + + + + InteractiveTerminalViewStep + + + Script + + + + + KeyboardQmlViewStep + + + Keyboard + + + + + KeyboardViewStep + + + Keyboard + + + + + LCLocaleDialog + + + System locale setting + + + + + The system locale setting affects the language and character set for some command line user interface elements.<br/>The current setting is <strong>%1</strong>. + + + + + &Cancel + + + + + &OK + + + + + LicensePage + + + Form + + + + + <h1>License Agreement</h1> + + + + + I accept the terms and conditions above. + + + + + Please review the End User License Agreements (EULAs). + + + + + This setup procedure will install proprietary software that is subject to licensing terms. + + + + + If you do not agree with the terms, the setup procedure cannot continue. + + + + + This setup procedure can install proprietary software that is subject to licensing terms in order to provide additional features and enhance the user experience. + + + + + If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. + + + + + LicenseViewStep + + + License + + + + + LicenseWidget + + + URL: %1 + + + + + <strong>%1 driver</strong><br/>by %2 + %1 is an untranslatable product name, example: Creative Audigy driver + + + + + <strong>%1 graphics driver</strong><br/><font color="Grey">by %2</font> + %1 is usually a vendor name, example: Nvidia graphics driver + + + + + <strong>%1 browser plugin</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1 codec</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1 package</strong><br/><font color="Grey">by %2</font> + + + + + <strong>%1</strong><br/><font color="Grey">by %2</font> + + + + + File: %1 + + + + + Hide license text + + + + + Show the license text + + + + + Open license agreement in browser. + + + + + LocalePage + + + Region: + + + + + Zone: + + + + + + &Change... + + + + + LocaleQmlViewStep + + + Location + + + + + LocaleTests + + + Quit + + + + + LocaleViewStep + + + Location + + + + + LuksBootKeyFileJob + + + Configuring LUKS key file. + + + + + + No partitions are defined. + + + + + + + Encrypted rootfs setup error + + + + + Root partition %1 is LUKS but no passphrase has been set. + + + + + Could not create LUKS key file for root partition %1. + + + + + Could not configure LUKS key file on partition %1. + + + + + MachineIdJob + + + Generate machine-id. + + + + + Configuration Error + + + + + No root mount point is set for MachineId. + + + + + Map + + + Timezone: %1 + + + + + Please select your preferred location on the map so the installer can suggest the locale + and timezone settings for you. You can fine-tune the suggested settings below. Search the map by dragging + to move and using the +/- buttons to zoom in/out or use mouse scrolling for zooming. + + + + + NetInstallViewStep + + + Package selection + + + + + Office software + + + + + Office package + + + + + Browser software + + + + + Browser package + + + + + Web browser + + + + + Kernel + + + + + Services + + + + + Login + + + + + Desktop + + + + + Applications + + + + + Communication + + + + + Development + + + + + Office + + + + + Multimedia + + + + + Internet + + + + + Theming + + + + + Gaming + + + + + Utilities + + + + + NotesQmlViewStep + + + Notes + + + + + OEMPage + + + Ba&tch: + + + + + <html><head/><body><p>Enter a batch-identifier here. This will be stored in the target system.</p></body></html> + + + + + <html><head/><body><h1>OEM Configuration</h1><p>Calamares will use OEM settings while configuring the target system.</p></body></html> + + + + + OEMViewStep + + + OEM Configuration + + + + + Set the OEM Batch Identifier to <code>%1</code>. + + + + + Offline + + + Select your preferred Region, or use the default settings. + + + + + + + Timezone: %1 + + + + + Select your preferred Zone within your Region. + + + + + Zones + + + + + You can fine-tune Language and Locale settings below. + + + + + PWQ + + + Password is too short + + + + + Password is too long + + + + + Password is too weak + + + + + Memory allocation error when setting '%1' + + + + + Memory allocation error + + + + + The password is the same as the old one + + + + + The password is a palindrome + + + + + The password differs with case changes only + + + + + The password is too similar to the old one + + + + + The password contains the user name in some form + + + + + The password contains words from the real name of the user in some form + + + + + The password contains forbidden words in some form + + + + + The password contains too few digits + + + + + The password contains too few uppercase letters + + + + + The password contains fewer than %n lowercase letters + + + + + + + The password contains too few lowercase letters + + + + + The password contains too few non-alphanumeric characters + + + + + The password is too short + + + + + The password does not contain enough character classes + + + + + The password contains too many same characters consecutively + + + + + The password contains too many characters of the same class consecutively + + + + + The password contains fewer than %n digits + + + + + + + The password contains fewer than %n uppercase letters + + + + + + + The password contains fewer than %n non-alphanumeric characters + + + + + + + The password is shorter than %n characters + + + + + + + The password is a rotated version of the previous one + + + + + The password contains fewer than %n character classes + + + + + + + The password contains more than %n same characters consecutively + + + + + + + The password contains more than %n characters of the same class consecutively + + + + + + + The password contains monotonic sequence longer than %n characters + + + + + + + The password contains too long of a monotonic character sequence + + + + + No password supplied + + + + + Cannot obtain random numbers from the RNG device + + + + + Password generation failed - required entropy too low for settings + + + + + The password fails the dictionary check - %1 + + + + + The password fails the dictionary check + + + + + Unknown setting - %1 + + + + + Unknown setting + + + + + Bad integer value of setting - %1 + + + + + Bad integer value + + + + + Setting %1 is not of integer type + + + + + Setting is not of integer type + + + + + Setting %1 is not of string type + + + + + Setting is not of string type + + + + + Opening the configuration file failed + + + + + The configuration file is malformed + + + + + Fatal failure + + + + + Unknown error + + + + + Password is empty + + + + + PackageChooserPage + + + Form + + + + + Product Name + + + + + TextLabel + + + + + Long Product Description + + + + + Package Selection + + + + + Please pick a product from the list. The selected product will be installed. + + + + + PackageChooserQmlViewStep + + + Packages + + + + + PackageChooserViewStep + + + Packages + + + + + PackageModel + + + Name + + + + + Description + + + + + Page_Keyboard + + + Form + + + + + Keyboard Model: + + + + + Type here to test your keyboard + + + + + Page_UserSetup + + + Form + + + + + What is your name? + + + + + Your Full Name + + + + + What name do you want to use to log in? + + + + + login + + + + + What is the name of this computer? + + + + + <small>This name will be used if you make the computer visible to others on a network.</small> + + + + + Computer Name + + + + + Choose a password to keep your account safe. + + + + + + <small>Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals.</small> + + + + + + Password + + + + + + Repeat Password + + + + + When this box is checked, password-strength checking is done and you will not be able to use a weak password. + + + + + Require strong passwords. + + + + + Log in automatically without asking for the password. + + + + + Use the same password for the administrator account. + + + + + Choose a password for the administrator account. + + + + + + <small>Enter the same password twice, so that it can be checked for typing errors.</small> + + + + + PartitionLabelsView + + + Root + + + + + Home + + + + + Boot + + + + + EFI system + + + + + Swap + + + + + New partition for %1 + + + + + New partition + + + + + %1 %2 + size[number] filesystem[name] + + + + + PartitionModel + + + + Free Space + + + + + + New partition + + + + + Name + + + + + File System + + + + + File System Label + + + + + Mount Point + + + + + Size + + + + + PartitionPage + + + Form + + + + + Storage de&vice: + + + + + &Revert All Changes + + + + + New Partition &Table + + + + + Cre&ate + + + + + &Edit + + + + + &Delete + + + + + New Volume Group + + + + + Resize Volume Group + + + + + Deactivate Volume Group + + + + + Remove Volume Group + + + + + I&nstall boot loader on: + + + + + Are you sure you want to create a new partition table on %1? + + + + + Can not create new partition + + + + + The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead. + + + + + PartitionViewStep + + + Gathering system information... + + + + + Partitions + + + + + Current: + + + + + After: + + + + + No EFI system partition configured + + + + + EFI system partition configured incorrectly + + + + + An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem. + + + + + The filesystem must be mounted on <strong>%1</strong>. + + + + + The filesystem must have type FAT32. + + + + + The filesystem must be at least %1 MiB in size. + + + + + The filesystem must have flag <strong>%1</strong> set. + + + + + You can continue without setting up an EFI system partition but your system may fail to start. + + + + + Option to use GPT on BIOS + + + + + A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>bios_grub</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. + + + + + Boot partition not encrypted + + + + + A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window. + + + + + has at least one disk device available. + + + + + There are no partitions to install on. + + + + + PlasmaLnfJob + + + Plasma Look-and-Feel Job + + + + + + Could not select KDE Plasma Look-and-Feel package + + + + + PlasmaLnfPage + + + Form + + + + + Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is set up. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. + + + + + Please choose a look-and-feel for the KDE Plasma Desktop. You can also skip this step and configure the look-and-feel once the system is installed. Clicking on a look-and-feel selection will give you a live preview of that look-and-feel. + + + + + PlasmaLnfViewStep + + + Look-and-Feel + + + + + PreserveFiles + + + Saving files for later ... + + + + + No files configured to save for later. + + + + + Not all of the configured files could be preserved. + + + + + ProcessResult + + + +There was no output from the command. + + + + + +Output: + + + + + + External command crashed. + + + + + Command <i>%1</i> crashed. + + + + + External command failed to start. + + + + + Command <i>%1</i> failed to start. + + + + + Internal error when starting command. + + + + + Bad parameters for process job call. + + + + + External command failed to finish. + + + + + Command <i>%1</i> failed to finish in %2 seconds. + + + + + External command finished with errors. + + + + + Command <i>%1</i> finished with exit code %2. + + + + + QObject + + + %1 (%2) + + + + + unknown + + + + + extended + + + + + unformatted + + + + + swap + + + + + + Default + + + + + + + + File not found + + + + + Path <pre>%1</pre> must be an absolute path. + + + + + Directory not found + + + + + + Could not create new random file <pre>%1</pre>. + + + + + No product + + + + + No description provided. + + + + + (no mount point) + + + + + Unpartitioned space or unknown partition table + + + + + Recommended + + + <p>This computer does not satisfy some of the recommended requirements for setting up %1.<br/> + Setup can continue, but some features might be disabled.</p> + + + + + RemoveUserJob + + + Remove live user from target system + + + + + RemoveVolumeGroupJob + + + + Remove Volume Group named %1. + + + + + Remove Volume Group named <strong>%1</strong>. + + + + + The installer failed to remove a volume group named '%1'. + + + + + ReplaceWidget + + + Form + + + + + Select where to install %1.<br/><font color="red">Warning: </font>this will delete all files on the selected partition. + + + + + The selected item does not appear to be a valid partition. + + + + + %1 cannot be installed on empty space. Please select an existing partition. + + + + + %1 cannot be installed on an extended partition. Please select an existing primary or logical partition. + + + + + %1 cannot be installed on this partition. + + + + + Data partition (%1) + + + + + Unknown system partition (%1) + + + + + %1 system partition (%2) + + + + + <strong>%4</strong><br/><br/>The partition %1 is too small for %2. Please select a partition with capacity at least %3 GiB. + + + + + <strong>%2</strong><br/><br/>An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. + + + + + + + <strong>%3</strong><br/><br/>%1 will be installed on %2.<br/><font color="red">Warning: </font>all data on partition %2 will be lost. + + + + + The EFI system partition at %1 will be used for starting %2. + + + + + EFI system partition: + + + + + Requirements + + + <p>This computer does not satisfy the minimum requirements for installing %1.<br/> + Installation cannot continue.</p> + + + + + <p>This computer does not satisfy some of the recommended requirements for setting up %1.<br/> + Setup can continue, but some features might be disabled.</p> + + + + + ResizeFSJob + + + Resize Filesystem Job + + + + + Invalid configuration + + + + + The file-system resize job has an invalid configuration and will not run. + + + + + KPMCore not Available + + + + + Calamares cannot start KPMCore for the file-system resize job. + + + + + + + + + Resize Failed + + + + + The filesystem %1 could not be found in this system, and cannot be resized. + + + + + The device %1 could not be found in this system, and cannot be resized. + + + + + + The filesystem %1 cannot be resized. + + + + + + The device %1 cannot be resized. + + + + + The filesystem %1 must be resized, but cannot. + + + + + The device %1 must be resized, but cannot + + + + + ResizePartitionJob + + + Resize partition %1. + + + + + Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. + + + + + Resizing %2MiB partition %1 to %3MiB. + + + + + The installer failed to resize partition %1 on disk '%2'. + + + + + ResizeVolumeGroupDialog + + + Resize Volume Group + + + + + ResizeVolumeGroupJob + + + + Resize volume group named %1 from %2 to %3. + + + + + Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. + + + + + The installer failed to resize a volume group named '%1'. + + + + + ResultsListDialog + + + For best results, please ensure that this computer: + + + + + System requirements + + + + + ScanningDialog + + + Scanning storage devices... + + + + + Partitioning + + + + + SetHostNameJob + + + Set hostname %1 + + + + + Set hostname <strong>%1</strong>. + + + + + Setting hostname %1. + + + + + + Internal Error + + + + + + Cannot write hostname to target system + + + + + SetKeyboardLayoutJob + + + Set keyboard model to %1, layout to %2-%3 + + + + + Failed to write keyboard configuration for the virtual console. + + + + + + + Failed to write to %1 + + + + + Failed to write keyboard configuration for X11. + + + + + Failed to write keyboard configuration to existing /etc/default directory. + + + + + SetPartFlagsJob + + + Set flags on partition %1. + + + + + Set flags on %1MiB %2 partition. + + + + + Set flags on new partition. + + + + + Clear flags on partition <strong>%1</strong>. + + + + + Clear flags on %1MiB <strong>%2</strong> partition. + + + + + Clear flags on new partition. + + + + + Flag partition <strong>%1</strong> as <strong>%2</strong>. + + + + + Flag %1MiB <strong>%2</strong> partition as <strong>%3</strong>. + + + + + Flag new partition as <strong>%1</strong>. + + + + + Clearing flags on partition <strong>%1</strong>. + + + + + Clearing flags on %1MiB <strong>%2</strong> partition. + + + + + Clearing flags on new partition. + + + + + Setting flags <strong>%2</strong> on partition <strong>%1</strong>. + + + + + Setting flags <strong>%3</strong> on %1MiB <strong>%2</strong> partition. + + + + + Setting flags <strong>%1</strong> on new partition. + + + + + The installer failed to set flags on partition %1. + + + + + SetPasswordJob + + + Set password for user %1 + + + + + Setting password for user %1. + + + + + Bad destination system path. + + + + + rootMountPoint is %1 + + + + + Cannot disable root account. + + + + + passwd terminated with error code %1. + + + + + Cannot set password for user %1. + + + + + usermod terminated with error code %1. + + + + + SetTimezoneJob + + + Set timezone to %1/%2 + + + + + Cannot access selected timezone path. + + + + + Bad path: %1 + + + + + Cannot set timezone. + + + + + Link creation failed, target: %1; link name: %2 + + + + + Cannot set timezone, + + + + + Cannot open /etc/timezone for writing + + + + + SetupGroupsJob + + + Preparing groups. + + + + + + Could not create groups in target system + + + + + These groups are missing in the target system: %1 + + + + + SetupSudoJob + + + Configure <pre>sudo</pre> users. + + + + + Cannot chmod sudoers file. + + + + + Cannot create sudoers file for writing. + + + + + ShellProcessJob + + + Shell Processes Job + + + + + SlideCounter + + + %L1 / %L2 + slide counter, %1 of %2 (numeric) + + + + + StandardButtons + + + &OK + + + + + &Yes + + + + + &No + + + + + &Cancel + + + + + &Close + + + + + TrackingInstallJob + + + Installation feedback + + + + + Sending installation feedback. + + + + + Internal error in install-tracking. + + + + + HTTP request timed out. + + + + + TrackingKUserFeedbackJob + + + KDE user feedback + + + + + Configuring KDE user feedback. + + + + + + Error in KDE user feedback configuration. + + + + + Could not configure KDE user feedback correctly, script error %1. + + + + + Could not configure KDE user feedback correctly, Calamares error %1. + + + + + TrackingMachineUpdateManagerJob + + + Machine feedback + + + + + Configuring machine feedback. + + + + + + Error in machine feedback configuration. + + + + + Could not configure machine feedback correctly, script error %1. + + + + + Could not configure machine feedback correctly, Calamares error %1. + + + + + TrackingPage + + + Form + + + + + Placeholder + + + + + <html><head/><body><p>Click here to send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> + + + + + <html><head/><body><p><a href="placeholder"><span style=" text-decoration: underline; color:#2980b9;">Click here for more information about user feedback</span></a></p></body></html> + + + + + Tracking helps %1 to see how often it is installed, what hardware it is installed on and which applications are used. To see what will be sent, please click the help icon next to each area. + + + + + By selecting this you will send information about your installation and hardware. This information will only be sent <b>once</b> after the installation finishes. + + + + + By selecting this you will periodically send information about your <b>machine</b> installation, hardware and applications, to %1. + + + + + By selecting this you will regularly send information about your <b>user</b> installation, hardware, applications and application usage patterns, to %1. + + + + + TrackingViewStep + + + Feedback + + + + + UsersPage + + + <small>If more than one person will use this computer, you can create multiple accounts after setup.</small> + + + + + <small>If more than one person will use this computer, you can create multiple accounts after installation.</small> + + + + + UsersQmlViewStep + + + Users + + + + + UsersViewStep + + + Users + + + + + VariantModel + + + Key + Column header for key/value + + + + + Value + Column header for key/value + + + + + VolumeGroupBaseDialog + + + Create Volume Group + + + + + List of Physical Volumes + + + + + Volume Group Name: + + + + + Volume Group Type: + + + + + Physical Extent Size: + + + + + MiB + + + + + Total Size: + + + + + Used Size: + + + + + Total Sectors: + + + + + Quantity of LVs: + + + + + WelcomePage + + + Form + + + + + + Select application and system language + + + + + &About + + + + + Open donations website + + + + + &Donate + + + + + Open help and support website + + + + + &Support + + + + + Open issues and bug-tracking website + + + + + &Known issues + + + + + Open release notes website + + + + + &Release notes + + + + + <h1>Welcome to the Calamares setup program for %1.</h1> + + + + + <h1>Welcome to %1 setup.</h1> + + + + + <h1>Welcome to the Calamares installer for %1.</h1> + + + + + <h1>Welcome to the %1 installer.</h1> + + + + + %1 support + + + + + About %1 setup + + + + + About %1 installer + + + + + <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. + + + + + WelcomeQmlViewStep + + + Welcome + + + + + WelcomeViewStep + + + Welcome + + + + + about + + + <h1>%1</h1><br/> + <strong>%2<br/> + for %3</strong><br/><br/> + Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/> + Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/> + Thanks to <a href='https://calamares.io/team/'>the Calamares team</a> + and the <a href='https://www.transifex.com/calamares/calamares/'>Calamares + translators team</a>.<br/><br/> + <a href='https://calamares.io/'>Calamares</a> + development is sponsored by <br/> + <a href='http://www.blue-systems.com/'>Blue Systems</a> - + Liberating Software. + + + + + Back + + + + + calamares-sidebar + + + Show debug information + + + + + finishedq + + + Installation Completed + + + + + %1 has been installed on your computer.<br/> + You may now restart into your new system, or continue using the Live environment. + + + + + Close Installer + + + + + Restart System + + + + + <p>A full log of the install is available as installation.log in the home directory of the Live user.<br/> + This log is copied to /var/log/installation.log of the target system.</p> + + + + + i18n + + + <h1>Languages</h1> </br> + The system locale setting affects the language and character set for some command line user interface elements. The current setting is <strong>%1</strong>. + + + + + <h1>Locales</h1> </br> + The system locale setting affects the numbers and dates format. The current setting is <strong>%1</strong>. + + + + + Back + + + + + keyboardq + + + To activate keyboard preview, select a layout. + + + + + Keyboard Model: + + + + + Layouts + + + + + Type here to test your keyboard + + + + + Variants + + + + + localeq + + + Change + + + + + notesqml + + + <h3>%1</h3> + <p>These are example release notes.</p> + + + + + packagechooserq + + + LibreOffice is a powerful and free office suite, used by millions of people around the world. It includes several applications that make it the most versatile Free and Open Source office suite on the market.<br/> + Default option. + + + + + LibreOffice + + + + + If you don't want to install an office suite, just select No Office Suite. You can always add one (or more) later on your installed system as the need arrives. + + + + + No Office Suite + + + + + Create a minimal Desktop install, remove all extra applications and decide later on what you would like to add to your system. Examples of what won't be on such an install, there will be no Office Suite, no media players, no image viewer or print support. It will be just a desktop, file browser, package manager, text editor and simple web-browser. + + + + + Minimal Install + + + + + Please select an option for your install, or use the default: LibreOffice included. + + + + + release_notes + + + <h3>%1</h3> + <p>This an example QML file, showing options in RichText with Flickable content.</p> + + <p>QML with RichText can use HTML tags, Flickable content is useful for touchscreens.</p> + + <p><b>This is bold text</b></p> + <p><i>This is italic text</i></p> + <p><u>This is underlined text</u></p> + <p><center>This text will be center-aligned.</center></p> + <p><s>This is strikethrough</s></p> + + <p>Code example: + <code>ls -l /home</code></p> + + <p><b>Lists:</b></p> + <ul> + <li>Intel CPU systems</li> + <li>AMD CPU systems</li> + </ul> + + <p>The vertical scrollbar is adjustable, current width set to 10.</p> + + + + + Back + + + + + usersq + + + Pick your user name and credentials to login and perform admin tasks + + + + + What is your name? + + + + + Your Full Name + + + + + What name do you want to use to log in? + + + + + Login Name + + + + + If more than one person will use this computer, you can create multiple accounts after installation. + + + + + Only lowercase letters, numbers, underscore and hyphen are allowed. + + + + + root is not allowed as username. + + + + + What is the name of this computer? + + + + + Computer Name + + + + + This name will be used if you make the computer visible to others on a network. + + + + + localhost is not allowed as hostname. + + + + + Choose a password to keep your account safe. + + + + + Password + + + + + Repeat Password + + + + + Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals. + + + + + Validate passwords quality + + + + + When this box is checked, password-strength checking is done and you will not be able to use a weak password. + + + + + Log in automatically without asking for the password + + + + + Only letters, numbers, underscore and hyphen are allowed, minimal of two characters. + + + + + Reuse user password as root password + + + + + Use the same password for the administrator account. + + + + + Choose a root password to keep your account safe. + + + + + Root Password + + + + + Repeat Root Password + + + + + Enter the same password twice, so that it can be checked for typing errors. + + + + + welcomeq + + + <h3>Welcome to the %1 <quote>%2</quote> installer</h3> + <p>This program will ask you some questions and set up %1 on your computer.</p> + + + + + About + + + + + Support + + + + + Known issues + + + + + Release notes + + + + + Donate + + + + diff --git a/lang/calamares_pt_PT.ts b/lang/calamares_pt_PT.ts index 951645ab1..3ec8b295e 100644 --- a/lang/calamares_pt_PT.ts +++ b/lang/calamares_pt_PT.ts @@ -2014,7 +2014,7 @@ O instalador será encerrado e todas as alterações serão perdidas.Please select your preferred location on the map so the installer can suggest the locale and timezone settings for you. You can fine-tune the suggested settings below. Search the map by dragging to move and using the +/- buttons to zoom in/out or use mouse scrolling for zooming. - Por favor selecione o seu local preferido no mapa para que o instalador possa sugerir a localização + Selecione o seu local preferido no mapa para que o instalador possa sugerir a localização e fuso horário para si. Pode ajustar as definições sugeridas abaixo. Procure no mapa arrastando para mover e utilizando os botões +/- para aumentar/diminuir ou utilize a roda do rato para dar zoom.
@@ -4003,7 +4003,7 @@ Saída de Dados: <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. - <h1>%1</h1><br/><strong>%2<br/>para %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Obrigado à <a href="https://calamares.io/team/">equipa Calamares</a> e à <a href="https://www.transifex.com/calamares/calamares/">equipa de tradutores do Calamares</a>.<br/><br/>O desenvolvimento do <a href="https://calamares.io/">Calamares</a> é patrocinado pela <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software. + <h1>%1</h1><br/><strong>%2<br/>para o %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac &lt;teo@kde.org&gt;<br/>Copyright 2017-2020 Adriaan de Groot &lt;groot@kde.org&gt;<br/>Obrigado à <a href="https://calamares.io/team/">equipa Calamares</a> e à <a href="https://www.transifex.com/calamares/calamares/">equipa de tradutores do Calamares</a>.<br/><br/>O desenvolvimento do <a href="https://calamares.io/">Calamares</a> é patrocinado pela <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software.
diff --git a/lang/calamares_ro.ts b/lang/calamares_ro.ts index 39573886d..a4ac28ce6 100644 --- a/lang/calamares_ro.ts +++ b/lang/calamares_ro.ts @@ -104,17 +104,17 @@ Crashes Calamares, so that Dr. Konqui can look at it. - + Dă crash lui Calamares, pentru ca doctorul Konqui să se uite la el. Reloads the stylesheet from the branding directory. - + Reîncarcă foaia de stil din directorul branding. Uploads the session log to the configured pastebin. - + Încarcă jurnalul sesiunii pe pastebin-ul configurat. @@ -134,7 +134,7 @@ Widget Tree - Lista widget + Arborele de widget diff --git a/lang/calamares_tg.ts b/lang/calamares_tg.ts index 1c64c5d8c..b4124be17 100644 --- a/lang/calamares_tg.ts +++ b/lang/calamares_tg.ts @@ -6,7 +6,7 @@ Manage auto-mount settings - + Идора кардани танзимоти васлкунии худкор diff --git a/lang/calamares_zh_CN.ts b/lang/calamares_zh_CN.ts index 5b58024ad..df04d1dd6 100644 --- a/lang/calamares_zh_CN.ts +++ b/lang/calamares_zh_CN.ts @@ -688,27 +688,27 @@ The installer will quit and all changes will be lost. Successfully unmounted %1. - + 成功卸载了 %1。 Successfully disabled swap %1. - + 成功禁用了交换空间 %1。 Successfully cleared swap %1. - + 成功清理了交换空间 %1。 Successfully closed mapper device %1. - + 成功关闭了映射设备 %1。 Successfully disabled volume group %1. - + 成功禁用了卷组 %1。 From 98bbc222cbc2c06500316f5453f0c59a6ae96d83 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Mon, 17 Jan 2022 13:50:42 +0100 Subject: [PATCH 109/168] i18n: [python] Automatic merge of Transifex translations --- lang/python/ja-Hira/LC_MESSAGES/python.po | 385 ++++++++++++++++++++++ lang/python/zh_CN/LC_MESSAGES/python.po | 7 +- 2 files changed, 389 insertions(+), 3 deletions(-) create mode 100644 lang/python/ja-Hira/LC_MESSAGES/python.po diff --git a/lang/python/ja-Hira/LC_MESSAGES/python.po b/lang/python/ja-Hira/LC_MESSAGES/python.po new file mode 100644 index 000000000..9a869c5bc --- /dev/null +++ b/lang/python/ja-Hira/LC_MESSAGES/python.po @@ -0,0 +1,385 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-11-02 15:45+0100\n" +"PO-Revision-Date: 2017-08-09 10:34+0000\n" +"Language-Team: Japanese (Hiragana) (https://www.transifex.com/calamares/teams/20061/ja-Hira/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ja-Hira\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: src/modules/initramfscfg/main.py:32 +msgid "Configuring initramfs." +msgstr "" + +#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 +#: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361 +#: src/modules/fstab/main.py:388 src/modules/networkcfg/main.py:105 +#: src/modules/initcpiocfg/main.py:227 src/modules/initcpiocfg/main.py:231 +#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:144 +#: src/modules/rawfs/main.py:164 src/modules/openrcdmcryptcfg/main.py:72 +#: src/modules/openrcdmcryptcfg/main.py:76 +#: src/modules/luksopenswaphookcfg/main.py:86 +#: src/modules/luksopenswaphookcfg/main.py:90 +msgid "Configuration Error" +msgstr "" + +#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356 +#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145 +#: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73 +#: src/modules/luksopenswaphookcfg/main.py:87 +msgid "No partitions are defined for
{!s}
to use." +msgstr "" + +#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362 +#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232 +#: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77 +#: src/modules/luksopenswaphookcfg/main.py:91 +msgid "No root mount point is given for
{!s}
to use." +msgstr "" + +#: src/modules/grubcfg/main.py:28 +msgid "Configure GRUB." +msgstr "" + +#: src/modules/bootloader/main.py:43 +msgid "Install bootloader." +msgstr "" + +#: src/modules/bootloader/main.py:508 +msgid "Bootloader installation error" +msgstr "" + +#: src/modules/bootloader/main.py:509 +msgid "" +"The bootloader could not be installed. The installation command " +"
{!s}
returned error code {!s}." +msgstr "" + +#: src/modules/fstab/main.py:29 +msgid "Writing fstab." +msgstr "" + +#: src/modules/fstab/main.py:389 +msgid "No
{!s}
configuration is given for
{!s}
to use." +msgstr "" + +#: src/modules/dracut/main.py:27 +msgid "Creating initramfs with dracut." +msgstr "" + +#: src/modules/dracut/main.py:49 +msgid "Failed to run dracut on the target" +msgstr "" + +#: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50 +msgid "The exit code was {}" +msgstr "" + +#: src/modules/displaymanager/main.py:526 +msgid "Cannot write KDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:527 +msgid "KDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:588 +msgid "Cannot write LXDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:589 +msgid "LXDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:672 +msgid "Cannot write LightDM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:673 +msgid "LightDM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:747 +msgid "Cannot configure LightDM" +msgstr "" + +#: src/modules/displaymanager/main.py:748 +msgid "No LightDM greeter installed." +msgstr "" + +#: src/modules/displaymanager/main.py:779 +msgid "Cannot write SLIM configuration file" +msgstr "" + +#: src/modules/displaymanager/main.py:780 +msgid "SLIM config file {!s} does not exist" +msgstr "" + +#: src/modules/displaymanager/main.py:906 +msgid "No display managers selected for the displaymanager module." +msgstr "" + +#: src/modules/displaymanager/main.py:907 +msgid "" +"The displaymanagers list is empty or undefined in both globalstorage and " +"displaymanager.conf." +msgstr "" + +#: src/modules/displaymanager/main.py:989 +msgid "Display manager configuration was incomplete" +msgstr "" + +#: src/modules/services-openrc/main.py:29 +msgid "Configure OpenRC services" +msgstr "" + +#: src/modules/services-openrc/main.py:57 +msgid "Cannot add service {name!s} to run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:59 +msgid "Cannot remove service {name!s} from run-level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:61 +msgid "" +"Unknown service-action {arg!s} for service {name!s} in run-" +"level {level!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:93 +#: src/modules/services-systemd/main.py:59 +msgid "Cannot modify service" +msgstr "" + +#: src/modules/services-openrc/main.py:94 +msgid "" +"rc-update {arg!s} call in chroot returned error code {num!s}." +msgstr "" + +#: src/modules/services-openrc/main.py:101 +msgid "Target runlevel does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:102 +msgid "" +"The path for runlevel {level!s} is {path!s}, which does not " +"exist." +msgstr "" + +#: src/modules/services-openrc/main.py:110 +msgid "Target service does not exist" +msgstr "" + +#: src/modules/services-openrc/main.py:111 +msgid "" +"The path for service {name!s} is {path!s}, which does not " +"exist." +msgstr "" + +#: src/modules/networkcfg/main.py:29 +msgid "Saving network configuration." +msgstr "" + +#: src/modules/packages/main.py:50 src/modules/packages/main.py:59 +#: src/modules/packages/main.py:69 +msgid "Install packages." +msgstr "" + +#: src/modules/packages/main.py:57 +#, python-format +msgid "Processing packages (%(count)d / %(total)d)" +msgstr "" + +#: src/modules/packages/main.py:62 +#, python-format +msgid "Installing one package." +msgid_plural "Installing %(num)d packages." +msgstr[0] "" + +#: src/modules/packages/main.py:65 +#, python-format +msgid "Removing one package." +msgid_plural "Removing %(num)d packages." +msgstr[0] "" + +#: src/modules/packages/main.py:638 src/modules/packages/main.py:650 +#: src/modules/packages/main.py:678 +msgid "Package Manager error" +msgstr "" + +#: src/modules/packages/main.py:639 +msgid "" +"The package manager could not prepare updates. The command
{!s}
" +"returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:651 +msgid "" +"The package manager could not update the system. The command
{!s}
" +" returned error code {!s}." +msgstr "" + +#: src/modules/packages/main.py:679 +msgid "" +"The package manager could not make changes to the installed system. The " +"command
{!s}
returned error code {!s}." +msgstr "" + +#: src/modules/plymouthcfg/main.py:27 +msgid "Configure Plymouth theme" +msgstr "" + +#: src/modules/initcpiocfg/main.py:28 +msgid "Configuring mkinitcpio." +msgstr "" + +#: src/modules/localecfg/main.py:30 +msgid "Configuring locales." +msgstr "" + +#: src/modules/mount/main.py:30 +msgid "Mounting partitions." +msgstr "" + +#: src/modules/rawfs/main.py:26 +msgid "Installing data." +msgstr "" + +#: src/modules/dummypython/main.py:35 +msgid "Dummy python job." +msgstr "" + +#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 +#: src/modules/dummypython/main.py:94 +msgid "Dummy python step {}" +msgstr "" + +#: src/modules/hwclock/main.py:26 +msgid "Setting hardware clock." +msgstr "" + +#: src/modules/umount/main.py:31 +msgid "Unmount file systems." +msgstr "" + +#: src/modules/openrcdmcryptcfg/main.py:26 +msgid "Configuring OpenRC dmcrypt service." +msgstr "" + +#: src/modules/services-systemd/main.py:26 +msgid "Configure systemd services" +msgstr "" + +#: src/modules/services-systemd/main.py:60 +msgid "" +"systemctl {arg!s} call in chroot returned error code {num!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:63 +#: src/modules/services-systemd/main.py:69 +msgid "Cannot enable systemd service {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:65 +msgid "Cannot enable systemd target {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:67 +msgid "Cannot enable systemd timer {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:71 +msgid "Cannot disable systemd target {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:73 +msgid "Cannot mask systemd unit {name!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:75 +msgid "" +"Unknown systemd commands {command!s} and " +"{suffix!s} for unit {name!s}." +msgstr "" + +#: src/modules/mkinitfs/main.py:27 +msgid "Creating initramfs with mkinitfs." +msgstr "" + +#: src/modules/mkinitfs/main.py:49 +msgid "Failed to run mkinitfs on the target" +msgstr "" + +#: src/modules/unpackfs/main.py:34 +msgid "Filling up filesystems." +msgstr "" + +#: src/modules/unpackfs/main.py:254 +msgid "rsync failed with error code {}." +msgstr "" + +#: src/modules/unpackfs/main.py:299 +msgid "Unpacking image {}/{}, file {}/{}" +msgstr "" + +#: src/modules/unpackfs/main.py:314 +msgid "Starting to unpack {}" +msgstr "" + +#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:465 +msgid "Failed to unpack image \"{}\"" +msgstr "" + +#: src/modules/unpackfs/main.py:430 +msgid "No mount point for root partition" +msgstr "" + +#: src/modules/unpackfs/main.py:431 +msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" +msgstr "" + +#: src/modules/unpackfs/main.py:436 +msgid "Bad mount point for root partition" +msgstr "" + +#: src/modules/unpackfs/main.py:437 +msgid "rootMountPoint is \"{}\", which does not exist, doing nothing" +msgstr "" + +#: src/modules/unpackfs/main.py:453 src/modules/unpackfs/main.py:457 +#: src/modules/unpackfs/main.py:463 src/modules/unpackfs/main.py:478 +msgid "Bad unsquash configuration" +msgstr "" + +#: src/modules/unpackfs/main.py:454 +msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel" +msgstr "" + +#: src/modules/unpackfs/main.py:458 +msgid "The source filesystem \"{}\" does not exist" +msgstr "" + +#: src/modules/unpackfs/main.py:464 +msgid "" +"Failed to find unsquashfs, make sure you have the squashfs-tools package " +"installed." +msgstr "" + +#: src/modules/unpackfs/main.py:479 +msgid "The destination \"{}\" in the target system is not a directory" +msgstr "" + +#: src/modules/luksopenswaphookcfg/main.py:26 +msgid "Configuring encrypted swap." +msgstr "" diff --git a/lang/python/zh_CN/LC_MESSAGES/python.po b/lang/python/zh_CN/LC_MESSAGES/python.po index 706b02d24..c6972b0f5 100644 --- a/lang/python/zh_CN/LC_MESSAGES/python.po +++ b/lang/python/zh_CN/LC_MESSAGES/python.po @@ -9,6 +9,7 @@ # Feng Chao , 2020 # Bobby Rong , 2020 # 玉堂白鹤 , 2021 +# Giovanni Schiano-Moriello, 2022 # #, fuzzy msgid "" @@ -17,7 +18,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: 玉堂白鹤 , 2021\n" +"Last-Translator: Giovanni Schiano-Moriello, 2022\n" "Language-Team: Chinese (China) (https://www.transifex.com/calamares/teams/20061/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -305,7 +306,7 @@ msgstr "无法启用 systemd 目标 {name!s}." #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "" +msgstr "无法启用 systemd 计时器 {name!s}。" #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." @@ -384,7 +385,7 @@ msgstr "源文件系统 \"{}\" 不存在" msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." -msgstr "" +msgstr "寻找 unsquashfs 失败,请确定您已安装 squashfs-tools 软体包。" #: src/modules/unpackfs/main.py:479 msgid "The destination \"{}\" in the target system is not a directory" From 112d0b2e9004a88228e49ad20e56432f7f3640d5 Mon Sep 17 00:00:00 2001 From: dalto Date: Mon, 17 Jan 2022 07:07:09 -0600 Subject: [PATCH 110/168] [packages] Ensure all pacman output is available in debug log --- src/modules/packages/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index 10371777e..ffa0d06e3 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -392,7 +392,7 @@ class PMPacman(PackageManager): global custom_status_message custom_status_message = "pacman: " + line.strip() libcalamares.job.setprogress(self.progress_fraction) - libcalamares.utils.debug(line) + libcalamares.utils.debug(line) self.in_package_changes = False self.line_cb = line_cb From a93126a6d0602d531ad90074ffa5886281212a5f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 14:19:28 +0100 Subject: [PATCH 111/168] [libcalamares] More meaningful name for JobResult success --- src/libcalamares/Job.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/Job.h b/src/libcalamares/Job.h index 33965e15f..dc89f1c49 100644 --- a/src/libcalamares/Job.h +++ b/src/libcalamares/Job.h @@ -47,7 +47,7 @@ public: /** @brief Is this JobResult a success? * - * Equivalent to errorCode() == 0, might be named isValid(). + * Equivalent to errorCode() == 0, see succeeded(). */ virtual operator bool() const; @@ -58,6 +58,11 @@ public: virtual void setDetails( const QString& details ); int errorCode() const { return m_number; } + /** @brief Is this JobResult a success? + * + * Equivalent to errorCode() == 0. + */ + bool succeeded() const { return this->operator bool(); } /// @brief an "ok status" result static JobResult ok(); From 2aaaabe152c41557475ae9fad2f78fc011690e24 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 14:50:37 +0100 Subject: [PATCH 112/168] [partition] Set bigtime on XFS filesystems FIXES #1874 --- CHANGES-3.2 | 2 ++ .../partition/jobs/FormatPartitionJob.cpp | 18 +++++++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index c1eb11caa..4ab226302 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -31,6 +31,8 @@ will be removed in that release. Use the *preservefiles* module instead. if the SSID or username contained non-ASCII characters **and** the default Python text-file encoding was set to ASCII. The files are now read and written in UTF-8, explicitly. #1848 + - *partition* always sets *bigtime* option on XFS filesystems, if possible. + Requires sufficiently-recent xfsprogs. #1874 - *preservefiles* was missing some necessary features, needed for it to replace the deprecated log-file-saving functionality in the *umount* module. (Thanks Erik and Joe for testing) #1851 diff --git a/src/modules/partition/jobs/FormatPartitionJob.cpp b/src/modules/partition/jobs/FormatPartitionJob.cpp index 1ccc6e617..63d233426 100644 --- a/src/modules/partition/jobs/FormatPartitionJob.cpp +++ b/src/modules/partition/jobs/FormatPartitionJob.cpp @@ -14,6 +14,7 @@ #include "core/KPMHelpers.h" #include "partition/FileSystem.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include @@ -67,7 +68,18 @@ FormatPartitionJob::prettyStatusMessage() const Calamares::JobResult FormatPartitionJob::exec() { - return KPMHelpers::execute( CreateFileSystemOperation( *m_device, *m_partition, m_partition->fileSystem().type() ), - tr( "The installer failed to format partition %1 on disk '%2'." ) - .arg( m_partition->partitionPath(), m_device->name() ) ); + const auto fsType = m_partition->fileSystem().type(); + auto r = KPMHelpers::execute( CreateFileSystemOperation( *m_device, *m_partition, fsType ), + tr( "The installer failed to format partition %1 on disk '%2'." ) + .arg( m_partition->partitionPath(), m_device->name() ) ); + if ( fsType == FileSystem::Xfs && r.succeeded() ) + { + // We are going to try to set modern timestamps for the filesystem, + // (ignoring whether this succeeds). Requires a sufficiently-new + // xfs_admin and xfs_repair and might be made obsolete by newer + // kpmcore releases. + CalamaresUtils::System::runCommand( { "xfs_admin", "-O", "bigtime=1", m_partition->partitionPath() }, + std::chrono::seconds( 60 ) ); + } + return r; } From 79a91b486a591494b7b8b2447b19da515ea2e595 Mon Sep 17 00:00:00 2001 From: tjpark88 Date: Thu, 30 Dec 2021 17:40:26 +0900 Subject: [PATCH 113/168] [locale] Update language always onActivate of locale updates the language only when currentLocation changed or when onActivate of locale is called for the first time. However, It is irrelevant solution since the language is set by the welcome. So language should be updated always. The language is used by keyboard module to guessing a layout of keyboard. Once you face the locale, you can't change language in the welcome if you don't change the timezone. --- src/modules/locale/Config.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index ce48edd82..c8245e4eb 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -252,15 +252,21 @@ Config::setCurrentLocation( const QString& regionName, const QString& zoneName ) void Config::setCurrentLocation( const CalamaresUtils::Locale::TimeZoneData* location ) { - if ( location != m_currentLocation ) + bool updateLocation = ( location != m_currentLocation ); + if ( updateLocation ) { m_currentLocation = location; - // Overwrite those settings that have not been made explicit. - auto newLocale = automaticLocaleConfiguration(); - if ( !m_selectedLocaleConfiguration.explicit_lang ) - { - setLanguage( newLocale.language() ); - } + } + + // Always lang should be updated + auto newLocale = automaticLocaleConfiguration(); + if ( !m_selectedLocaleConfiguration.explicit_lang ) + { + setLanguage( newLocale.language() ); + } + + if ( updateLocation ) + { if ( !m_selectedLocaleConfiguration.explicit_lc ) { m_selectedLocaleConfiguration.lc_numeric = newLocale.lc_numeric; From 6101dd90799fec671aaaaaa2d341ab1088facf84 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 13:11:42 +0100 Subject: [PATCH 114/168] [locale] Code style --- src/modules/locale/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index c8245e4eb..22a942b2a 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -252,13 +252,13 @@ Config::setCurrentLocation( const QString& regionName, const QString& zoneName ) void Config::setCurrentLocation( const CalamaresUtils::Locale::TimeZoneData* location ) { - bool updateLocation = ( location != m_currentLocation ); + const bool updateLocation = ( location != m_currentLocation ); if ( updateLocation ) { m_currentLocation = location; } - // Always lang should be updated + // lang should be always be updated auto newLocale = automaticLocaleConfiguration(); if ( !m_selectedLocaleConfiguration.explicit_lang ) { From 85a3d1dc847f5a9ee8c6afe68ed831d159ed2770 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 13:19:25 +0100 Subject: [PATCH 115/168] Changes: document locale fix --- CHANGES-3.2 | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 4ab226302..1fc05cd84 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -14,6 +14,7 @@ This release contains contributions from (alphabetically by first name): - Erik Dubois - Evan James - Johannes Kamprad + - Taejun Park (new contributor, welcome!) **Replacement notice:** The *umount* module will be replaced by a C++ implementation in the next release. The "preserve log file" feature @@ -38,6 +39,10 @@ will be removed in that release. Use the *preservefiles* module instead. module. (Thanks Erik and Joe for testing) #1851 - *umount* is now marked as an emergency module in the example configuration, since it should **probably** be run as a cleanup. (Thanks Evan) + - *welcome* and *locale* could be confusing, together, and configure + the target system with a language that does not match the installer + language, even though the user did not make any explicit choice. + (Thanks Taejun) #1864 # 3.2.49.1 (2021-12-11) # From 4811c59e334aa560c6dbc93883807ee1cc5525b4 Mon Sep 17 00:00:00 2001 From: dalto Date: Mon, 17 Jan 2022 16:24:56 -0600 Subject: [PATCH 116/168] [packages] Make pacman output more verbose --- src/modules/packages/main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index ffa0d06e3..59777cedb 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -382,7 +382,7 @@ class PMPacman(PackageManager): def line_cb(line): if line.startswith(":: "): - self.in_package_changes = "package changes" in line + self.in_package_changes = "package" in line or "hooks" in line else: if self.in_package_changes and line.endswith("...\n"): # Update the message, untranslated; do not change the @@ -444,8 +444,12 @@ class PMPacman(PackageManager): else: command.append("-S") + # Don't ask for user intervention, take the default action command.append("--noconfirm") + # Don't report download progress for each file + command.append("--noprogressbar") + if self.pacman_needed_only is True: command.append("--needed") From da2612d2d9a8a7ed1e9542d2c4a2ce4c78a5b01f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 12:28:57 +0100 Subject: [PATCH 117/168] [locale] Update language even if there is a current location - the first time we arrive at locale, there isn't a current location and the setCurrentLocation(...) method ends up calling setLanguage(), usually. The second time, this call is skipped (not called from the overloaded setCurrentLocation() which is called from onActivate), so the language didn't update. - now call setLanguage() unless there has been one set explicitly. --- src/modules/locale/Config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/locale/Config.cpp b/src/modules/locale/Config.cpp index 22a942b2a..8593f8385 100644 --- a/src/modules/locale/Config.cpp +++ b/src/modules/locale/Config.cpp @@ -221,6 +221,11 @@ Config::setCurrentLocation() { setCurrentLocation( m_startingTimezone.first, m_startingTimezone.second ); } + if ( !m_selectedLocaleConfiguration.explicit_lang ) + { + auto newLocale = automaticLocaleConfiguration(); + setLanguage( newLocale.language() ); + } } void From bca4b736776261f7b585f2291c12396c744268f9 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 18 Jan 2022 12:38:45 +0100 Subject: [PATCH 118/168] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_cs_CZ.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lang/calamares_cs_CZ.ts b/lang/calamares_cs_CZ.ts index 4525d7418..b61f36b81 100644 --- a/lang/calamares_cs_CZ.ts +++ b/lang/calamares_cs_CZ.ts @@ -693,27 +693,27 @@ Instalační program bude ukončen a všechny změny ztraceny. Successfully unmounted %1. - + Úspěšně odpojeno %1. Successfully disabled swap %1. - + Úspěšně vypnut swap %1. Successfully cleared swap %1. - + Úspěšně vyčištěn swap %1. Successfully closed mapper device %1. - + Úspěšně zavřeno mapper zařízení %1. Successfully disabled volume group %1. - + Úspěšně vypnuta skupina svazků %1. From ac083f787d7ab5483c6cfb8b695c996697a64a4e Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 18 Jan 2022 12:38:45 +0100 Subject: [PATCH 119/168] i18n: [python] Automatic merge of Transifex translations --- lang/python/cs_CZ/LC_MESSAGES/python.po | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lang/python/cs_CZ/LC_MESSAGES/python.po b/lang/python/cs_CZ/LC_MESSAGES/python.po index 70e9d5b77..23737551a 100644 --- a/lang/python/cs_CZ/LC_MESSAGES/python.po +++ b/lang/python/cs_CZ/LC_MESSAGES/python.po @@ -6,7 +6,7 @@ # Translators: # pavelrz, 2017 # LiberteCzech , 2020 -# Pavel Borecki , 2021 +# Pavel Borecki , 2022 # #, fuzzy msgid "" @@ -15,7 +15,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-02 15:45+0100\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: Pavel Borecki , 2021\n" +"Last-Translator: Pavel Borecki , 2022\n" "Language-Team: Czech (Czech Republic) (https://www.transifex.com/calamares/teams/20061/cs_CZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -331,7 +331,7 @@ msgstr "Nedaří se zapnout systemd službu {name!s}." #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "" +msgstr "Nedaří se zapnout systemd časovač {name!s}." #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." @@ -413,6 +413,8 @@ msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." msgstr "" +"Nepodařilo se nalézt nástroj unsquashfs – ověřte, že je nainstalovaný " +"balíček squashfs-tools." #: src/modules/unpackfs/main.py:479 msgid "The destination \"{}\" in the target system is not a directory" From 5d6375dab796c694d840e31cd51202b5e2369e21 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 12:50:47 +0100 Subject: [PATCH 120/168] Changes: pre-release housekeeping --- CHANGES-3.2 | 2 +- CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 1fc05cd84..d574dba0e 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,7 +7,7 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.50 (unreleased) # +# 3.2.50 (2022-01-18) # This release contains contributions from (alphabetically by first name): - Anke Boersma diff --git a/CMakeLists.txt b/CMakeLists.txt index c8b233f50..2f893c65e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ project( CALAMARES LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 4c5ee3b53abf424e557e9560419b40bf3e733faa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 13:20:49 +0100 Subject: [PATCH 121/168] Changes: post-release housekeeping - update the automatically-selected GPG signing-key --- CHANGES-3.2 | 12 ++++++++++++ CMakeLists.txt | 4 ++-- ci/RELEASE.sh | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index d574dba0e..8cf5c0761 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,6 +7,18 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. +# 3.2.51 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - No external contributors yet + +## Core ## + - No core changes yet + +## Modules ## + - No module changes yet + + # 3.2.50 (2022-01-18) # This release contains contributions from (alphabetically by first name): diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f893c65e..aec04f315 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.50 + VERSION 3.2.51 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() diff --git a/ci/RELEASE.sh b/ci/RELEASE.sh index f09285fb7..e46ca2cc2 100755 --- a/ci/RELEASE.sh +++ b/ci/RELEASE.sh @@ -75,7 +75,7 @@ fi # # BUILDDIR=$(mktemp -d --suffix=-build --tmpdir=.) -KEY_ID="CFDDC96F12B1915C" +KEY_ID="328D742D8807A435" # Try to make gpg cache the signing key, so we can leave the process # to run and sign. From 0070dd2c01bcb06f9dcd5072a7e0b186b0a2d807 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 17:10:25 +0100 Subject: [PATCH 122/168] [libcalamares] Add a convenience for reading mtab - used by umount and cleartempmounts (in future) --- src/libcalamares/partition/Mount.cpp | 30 +++++++++++++++++++++- src/libcalamares/partition/Mount.h | 38 ++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/partition/Mount.cpp b/src/libcalamares/partition/Mount.cpp index 89e17a885..6bc3a7cd2 100644 --- a/src/libcalamares/partition/Mount.cpp +++ b/src/libcalamares/partition/Mount.cpp @@ -14,6 +14,7 @@ #include "partition/Sync.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" +#include "utils/String.h" #include #include @@ -92,7 +93,7 @@ struct TemporaryMount::Private TemporaryMount::TemporaryMount( const QString& devicePath, const QString& filesystemName, const QString& options ) - : m_d( std::make_unique() ) + : m_d( std::make_unique< Private >() ) { m_d->m_devicePath = devicePath; m_d->m_mountDir.setAutoRemove( false ); @@ -123,5 +124,32 @@ TemporaryMount::path() const return m_d ? m_d->m_mountDir.path() : QString(); } +QList< MtabInfo > +MtabInfo::fromMtabFilteredByPrefix( const QString& mountPrefix, const QString& mtabPath ) +{ + QFile f( mtabPath.isEmpty() ? "/etc/mtab" : mtabPath ); + if ( !f.open( QIODevice::ReadOnly ) ) + { + return {}; + } + + QTextStream in( &f ); + QList< MtabInfo > l; + while ( !f.atEnd() ) + { + QStringList line = in.readLine().split( ' ', SplitSkipEmptyParts ); + if ( line.length() == 3 && !line[ 0 ].startsWith( '#' ) ) + { + // Lines have format: , so check + // the mountpoint field. Everything starts with an empty string. + if ( line[ 1 ].startsWith( mountPrefix ) ) + { + l.append( { line[ 0 ], line[ 1 ] } ); + } + } + } + return l; +} + } // namespace Partition } // namespace CalamaresUtils diff --git a/src/libcalamares/partition/Mount.h b/src/libcalamares/partition/Mount.h index d088b108f..f772c33a4 100644 --- a/src/libcalamares/partition/Mount.h +++ b/src/libcalamares/partition/Mount.h @@ -14,6 +14,7 @@ #include "DllMacro.h" +#include #include #include @@ -50,6 +51,13 @@ DLLEXPORT int mount( const QString& devicePath, */ DLLEXPORT int unmount( const QString& path, const QStringList& options = QStringList() ); + +/** @brief Mount and automatically unmount a device + * + * The TemporaryMount object mounts a filesystem, and is like calling + * the mount() function, above. When the object is destroyed, unmount() + * is called with suitable options to undo the original mount. + */ class DLLEXPORT TemporaryMount { public: @@ -68,6 +76,36 @@ private: std::unique_ptr< Private > m_d; }; + +/** @brief Information about a mount point from /etc/mtab + * + * Entries in /etc/mtab are of the form: + * This struct only stores device and mountpoint. + * + * The main way of getting these structs is to call fromMtab() to read + * an /etc/mtab-like file and storing all of the entries from it. + */ +struct DLLEXPORT MtabInfo +{ + QString device; + QString mountPoint; + + /** @brief Reads an mtab-like file and returns the entries from it + * + * When @p mtabPath is given, that file is read. If the given name is + * empty (e.g. the default) then /etc/mtab is read, instead. + * + * If @p mountPrefix is given, then only entries that have a mount point + * that starts with that prefix are returned. + */ + static QList< MtabInfo > fromMtabFilteredByPrefix( const QString& mountPrefix = QString(), + const QString& mtabPath = QString() ); + /// @brief Predicate to sort MtabInfo objects by device-name + static bool deviceOrder( const MtabInfo& a, const MtabInfo& b ) { return a.device > b.device; } + /// @brief Predicate to sort MtabInfo objects by mount-point + static bool mountPointOrder( const MtabInfo& a, const MtabInfo& b ) { return a.mountPoint > b.mountPoint; } +}; + } // namespace Partition } // namespace CalamaresUtils From 5e4866c4394963e332abbbfff45e0858bef9b5e4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 17:27:58 +0100 Subject: [PATCH 123/168] [partition] Simplify ClearTempMounts - use the shared function for reading mtab entries --- .../partition/jobs/ClearTempMountsJob.cpp | 47 ++++--------------- 1 file changed, 10 insertions(+), 37 deletions(-) diff --git a/src/modules/partition/jobs/ClearTempMountsJob.cpp b/src/modules/partition/jobs/ClearTempMountsJob.cpp index ffbc35044..6219de004 100644 --- a/src/modules/partition/jobs/ClearTempMountsJob.cpp +++ b/src/modules/partition/jobs/ClearTempMountsJob.cpp @@ -9,6 +9,7 @@ #include "ClearTempMountsJob.h" +#include "partition/Mount.h" #include "utils/Logger.h" #include "utils/String.h" @@ -45,51 +46,23 @@ ClearTempMountsJob::exec() { Logger::Once o; // Fetch a list of current mounts to Calamares temporary directories. - QList< QPair< QString, QString > > lst; - QFile mtab( "/etc/mtab" ); - if ( !mtab.open( QFile::ReadOnly | QFile::Text ) ) - { - return Calamares::JobResult::error( tr( "Cannot get list of temporary mounts." ) ); - } + using MtabInfo = CalamaresUtils::Partition::MtabInfo; + auto targetMounts = MtabInfo::fromMtabFilteredByPrefix( QStringLiteral( "/tmp/calamares-" ) ); - cVerbose() << o << "Opened mtab. Lines:"; - QTextStream in( &mtab ); - QString lineIn = in.readLine(); - while ( !lineIn.isNull() ) - { - QStringList line = lineIn.split( ' ', SplitSkipEmptyParts ); - cVerbose() << o << line.join( ' ' ); - QString device = line.at( 0 ); - QString mountPoint = line.at( 1 ); - if ( mountPoint.startsWith( "/tmp/calamares-" ) ) - { - lst.append( qMakePair( device, mountPoint ) ); - } - lineIn = in.readLine(); - } - - if ( lst.empty() ) + if ( targetMounts.isEmpty() ) { return Calamares::JobResult::ok(); } - - std::sort( - lst.begin(), lst.end(), []( const QPair< QString, QString >& a, const QPair< QString, QString >& b ) -> bool { - return a.first > b.first; - } ); + std::sort( targetMounts.begin(), targetMounts.end(), MtabInfo::mountPointOrder ); QStringList goodNews; - QProcess process; - - for ( const auto& line : qAsConst( lst ) ) + for ( const auto& m : qAsConst( targetMounts ) ) { - QString partPath = line.second; - cDebug() << o << "Will try to umount path" << partPath; - process.start( "umount", { "-lv", partPath } ); - process.waitForFinished(); - if ( process.exitCode() == 0 ) + cDebug() << o << "Will try to umount path" << m.mountPoint; + if ( CalamaresUtils::Partition::unmount( m.mountPoint, { "-lv" } ) == 0 ) { - goodNews.append( QString( "Successfully unmounted %1." ).arg( partPath ) ); + // Returns the program's exit code, so 0 is success + goodNews.append( QString( "Successfully unmounted %1." ).arg( m.mountPoint ) ); } } From afa5e75d76c09458587408a3a7dc4adea3c4f9e6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 20 Nov 2021 00:03:31 +0100 Subject: [PATCH 124/168] [umount] Start C++ port --- src/modules/umount/CMakeLists.txt | 18 +++++ src/modules/umount/Tests.cpp | 52 ++++++++++++ src/modules/umount/UmountJob.cpp | 51 ++++++++++++ src/modules/umount/UmountJob.h | 41 ++++++++++ src/modules/umount/main.py | 126 ------------------------------ src/modules/umount/module.desc | 8 -- 6 files changed, 162 insertions(+), 134 deletions(-) create mode 100644 src/modules/umount/CMakeLists.txt create mode 100644 src/modules/umount/Tests.cpp create mode 100644 src/modules/umount/UmountJob.cpp create mode 100644 src/modules/umount/UmountJob.h delete mode 100644 src/modules/umount/main.py delete mode 100644 src/modules/umount/module.desc diff --git a/src/modules/umount/CMakeLists.txt b/src/modules/umount/CMakeLists.txt new file mode 100644 index 000000000..a3f0e0f54 --- /dev/null +++ b/src/modules/umount/CMakeLists.txt @@ -0,0 +1,18 @@ +# === This file is part of Calamares - === +# +# SPDX-FileCopyrightText: 2021 Adriaan de Groot +# SPDX-License-Identifier: BSD-2-Clause +# +calamares_add_plugin( umount + TYPE job + EXPORT_MACRO PLUGINDLLEXPORT_PRO + SOURCES + UmountJob.cpp + SHARED_LIB +) + +calamares_add_test( + umounttest + SOURCES + Tests.cpp +) diff --git a/src/modules/umount/Tests.cpp b/src/modules/umount/Tests.cpp new file mode 100644 index 000000000..dc0198619 --- /dev/null +++ b/src/modules/umount/Tests.cpp @@ -0,0 +1,52 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "UmountJob.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" + +#include +#include +#include + +// Internals of UmountJob.cpp + +// Actual tests +class UmountTests : public QObject +{ + Q_OBJECT +public: + UmountTests() {} + ~UmountTests() override {} + +private Q_SLOTS: + void initTestCase(); + void testTrue(); +}; + +void +UmountTests::initTestCase() +{ + Logger::setupLogLevel( Logger::LOGDEBUG ); +} + +void +UmountTests::testTrue() +{ + QVERIFY( true ); +} + +QTEST_GUILESS_MAIN( UmountTests ) + +#include "utils/moc-warnings.h" + +#include "Tests.moc" diff --git a/src/modules/umount/UmountJob.cpp b/src/modules/umount/UmountJob.cpp new file mode 100644 index 000000000..1529edd04 --- /dev/null +++ b/src/modules/umount/UmountJob.cpp @@ -0,0 +1,51 @@ +/* === This file is part of Calamares - === + * + * Tags from the Python version of this module: + * SPDX-FileCopyrightText: 2014 Aurélien Gâteau + * SPDX-FileCopyrightText: 2016 Anke Boersma + * SPDX-FileCopyrightText: 2018 Adriaan de Groot + * Tags for the C++ version of this module: + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "UmountJob.h" + +#include "utils/CalamaresUtilsSystem.h" +#include "utils/Logger.h" +#include "utils/Variant.h" + +#include "GlobalStorage.h" +#include "JobQueue.h" + +#include + + +UmountJob::UmountJob( QObject* parent ) + : Calamares::CppJob( parent ) +{ +} + +UmountJob::~UmountJob() {} + +QString +UmountJob::prettyName() const +{ + return tr( "Unmount file systems." ); +} + +Calamares::JobResult +UmountJob::exec() +{ + return Calamares::JobResult::ok(); +} + +void +UmountJob::setConfigurationMap( const QVariantMap& map ) +{ +} + +CALAMARES_PLUGIN_FACTORY_DEFINITION( UmountJobFactory, registerPlugin< UmountJob >(); ) diff --git a/src/modules/umount/UmountJob.h b/src/modules/umount/UmountJob.h new file mode 100644 index 000000000..6ca5428bc --- /dev/null +++ b/src/modules/umount/UmountJob.h @@ -0,0 +1,41 @@ +/* === This file is part of Calamares - === + * + * SPDX-FileCopyrightText: 2021 Adriaan de Groot + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#ifndef UMOUNTJOB_H +#define UMOUNTJOB_H + +#include "CppJob.h" +#include "DllMacro.h" +#include "utils/PluginFactory.h" + +#include +#include +#include + +/** @brief Write 'random' data: machine id, entropy, UUIDs + * + */ +class PLUGINDLLEXPORT UmountJob : public Calamares::CppJob +{ + Q_OBJECT + +public: + explicit UmountJob( QObject* parent = nullptr ); + ~UmountJob() override; + + QString prettyName() const override; + + Calamares::JobResult exec() override; + + void setConfigurationMap( const QVariantMap& configurationMap ) override; +}; + +CALAMARES_PLUGIN_FACTORY_DECLARATION( UmountJobFactory ) + +#endif // UMOUNTJOB_H diff --git a/src/modules/umount/main.py b/src/modules/umount/main.py deleted file mode 100644 index f7bb3ca5a..000000000 --- a/src/modules/umount/main.py +++ /dev/null @@ -1,126 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# === This file is part of Calamares - === -# -# SPDX-FileCopyrightText: 2014 Aurélien Gâteau -# SPDX-FileCopyrightText: 2016 Anke Boersma -# SPDX-FileCopyrightText: 2018 Adriaan de Groot -# SPDX-License-Identifier: GPL-3.0-or-later -# -# Calamares is Free Software: see the License-Identifier above. -# - -import os -import subprocess -import shutil - -import libcalamares -from libcalamares.utils import gettext_path, gettext_languages - -import gettext -_translation = gettext.translation("calamares-python", - localedir=gettext_path(), - languages=gettext_languages(), - fallback=True) -_ = _translation.gettext -_n = _translation.ngettext - - -def pretty_name(): - return _( "Unmount file systems." ) - - -def list_mounts(root_mount_point): - """ List mount points. - - :param root_mount_point: - :return: - """ - lst = [] - - root_mount_point = os.path.normpath(root_mount_point) - for line in open("/etc/mtab").readlines(): - device, mount_point, _ = line.split(" ", 2) - - if os.path.commonprefix([root_mount_point, mount_point]) == root_mount_point: - lst.append((device, mount_point)) - - return lst - - -def export_zpools(root_mount_point): - """ Exports the zpools if defined in global storage - - :param root_mount_point: The absolute path to the root of the install - :return: - """ - try: - zfs_pool_list = libcalamares.globalstorage.value("zfsPoolInfo") - zfs_pool_list.sort(reverse=True, key=lambda x: x["poolName"]) - if zfs_pool_list: - for zfs_pool in zfs_pool_list: - try: - libcalamares.utils.host_env_process_output(['zpool', 'export', zfs_pool["poolName"]]) - except subprocess.CalledProcessError: - libcalamares.utils.warning("Failed to export zpool") - except Exception as e: - # If this fails it shouldn't cause the installation to fail - libcalamares.utils.warning("Received exception while exporting zpools: " + format(e)) - pass - - -def run(): - """ Unmounts given mountpoints in decreasing order. - - :return: - """ - root_mount_point = libcalamares.globalstorage.value("rootMountPoint") - - if(libcalamares.job.configuration and - "srcLog" in libcalamares.job.configuration or - "destLog" in libcalamares.job.configuration): - libcalamares.utils.error("Log-file preserving is **deprecated** in the *umount* module and removed in the next release") - if(libcalamares.job.configuration and - "srcLog" in libcalamares.job.configuration and - "destLog" in libcalamares.job.configuration): - log_source = libcalamares.job.configuration["srcLog"] - log_destination = libcalamares.job.configuration["destLog"] - # Relocate log_destination into target system - log_destination = '{!s}/{!s}'.format(root_mount_point, log_destination) - # Make sure source is a string - log_source = '{!s}'.format(log_source) - - # copy installation log before umount - if os.path.exists(log_source): - try: - shutil.copy2(log_source, log_destination) - except Exception as e: - libcalamares.utils.warning("Could not preserve file {!s}, " - "error {!s}".format(log_source, e)) - - if not root_mount_point: - return ("No mount point for root partition in globalstorage", - "globalstorage does not contain a \"rootMountPoint\" key, " - "doing nothing") - - if not os.path.exists(root_mount_point): - return ("Bad mount point for root partition in globalstorage", - "globalstorage[\"rootMountPoint\"] is \"{}\", which does not " - "exist, doing nothing".format(root_mount_point)) - - lst = list_mounts(root_mount_point) - # Sort the list by mount point in decreasing order. This way we can be sure - # we unmount deeper dirs first. - lst.sort(key=lambda x: x[1], reverse=True) - - for device, mount_point in lst: - # On success, no output; if the command fails, its output is - # in the exception object. - subprocess.check_output(["umount", "-lv", mount_point], stderr=subprocess.STDOUT) - - export_zpools(root_mount_point) - - os.rmdir(root_mount_point) - - return None diff --git a/src/modules/umount/module.desc b/src/modules/umount/module.desc deleted file mode 100644 index 1515e63df..000000000 --- a/src/modules/umount/module.desc +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-FileCopyrightText: no -# SPDX-License-Identifier: CC0-1.0 ---- -type: "job" -name: "umount" -interface: "python" -script: "main.py" -emergency: true \ No newline at end of file From 6034feb69da50c21229ce03f9bc17b575ccabc27 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 8 Dec 2021 17:20:35 +0100 Subject: [PATCH 125/168] [umount] Complete C++ implementation - as a design decision, the deprecated "save some files" functionality has been dropped from this implementation. --- src/modules/umount/UmountJob.cpp | 111 ++++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 2 deletions(-) diff --git a/src/modules/umount/UmountJob.cpp b/src/modules/umount/UmountJob.cpp index 1529edd04..b9d92fa87 100644 --- a/src/modules/umount/UmountJob.cpp +++ b/src/modules/umount/UmountJob.cpp @@ -14,6 +14,7 @@ #include "UmountJob.h" +#include "partition/Mount.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include "utils/Variant.h" @@ -21,8 +22,9 @@ #include "GlobalStorage.h" #include "JobQueue.h" -#include - +#include +#include +#include UmountJob::UmountJob( QObject* parent ) : Calamares::CppJob( parent ) @@ -37,9 +39,114 @@ UmountJob::prettyName() const return tr( "Unmount file systems." ); } +static Calamares::JobResult +unmountTargetMounts( const QString& rootMountPoint ) +{ + QDir targetMount( rootMountPoint ); + if ( !targetMount.exists() ) + { + return Calamares::JobResult::internalError( + QCoreApplication::translate( UmountJob::staticMetaObject.className(), "Could not unmount target system." ), + QCoreApplication::translate( UmountJob::staticMetaObject.className(), + "The target system is not mounted at '%1'." ) + .arg( rootMountPoint ), + Calamares::JobResult::GenericError ); + } + QString targetMountPath = targetMount.absolutePath(); + if ( !targetMountPath.endsWith( '/' ) ) + { + targetMountPath.append( '/' ); + } + + using MtabInfo = CalamaresUtils::Partition::MtabInfo; + auto targetMounts = MtabInfo::fromMtabFilteredByPrefix( targetMountPath ); + std::sort( targetMounts.begin(), targetMounts.end(), MtabInfo::mountPointOrder ); + + for ( const auto& m : qAsConst( targetMounts ) ) + { + if ( CalamaresUtils::Partition::unmount( m.mountPoint, { "-lv" } ) ) + { + // Returns the program's exit code, so 0 is success + return Calamares::JobResult::error( + QCoreApplication::translate( UmountJob::staticMetaObject.className(), + "Could not unmount target system." ), + QCoreApplication::translate( UmountJob::staticMetaObject.className(), + "The device '%1' is mounted in the target system. It is mounted at '%2'. " + "The device could not be unmounted." ) + .arg( m.device, m.mountPoint ) ); + } + } + return Calamares::JobResult::ok(); +} + +static Calamares::JobResult +exportZFSPools( const QString& rootMountPoint ) +{ + auto* gs = Calamares::JobQueue::instance()->globalStorage(); + QStringList poolNames; + { + // The pools are dictionaries / VariantMaps + auto zfs_pool_list = gs->value( "zfsPoolInfo" ).toList(); + for ( const auto& v : zfs_pool_list ) + { + auto m = v.toMap(); + QString poolName = m.value( "poolName" ).toString(); + if ( !poolName.isEmpty() ) + { + poolNames.append( poolName ); + } + } + poolNames.sort(); + } + + for ( const auto& poolName : poolNames ) + { + auto result = CalamaresUtils::System::runCommand( { "zpool", "export", poolName }, std::chrono::seconds( 30 ) ); + if ( result.getExitCode() ) + { + cWarning() << "Failed to export pool" << result.getOutput(); + } + } + // Exporting ZFS pools does not cause the install to fail + return Calamares::JobResult::ok(); +} + + Calamares::JobResult UmountJob::exec() { + const auto* sys = CalamaresUtils::System::instance(); + if ( !sys ) + { + return Calamares::JobResult::internalError( + "UMount", tr( "No target system available." ), Calamares::JobResult::InvalidConfiguration ); + } + + Calamares::GlobalStorage* gs + = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; + if ( !gs || gs->value( "rootMountPoint" ).toString().isEmpty() ) + { + return Calamares::JobResult::internalError( + "UMount", tr( "No rootMountPoint is set." ), Calamares::JobResult::InvalidConfiguration ); + } + + // Do the unmounting of target-system filesystems + { + auto r = unmountTargetMounts( gs->value( "rootMountPoint" ).toString() ); + if ( !r ) + { + return r; + } + } + // For ZFS systems, export the pools + { + auto r = exportZFSPools( gs->value( "rootMountPoint" ).toString() ); + if ( !r ) + { + return r; + } + } + return Calamares::JobResult::ok(); } From 4d5ae96db6e483e34a97ea4f749beaf721d4c317 Mon Sep 17 00:00:00 2001 From: dalto Date: Mon, 17 Jan 2022 13:33:13 +0100 Subject: [PATCH 126/168] [umount] Add support for umount to be an emergency module --- src/modules/umount/umount.conf | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 04d68e477..9743b12df 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -10,23 +10,12 @@ # The "copy log files" functionality is deprecated; use the *preservefiles* # module instead, which is more flexible. # +# This module has two deprecated configuration keys: +# srcLog location in the live system where the log is +# destLog location in the target system to copy the log # --- -# This is a **deprecated** example. Use the *preservefiles* module -# instead, where the equivalent configuration is this: -# -# files: -# - from: log -# dest: /var/log/installation.log -# -# Note that the "equivalent configuration" always finds the log, -# and is not dependent on specific user names or the vagaries of -# polkit configuration -- so it is a **better** "equivalent". -# -# example when using a log created by `sudo calamares -d`: -#srcLog: "/home/live/installation.log" -#destLog: "/var/log/installation.log" srcLog: "/bogus/just/do/not/use/this/anymore.txt" # Setting emergency to true will make it so this module is still run From c587145bdde3c5e66a99f6025ef4770aff27362b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 17 Jan 2022 13:37:47 +0100 Subject: [PATCH 127/168] [umount] Drop all mention of removed configuration keys --- src/modules/umount/CMakeLists.txt | 1 + src/modules/umount/umount.conf | 15 +++------------ src/modules/umount/umount.schema.yaml | 3 +-- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/modules/umount/CMakeLists.txt b/src/modules/umount/CMakeLists.txt index a3f0e0f54..d72847007 100644 --- a/src/modules/umount/CMakeLists.txt +++ b/src/modules/umount/CMakeLists.txt @@ -9,6 +9,7 @@ calamares_add_plugin( umount SOURCES UmountJob.cpp SHARED_LIB + EMERGENCY ) calamares_add_test( diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 9743b12df..9fb922740 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -4,20 +4,11 @@ ### Umount Module # # This module represents the last part of the installation, the unmounting -# of partitions used for the install. It is also the last place where it -# is possible to copy files to the target system. -# -# The "copy log files" functionality is deprecated; use the *preservefiles* -# module instead, which is more flexible. -# -# This module has two deprecated configuration keys: -# srcLog location in the live system where the log is -# destLog location in the target system to copy the log +# of partitions used for the install. After this, there is no regular way +# to modify the target system anymore. # --- -srcLog: "/bogus/just/do/not/use/this/anymore.txt" - # Setting emergency to true will make it so this module is still run # when a prior module fails -# emergency: true +emergency: false diff --git a/src/modules/umount/umount.schema.yaml b/src/modules/umount/umount.schema.yaml index 9b81db3d9..37771e5f6 100644 --- a/src/modules/umount/umount.schema.yaml +++ b/src/modules/umount/umount.schema.yaml @@ -6,5 +6,4 @@ $id: https://calamares.io/schemas/umount additionalProperties: false type: object properties: - srcLog: { type: string } - destLog: { type: string } + emergency: { type: boolean } From d1866edfe590fe2786682a8ae4953b1a06feaabc Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 13:28:45 +0100 Subject: [PATCH 128/168] Changes: log the changes to umount --- CHANGES-3.2 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 8cf5c0761..cf02ff29d 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -16,7 +16,8 @@ This release contains contributions from (alphabetically by first name): - No core changes yet ## Modules ## - - No module changes yet + - The *umount* module has been re-written in C++. The copy-a-log-file + functionality has been removed. Use the *preservefiles* module for that. # 3.2.50 (2022-01-18) # From b4b7deac2da76e0567e4680d6e1b0350a234d8ee Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 19 Nov 2021 11:46:42 +0100 Subject: [PATCH 129/168] [bootloader] Document intentions It may be easiest to modify the efiBootloaderId, since that does not normally show up in the UI. I cannot quickly come up with a way to do the same kind of suffixing on the user-visible name. SEE #1820 --- src/modules/bootloader/bootloader.conf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index f471c2ee0..e2401cf11 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -46,6 +46,14 @@ efiBootMgr: "efibootmgr" # setting the option here, keep in mind that the name is sanitized # (problematic characters, see above, are replaced). # +# There are some special words possible at the end of *efiBootloaderId*: +# @@SERIAL@@ can be used to obtain a uniquely-numbered suffix +# that is added to the Id (yielding, e.g., `dirname1` or `dirname72`) +# @@RANDOM@@ can be used to obtain a unique 4-digit hex suffix +# @@PHRASE@@ can be used to obtain a unique 1-to-3-word suffix +# from a dictionary of space-themed words +# Note that these must be at the **end** of the *efiBootloaderId* value. +# # efiBootloaderId: "dirname" # Optionally install a copy of the GRUB EFI bootloader as the EFI From ed5c4c9c8716dc6931e9b3eabed2ee41d3a157a6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 19 Nov 2021 12:34:35 +0100 Subject: [PATCH 130/168] [bootloader] Add generators for various suffix-flavors --- src/modules/bootloader/main.py | 115 +++++++++++++++++- src/modules/bootloader/tests/CMakeTests.txt | 7 ++ .../tests/test-bootloader-efiname.py | 39 ++++++ 3 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 src/modules/bootloader/tests/CMakeTests.txt create mode 100644 src/modules/bootloader/tests/test-bootloader-efiname.py diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index 0182d1110..e641f0c0a 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -268,10 +268,121 @@ def create_loader(loader_path, entry): loader_file.write(line) +class serialEfi(object): + """ + EFI Id generator that appends a serial number to the given name. + """ + def __init__(self, name): + self.name = name + # So the first call to next() will bump it to 0 + self.counter = -1 + + def next(self): + self.counter += 1 + if self.counter > 0: + return "{!s}{!s}".format(self.name, self.counter) + else: + return self.name + + +def render_in_base(value, base_values, length=-1): + """ + Renders @p value in base-N, where N is the number of + items in @p base_values. When rendering, use the items + of @p base_values (e.g. use "0123456789" to get regular decimal + rendering, or "ABCDEFGHIJ" for letters-as-numbers 'encoding'). + + If length is positive, pads out to at least that long with + leading "zeroes", whatever base_values[0] is. + """ + if value < 0: + raise ValueError("Cannot render negative values") + if len(base_values) < 2: + raise ValueError("Insufficient items for base-N rendering") + if length < 1: + length = 1 + digits = [] + base = len(base_values) + while value > 0: + place = value % base + value = value // base + digits.append(base_values[place]) + while len(digits) < length: + digits.append(base_values[0]) + return "".join(reversed(digits)) + + +class randomEfi(object): + """ + EFI Id generator that appends a random 4-digit hex number to the given name. + """ + def __init__(self, name): + self.name = name + # So the first call to next() will bump it to 0 + self.counter = -1 + + def next(self): + self.counter += 1 + if self.counter > 0: + import random + v = random.randint(0, 65535) # 16 bits + return "{!s}{!s}".format(self.name, render_in_base(v, "0123456789ABCDEF", 4)) + else: + return self.name + + +class phraseEfi(object): + """ + EFI Id generator that appends a random phrase to the given name. + """ + words = ("Sun", "Moon", "Mars", "Soyuz", "Falcon", "Kuaizhou", "Gaganyaan") + + def __init__(self, name): + self.name = name + # So the first call to next() will bump it to 0 + self.counter = -1 + + def next(self): + self.counter += 1 + if self.counter > 0: + import random + desired_length = 1 + self.counter // 5 + v = random.randint(0, len(self.words) ** desired_length) + return "{!s}{!s}".format(self.name, render_in_base(v, self.words, 4)) + else: + return self.name + + +def get_efi_suffix_generator(name): + if "@@" not in name: + raise ValueError("Misplaced call to change_efi_suffix, no @@") + parts = name.split("@@") + if len(parts) != 3: + raise ValueError("EFI Id {!r} is malformed".format(name)) + if parts[2]: + # Supposed to be empty because the string ends with "@@" + raise ValueError("EFI Id {!r} is malformed".format(name)) + if parts[1] not in ("SERIAL", "RANDOM", "PHRASE"): + raise ValueError("EFI suffix {!r} is unknown".format(parts[1])) + + generator = None + if parts[1] == "SERIAL": + generator = serialEfi(name) + elif parts[1] == "RANDOM": + generator = randomEfi(name) + elif parts[1] == "PHRASE": + generator = phraseEfi(name) + if generator is None: + raise ValueError("EFI suffix {!r} is unsupported".format(parts[1])) + + return generator + + def efi_label(): if "efiBootloaderId" in libcalamares.job.configuration: - efi_bootloader_id = libcalamares.job.configuration[ - "efiBootloaderId"] + efi_bootloader_id = libcalamares.job.configuration["efiBootloaderId"] + if efi_bootloader_id.endswith("@@"): + efi_bootloader_id = change_efi_suffix(efi_bootloader_id) else: branding = libcalamares.globalstorage.value("branding") efi_bootloader_id = branding["bootloaderEntryName"] diff --git a/src/modules/bootloader/tests/CMakeTests.txt b/src/modules/bootloader/tests/CMakeTests.txt new file mode 100644 index 000000000..5b16d5009 --- /dev/null +++ b/src/modules/bootloader/tests/CMakeTests.txt @@ -0,0 +1,7 @@ +# We have tests to exercise some of the module internals. +# Those tests conventionally live in Python files here in the tests/ directory. Add them. +add_test( + NAME test-bootloader-efiname + COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-bootloader-efiname.py + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} +) diff --git a/src/modules/bootloader/tests/test-bootloader-efiname.py b/src/modules/bootloader/tests/test-bootloader-efiname.py new file mode 100644 index 000000000..f40f6bcdd --- /dev/null +++ b/src/modules/bootloader/tests/test-bootloader-efiname.py @@ -0,0 +1,39 @@ +# Calamares Boilerplate +import libcalamares +libcalamares.globalstorage = libcalamares.GlobalStorage(None) +libcalamares.globalstorage.insert("testing", True) + +# Module prep-work +from src.modules.bootloader import main + +# Specific Bootloader test +g = main.get_efi_suffix_generator("derp@@SERIAL@@") +assert g is not None +for n in range(10): + print(g.next()) +assert g.next() == "derp11" + +g = main.get_efi_suffix_generator("derp@@RANDOM@@") +assert g is not None +for n in range(10): + print(g.next()) +# it's random, nothing to assert + +g = main.get_efi_suffix_generator("derp@@PHRASE@@") +assert g is not None +for n in range(10): + print(g.next()) +# it's random, nothing to assert + +# Check two invalid things +try: + g = main.get_efi_suffix_generator("derp") + raise TypeError("Shouldn't get generator") +except ValueError as e: + pass + +try: + g = main.get_efi_suffix_generator("derp@@HEX@@") + raise TypeError("Shouldn't get generator") +except ValueError as e: + pass From 7a462f4522c8e38797dc154c890e11343911de8e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 19 Nov 2021 12:42:34 +0100 Subject: [PATCH 131/168] [bootloader] Fix issues identified by tests - expectation derp11 was wrong, there were only 10 calls to next() - using whole name instead of the not-the-suffix-bit was wrong - phrase generator wrong length --- src/modules/bootloader/main.py | 8 ++++---- src/modules/bootloader/tests/test-bootloader-efiname.py | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index e641f0c0a..d27d83c97 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -348,7 +348,7 @@ class phraseEfi(object): import random desired_length = 1 + self.counter // 5 v = random.randint(0, len(self.words) ** desired_length) - return "{!s}{!s}".format(self.name, render_in_base(v, self.words, 4)) + return "{!s}{!s}".format(self.name, render_in_base(v, self.words)) else: return self.name @@ -367,11 +367,11 @@ def get_efi_suffix_generator(name): generator = None if parts[1] == "SERIAL": - generator = serialEfi(name) + generator = serialEfi(parts[0]) elif parts[1] == "RANDOM": - generator = randomEfi(name) + generator = randomEfi(parts[0]) elif parts[1] == "PHRASE": - generator = phraseEfi(name) + generator = phraseEfi(parts[0]) if generator is None: raise ValueError("EFI suffix {!r} is unsupported".format(parts[1])) diff --git a/src/modules/bootloader/tests/test-bootloader-efiname.py b/src/modules/bootloader/tests/test-bootloader-efiname.py index f40f6bcdd..bb3952b0d 100644 --- a/src/modules/bootloader/tests/test-bootloader-efiname.py +++ b/src/modules/bootloader/tests/test-bootloader-efiname.py @@ -9,9 +9,11 @@ from src.modules.bootloader import main # Specific Bootloader test g = main.get_efi_suffix_generator("derp@@SERIAL@@") assert g is not None -for n in range(10): +assert g.next() == "derp" # First time, no suffix +for n in range(9): print(g.next()) -assert g.next() == "derp11" +# We called next() 10 times in total, starting from 0 +assert g.next() == "derp10" g = main.get_efi_suffix_generator("derp@@RANDOM@@") assert g is not None From c9156d41b13ac68938201b3519e09d1ebbc0bf32 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 14:27:54 +0100 Subject: [PATCH 132/168] [bootloader] Extend tests and docs with a few more error cases --- src/modules/bootloader/bootloader.conf | 2 ++ .../tests/test-bootloader-efiname.py | 19 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index e2401cf11..804f3a00a 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -53,6 +53,8 @@ efiBootMgr: "efibootmgr" # @@PHRASE@@ can be used to obtain a unique 1-to-3-word suffix # from a dictionary of space-themed words # Note that these must be at the **end** of the *efiBootloaderId* value. +# There must also be at most one of them. If there is none, no suffix- +# processing is done and the *efiBootloaderId* is used unchanged. # # efiBootloaderId: "dirname" diff --git a/src/modules/bootloader/tests/test-bootloader-efiname.py b/src/modules/bootloader/tests/test-bootloader-efiname.py index bb3952b0d..a6643743f 100644 --- a/src/modules/bootloader/tests/test-bootloader-efiname.py +++ b/src/modules/bootloader/tests/test-bootloader-efiname.py @@ -27,15 +27,28 @@ for n in range(10): print(g.next()) # it's random, nothing to assert -# Check two invalid things +# Check invalid things try: g = main.get_efi_suffix_generator("derp") - raise TypeError("Shouldn't get generator") + raise TypeError("Shouldn't get generator (no indicator)") except ValueError as e: pass try: g = main.get_efi_suffix_generator("derp@@HEX@@") - raise TypeError("Shouldn't get generator") + raise TypeError("Shouldn't get generator (unknown indicator)") except ValueError as e: pass + +try: + g = main.get_efi_suffix_generator("derp@@SERIAL@@x") + raise TypeError("Shouldn't get generator (trailing garbage)") +except ValueError as e: + pass + +try: + g = main.get_efi_suffix_generator("derp@@SERIAL@@@@RANDOM@@") + raise TypeError("Shouldn't get generator (multiple indicators)") +except ValueError as e: + pass + From 929496552e663946bb672035e15b7c77522ae92d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 18 Jan 2022 15:09:44 +0100 Subject: [PATCH 133/168] [bootloader] Optionally generate unique suffix for bootloader --- src/modules/bootloader/main.py | 63 ++++++++++++++++--- .../tests/test-bootloader-efiname.py | 10 +++ 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index d27d83c97..81e271a71 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -268,6 +268,27 @@ def create_loader(loader_path, entry): loader_file.write(line) +class suffix_iterator(object): + """ + Wrapper for one of the "generator" classes below to behave like + a proper Python iterator. The iterator is initialized with a + maximum number of attempts to generate a new suffix. + """ + def __init__(self, attempts, generator): + self.generator = generator + self.attempts = attempts + self.counter = 0 + + def __iter__(self): + return self + + def __next__(self): + self.counter += 1 + if self.counter <= self.attempts: + return self.generator.next() + raise StopIteration + + class serialEfi(object): """ EFI Id generator that appends a serial number to the given name. @@ -354,8 +375,11 @@ class phraseEfi(object): def get_efi_suffix_generator(name): + """ + Handle EFI bootloader Ids with @@@@ for suffix-processing. + """ if "@@" not in name: - raise ValueError("Misplaced call to change_efi_suffix, no @@") + raise ValueError("Misplaced call to get_efi_suffix_generator, no @@") parts = name.split("@@") if len(parts) != 3: raise ValueError("EFI Id {!r} is malformed".format(name)) @@ -378,11 +402,32 @@ def get_efi_suffix_generator(name): return generator -def efi_label(): +def change_efi_suffix(efi_directory, bootloader_id): + """ + Returns a label based on @p bootloader_id that is usable within + @p efi_directory. If there is a @@@@ suffix marker + in the given id, tries to generate a unique label. + """ + if bootloader_id.endswith("@@"): + # Do 10 attempts with any suffix generator + g = suffix_iterator(10, get_efi_suffix_generator(bootloader_id)) + else: + # Just one attempt + g = [bootloader_id] + + for candidate_name in g: + if not os.path.exists(os.path.join(efi_directory, candidate_name)): + return candidate_name + return bootloader_id + + +def efi_label(efi_directory): + """ + Returns a sanitized label, possibly unique, that can be + used within @p efi_directory. + """ if "efiBootloaderId" in libcalamares.job.configuration: - efi_bootloader_id = libcalamares.job.configuration["efiBootloaderId"] - if efi_bootloader_id.endswith("@@"): - efi_bootloader_id = change_efi_suffix(efi_bootloader_id) + efi_bootloader_id = change_efi_suffix( efi_directory, calamares.job.configuration["efiBootloaderId"] ) else: branding = libcalamares.globalstorage.value("branding") efi_bootloader_id = branding["bootloaderEntryName"] @@ -501,7 +546,7 @@ def run_grub_mkconfig(partitions, output_file): check_target_env_call([libcalamares.job.configuration["grubMkconfig"], "-o", output_file]) -def run_grub_install(fw_type, partitions, efi_directory=None): +def run_grub_install(fw_type, partitions, efi_directory): """ Runs grub-install in the target environment @@ -518,7 +563,7 @@ def run_grub_install(fw_type, partitions, efi_directory=None): check_target_env_call(["sh", "-c", "echo ZPOOL_VDEV_NAME_PATH=1 >> /etc/environment"]) if fw_type == "efi": - efi_bootloader_id = efi_label() + efi_bootloader_id = efi_label(efi_directory) efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters() if is_zfs: @@ -573,7 +618,7 @@ def install_grub(efi_directory, fw_type): if not os.path.isdir(install_efi_directory): os.makedirs(install_efi_directory) - efi_bootloader_id = efi_label() + efi_bootloader_id = efi_label(efi_directory) efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters() @@ -617,7 +662,7 @@ def install_secureboot(efi_directory): """ Installs the secureboot shim in the system by calling efibootmgr. """ - efi_bootloader_id = efi_label() + efi_bootloader_id = efi_label(efi_directory) install_path = libcalamares.globalstorage.value("rootMountPoint") install_efi_directory = install_path + efi_directory diff --git a/src/modules/bootloader/tests/test-bootloader-efiname.py b/src/modules/bootloader/tests/test-bootloader-efiname.py index a6643743f..67cb91747 100644 --- a/src/modules/bootloader/tests/test-bootloader-efiname.py +++ b/src/modules/bootloader/tests/test-bootloader-efiname.py @@ -52,3 +52,13 @@ try: except ValueError as e: pass + +# Try the generator (assuming no calamares- test files exist in /tmp) +import os +assert "calamares-single" == main.change_efi_suffix("/tmp", "calamares-single") +assert "calamares-serial" == main.change_efi_suffix("/tmp", "calamares-serial@@SERIAL@@") +try: + os.makedirs("/tmp/calamares-serial", exist_ok=True) + assert "calamares-serial1" == main.change_efi_suffix("/tmp", "calamares-serial@@SERIAL@@") +finally: + os.rmdir("/tmp/calamares-serial") From 2aa8c2f0e0fd29edec1935d225f78d0a317e4f64 Mon Sep 17 00:00:00 2001 From: dalto Date: Wed, 19 Jan 2022 16:48:56 -0600 Subject: [PATCH 134/168] [packagechooser] Ensure multiple instances don't override the GS values --- src/modules/packagechooser/Config.cpp | 37 +++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index abf6a640e..2f54442b7 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -132,13 +132,46 @@ Config::updateGlobalStorage( const QStringList& selected ) const } else { - Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallAdd", netinstallDataList ); + auto* gs = Calamares::JobQueue::instance()->globalStorage(); + + // If an earlier packagechooser instance added this data to global storage, combine them + if ( gs->contains( "NetinstallAdd" ) ) + { + auto netinstallAddOrig = gs->value( "NetinstallAdd" ); + if ( netinstallAddOrig.canConvert( QVariant::List ) ) + { + netinstallDataList += netinstallAddOrig.toList(); + } + else + { + cWarning() << "Invalid NetinstallAdd data in global storage. Earlier selections purged"; + } + gs->remove( "NetinstallAdd" ); + } + gs->insert( "NetinstallAdd", netinstallDataList ); } } else if ( m_method == PackageChooserMethod::NetSelect ) { cDebug() << m_defaultId << "groups to select in netinstall" << selected; - Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallSelect", selected ); + QStringList newSelected = selected; + auto* gs = Calamares::JobQueue::instance()->globalStorage(); + + // If an earlier packagechooser instance added this data to global storage, combine them + if ( gs->contains( "NetinstallSelect" ) ) + { + auto selectedOrig = gs->value( "NetinstallSelect" ); + if ( selectedOrig.canConvert( QVariant::StringList ) ) + { + newSelected += selectedOrig.toStringList(); + } + else + { + cWarning() << "Invalid NetinstallSelect data in global storage. Earlier selections purged"; + } + gs->remove( "NetinstallSelect" ); + } + gs->insert( "NetinstallSelect", newSelected ); } else { From 95122fdcf5f182e68bb7ddbf47caec6b77a738a6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 22 Jan 2022 22:52:21 +0100 Subject: [PATCH 135/168] [partition] Warn if the system won't support encryption in a useful way This is the infrastructure bit; if someone can come up with a way of **meaningfully** detecting support, the detection function can be given a better implementation. FIXES #1725 --- src/modules/partition/gui/EncryptWidget.cpp | 29 +++++++++++++++++++++ src/modules/partition/gui/EncryptWidget.ui | 26 ++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index ee50e7d66..e62ae512e 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -13,9 +13,26 @@ #include "ui_EncryptWidget.h" +#include "Branding.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Retranslator.h" +/** @brief Does this system support whole-disk encryption? + * + * Returns @c true if the system is likely to support encryption + * with sufficient performance to be usable. A machine that can't + * doe hardware-assisted AES is **probably** too slow, so we could + * warn the user that ticking the "encrypt system" box is a bad + * idea. + * + * Since we don't have an oracle that can answer that question, + * just pretend every system can do it. + */ +static inline bool systemSupportsEncryptionAcceptably() +{ + return true; +} + EncryptWidget::EncryptWidget( QWidget* parent ) : QWidget( parent ) , m_ui( new Ui::EncryptWidget ) @@ -27,6 +44,18 @@ EncryptWidget::EncryptWidget( QWidget* parent ) m_ui->m_passphraseLineEdit->hide(); m_ui->m_confirmLineEdit->hide(); m_ui->m_iconLabel->hide(); + // TODO: this deserves better rendering, an icon or something, but that will + // depend on having a non-bogus implementation of systemSupportsEncryptionAcceptably + if ( systemSupportsEncryptionAcceptably() ) + { + m_ui->m_encryptionUnsupportedLabel->hide(); + } + else + { + // This is really ugly, but the character is unicode "unlocked" + m_ui->m_encryptionUnsupportedLabel->setText( QStringLiteral("🔓") ); + m_ui->m_encryptionUnsupportedLabel->show(); + } connect( m_ui->m_encryptCheckBox, &QCheckBox::stateChanged, this, &EncryptWidget::onCheckBoxStateChanged ); connect( m_ui->m_passphraseLineEdit, &QLineEdit::textEdited, this, &EncryptWidget::onPassphraseEdited ); diff --git a/src/modules/partition/gui/EncryptWidget.ui b/src/modules/partition/gui/EncryptWidget.ui index 212300291..a629163d3 100644 --- a/src/modules/partition/gui/EncryptWidget.ui +++ b/src/modules/partition/gui/EncryptWidget.ui @@ -37,6 +37,19 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + + Your system does not seem to support encryption well enough to encrypt the entire system. You may enable encryption, but performance may suffer. + + + 🔓 + + + Qt::AlignCenter + + + @@ -57,6 +70,19 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + + Qt::Horizontal + + + + 40 + 20 + + + + From f4c2db7f21214ba29cb4a9038fbfee759eee7224 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 23 Jan 2022 13:58:10 -0600 Subject: [PATCH 136/168] [packagechooser,netinstall] Fix issues where going back and forth between pkgchooser and netinstall produced unexpected behavior --- src/modules/netinstall/NetInstallPage.cpp | 2 +- src/modules/netinstall/PackageModel.cpp | 22 +++++++++++++-------- src/modules/netinstall/PackageModel.h | 15 ++++++++++++-- src/modules/netinstall/PackageTreeItem.cpp | 14 +++++++++++++ src/modules/netinstall/PackageTreeItem.h | 4 ++++ src/modules/packagechooser/Config.cpp | 2 +- src/modules/packagechooser/PackageModel.cpp | 9 +++++++-- 7 files changed, 54 insertions(+), 14 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index f897c0018..4468e9cc0 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -78,6 +78,6 @@ NetInstallPage::onActivate() { const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); - static_cast< PackageModel* >( ui->groupswidget->model() )->appendModelData( groups ); + static_cast< PackageModel* >( ui->groupswidget->model() )->appendModelData( groups, "packageChooser" ); } } diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 9eafd898e..d139a89f6 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -342,20 +342,26 @@ PackageModel::setupModelData( const QVariantList& l ) emit endResetModel(); } -/** @brief Appends groups to the tree - * - * Uses the data from @p groupList to add elements to the - * existing tree that m_rootItem points to. If m_rootItem - * is not valid, it does nothing - * - */ void -PackageModel::appendModelData( const QVariantList& groupList ) +PackageModel::appendModelData( const QVariantList& groupList, const QString source ) { if ( m_rootItem ) { emit beginResetModel(); + + // Prune any existing data from the same source + for ( int i = 0; i < m_rootItem->childCount(); i++ ) + { + PackageTreeItem* child = m_rootItem->child( i ); + if ( child->source() == source ) + { + m_rootItem->removeChild( i ); + } + } + + // Add the new data to the model setupModelData( groupList, m_rootItem ); + emit endResetModel(); } } diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index fcdfe5daa..49a17f0b6 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -55,12 +55,23 @@ public: int columnCount( const QModelIndex& parent = QModelIndex() ) const override; void setSelections( QStringList selectNames ); - void setSelections(QStringList selectNames, PackageTreeItem *item ); + void setSelections( QStringList selectNames, PackageTreeItem* item ); PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; - void appendModelData( const QVariantList& groupList ); + /** @brief Appends groups to the tree + * + * Uses the data from @p groupList to add elements to the + * existing tree that m_rootItem points to. If m_rootItem + * is not valid, it does nothing + * + * Before adding anything to the model, it ensures that there + * is no existing data from the same source. If there is, that + * data is pruned first + * + */ + void appendModelData( const QVariantList& groupList, const QString source ); private: friend class ItemTests; diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index b30cdf915..245f1ddc6 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -70,6 +70,7 @@ PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, GroupTag&& paren , m_description( CalamaresUtils::getString( groupData, "description" ) ) , m_preScript( CalamaresUtils::getString( groupData, "pre-install" ) ) , m_postScript( CalamaresUtils::getString( groupData, "post-install" ) ) + , m_source( CalamaresUtils::getString( groupData, "source" ) ) , m_isGroup( true ) , m_isCritical( parentCriticality( groupData, parent.parent ) ) , m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) ) @@ -248,6 +249,19 @@ PackageTreeItem::setChildrenSelected( Qt::CheckState isSelected ) } } +void +PackageTreeItem::removeChild( int row ) +{ + if ( row < m_childItems.count() ) + { + m_childItems.removeAt( row ); + } + else + { + cWarning() << "Attempt to remove invalid child in removeChild() at row " + QString::number( row ); + } +} + int PackageTreeItem::type() const { diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index c04b9a21d..2a0fca83e 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -56,6 +56,7 @@ public: QString description() const { return m_description; } QString preScript() const { return m_preScript; } QString postScript() const { return m_postScript; } + QString source() const { return m_source; } /** @brief Is this item a group-item? * @@ -124,6 +125,8 @@ public: void setSelected( Qt::CheckState isSelected ); void setChildrenSelected( Qt::CheckState isSelected ); + void removeChild( int row ); + /** @brief Update selectedness based on the children's states * * This only makes sense for groups, which might have packages @@ -157,6 +160,7 @@ private: QString m_description; QString m_preScript; QString m_postScript; + QString m_source; bool m_isGroup = false; bool m_isCritical = false; bool m_isHidden = false; diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index 2f54442b7..c573889ab 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -140,7 +140,7 @@ Config::updateGlobalStorage( const QStringList& selected ) const auto netinstallAddOrig = gs->value( "NetinstallAdd" ); if ( netinstallAddOrig.canConvert( QVariant::List ) ) { - netinstallDataList += netinstallAddOrig.toList(); + //netinstallDataList += netinstallAddOrig.toList(); } else { diff --git a/src/modules/packagechooser/PackageModel.cpp b/src/modules/packagechooser/PackageModel.cpp index 7b7cfc08f..3d1c0c044 100644 --- a/src/modules/packagechooser/PackageModel.cpp +++ b/src/modules/packagechooser/PackageModel.cpp @@ -140,11 +140,16 @@ QVariantList PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const { QVariantList l; - for ( const auto& p : qAsConst( m_packages ) ) + for ( auto &p : m_packages ) { if ( ids.contains( p.id ) ) { - l.append( p.netinstallData ); + if ( !p.netinstallData.isEmpty() ) + { + QVariantMap newData = p.netinstallData; + newData["source"] = "packageChooser"; + l.append( newData ); + } } } return l; From a657d7388cdbea6c0363034829b7eae2d7f3fbd7 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 23 Jan 2022 14:47:14 -0600 Subject: [PATCH 137/168] [packagechooser] Remove obsolete functionality from netinstall-add --- src/modules/packagechooser/Config.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index c573889ab..ffe816f17 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -132,23 +132,7 @@ Config::updateGlobalStorage( const QStringList& selected ) const } else { - auto* gs = Calamares::JobQueue::instance()->globalStorage(); - - // If an earlier packagechooser instance added this data to global storage, combine them - if ( gs->contains( "NetinstallAdd" ) ) - { - auto netinstallAddOrig = gs->value( "NetinstallAdd" ); - if ( netinstallAddOrig.canConvert( QVariant::List ) ) - { - //netinstallDataList += netinstallAddOrig.toList(); - } - else - { - cWarning() << "Invalid NetinstallAdd data in global storage. Earlier selections purged"; - } - gs->remove( "NetinstallAdd" ); - } - gs->insert( "NetinstallAdd", netinstallDataList ); + Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallAdd", netinstallDataList ); } } else if ( m_method == PackageChooserMethod::NetSelect ) From 1db217931bf16afc858662f1a2980b88a7b36824 Mon Sep 17 00:00:00 2001 From: dalto Date: Mon, 24 Jan 2022 15:39:14 -0600 Subject: [PATCH 138/168] [netinstall] Minor changes from code review --- src/modules/netinstall/NetInstallPage.cpp | 16 +++---- src/modules/netinstall/PackageModel.cpp | 51 +++++++++------------- src/modules/netinstall/PackageModel.h | 14 ++++-- src/modules/netinstall/PackageTreeItem.cpp | 2 +- 4 files changed, 40 insertions(+), 43 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 4468e9cc0..80e6a58f9 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -64,20 +64,18 @@ NetInstallPage::onActivate() { ui->groupswidget->setFocus(); - // The NetInstallSelect global sotrage value can be used to make additional items selected by default + // The NetInstallSelect global storage value can be used to make additional items selected by default Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - if ( gs->contains( "NetinstallSelect" ) && gs->value( "NetinstallSelect" ).canConvert( QVariant::StringList ) ) + const QStringList selectNames = gs->value( "NetinstallSelect" ).toStringList(); + if ( !selectNames.isEmpty() ) { - const QStringList selectNames = gs->value( "NetinstallSelect" ).toStringList(); - - static_cast< PackageModel* >( ui->groupswidget->model() )->setSelections( selectNames ); + m_config->model()->setSelections( selectNames ); } // If NetInstallAdd is found in global storage, add those items to the tree - if ( gs->contains( "NetinstallAdd" ) && gs->value( "NetinstallAdd" ).canConvert( QVariant::List ) ) + const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); + if ( !groups.isEmpty() ) { - const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); - - static_cast< PackageModel* >( ui->groupswidget->model() )->appendModelData( groups, "packageChooser" ); + m_config->model()->appendModelData( groups, "packageChooser" ); } } diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index d139a89f6..9ffaa2650 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -14,6 +14,20 @@ #include "utils/Variant.h" #include "utils/Yaml.h" +static void +setSelections2( const QStringList& selectNames, PackageTreeItem* item ) +{ + for ( int i = 0; i < item->childCount(); i++ ) + { + auto* child = item->child( i ); + setSelections2( selectNames, child ); + } + if ( item->isGroup() && selectNames.contains( item->name() ) ) + { + item->setSelected( Qt::CheckState::Checked ); + } +} + PackageModel::PackageModel( QObject* parent ) : QAbstractItemModel( parent ) { @@ -170,35 +184,12 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c return QVariant(); } -/** @brief Sets the checked flag on matching groups in the tree - * - * Recursively traverses the tree pointed to by m_rootItem and - * checks if a group name matches any of the items in @p selectNames. - * If a match is found, set check the box for that group and it's children. - * - * Individual packages will not be matched. - * - */ void -PackageModel::setSelections( QStringList selectNames ) +PackageModel::setSelections( const QStringList& selectNames ) { if ( m_rootItem ) { - setSelections( selectNames, m_rootItem ); - } -} - -void -PackageModel::setSelections( QStringList selectNames, PackageTreeItem* item ) -{ - for ( int i = 0; i < item->childCount(); i++ ) - { - auto* child = item->child( i ); - setSelections( selectNames, child ); - } - if ( item->isGroup() && selectNames.contains( item->name() ) ) - { - item->setSelected( Qt::CheckState::Checked ); + setSelections2( selectNames, m_rootItem ); } } @@ -335,19 +326,19 @@ PackageModel::setupModelData( const QVariantList& groupList, PackageTreeItem* pa void PackageModel::setupModelData( const QVariantList& l ) { - emit beginResetModel(); + Q_EMIT beginResetModel(); delete m_rootItem; m_rootItem = new PackageTreeItem(); setupModelData( l, m_rootItem ); - emit endResetModel(); + Q_EMIT endResetModel(); } void -PackageModel::appendModelData( const QVariantList& groupList, const QString source ) +PackageModel::appendModelData( const QVariantList& groupList, const QString& source ) { if ( m_rootItem ) { - emit beginResetModel(); + Q_EMIT beginResetModel(); // Prune any existing data from the same source for ( int i = 0; i < m_rootItem->childCount(); i++ ) @@ -362,6 +353,6 @@ PackageModel::appendModelData( const QVariantList& groupList, const QString sour // Add the new data to the model setupModelData( groupList, m_rootItem ); - emit endResetModel(); + Q_EMIT endResetModel(); } } diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 49a17f0b6..3e79faf98 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -54,8 +54,16 @@ public: int rowCount( const QModelIndex& parent = QModelIndex() ) const override; int columnCount( const QModelIndex& parent = QModelIndex() ) const override; - void setSelections( QStringList selectNames ); - void setSelections( QStringList selectNames, PackageTreeItem* item ); + /** @brief Sets the checked flag on matching groups in the tree + * + * Recursively traverses the tree pointed to by m_rootItem and + * checks if a group name matches any of the items in @p selectNames. + * If a match is found, set check the box for that group and it's children. + * + * Individual packages will not be matched. + * + */ + void setSelections(const QStringList &selectNames ); PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; @@ -71,7 +79,7 @@ public: * data is pruned first * */ - void appendModelData( const QVariantList& groupList, const QString source ); + void appendModelData(const QVariantList& groupList, const QString &source ); private: friend class ItemTests; diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index 245f1ddc6..36a2e7d88 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -258,7 +258,7 @@ PackageTreeItem::removeChild( int row ) } else { - cWarning() << "Attempt to remove invalid child in removeChild() at row " + QString::number( row ); + cWarning() << "Attempt to remove invalid child in removeChild() at row " << row; } } From 22c9d888b475a42e17c393bb489b70501f514376 Mon Sep 17 00:00:00 2001 From: dalto Date: Mon, 24 Jan 2022 17:01:16 -0600 Subject: [PATCH 139/168] [packagechooser,netinstall] Proper implementation of source field --- src/modules/netinstall/NetInstallPage.cpp | 2 +- src/modules/netinstall/PackageModel.cpp | 50 ++++++++++++++++++--- src/modules/netinstall/PackageModel.h | 13 +----- src/modules/packagechooser/PackageModel.cpp | 4 +- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 80e6a58f9..17c16a472 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -76,6 +76,6 @@ NetInstallPage::onActivate() const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); if ( !groups.isEmpty() ) { - m_config->model()->appendModelData( groups, "packageChooser" ); + m_config->model()->appendModelData( groups ); } } diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 9ffaa2650..ac7443c15 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -14,6 +14,17 @@ #include "utils/Variant.h" #include "utils/Yaml.h" +/** @brief Appends groups to the tree + * + * Uses the data from @p groupList to add elements to the + * existing tree that m_rootItem points to. If m_rootItem + * is not valid, it does nothing + * + * Before adding anything to the model, it ensures that there + * is no existing data from the same source. If there is, that + * data is pruned first + * + */ static void setSelections2( const QStringList& selectNames, PackageTreeItem* item ) { @@ -28,6 +39,28 @@ setSelections2( const QStringList& selectNames, PackageTreeItem* item ) } } +/** @brief Collects all the "source" values from @p groupList + * + * Iterates over @p groupList and returns all nonempty "source" + * values from the maps. + * + */ +static QStringList +collectSources( const QVariantList& groupList ) +{ + QStringList sources; + for ( const QVariant& group : groupList ) + { + QVariantMap groupMap = group.toMap(); + if ( !groupMap[ "source" ].toString().isEmpty() ) + { + sources.append( groupMap[ "source" ].toString() ); + } + } + + return sources; +} + PackageModel::PackageModel( QObject* parent ) : QAbstractItemModel( parent ) { @@ -334,19 +367,24 @@ PackageModel::setupModelData( const QVariantList& l ) } void -PackageModel::appendModelData( const QVariantList& groupList, const QString& source ) +PackageModel::appendModelData( const QVariantList& groupList ) { if ( m_rootItem ) { Q_EMIT beginResetModel(); - // Prune any existing data from the same source - for ( int i = 0; i < m_rootItem->childCount(); i++ ) + const QStringList sources = collectSources( groupList ); + + if ( !sources.isEmpty() ) { - PackageTreeItem* child = m_rootItem->child( i ); - if ( child->source() == source ) + // Prune any existing data from the same source + for ( int i = 0; i < m_rootItem->childCount(); i++ ) { - m_rootItem->removeChild( i ); + PackageTreeItem* child = m_rootItem->child( i ); + if ( sources.contains( child->source() ) ) + { + m_rootItem->removeChild( i ); + } } } diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 3e79faf98..5146c63dd 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -68,18 +68,7 @@ public: PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; - /** @brief Appends groups to the tree - * - * Uses the data from @p groupList to add elements to the - * existing tree that m_rootItem points to. If m_rootItem - * is not valid, it does nothing - * - * Before adding anything to the model, it ensures that there - * is no existing data from the same source. If there is, that - * data is pruned first - * - */ - void appendModelData(const QVariantList& groupList, const QString &source ); + void appendModelData(const QVariantList& groupList); private: friend class ItemTests; diff --git a/src/modules/packagechooser/PackageModel.cpp b/src/modules/packagechooser/PackageModel.cpp index 3d1c0c044..f1d1184ad 100644 --- a/src/modules/packagechooser/PackageModel.cpp +++ b/src/modules/packagechooser/PackageModel.cpp @@ -140,14 +140,14 @@ QVariantList PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const { QVariantList l; - for ( auto &p : m_packages ) + for ( auto& p : m_packages ) { if ( ids.contains( p.id ) ) { if ( !p.netinstallData.isEmpty() ) { QVariantMap newData = p.netinstallData; - newData["source"] = "packageChooser"; + newData[ "source" ] = QStringLiteral( "packageChooser" ); l.append( newData ); } } From 63ed2e5fb8427b80677523c45f9a0bf3ed67c5d4 Mon Sep 17 00:00:00 2001 From: dalto Date: Tue, 25 Jan 2022 17:43:19 -0600 Subject: [PATCH 140/168] [packagechooser,netinstall] Change globalstorage keys to camel case --- src/modules/netinstall/NetInstallPage.cpp | 4 ++-- src/modules/packagechooser/Config.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index 17c16a472..ec350a6c6 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -66,14 +66,14 @@ NetInstallPage::onActivate() // The NetInstallSelect global storage value can be used to make additional items selected by default Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - const QStringList selectNames = gs->value( "NetinstallSelect" ).toStringList(); + const QStringList selectNames = gs->value( "netinstallSelect" ).toStringList(); if ( !selectNames.isEmpty() ) { m_config->model()->setSelections( selectNames ); } // If NetInstallAdd is found in global storage, add those items to the tree - const QVariantList groups = gs->value( "NetinstallAdd" ).toList(); + const QVariantList groups = gs->value( "netinstallAdd" ).toList(); if ( !groups.isEmpty() ) { m_config->model()->appendModelData( groups ); diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index ffe816f17..c6f5c9658 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -132,7 +132,7 @@ Config::updateGlobalStorage( const QStringList& selected ) const } else { - Calamares::JobQueue::instance()->globalStorage()->insert( "NetinstallAdd", netinstallDataList ); + Calamares::JobQueue::instance()->globalStorage()->insert( "netinstallAdd", netinstallDataList ); } } else if ( m_method == PackageChooserMethod::NetSelect ) @@ -142,9 +142,9 @@ Config::updateGlobalStorage( const QStringList& selected ) const auto* gs = Calamares::JobQueue::instance()->globalStorage(); // If an earlier packagechooser instance added this data to global storage, combine them - if ( gs->contains( "NetinstallSelect" ) ) + if ( gs->contains( "netinstallSelect" ) ) { - auto selectedOrig = gs->value( "NetinstallSelect" ); + auto selectedOrig = gs->value( "netinstallSelect" ); if ( selectedOrig.canConvert( QVariant::StringList ) ) { newSelected += selectedOrig.toStringList(); @@ -153,9 +153,9 @@ Config::updateGlobalStorage( const QStringList& selected ) const { cWarning() << "Invalid NetinstallSelect data in global storage. Earlier selections purged"; } - gs->remove( "NetinstallSelect" ); + gs->remove( "netinstallSelect" ); } - gs->insert( "NetinstallSelect", newSelected ); + gs->insert( "netinstallSelect", newSelected ); } else { From 6be12084881ec67cc4d5e126fae6d70deadee61c Mon Sep 17 00:00:00 2001 From: dalto Date: Tue, 25 Jan 2022 17:52:45 -0600 Subject: [PATCH 141/168] Document global storage keys --- src/modules/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/modules/README.md b/src/modules/README.md index 97a8556a1..62d92c260 100644 --- a/src/modules/README.md +++ b/src/modules/README.md @@ -179,6 +179,26 @@ it is possible to take the whole installation-process into account for determining the relative weights there. +## Global storage keys +Some modules place values in global storage so that they can be referenced later by other modules or even other parts of the same module. The following table represents a partial list of the values available as well as where they originate from and which module consume them. + +Key|Source|Consumers|Description +---|---|---|--- +btrfsSubvolumes|mount|fstab|List of maps containing the mountpoint and btrtfs subvolume +btrfsRootSubvolume|mount|bootloader, luksopenswaphook|String containing the subvolume mounted at root +efiSystemPartition|partition|bootloader, fstab|String containing the path to the ESP relative to the installed system +extraMounts|mount|unpackfs|List of maps holding metadata for the temporary mountpoints used by the installer +hostname|users||A string containing the hostname of the new system +netinstallAdd|packagechooser|netinstall|Data to add to netinstall tree. Same format as netinstall.yaml +netinstallSelect|packagechooser|netinstall|List of group names to select in the netinstall tree +partitions|partition, rawfs|numerous modules|List of maps of metadata about each partition +rootMountPoint|mount|numerous modules|A string with the absolute path to the root mountpoint +username|users|networkcfg, plasmainf, preservefiles|A string containing the username of the new user +zfsDatasets|zfs|bootloader, grubcfg, mount|List of maps of zfs datasets including the name and mount information +zfsInfo|partition|mount, zfs|List of encrypted zfs partitions and the encription info +zfsPoolInfo|zfs|mount, umount|List of maps of zfs pool info including the name and mountpoint + + ## C++ modules > Type: viewmodule, jobmodule From f65feedccef12344eb69d7d9c0aecc6b4633741d Mon Sep 17 00:00:00 2001 From: dalto Date: Thu, 27 Jan 2022 15:53:34 -0600 Subject: [PATCH 142/168] [grubcfg] Add configuration for default kernel_params --- src/modules/grubcfg/grubcfg.conf | 4 ++++ src/modules/grubcfg/grubcfg.schema.yaml | 1 + src/modules/grubcfg/main.py | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index 33c2a72ab..e9adc8acb 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -31,6 +31,10 @@ prefer_grub_d: false # some way (e.g. uses shell-command substitution). keepDistributor: false +# The default kernel params that should always be applied +# This is an array of strings +kernel_params: [ "quiet" ] + # Default entries to write to /etc/default/grub if it does not exist yet or if # we are overwriting it. # diff --git a/src/modules/grubcfg/grubcfg.schema.yaml b/src/modules/grubcfg/grubcfg.schema.yaml index f1bf2cc03..c09c7e7fa 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -9,6 +9,7 @@ properties: overwrite: { type: boolean, default: false } keepDistributor: { type: boolean, default: false } prefer_grub_d: { type: boolean, default: false } + kernel_params: { type: array } defaults: type: object additionalProperties: true # Other fields are acceptable diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index bc459ac67..326e03d53 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -172,7 +172,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): if partition["fs"] == "zfs" and partition["mountPoint"] == "/": zfs_root_path = get_zfs_root() - kernel_params = ["quiet"] + kernel_params = libcalamares.job.configuration.get("kernel_params", []) # Currently, grub doesn't detect this properly so it must be set manually if zfs_root_path: From e5979980218edb7058138a6078a642b3b69971f7 Mon Sep 17 00:00:00 2001 From: dalto Date: Thu, 27 Jan 2022 19:31:34 -0600 Subject: [PATCH 143/168] [packagechooser,netinstall] Clean up duplication and pruning logic for netinstall-add --- src/modules/netinstall/PackageModel.cpp | 7 +++++- src/modules/packagechooser/Config.cpp | 32 ++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index ac7443c15..3fc2f4d43 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -378,14 +378,19 @@ PackageModel::appendModelData( const QVariantList& groupList ) if ( !sources.isEmpty() ) { // Prune any existing data from the same source + QList< int > removeList; for ( int i = 0; i < m_rootItem->childCount(); i++ ) { PackageTreeItem* child = m_rootItem->child( i ); if ( sources.contains( child->source() ) ) { - m_rootItem->removeChild( i ); + removeList.insert( 0, i ); } } + for ( const int& item : qAsConst( removeList ) ) + { + m_rootItem->removeChild( item ); + } } // Add the new data to the model diff --git a/src/modules/packagechooser/Config.cpp b/src/modules/packagechooser/Config.cpp index c6f5c9658..491fe5c25 100644 --- a/src/modules/packagechooser/Config.cpp +++ b/src/modules/packagechooser/Config.cpp @@ -27,6 +27,29 @@ #include "utils/Logger.h" #include "utils/Variant.h" +/** @brief This removes any values from @p groups that match @p source + * + * This is used to remove duplicates from the netinstallAdd structure + * It iterates over @p groups and for each map in the list, if the + * "source" element matches @p source, it is removed from the returned + * list. + */ +static QVariantList +pruneNetinstallAdd( const QString& source, const QVariant& groups ) +{ + QVariantList newGroupList; + const QVariantList groupList = groups.toList(); + for ( const QVariant& group : groupList ) + { + QVariantMap groupMap = group.toMap(); + if ( groupMap.value( "source", "" ).toString() != source ) + { + newGroupList.append( groupMap ); + } + } + return newGroupList; +} + const NamedEnumTable< PackageChooserMode >& packageChooserModeNames() { @@ -132,7 +155,14 @@ Config::updateGlobalStorage( const QStringList& selected ) const } else { - Calamares::JobQueue::instance()->globalStorage()->insert( "netinstallAdd", netinstallDataList ); + // If an earlier packagechooser instance added this data to global storage, combine them + auto* gs = Calamares::JobQueue::instance()->globalStorage(); + if ( gs->contains( "netinstallAdd" ) ) + { + netinstallDataList + += pruneNetinstallAdd( QStringLiteral( "packageChooser" ), gs->value( "netinstallAdd" ) ); + } + gs->insert( "netinstallAdd", netinstallDataList ); } } else if ( m_method == PackageChooserMethod::NetSelect ) From f7d4f049a7f4f8f8f1c4662480c5c235abb626e1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 12:22:48 +0100 Subject: [PATCH 144/168] Changes: document new PRs --- CHANGES-3.2 | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index cf02ff29d..c52cd0bcc 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -10,12 +10,20 @@ website will have to do for older versions. # 3.2.51 (unreleased) # This release contains contributions from (alphabetically by first name): - - No external contributors yet + - Evan James ## Core ## - - No core changes yet + - Evan has made a start on documenting which Global Storage keys there + are and how they tie modules together. This can be found in the + `src/modules/README.md` documentation. ## Modules ## + - *bootloader* can now be configured to try to generate a unique + suffix for the bootloader-id. #1820 + - *grubcfg* now has a configurable default for kernel parameters, + which allows distributions to change the value from `quiet`. + The default, if nothing is set, remains `quiet`. Use an explicitly- + empty list to specify no-arguments-at-all. - The *umount* module has been re-written in C++. The copy-a-log-file functionality has been removed. Use the *preservefiles* module for that. From 5b994f85c9cf4601a60bfa6c4dea909f2bcc12d9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 12:38:13 +0100 Subject: [PATCH 145/168] [grubcfg] Keep kernel_params as 'quiet' by default - mark some TODO - tighten up the YAML schema a little bit - when unset, use 'quiet' rather than empty, to preserve compatibility with existing configuration files. SEE #1882 --- src/modules/grubcfg/grubcfg.conf | 8 ++++++-- src/modules/grubcfg/grubcfg.schema.yaml | 3 ++- src/modules/grubcfg/main.py | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index e9adc8acb..afc5e89b8 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -29,10 +29,14 @@ prefer_grub_d: false # kept, not updated to the *bootloaderEntryName* from the branding file. # Use this if the GRUB_DISTRIBUTOR setting in the file is "smart" in # some way (e.g. uses shell-command substitution). +# +# TODO:3.3:snake-case this key keepDistributor: false -# The default kernel params that should always be applied -# This is an array of strings +# The default kernel params that should always be applied. +# This is an array of strings. If it is unset, the default is +# `["quiet"]`. To avoid the default, explicitly set this key +# to an empty list, `[]`. kernel_params: [ "quiet" ] # Default entries to write to /etc/default/grub if it does not exist yet or if diff --git a/src/modules/grubcfg/grubcfg.schema.yaml b/src/modules/grubcfg/grubcfg.schema.yaml index c09c7e7fa..35d63c063 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -7,9 +7,10 @@ additionalProperties: false type: object properties: overwrite: { type: boolean, default: false } + # TODO:3.3:snake-case this key keepDistributor: { type: boolean, default: false } prefer_grub_d: { type: boolean, default: false } - kernel_params: { type: array } + kernel_params: { type: array, items: { type: string } } defaults: type: object additionalProperties: true # Other fields are acceptable diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index 326e03d53..ec8b01308 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -172,7 +172,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): if partition["fs"] == "zfs" and partition["mountPoint"] == "/": zfs_root_path = get_zfs_root() - kernel_params = libcalamares.job.configuration.get("kernel_params", []) + kernel_params = libcalamares.job.configuration.get("kernel_params", ["quiet"]) # Currently, grub doesn't detect this properly so it must be set manually if zfs_root_path: From 19afa469782e01379c30b608024a16594480f254 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 12:51:56 +0100 Subject: [PATCH 146/168] [netinstall] Match comment to code (casing of the identifier) --- src/modules/netinstall/NetInstallPage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/netinstall/NetInstallPage.cpp b/src/modules/netinstall/NetInstallPage.cpp index ec350a6c6..f7a2f66fc 100644 --- a/src/modules/netinstall/NetInstallPage.cpp +++ b/src/modules/netinstall/NetInstallPage.cpp @@ -64,7 +64,7 @@ NetInstallPage::onActivate() { ui->groupswidget->setFocus(); - // The NetInstallSelect global storage value can be used to make additional items selected by default + // The netinstallSelect global storage value can be used to make additional items selected by default Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); const QStringList selectNames = gs->value( "netinstallSelect" ).toStringList(); if ( !selectNames.isEmpty() ) From c0f4b80cbe285da80e29d07ad614c8ac6d15606d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 12:55:54 +0100 Subject: [PATCH 147/168] [netinstall] Tighten up comments and code - comment wandered away from the function it applies to - use overloaded name for recursive helpers - document this new feature --- CHANGES-3.2 | 3 +++ src/modules/netinstall/PackageModel.cpp | 18 ++++-------------- src/modules/netinstall/PackageModel.h | 11 +++++++++++ 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index c52cd0bcc..cbf391361 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -24,6 +24,9 @@ This release contains contributions from (alphabetically by first name): which allows distributions to change the value from `quiet`. The default, if nothing is set, remains `quiet`. Use an explicitly- empty list to specify no-arguments-at-all. + - *packagechooser* can now export its choices for use by the *netinstall* + module. This makes it possible to use *packagechooser* for large-scale + choices, followed by *netinstall* for fine-grained control. (Thanks Evan) - The *umount* module has been re-written in C++. The copy-a-log-file functionality has been removed. Use the *preservefiles* module for that. diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index 3fc2f4d43..256a77afd 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -14,24 +14,14 @@ #include "utils/Variant.h" #include "utils/Yaml.h" -/** @brief Appends groups to the tree - * - * Uses the data from @p groupList to add elements to the - * existing tree that m_rootItem points to. If m_rootItem - * is not valid, it does nothing - * - * Before adding anything to the model, it ensures that there - * is no existing data from the same source. If there is, that - * data is pruned first - * - */ +/// Recursive helper for setSelections() static void -setSelections2( const QStringList& selectNames, PackageTreeItem* item ) +setSelections( const QStringList& selectNames, PackageTreeItem* item ) { for ( int i = 0; i < item->childCount(); i++ ) { auto* child = item->child( i ); - setSelections2( selectNames, child ); + setSelections( selectNames, child ); } if ( item->isGroup() && selectNames.contains( item->name() ) ) { @@ -222,7 +212,7 @@ PackageModel::setSelections( const QStringList& selectNames ) { if ( m_rootItem ) { - setSelections2( selectNames, m_rootItem ); + ::setSelections( selectNames, m_rootItem ); } } diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 5146c63dd..88e0744df 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -68,6 +68,17 @@ public: PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; + /** @brief Appends groups to the tree + * + * Uses the data from @p groupList to add elements to the + * existing tree that m_rootItem points to. If m_rootItem + * is not valid, it does nothing + * + * Before adding anything to the model, it ensures that there + * is no existing data from the same source. If there is, that + * data is pruned first + * + */ void appendModelData(const QVariantList& groupList); private: From cf2899b1e6a2ca28870e38f359e5b4a5589fab58 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 12:59:03 +0100 Subject: [PATCH 148/168] [netinstall] Avoid negative row indexes --- src/modules/netinstall/PackageTreeItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index 36a2e7d88..5841606c4 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -252,7 +252,7 @@ PackageTreeItem::setChildrenSelected( Qt::CheckState isSelected ) void PackageTreeItem::removeChild( int row ) { - if ( row < m_childItems.count() ) + if ( 0 <= row && row < m_childItems.count() ) { m_childItems.removeAt( row ); } From 51f67f6c3e7bbab8405ea74ca3ced7e69b4ab0dd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 23:15:04 +0100 Subject: [PATCH 149/168] [partition] If initialSwapChoice can't be satisfied, add it There is a mismatch between how the configuration interprets *initialSwapChoice* when it is not a valid choice, and how the UI interprets it. If you e.g. do not have a *userSwapChoices* setting at all, whatever *initialSwapChoice* is set is interpreted by the UI as "suspend". Avoid that by putting the choice in the configuration and warning the user (which ought to be a warning to the distro). FIXES #1881 --- src/modules/partition/Config.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 155622570..550e17460 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -345,6 +345,11 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) if ( !m_swapChoices.contains( m_initialSwapChoice ) ) { cWarning() << "Configuration for *initialSwapChoice* is not one of the *userSwapChoices*"; + if ( nameFound ) + { + cWarning() << Logger::SubEntry << "Choice" << swapChoiceNames().find( m_initialSwapChoice ) << "added."; + m_swapChoices.insert( m_initialSwapChoice ); + } m_initialSwapChoice = pickOne( m_swapChoices ); } setSwapChoice( m_initialSwapChoice ); From 80300e412c6e74815a0b8bd438685dbdffb81cc0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 23:27:35 +0100 Subject: [PATCH 150/168] [libcalamares] When logging extra lines to warning or error, suppress label Avoid logs like 23:29:57 [2]: void Config::setConfigurationMap(const QVariantMap&) WARNING: Configuration for *initialSwapChoice* is not one of the *userSwapChoices* WARNING: .. Choice "small" added. where the label is duplicated. --- src/libcalamares/utils/Logger.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h index 0d7d5c870..25c19cf58 100644 --- a/src/libcalamares/utils/Logger.h +++ b/src/libcalamares/utils/Logger.h @@ -71,8 +71,11 @@ private: inline CDebug& operator<<( CDebug&& s, const FuncSuppressor& f ) { - s.m_funcinfo = nullptr; - s << f.m_s; + if ( s.m_funcinfo ) + { + s.m_funcinfo = nullptr; + s.m_msg = QString( f.m_s ); + } return s; } From ffeab3240391ea9b3e1d6fef1cf1d9be5cd887ad Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 23:41:37 +0100 Subject: [PATCH 151/168] [libcalamares] Apply coding style --- src/libcalamares/JobQueue.cpp | 5 +++-- src/libcalamares/utils/Logger.cpp | 13 +++++++------ src/libcalamares/utils/Logger.h | 3 ++- src/libcalamares/utils/Retranslator.h | 15 ++++++++++----- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index 039a28e26..d7078c6d2 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -122,8 +122,9 @@ public: } else { - cDebug() << o << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" ) << jobitem.job->prettyName() - << '(' << ( m_jobIndex + 1 ) << '/' << m_runningJobs->count() << ')'; + cDebug() << o << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" ) + << jobitem.job->prettyName() << '(' << ( m_jobIndex + 1 ) << '/' << m_runningJobs->count() + << ')'; o.refresh(); // So next time it shows the function header again emitProgress( 0.0 ); // 0% for *this job* connect( jobitem.job.data(), &Job::progress, this, &JobThread::emitProgress ); diff --git a/src/libcalamares/utils/Logger.cpp b/src/libcalamares/utils/Logger.cpp index d35d6891b..adb082687 100644 --- a/src/libcalamares/utils/Logger.cpp +++ b/src/libcalamares/utils/Logger.cpp @@ -259,21 +259,22 @@ operator<<( QDebug& s, const RedactedCommand& l ) * Identical strings with the same context will be hashed the same, * so that they can be logged and still recognized as the-same. */ -static uint insertRedactedName( const QString& context, const QString& s ) +static uint +insertRedactedName( const QString& context, const QString& s ) { static uint salt = QRandomGenerator::global()->generate(); // Just once - uint val = qHash(context, salt); - return qHash(s, val); + uint val = qHash( context, salt ); + return qHash( s, val ); } RedactedName::RedactedName( const QString& context, const QString& s ) - : m_id( insertRedactedName(context, s) ), - m_context(context) + : m_id( insertRedactedName( context, s ) ) + , m_context( context ) { } -RedactedName::RedactedName(const char *context, const QString& s ) +RedactedName::RedactedName( const char* context, const QString& s ) : RedactedName( QString::fromLatin1( context ), s ) { } diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h index 25c19cf58..f4079388d 100644 --- a/src/libcalamares/utils/Logger.h +++ b/src/libcalamares/utils/Logger.h @@ -247,7 +247,8 @@ private: const QString m_context; }; -inline QDebug& operator<<( QDebug& s, const RedactedName& n ) +inline QDebug& +operator<<( QDebug& s, const RedactedName& n ) { return s << NoQuote << QString( n ) << Quote; } diff --git a/src/libcalamares/utils/Retranslator.h b/src/libcalamares/utils/Retranslator.h index efe12ef8a..8bb044983 100644 --- a/src/libcalamares/utils/Retranslator.h +++ b/src/libcalamares/utils/Retranslator.h @@ -29,7 +29,8 @@ namespace CalamaresUtils * @param locale the new locale (names as defined by Calamares). * @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding. */ -DLLEXPORT void installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix ); +DLLEXPORT void installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, + const QString& brandingTranslationsPrefix ); /** @brief Initializes the translations with the current system settings */ @@ -56,7 +57,8 @@ DLLEXPORT CalamaresUtils::Locale::Translation::Id translatorLocaleName(); * * @returns @c true on success */ -DLLEXPORT bool loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator ); +DLLEXPORT bool +loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator ); /** @brief Set @p allow to true to load translations from current dir. * @@ -88,7 +90,7 @@ public: static Retranslator* instance(); /// @brief Helper function for attaching lambdas - static void attach( QObject* o, std::function< void( void ) > f); + static void attach( QObject* o, std::function< void( void ) > f ); signals: void languageChanged(); @@ -138,8 +140,11 @@ private: #define CALAMARES_RETRANSLATE_SLOT( slotfunc ) \ do \ { \ - connect( CalamaresUtils::Retranslator::instance(), &CalamaresUtils::Retranslator::languageChanged, this, slotfunc ); \ - (this->*slotfunc)(); \ + connect( CalamaresUtils::Retranslator::instance(), \ + &CalamaresUtils::Retranslator::languageChanged, \ + this, \ + slotfunc ); \ + ( this->*slotfunc )(); \ } while ( false ) #endif From e9899d0345e772b075fc39aba53228021c184849 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 31 Jan 2022 23:41:48 +0100 Subject: [PATCH 152/168] [packagechooser,netinstall] Apply coding style --- src/modules/netinstall/PackageModel.h | 4 ++-- src/modules/netinstall/Tests.cpp | 2 +- src/modules/packagechooser/Config.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/netinstall/PackageModel.h b/src/modules/netinstall/PackageModel.h index 88e0744df..e97359a46 100644 --- a/src/modules/netinstall/PackageModel.h +++ b/src/modules/netinstall/PackageModel.h @@ -63,7 +63,7 @@ public: * Individual packages will not be matched. * */ - void setSelections(const QStringList &selectNames ); + void setSelections( const QStringList& selectNames ); PackageTreeItem::List getPackages() const; PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const; @@ -79,7 +79,7 @@ public: * data is pruned first * */ - void appendModelData(const QVariantList& groupList); + void appendModelData( const QVariantList& groupList ); private: friend class ItemTests; diff --git a/src/modules/netinstall/Tests.cpp b/src/modules/netinstall/Tests.cpp index df5d5ad60..6b1db020c 100644 --- a/src/modules/netinstall/Tests.cpp +++ b/src/modules/netinstall/Tests.cpp @@ -410,7 +410,7 @@ ItemTests::testUrlFallback() QEventLoop loop; connect( &c, &Config::statusReady, &loop, &QEventLoop::quit ); QSignalSpy spy( &c, &Config::statusReady ); - QTimer::singleShot( std::chrono::seconds(1), &loop, &QEventLoop::quit ); + QTimer::singleShot( std::chrono::seconds( 1 ), &loop, &QEventLoop::quit ); loop.exec(); // Check it didn't time out diff --git a/src/modules/packagechooser/Config.h b/src/modules/packagechooser/Config.h index 76aa0c0f3..b04b1c30b 100644 --- a/src/modules/packagechooser/Config.h +++ b/src/modules/packagechooser/Config.h @@ -34,7 +34,7 @@ enum class PackageChooserMethod Legacy, // use contextualprocess or other custom Packages, // use the packages module NetAdd, // adds packages to the netinstall module - NetSelect, // makes selections in the netinstall module + NetSelect, // makes selections in the netinstall module }; const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames(); From 691951974dc9d1df1c30320320db04bdb85d0e44 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 11:33:20 +0100 Subject: [PATCH 153/168] Changes: document partition-swap fix --- CHANGES-3.2 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index cbf391361..04ac311c6 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -27,6 +27,9 @@ This release contains contributions from (alphabetically by first name): - *packagechooser* can now export its choices for use by the *netinstall* module. This makes it possible to use *packagechooser* for large-scale choices, followed by *netinstall* for fine-grained control. (Thanks Evan) + - When the *partition* module has a conflicting configuration for the + swap choices, it prints a warning and uses the configured choice, rather + than always using "suspend". #1881 - The *umount* module has been re-written in C++. The copy-a-log-file functionality has been removed. Use the *preservefiles* module for that. From 4a30aae9bb6bb4f95cf40ec8c8436a05b6c21d88 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 11:49:26 +0100 Subject: [PATCH 154/168] [calamares] Tighten logging in 'loadmodule' test-executable --- src/calamares/testmain.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/calamares/testmain.cpp b/src/calamares/testmain.cpp index 9d0189031..ecbf77888 100644 --- a/src/calamares/testmain.cpp +++ b/src/calamares/testmain.cpp @@ -485,7 +485,7 @@ main( int argc, char* argv[] ) return 1; } - cDebug() << Logger::SubEntry << " .. got" << m->name() << m->typeString() << m->interfaceString(); + cDebug() << Logger::SubEntry << "got" << m->name() << m->typeString() << m->interfaceString(); if ( m->type() == Calamares::Module::Type::View ) { // If we forgot the --ui, any ViewModule will core dump as it @@ -535,7 +535,7 @@ main( int argc, char* argv[] ) using TR = Logger::DebugRow< const char*, const QString >; - cDebug() << "Module metadata" << TR( "name", m->name() ) << TR( "type", m->typeString() ) + cDebug() << Logger::SubEntry << "Module metadata" << TR( "name", m->name() ) << TR( "type", m->typeString() ) << TR( "interface", m->interfaceString() ); Calamares::JobList jobList = m->jobs(); @@ -543,6 +543,8 @@ main( int argc, char* argv[] ) unsigned int count = 1; for ( const auto& p : jobList ) { + // This doesn't get a SubEntry because the jobs may log a bunch of + // things; print the function-header to make clear that we're back in main. cDebug() << "Job #" << count << "name" << p->prettyName(); Calamares::JobResult r = p->exec(); if ( !r ) From 6f738813a678e65e7bf1a3a21dc6d7fa0009c1a9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 12:15:40 +0100 Subject: [PATCH 155/168] [fstab] GS configuration for a btrfs setup --- src/modules/fstab/test2.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/modules/fstab/test2.yaml diff --git a/src/modules/fstab/test2.yaml b/src/modules/fstab/test2.yaml new file mode 100644 index 000000000..0e91bf649 --- /dev/null +++ b/src/modules/fstab/test2.yaml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +# +# This test shows how btrfs root would work +rootMountPoint: /tmp/mount +partitions: + - device: /dev/sda1 + fs: btrfs + mountPoint: / + uuid: 2a00f1d5-1217-49a7-bedd-b55c85764732 + - device: /dev/sda2 + fs: swap + uuid: 59406569-446f-4730-a874-9f6b4b44fee3 + mountPoint: + - device: /dev/sdb1 + fs: btrfs + mountPoint: /home + uuid: 59406569-abcd-1234-a874-9f6b4b44fee3 +btrfsSubvolumes: + - mountPoint: / + subvolume: "@ROOT" + - mountPoint: /var + subvolume: "@var" + - mountPoint: /usr/local + subvolume: "@local" From d8c875f3515749c97e7f9d2751a94d53b7b8edc5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 13:13:29 +0100 Subject: [PATCH 156/168] [partition] UI-tweak mount-point and fs-label boxes - make the boxes expand, rather than stick to a minimum size that doesn't align with other boxes in the dialog, and which may be too small to contain the text they display. --- src/modules/partition/gui/CreatePartitionDialog.ui | 14 +++++++------- .../partition/gui/EditExistingPartitionDialog.ui | 14 +++++++------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.ui b/src/modules/partition/gui/CreatePartitionDialog.ui index dad932101..65392dbe2 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.ui +++ b/src/modules/partition/gui/CreatePartitionDialog.ui @@ -68,7 +68,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - &Primary + Primar&y true @@ -171,6 +171,12 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + 0 + 0 + + true @@ -221,12 +227,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - 150 - 16777215 - - Label for the filesystem diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.ui b/src/modules/partition/gui/EditExistingPartitionDialog.ui index 7599bc772..1b1ef42fe 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.ui +++ b/src/modules/partition/gui/EditExistingPartitionDialog.ui @@ -51,7 +51,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - Content: + Con&tent: keepRadioButton @@ -109,6 +109,12 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + 0 + 0 + + true @@ -176,12 +182,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - 150 - 16777215 - - Label for the filesystem From fbcd1ffbbe797ed7fe76111941430ea1e5965457 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 14:06:30 +0100 Subject: [PATCH 157/168] [partition] Make the "no mount point" a placeholder --- src/modules/partition/gui/PartitionDialogHelpers.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp index 65e88f898..a73314d18 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.cpp +++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp @@ -18,6 +18,7 @@ #include "utils/Logger.h" #include +#include #include QStringList @@ -37,7 +38,7 @@ void standardMountPoints( QComboBox& combo ) { combo.clear(); - combo.addItem( QObject::tr( "(no mount point)" ) ); + combo.lineEdit()->setPlaceholderText( QObject::tr( "(no mount point)" ) ); combo.addItems( standardMountPoints() ); } @@ -51,7 +52,7 @@ standardMountPoints( QComboBox& combo, const QString& selected ) QString selectedMountPoint( QComboBox& combo ) { - if ( combo.currentIndex() == 0 ) + if ( combo.currentIndex() == -1 ) { return QString(); } @@ -63,7 +64,7 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected ) { if ( selected.isEmpty() ) { - combo.setCurrentIndex( 0 ); // (no mount point) + combo.setCurrentIndex( -1 ); // (no mount point) } else { From d8be9a94438cfc81d3249823453d2853ce15f227 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 14:07:38 +0100 Subject: [PATCH 158/168] [partition] Mount points should start with a / --- src/modules/partition/gui/CreatePartitionDialog.cpp | 8 +++++++- src/modules/partition/gui/EditExistingPartitionDialog.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 6bde9a148..789909867 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -325,11 +325,17 @@ CreatePartitionDialog::updateMountPointUi() void CreatePartitionDialog::checkMountPointSelection() { - if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) ) + const QString mountPoint = selectedMountPoint( m_ui->mountPointComboBox ); + if ( m_usedMountPoints.contains( mountPoint ) ) { m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) ); m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); } + else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) ) + { + m_ui->labelMountPoint->setText( tr( "Mountpoint must start with a
/
." ) ); + m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); + } else { m_ui->labelMountPoint->setText( QString() ); diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index a3052b3b7..2d25d71ac 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -295,11 +295,17 @@ EditExistingPartitionDialog::updateMountPointPicker() void EditExistingPartitionDialog::checkMountPointSelection() { - if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) ) + const QString mountPoint = selectedMountPoint( m_ui->mountPointComboBox ); + if ( m_usedMountPoints.contains( mountPoint ) ) { m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) ); m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); } + else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) ) + { + m_ui->labelMountPoint->setText( tr( "Mountpoint must start with a
/
." ) ); + m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); + } else { m_ui->labelMountPoint->setText( QString() ); From 82dcc1b57ba8503745984b9197c1b7dd842181ca Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 14:42:18 +0100 Subject: [PATCH 159/168] [partition] Refactor common validate-the-mount-point logic --- .../partition/gui/CreatePartitionDialog.cpp | 17 +---------- .../gui/EditExistingPartitionDialog.cpp | 17 +---------- .../partition/gui/PartitionDialogHelpers.cpp | 30 +++++++++++++++++++ .../partition/gui/PartitionDialogHelpers.h | 12 ++++++++ 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 789909867..7d9148886 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -325,22 +325,7 @@ CreatePartitionDialog::updateMountPointUi() void CreatePartitionDialog::checkMountPointSelection() { - const QString mountPoint = selectedMountPoint( m_ui->mountPointComboBox ); - if ( m_usedMountPoints.contains( mountPoint ) ) - { - m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); - } - else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) ) - { - m_ui->labelMountPoint->setText( tr( "Mountpoint must start with a
/
." ) ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); - } - else - { - m_ui->labelMountPoint->setText( QString() ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); - } + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->labelMountPoint, m_ui->buttonBox->button( QDialogButtonBox::Ok )); } void diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 2d25d71ac..d2377db03 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -295,20 +295,5 @@ EditExistingPartitionDialog::updateMountPointPicker() void EditExistingPartitionDialog::checkMountPointSelection() { - const QString mountPoint = selectedMountPoint( m_ui->mountPointComboBox ); - if ( m_usedMountPoints.contains( mountPoint ) ) - { - m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); - } - else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) ) - { - m_ui->labelMountPoint->setText( tr( "Mountpoint must start with a
/
." ) ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false ); - } - else - { - m_ui->labelMountPoint->setText( QString() ); - m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true ); - } + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->labelMountPoint, m_ui->buttonBox->button( QDialogButtonBox::Ok )); } diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp index a73314d18..b8402dc2f 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.cpp +++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp @@ -12,14 +12,17 @@ #include "PartitionDialogHelpers.h" #include "core/PartUtils.h" +#include "gui/CreatePartitionDialog.h" #include "GlobalStorage.h" #include "JobQueue.h" #include "utils/Logger.h" #include +#include #include #include +#include QStringList standardMountPoints() @@ -81,6 +84,33 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected ) } } +bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ) +{ + QString msg; + bool ok = true; + + if ( inUse.contains( mountPoint ) ) + { + msg = CreatePartitionDialog::tr( "Mountpoint already in use. Please select another one." ); + ok = false; + } + else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) ) + { + msg = CreatePartitionDialog::tr( "Mountpoint must start with a
/
." ); + ok = false; + } + + if ( label ) + { + label->setText( msg ); + } + if ( button ) + { + button->setEnabled( ok ); + } + return ok; +} + PartitionTable::Flags flagsFromList( const QListWidget& list ) diff --git a/src/modules/partition/gui/PartitionDialogHelpers.h b/src/modules/partition/gui/PartitionDialogHelpers.h index 7761004b5..eea0998c4 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.h +++ b/src/modules/partition/gui/PartitionDialogHelpers.h @@ -16,7 +16,9 @@ #include +class QPushButton; class QComboBox; +class QLabel; class QListWidget; /** @@ -58,6 +60,16 @@ setSelectedMountPoint( QComboBox* combo, const QString& selected ) setSelectedMountPoint( *combo, selected ); } +/** @brief Validate a @p mountPoint and adjust the UI + * + * If @p mountPoint is valid -- unused and starts with a /, for instance -- + * then the button is enabled, label is cleared, and returns @c true. + * + * If it is not valid, returns @c false and sets the UI + * to explain why. + */ +bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ); + /** * Get the flags that have been checked in the list widget. */ From 45fff2349970b36314209f12e7eeea99f15deb14 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 14:50:53 +0100 Subject: [PATCH 160/168] [partition] Move message closer to input field The warning about the mount point -- that it was in-use or invalid -- had been separated from the drop-down by the FSLabel field. Move it back, rename the variable for clarity while we're at it. --- .../partition/gui/CreatePartitionDialog.cpp | 2 +- .../partition/gui/CreatePartitionDialog.ui | 24 +++++++++---------- .../gui/EditExistingPartitionDialog.cpp | 2 +- .../gui/EditExistingPartitionDialog.ui | 20 ++++++++-------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 7d9148886..8a82d2901 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -325,7 +325,7 @@ CreatePartitionDialog::updateMountPointUi() void CreatePartitionDialog::checkMountPointSelection() { - validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->labelMountPoint, m_ui->buttonBox->button( QDialogButtonBox::Ok )); + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok )); } void diff --git a/src/modules/partition/gui/CreatePartitionDialog.ui b/src/modules/partition/gui/CreatePartitionDialog.ui index 65392dbe2..0ee715fe0 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.ui +++ b/src/modules/partition/gui/CreatePartitionDialog.ui @@ -185,21 +185,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
- - - - - - - - + Flags: - + true @@ -212,7 +205,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Qt::Vertical @@ -225,7 +218,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Label for the filesystem @@ -235,13 +228,20 @@ SPDX-License-Identifier: GPL-3.0-or-later - + FS Label: + + + + + + + diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index d2377db03..1568572f4 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -295,5 +295,5 @@ EditExistingPartitionDialog::updateMountPointPicker() void EditExistingPartitionDialog::checkMountPointSelection() { - validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->labelMountPoint, m_ui->buttonBox->button( QDialogButtonBox::Ok )); + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok )); } diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.ui b/src/modules/partition/gui/EditExistingPartitionDialog.ui index 1b1ef42fe..4a9982656 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.ui +++ b/src/modules/partition/gui/EditExistingPartitionDialog.ui @@ -153,14 +153,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Flags: - + true @@ -174,13 +174,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - - - - - Label for the filesystem @@ -190,13 +183,20 @@ SPDX-License-Identifier: GPL-3.0-or-later - + FS Label: + + + + + + + From f4720ae02c9ba0582bef8e0ab9edd9062c5f5efc Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 14:54:49 +0100 Subject: [PATCH 161/168] [partition]
 formatting is block-oriented

---
 src/modules/partition/gui/PartitionDialogHelpers.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp
index b8402dc2f..c8f4214eb 100644
--- a/src/modules/partition/gui/PartitionDialogHelpers.cpp
+++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp
@@ -96,7 +96,7 @@ bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QL
     }
     else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) )
     {
-        msg = CreatePartitionDialog::tr( "Mountpoint must start with a 
/
." ); + msg = CreatePartitionDialog::tr( "Mountpoint must start with a /." ); ok = false; } From 7f90b9938814ccc3c0d25c3053606439897e8eb3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 16:01:04 +0100 Subject: [PATCH 162/168] [partition Simplify mountpoint-input - if nothing is selected (index -1, which now shows the placeholder), the text is empty - if something has been entered, return it (e.g. if the user is typing) - if something is selected, the text gets set to that anyway --- src/modules/partition/gui/PartitionDialogHelpers.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp index c8f4214eb..46b26bc2d 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.cpp +++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp @@ -55,10 +55,6 @@ standardMountPoints( QComboBox& combo, const QString& selected ) QString selectedMountPoint( QComboBox& combo ) { - if ( combo.currentIndex() == -1 ) - { - return QString(); - } return combo.currentText(); } From c4eee7bb112ff1b50feb74966665aa4f343afb12 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 16:16:46 +0100 Subject: [PATCH 163/168] CI: demand clang-format 12 or 13 - use clang-format12 or 13 or unversioned executable, only - check it's actually 12 or 13 - set language standard explicitly to C++17, "Cpp11" is now an alias for "latest" which is weird This change does lead to some thrashing when applying styles, so I'm not going to do that across the board right now. Changes include: - extra spaces in lambda-captures - nicer alignment of lambda-bodies --- .clang-format | 3 ++- .clang-format.base | 35 ----------------------------------- ci/calamaresstyle | 29 ++++++----------------------- 3 files changed, 8 insertions(+), 59 deletions(-) delete mode 100644 .clang-format.base diff --git a/.clang-format b/.clang-format index 2cd8d678a..0965e5724 100644 --- a/.clang-format +++ b/.clang-format @@ -28,8 +28,9 @@ PointerAlignment: Left ReflowComments: "false" SortIncludes: "true" SpaceAfterCStyleCast: "false" +SpaceInEmptyBlock: "false" SpacesBeforeTrailingComments: "2" SpacesInAngles: "true" SpacesInParentheses: "true" SpacesInSquareBrackets: "true" -Standard: Cpp11 +Standard: c++17 diff --git a/.clang-format.base b/.clang-format.base deleted file mode 100644 index 2cd8d678a..000000000 --- a/.clang-format.base +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-FileCopyrightText: no -# SPDX-License-Identifier: CC0-1.0 ---- -BasedOnStyle: WebKit - -AlignAfterOpenBracket: Align -AlignEscapedNewlines: DontAlign -AllowAllParametersOfDeclarationOnNextLine: "false" -AllowShortFunctionsOnASingleLine: Inline -AllowShortIfStatementsOnASingleLine: "false" -AllowShortLambdasOnASingleLine: All -AllowShortLoopsOnASingleLine: "false" -AlwaysBreakAfterReturnType: TopLevelDefinitions -AlwaysBreakTemplateDeclarations: Yes -BinPackArguments: "false" -BinPackParameters: "false" -BreakBeforeBraces: Allman -BreakBeforeTernaryOperators: "true" -BreakConstructorInitializers: BeforeComma -ColumnLimit: 120 -Cpp11BracedListStyle: "false" -FixNamespaceComments: "true" -IncludeBlocks: Preserve -IndentWidth: "4" -MaxEmptyLinesToKeep: "2" -NamespaceIndentation: None -PointerAlignment: Left -ReflowComments: "false" -SortIncludes: "true" -SpaceAfterCStyleCast: "false" -SpacesBeforeTrailingComments: "2" -SpacesInAngles: "true" -SpacesInParentheses: "true" -SpacesInSquareBrackets: "true" -Standard: Cpp11 diff --git a/ci/calamaresstyle b/ci/calamaresstyle index ffcfe0902..f5bcd2bb9 100755 --- a/ci/calamaresstyle +++ b/ci/calamaresstyle @@ -19,12 +19,12 @@ BASEDIR=$(dirname $0) TOPDIR=$( cd $BASEDIR/.. && pwd -P ) test -d "$BASEDIR" || { echo "! Could not determine base for $0" ; exit 1 ; } test -d "$TOPDIR" || { echo "! Cound not determine top-level source dir" ; exit 1 ; } -test -f "$TOPDIR/.clang-format.base" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; } +test -f "$TOPDIR/.clang-format" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; } AS=$( which astyle ) # Allow specifying CF_VERSIONS outside already -CF_VERSIONS="$CF_VERSIONS clang-format-8 clang-format80 clang-format90 clang-format-9.0.1 clang-format" +CF_VERSIONS="$CF_VERSIONS clang-format13 clang-format12 clang-format" for _cf in $CF_VERSIONS do # Not an error if this particular clang-format isn't found @@ -40,31 +40,19 @@ test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; } ### CLANG-FORMAT-WRANGLING # # Version 7 and earlier doesn't understand all the options we would like -# Version 8 is ok -# Version 9 is ok -# Later versions change some defaults so need extra wrangling. -# .. there are extra files that are appended to the settings, per -# .. clang-format version. +# Version 12 handles lambdas nicely, so use that. +# Version 13 is also ok. format_version=`"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1` case "$format_version" in - [0-7] ) - echo "! Clang-format version 8+ required" - exit 1 - ;; - [89] ) + 12|13 ) : ;; * ) - echo "! Clang-format version '$format_version' unsupported." + echo "! Clang-format version '$format_version' unsupported, version 12 required." exit 1 ;; esac -_fmt="$TOPDIR/.clang-format" -cp "$_fmt.base" "$_fmt" -for f in "$extra_settings" ; do - test -f "$_fmt.$f" && cat "$_fmt.$f" >> "$_fmt" -done ### FILE PROCESSING @@ -98,8 +86,3 @@ if test "x$any_dirs" = "xyes" ; then else style_some "$@" fi - -### CLANG-FORMAT-WRANGLING -# -# Restore the original .clang-format -cp "$_fmt.base" "$_fmt" From cf913b87fff4b32777d4ac74f7d4aeafa7de9179 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 16:03:49 +0100 Subject: [PATCH 164/168] [partition] Apply coding style This applies the new(er) style to the whole module, rather than just the files that recently changed. --- src/modules/partition/PartitionViewStep.cpp | 14 +- src/modules/partition/core/DeviceModel.cpp | 6 +- .../partition/core/PartitionCoreModule.cpp | 32 ++-- .../partition/core/PartitionLayout.cpp | 2 +- src/modules/partition/core/SizeUtils.h | 3 +- src/modules/partition/gui/ChoicePage.cpp | 162 +++++++++++------- .../partition/gui/CreatePartitionDialog.cpp | 5 +- .../gui/EditExistingPartitionDialog.cpp | 30 ++-- src/modules/partition/gui/EncryptWidget.cpp | 5 +- .../partition/gui/PartitionBarsView.cpp | 12 +- .../partition/gui/PartitionDialogHelpers.cpp | 3 +- .../partition/gui/PartitionLabelsView.cpp | 2 +- src/modules/partition/gui/PartitionPage.cpp | 24 +-- .../partition/gui/PartitionSplitterWidget.cpp | 64 +++---- src/modules/partition/gui/ReplaceWidget.cpp | 7 +- src/modules/partition/gui/ScanningDialog.cpp | 16 +- .../partition/gui/VolumeGroupBaseDialog.cpp | 26 ++- .../partition/jobs/AutoMountManagementJob.cpp | 4 +- src/modules/partition/jobs/ClearMountsJob.cpp | 8 +- .../partition/tests/AutoMountTests.cpp | 4 +- .../partition/tests/ClearMountsJobTests.cpp | 8 +- 21 files changed, 258 insertions(+), 179 deletions(-) diff --git a/src/modules/partition/PartitionViewStep.cpp b/src/modules/partition/PartitionViewStep.cpp index 18f10d629..5e8bf2ef0 100644 --- a/src/modules/partition/PartitionViewStep.cpp +++ b/src/modules/partition/PartitionViewStep.cpp @@ -675,11 +675,15 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap ) // because it could take a while. Then when it's done, we can set up the widgets // and remove the spinner. m_future = new QFutureWatcher< void >(); - connect( m_future, &QFutureWatcher< void >::finished, this, [this] { - continueLoading(); - this->m_future->deleteLater(); - this->m_future = nullptr; - } ); + connect( m_future, + &QFutureWatcher< void >::finished, + this, + [ this ] + { + continueLoading(); + this->m_future->deleteLater(); + this->m_future = nullptr; + } ); QFuture< void > future = QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule ); m_future->setFuture( future ); diff --git a/src/modules/partition/core/DeviceModel.cpp b/src/modules/partition/core/DeviceModel.cpp index 25bdbff6c..6959ac9c2 100644 --- a/src/modules/partition/core/DeviceModel.cpp +++ b/src/modules/partition/core/DeviceModel.cpp @@ -28,9 +28,9 @@ static void sortDevices( DeviceModel::DeviceList& l ) { - std::sort( l.begin(), l.end(), []( const Device* dev1, const Device* dev2 ) { - return dev1->deviceNode() < dev2->deviceNode(); - } ); + std::sort( l.begin(), + l.end(), + []( const Device* dev1, const Device* dev2 ) { return dev1->deviceNode() < dev2->deviceNode(); } ); } DeviceModel::DeviceModel( QObject* parent ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 16e5a7ea1..989327ef0 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -262,11 +262,9 @@ PartitionCoreModule::doInit() // Gives ownership of the Device* to the DeviceInfo object auto deviceInfo = new DeviceInfo( device ); m_deviceInfos << deviceInfo; - cDebug() << Logger::SubEntry - << device->deviceNode() - << device->capacity() - << Logger::RedactedName( "DevName", device->name() ) - << Logger::RedactedName( "DevNamePretty", device->prettyName() ); + cDebug() << Logger::SubEntry << device->deviceNode() << device->capacity() + << Logger::RedactedName( "DevName", device->name() ) + << Logger::RedactedName( "DevNamePretty", device->prettyName() ); } else { @@ -685,9 +683,8 @@ PartitionCoreModule::lvmPVs() const bool PartitionCoreModule::hasVGwithThisName( const QString& name ) const { - auto condition = [name]( DeviceInfo* d ) { - return dynamic_cast< LvmDevice* >( d->device.data() ) && d->device.data()->name() == name; - }; + auto condition = [ name ]( DeviceInfo* d ) + { return dynamic_cast< LvmDevice* >( d->device.data() ) && d->device.data()->name() == name; }; return std::find_if( m_deviceInfos.begin(), m_deviceInfos.end(), condition ) != m_deviceInfos.end(); } @@ -695,7 +692,8 @@ PartitionCoreModule::hasVGwithThisName( const QString& name ) const bool PartitionCoreModule::isInVG( const Partition* partition ) const { - auto condition = [partition]( DeviceInfo* d ) { + auto condition = [ partition ]( DeviceInfo* d ) + { LvmDevice* vg = dynamic_cast< LvmDevice* >( d->device.data() ); return vg && vg->physicalVolumes().contains( partition ); }; @@ -964,9 +962,9 @@ PartitionCoreModule::layoutApply( Device* dev, const QString boot = QStringLiteral( "/boot" ); const QString root = QStringLiteral( "/" ); const auto is_boot - = [&]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == boot || p->mountPoint() == boot; }; + = [ & ]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == boot || p->mountPoint() == boot; }; const auto is_root - = [&]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == root || p->mountPoint() == root; }; + = [ & ]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == root || p->mountPoint() == root; }; const bool separate_boot_partition = std::find_if( partList.constBegin(), partList.constEnd(), is_boot ) != partList.constEnd(); @@ -1089,10 +1087,14 @@ void PartitionCoreModule::asyncRevertDevice( Device* dev, std::function< void() > callback ) { QFutureWatcher< void >* watcher = new QFutureWatcher< void >(); - connect( watcher, &QFutureWatcher< void >::finished, this, [watcher, callback] { - callback(); - watcher->deleteLater(); - } ); + connect( watcher, + &QFutureWatcher< void >::finished, + this, + [ watcher, callback ] + { + callback(); + watcher->deleteLater(); + } ); QFuture< void > future = QtConcurrent::run( this, &PartitionCoreModule::revertDevice, dev, true ); watcher->setFuture( future ); diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index 3813207ef..765d9fffa 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -283,7 +283,7 @@ PartitionLayout::createPartitions( Device* dev, } } - auto correctFS = [d = m_defaultFsType]( FileSystem::Type t ) { return t == FileSystem::Type::Unknown ? d : t; }; + auto correctFS = [ d = m_defaultFsType ]( FileSystem::Type t ) { return t == FileSystem::Type::Unknown ? d : t; }; // Create the partitions. currentSector = firstSector; diff --git a/src/modules/partition/core/SizeUtils.h b/src/modules/partition/core/SizeUtils.h index d474656c9..155cbd923 100644 --- a/src/modules/partition/core/SizeUtils.h +++ b/src/modules/partition/core/SizeUtils.h @@ -19,7 +19,8 @@ * to bother with one-byte accuracy (and anyway, a double has at least 50 bits * at which point we're printing giga (or gibi) bytes). */ -static inline QString formatByteSize( qint64 sizeValue ) +static inline QString +formatByteSize( qint64 sizeValue ) { return Capacity::formatByteSize( static_cast< double >( sizeValue ) ); } diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 9226eb3b6..588c1b643 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -176,10 +176,14 @@ ChoicePage::init( PartitionCoreModule* core ) // We need to do this because a PCM revert invalidates the deviceModel. - connect( core, &PartitionCoreModule::reverted, this, [=] { - setModelToComboBox( m_drivesCombo, core->deviceModel() ); - m_drivesCombo->setCurrentIndex( m_lastSelectedDeviceIndex ); - } ); + connect( core, + &PartitionCoreModule::reverted, + this, + [ = ] + { + setModelToComboBox( m_drivesCombo, core->deviceModel() ); + m_drivesCombo->setCurrentIndex( m_lastSelectedDeviceIndex ); + } ); setModelToComboBox( m_drivesCombo, core->deviceModel() ); connect( m_drivesCombo, qOverload< int >( &QComboBox::currentIndexChanged ), this, &ChoicePage::applyDeviceChoice ); @@ -303,26 +307,30 @@ ChoicePage::setupChoices() #else auto buttonSignal = &QButtonGroup::idToggled; #endif - connect( m_grp, buttonSignal, this, [this]( int id, bool checked ) { - if ( checked ) // An action was picked. - { - m_config->setInstallChoice( id ); - updateNextEnabled(); + connect( m_grp, + buttonSignal, + this, + [ this ]( int id, bool checked ) + { + if ( checked ) // An action was picked. + { + m_config->setInstallChoice( id ); + updateNextEnabled(); - Q_EMIT actionChosen(); - } - else // An action was unpicked, either on its own or because of another selection. - { - if ( m_grp->checkedButton() == nullptr ) // If no other action is chosen, we must - { - // set m_choice to NoChoice and reset previews. - m_config->setInstallChoice( InstallChoice::NoChoice ); - updateNextEnabled(); + Q_EMIT actionChosen(); + } + else // An action was unpicked, either on its own or because of another selection. + { + if ( m_grp->checkedButton() == nullptr ) // If no other action is chosen, we must + { + // set m_choice to NoChoice and reset previews. + m_config->setInstallChoice( InstallChoice::NoChoice ); + updateNextEnabled(); - Q_EMIT actionChosen(); - } - } - } ); + Q_EMIT actionChosen(); + } + } + } ); m_rightLayout->setStretchFactor( m_itemsLayout, 1 ); m_rightLayout->setStretchFactor( m_previewBeforeFrame, 0 ); @@ -401,11 +409,13 @@ ChoicePage::applyDeviceChoice() if ( m_core->isDirty() ) { ScanningDialog::run( - QtConcurrent::run( [=] { - QMutexLocker locker( &m_coreMutex ); - m_core->revertAllDevices(); - } ), - [this] { continueApplyDeviceChoice(); }, + QtConcurrent::run( + [ = ] + { + QMutexLocker locker( &m_coreMutex ); + m_core->revertAllDevices(); + } ), + [ this ] { continueApplyDeviceChoice(); }, this ); } else @@ -493,11 +503,14 @@ ChoicePage::applyActionChoice( InstallChoice choice ) if ( m_core->isDirty() ) { ScanningDialog::run( - QtConcurrent::run( [=] { - QMutexLocker locker( &m_coreMutex ); - m_core->revertDevice( selectedDevice() ); - } ), - [=] { + QtConcurrent::run( + [ = ] + { + QMutexLocker locker( &m_coreMutex ); + m_core->revertDevice( selectedDevice() ); + } ), + [ = ] + { PartitionActions::doAutopartition( m_core, selectedDevice(), options ); Q_EMIT deviceChosen(); }, @@ -514,10 +527,12 @@ ChoicePage::applyActionChoice( InstallChoice choice ) if ( m_core->isDirty() ) { ScanningDialog::run( - QtConcurrent::run( [=] { - QMutexLocker locker( &m_coreMutex ); - m_core->revertDevice( selectedDevice() ); - } ), + QtConcurrent::run( + [ = ] + { + QMutexLocker locker( &m_coreMutex ); + m_core->revertDevice( selectedDevice() ); + } ), [] {}, this ); } @@ -532,11 +547,14 @@ ChoicePage::applyActionChoice( InstallChoice choice ) if ( m_core->isDirty() ) { ScanningDialog::run( - QtConcurrent::run( [=] { - QMutexLocker locker( &m_coreMutex ); - m_core->revertDevice( selectedDevice() ); - } ), - [this] { + QtConcurrent::run( + [ = ] + { + QMutexLocker locker( &m_coreMutex ); + m_core->revertDevice( selectedDevice() ); + } ), + [ this ] + { // We need to reupdate after reverting because the splitter widget is // not a true view. updateActionChoicePreview( m_config->installChoice() ); @@ -772,7 +790,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) ScanningDialog::run( QtConcurrent::run( - [this, current, homePartitionPath]( bool doReuseHomePartition ) { + [ this, current, homePartitionPath ]( bool doReuseHomePartition ) + { QMutexLocker locker( &m_coreMutex ); if ( m_core->isDirty() ) @@ -853,7 +872,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) } }, m_reuseHomeCheckBox->isChecked() ), - [this, homePartitionPath] { + [ this, homePartitionPath ] + { m_reuseHomeCheckBox->setVisible( !homePartitionPath->isEmpty() ); if ( !homePartitionPath->isEmpty() ) m_reuseHomeCheckBox->setText( tr( "Reuse %1 as home partition for %2." ) @@ -1006,7 +1026,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) connect( m_afterPartitionSplitterWidget, &PartitionSplitterWidget::partitionResized, this, - [this, sizeLabel]( const QString& path, qint64 size, qint64 sizeNext ) { + [ this, sizeLabel ]( const QString& path, qint64 size, qint64 sizeNext ) + { Q_UNUSED( path ) sizeLabel->setText( tr( "%1 will be shrunk to %2MiB and a new " @@ -1020,7 +1041,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) m_previewAfterFrame->show(); m_previewAfterLabel->show(); - SelectionFilter filter = []( const QModelIndex& index ) { + SelectionFilter filter = []( const QModelIndex& index ) + { return PartUtils::canBeResized( static_cast< Partition* >( index.data( PartitionModel::PartitionPtrRole ).value< void* >() ), Logger::Once() ); @@ -1069,17 +1091,22 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) eraseBootloaderLabel->setText( tr( "Boot loader location:" ) ); m_bootloaderComboBox = createBootloaderComboBox( eraseWidget ); - connect( m_core->bootLoaderModel(), &QAbstractItemModel::modelReset, [this]() { - if ( !m_bootloaderComboBox.isNull() ) - { - Calamares::restoreSelectedBootLoader( *m_bootloaderComboBox, m_core->bootLoaderInstallPath() ); - } - } ); + connect( m_core->bootLoaderModel(), + &QAbstractItemModel::modelReset, + [ this ]() + { + if ( !m_bootloaderComboBox.isNull() ) + { + Calamares::restoreSelectedBootLoader( *m_bootloaderComboBox, + m_core->bootLoaderInstallPath() ); + } + } ); connect( m_core, &PartitionCoreModule::deviceReverted, this, - [this]( Device* dev ) { + [ this ]( Device* dev ) + { Q_UNUSED( dev ) if ( !m_bootloaderComboBox.isNull() ) { @@ -1110,7 +1137,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice ) } else { - SelectionFilter filter = []( const QModelIndex& index ) { + SelectionFilter filter = []( const QModelIndex& index ) + { return PartUtils::canBeReplaced( static_cast< Partition* >( index.data( PartitionModel::PartitionPtrRole ).value< void* >() ), Logger::Once() ); @@ -1217,18 +1245,22 @@ ChoicePage::createBootloaderComboBox( QWidget* parent ) comboForBootloader->setModel( m_core->bootLoaderModel() ); // When the chosen bootloader device changes, we update the choice in the PCM - connect( comboForBootloader, QOverload< int >::of( &QComboBox::currentIndexChanged ), this, [this]( int newIndex ) { - QComboBox* bootloaderCombo = qobject_cast< QComboBox* >( sender() ); - if ( bootloaderCombo ) - { - QVariant var = bootloaderCombo->itemData( newIndex, BootLoaderModel::BootLoaderPathRole ); - if ( !var.isValid() ) - { - return; - } - m_core->setBootLoaderInstallPath( var.toString() ); - } - } ); + connect( comboForBootloader, + QOverload< int >::of( &QComboBox::currentIndexChanged ), + this, + [ this ]( int newIndex ) + { + QComboBox* bootloaderCombo = qobject_cast< QComboBox* >( sender() ); + if ( bootloaderCombo ) + { + QVariant var = bootloaderCombo->itemData( newIndex, BootLoaderModel::BootLoaderPathRole ); + if ( !var.isValid() ) + { + return; + } + m_core->setBootLoaderInstallPath( var.toString() ); + } + } ); return comboForBootloader; } diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 8a82d2901..c5b17c69e 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -325,7 +325,10 @@ CreatePartitionDialog::updateMountPointUi() void CreatePartitionDialog::checkMountPointSelection() { - validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok )); + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), + m_usedMountPoints, + m_ui->mountPointExplanation, + m_ui->buttonBox->button( QDialogButtonBox::Ok ) ); } void diff --git a/src/modules/partition/gui/EditExistingPartitionDialog.cpp b/src/modules/partition/gui/EditExistingPartitionDialog.cpp index 1568572f4..0bc35cabe 100644 --- a/src/modules/partition/gui/EditExistingPartitionDialog.cpp +++ b/src/modules/partition/gui/EditExistingPartitionDialog.cpp @@ -69,22 +69,25 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device, replacePartResizerWidget(); - connect( m_ui->formatRadioButton, &QAbstractButton::toggled, [this]( bool doFormat ) { - replacePartResizerWidget(); + connect( m_ui->formatRadioButton, + &QAbstractButton::toggled, + [ this ]( bool doFormat ) + { + replacePartResizerWidget(); - m_ui->fileSystemLabel->setEnabled( doFormat ); - m_ui->fileSystemComboBox->setEnabled( doFormat ); + m_ui->fileSystemLabel->setEnabled( doFormat ); + m_ui->fileSystemComboBox->setEnabled( doFormat ); - if ( !doFormat ) - { - m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) ); - } + if ( !doFormat ) + { + m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) ); + } - updateMountPointPicker(); - } ); + updateMountPointPicker(); + } ); connect( - m_ui->fileSystemComboBox, &QComboBox::currentTextChanged, [this]( QString ) { updateMountPointPicker(); } ); + m_ui->fileSystemComboBox, &QComboBox::currentTextChanged, [ this ]( QString ) { updateMountPointPicker(); } ); // File system QStringList fsNames; @@ -295,5 +298,8 @@ EditExistingPartitionDialog::updateMountPointPicker() void EditExistingPartitionDialog::checkMountPointSelection() { - validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), m_usedMountPoints, m_ui->mountPointExplanation, m_ui->buttonBox->button( QDialogButtonBox::Ok )); + validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ), + m_usedMountPoints, + m_ui->mountPointExplanation, + m_ui->buttonBox->button( QDialogButtonBox::Ok ) ); } diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index e62ae512e..fe7623050 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -28,7 +28,8 @@ * Since we don't have an oracle that can answer that question, * just pretend every system can do it. */ -static inline bool systemSupportsEncryptionAcceptably() +static inline bool +systemSupportsEncryptionAcceptably() { return true; } @@ -53,7 +54,7 @@ EncryptWidget::EncryptWidget( QWidget* parent ) else { // This is really ugly, but the character is unicode "unlocked" - m_ui->m_encryptionUnsupportedLabel->setText( QStringLiteral("🔓") ); + m_ui->m_encryptionUnsupportedLabel->setText( QStringLiteral( "🔓" ) ); m_ui->m_encryptionUnsupportedLabel->show(); } diff --git a/src/modules/partition/gui/PartitionBarsView.cpp b/src/modules/partition/gui/PartitionBarsView.cpp index 81f518acc..305184b13 100644 --- a/src/modules/partition/gui/PartitionBarsView.cpp +++ b/src/modules/partition/gui/PartitionBarsView.cpp @@ -54,9 +54,10 @@ PartitionBarsView::PartitionBarsView( QWidget* parent ) setSelectionMode( QAbstractItemView::SingleSelection ); // Debug - connect( this, &PartitionBarsView::clicked, this, [=]( const QModelIndex& index ) { - cDebug() << "Clicked row" << index.row(); - } ); + connect( this, + &PartitionBarsView::clicked, + this, + [ = ]( const QModelIndex& index ) { cDebug() << "Clicked row" << index.row(); } ); setMouseTracking( true ); } @@ -399,7 +400,7 @@ void PartitionBarsView::setSelectionModel( QItemSelectionModel* selectionModel ) { QAbstractItemView::setSelectionModel( selectionModel ); - connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [=] { viewport()->repaint(); } ); + connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [ = ] { viewport()->repaint(); } ); } @@ -410,7 +411,8 @@ PartitionBarsView::setSelectionFilter( std::function< bool( const QModelIndex& ) } -QModelIndex PartitionBarsView::moveCursor( CursorAction, Qt::KeyboardModifiers ) +QModelIndex +PartitionBarsView::moveCursor( CursorAction, Qt::KeyboardModifiers ) { return QModelIndex(); } diff --git a/src/modules/partition/gui/PartitionDialogHelpers.cpp b/src/modules/partition/gui/PartitionDialogHelpers.cpp index 46b26bc2d..1ba110338 100644 --- a/src/modules/partition/gui/PartitionDialogHelpers.cpp +++ b/src/modules/partition/gui/PartitionDialogHelpers.cpp @@ -80,7 +80,8 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected ) } } -bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ) +bool +validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button ) { QString msg; bool ok = true; diff --git a/src/modules/partition/gui/PartitionLabelsView.cpp b/src/modules/partition/gui/PartitionLabelsView.cpp index e73d7f4af..e3a50c576 100644 --- a/src/modules/partition/gui/PartitionLabelsView.cpp +++ b/src/modules/partition/gui/PartitionLabelsView.cpp @@ -519,7 +519,7 @@ void PartitionLabelsView::setSelectionModel( QItemSelectionModel* selectionModel ) { QAbstractItemView::setSelectionModel( selectionModel ); - connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [=] { viewport()->repaint(); } ); + connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [ = ] { viewport()->repaint(); } ); } diff --git a/src/modules/partition/gui/PartitionPage.cpp b/src/modules/partition/gui/PartitionPage.cpp index 9d7a2f0d7..0b3cf2478 100644 --- a/src/modules/partition/gui/PartitionPage.cpp +++ b/src/modules/partition/gui/PartitionPage.cpp @@ -451,15 +451,18 @@ void PartitionPage::onRevertClicked() { ScanningDialog::run( - QtConcurrent::run( [this] { - QMutexLocker locker( &m_revertMutex ); + QtConcurrent::run( + [ this ] + { + QMutexLocker locker( &m_revertMutex ); - int oldIndex = m_ui->deviceComboBox->currentIndex(); - m_core->revertAllDevices(); - m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex ); - updateFromCurrentDevice(); - } ), - [this] { + int oldIndex = m_ui->deviceComboBox->currentIndex(); + m_core->revertAllDevices(); + m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex ); + updateFromCurrentDevice(); + } ), + [ this ] + { m_lastSelectedBootLoaderIndex = -1; if ( m_ui->bootLoaderComboBox->currentIndex() < 0 ) { @@ -606,7 +609,8 @@ PartitionPage::updateFromCurrentDevice() m_ui->partitionBarsView->selectionModel(), &QItemSelectionModel::currentChanged, this, - [=] { + [ = ] + { QModelIndex selectedIndex = m_ui->partitionBarsView->selectionModel()->currentIndex(); selectedIndex = selectedIndex.sibling( selectedIndex.row(), 0 ); m_ui->partitionBarsView->setCurrentIndex( selectedIndex ); @@ -625,7 +629,7 @@ PartitionPage::updateFromCurrentDevice() // model changes connect( m_ui->partitionTreeView->selectionModel(), &QItemSelectionModel::currentChanged, - [this]( const QModelIndex&, const QModelIndex& ) { updateButtons(); } ); + [ this ]( const QModelIndex&, const QModelIndex& ) { updateButtons(); } ); connect( model, &QAbstractItemModel::modelReset, this, &PartitionPage::onPartitionModelReset ); } diff --git a/src/modules/partition/gui/PartitionSplitterWidget.cpp b/src/modules/partition/gui/PartitionSplitterWidget.cpp index 0cafe7814..e52afaa74 100644 --- a/src/modules/partition/gui/PartitionSplitterWidget.cpp +++ b/src/modules/partition/gui/PartitionSplitterWidget.cpp @@ -159,14 +159,16 @@ PartitionSplitterWidget::setSplitPartition( const QString& path, qint64 minSize, m_itemToResizePath.clear(); } - PartitionSplitterItem itemToResize = _findItem( m_items, [path]( PartitionSplitterItem& item ) -> bool { - if ( path == item.itemPath ) - { - item.status = PartitionSplitterItem::Resizing; - return true; - } - return false; - } ); + PartitionSplitterItem itemToResize = _findItem( m_items, + [ path ]( PartitionSplitterItem& item ) -> bool + { + if ( path == item.itemPath ) + { + item.status = PartitionSplitterItem::Resizing; + return true; + } + return false; + } ); if ( itemToResize.isNull() ) { @@ -184,14 +186,16 @@ PartitionSplitterWidget::setSplitPartition( const QString& path, qint64 minSize, qint64 newSize = m_itemToResize.size - preferredSize; m_itemToResize.size = preferredSize; - int opCount = _eachItem( m_items, [preferredSize]( PartitionSplitterItem& item ) -> bool { - if ( item.status == PartitionSplitterItem::Resizing ) - { - item.size = preferredSize; - return true; - } - return false; - } ); + int opCount = _eachItem( m_items, + [ preferredSize ]( PartitionSplitterItem& item ) -> bool + { + if ( item.status == PartitionSplitterItem::Resizing ) + { + item.size = preferredSize; + return true; + } + return false; + } ); cDebug() << "each splitter item opcount:" << opCount; m_itemMinSize = minSize; m_itemMaxSize = maxSize; @@ -358,19 +362,21 @@ PartitionSplitterWidget::mouseMoveEvent( QMouseEvent* event ) m_itemToResize.size = qRound64( span * percent ); m_itemToResizeNext.size -= m_itemToResize.size - oldsize; - _eachItem( m_items, [this]( PartitionSplitterItem& item ) -> bool { - if ( item.status == PartitionSplitterItem::Resizing ) - { - item.size = m_itemToResize.size; - return true; - } - else if ( item.status == PartitionSplitterItem::ResizingNext ) - { - item.size = m_itemToResizeNext.size; - return true; - } - return false; - } ); + _eachItem( m_items, + [ this ]( PartitionSplitterItem& item ) -> bool + { + if ( item.status == PartitionSplitterItem::Resizing ) + { + item.size = m_itemToResize.size; + return true; + } + else if ( item.status == PartitionSplitterItem::ResizingNext ) + { + item.size = m_itemToResizeNext.size; + return true; + } + return false; + } ); repaint(); diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 2e5675a11..76f9ff963 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -46,9 +46,10 @@ ReplaceWidget::ReplaceWidget( PartitionCoreModule* core, QComboBox* devicesCombo m_ui->bootStatusLabel->clear(); updateFromCurrentDevice( devicesComboBox ); - connect( devicesComboBox, &QComboBox::currentTextChanged, this, [=]( const QString& /* text */ ) { - updateFromCurrentDevice( devicesComboBox ); - } ); + connect( devicesComboBox, + &QComboBox::currentTextChanged, + this, + [ = ]( const QString& /* text */ ) { updateFromCurrentDevice( devicesComboBox ); } ); CALAMARES_RETRANSLATE( onPartitionSelected(); ); } diff --git a/src/modules/partition/gui/ScanningDialog.cpp b/src/modules/partition/gui/ScanningDialog.cpp index 4dffa922b..56133e21f 100644 --- a/src/modules/partition/gui/ScanningDialog.cpp +++ b/src/modules/partition/gui/ScanningDialog.cpp @@ -47,12 +47,16 @@ ScanningDialog::run( const QFuture< void >& future, theDialog->show(); QFutureWatcher< void >* watcher = new QFutureWatcher< void >(); - connect( watcher, &QFutureWatcher< void >::finished, theDialog, [watcher, theDialog, callback] { - watcher->deleteLater(); - theDialog->hide(); - theDialog->deleteLater(); - callback(); - } ); + connect( watcher, + &QFutureWatcher< void >::finished, + theDialog, + [ watcher, theDialog, callback ] + { + watcher->deleteLater(); + theDialog->hide(); + theDialog->deleteLater(); + callback(); + } ); watcher->setFuture( future ); } diff --git a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp index 48b44f68d..818a60483 100644 --- a/src/modules/partition/gui/VolumeGroupBaseDialog.cpp +++ b/src/modules/partition/gui/VolumeGroupBaseDialog.cpp @@ -45,17 +45,25 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Pa updateOkButton(); updateTotalSize(); - connect( ui->pvList, &QListWidget::itemChanged, this, [&]( QListWidgetItem* ) { - updateTotalSize(); - updateOkButton(); - } ); + connect( ui->pvList, + &QListWidget::itemChanged, + this, + [ & ]( QListWidgetItem* ) + { + updateTotalSize(); + updateOkButton(); + } ); - connect( ui->peSize, qOverload< int >( &QSpinBox::valueChanged ), this, [&]( int ) { - updateTotalSectors(); - updateOkButton(); - } ); + connect( ui->peSize, + qOverload< int >( &QSpinBox::valueChanged ), + this, + [ & ]( int ) + { + updateTotalSectors(); + updateOkButton(); + } ); - connect( ui->vgName, &QLineEdit::textChanged, this, [&]( const QString& ) { updateOkButton(); } ); + connect( ui->vgName, &QLineEdit::textChanged, this, [ & ]( const QString& ) { updateOkButton(); } ); } VolumeGroupBaseDialog::~VolumeGroupBaseDialog() diff --git a/src/modules/partition/jobs/AutoMountManagementJob.cpp b/src/modules/partition/jobs/AutoMountManagementJob.cpp index e276447db..29b197933 100644 --- a/src/modules/partition/jobs/AutoMountManagementJob.cpp +++ b/src/modules/partition/jobs/AutoMountManagementJob.cpp @@ -26,7 +26,9 @@ Calamares::JobResult AutoMountManagementJob::exec() { cVerbose() << "this" << Logger::Pointer( this ) << "value" << Logger::Pointer( m_stored ) - << ( m_stored ? "restore" : m_disable ? "disable" : "enable" ); + << ( m_stored ? "restore" + : m_disable ? "disable" + : "enable" ); if ( m_stored ) { CalamaresUtils::Partition::automountRestore( m_stored ); diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index 2f5a8bd36..3d7b9d0de 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -157,9 +157,11 @@ getLVMVolumes() QStringList lvscanLines = QString::fromLocal8Bit( process.readAllStandardOutput() ).split( '\n' ); // Get the second column (`value(1)`) sinec that is the device name, // remove quoting. - std::transform( lvscanLines.begin(), lvscanLines.end(), lvscanLines.begin(), []( const QString& lvscanLine ) { - return lvscanLine.simplified().split( ' ' ).value( 1 ).replace( '\'', "" ); - } ); + std::transform( lvscanLines.begin(), + lvscanLines.end(), + lvscanLines.begin(), + []( const QString& lvscanLine ) + { return lvscanLine.simplified().split( ' ' ).value( 1 ).replace( '\'', "" ); } ); return lvscanLines; } else diff --git a/src/modules/partition/tests/AutoMountTests.cpp b/src/modules/partition/tests/AutoMountTests.cpp index 45a7b4f12..103fe6f82 100644 --- a/src/modules/partition/tests/AutoMountTests.cpp +++ b/src/modules/partition/tests/AutoMountTests.cpp @@ -69,8 +69,8 @@ AutoMountJobTests::testRunQueue() QVERIFY( !q.isRunning() ); QEventLoop loop; - QTimer::singleShot( std::chrono::milliseconds( 100 ), [&q]() { q.start(); } ); - QTimer::singleShot( std::chrono::milliseconds( 5000 ), [&loop]() { loop.quit(); } ); + QTimer::singleShot( std::chrono::milliseconds( 100 ), [ &q ]() { q.start(); } ); + QTimer::singleShot( std::chrono::milliseconds( 5000 ), [ &loop ]() { loop.quit(); } ); connect( &q, &Calamares::JobQueue::finished, &loop, &QEventLoop::quit ); loop.exec(); diff --git a/src/modules/partition/tests/ClearMountsJobTests.cpp b/src/modules/partition/tests/ClearMountsJobTests.cpp index 3af400fde..17565e756 100644 --- a/src/modules/partition/tests/ClearMountsJobTests.cpp +++ b/src/modules/partition/tests/ClearMountsJobTests.cpp @@ -32,10 +32,10 @@ getPartitionsForDevice_other( const QString& deviceName ) { QProcess process; process.setProgram( "sh" ); - process.setArguments( - { "-c", - QString( "echo $(awk '{print \"/dev/\"$4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" ) - .arg( deviceName ) } ); + process.setArguments( { "-c", + QString( "echo $(awk '{print \"/dev/\"$4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' " + "-e '/[1-9]/!d' | grep %1)" ) + .arg( deviceName ) } ); process.start(); process.waitForFinished(); From aede7056f20419f896e9df0ff51d27aa66593a35 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 16:38:08 +0100 Subject: [PATCH 165/168] Changes: pre-release housekeeping --- CHANGES-3.2 | 5 ++++- CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 04ac311c6..4cb793b64 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,11 +7,14 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.51 (unreleased) # +# 3.2.51 (2022-02-01) # This release contains contributions from (alphabetically by first name): - Evan James +**WARNING** The *umount* module has been rewritten in C++. Check your +configuration if you previously used the copy-a-log functionality. + ## Core ## - Evan has made a start on documenting which Global Storage keys there are and how they tie modules together. This can be found in the diff --git a/CMakeLists.txt b/CMakeLists.txt index aec04f315..aab5ee938 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ project( CALAMARES LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From 9127b76e5f771f9b5451fc2fb52e8bc545b881b8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 16:49:18 +0100 Subject: [PATCH 166/168] [bootloader] Fix typo's --- src/modules/bootloader/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index 81e271a71..c7bc741de 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -427,7 +427,7 @@ def efi_label(efi_directory): used within @p efi_directory. """ if "efiBootloaderId" in libcalamares.job.configuration: - efi_bootloader_id = change_efi_suffix( efi_directory, calamares.job.configuration["efiBootloaderId"] ) + efi_bootloader_id = change_efi_suffix( efi_directory, libcalamares.job.configuration["efiBootloaderId"] ) else: branding = libcalamares.globalstorage.value("branding") efi_bootloader_id = branding["bootloaderEntryName"] @@ -563,6 +563,7 @@ def run_grub_install(fw_type, partitions, efi_directory): check_target_env_call(["sh", "-c", "echo ZPOOL_VDEV_NAME_PATH=1 >> /etc/environment"]) if fw_type == "efi": + assert efi_directory is not None efi_bootloader_id = efi_label(efi_directory) efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters() @@ -577,6 +578,7 @@ def run_grub_install(fw_type, partitions, efi_directory): "--bootloader-id=" + efi_bootloader_id, "--force"]) else: + assert efi_directory is None if libcalamares.globalstorage.value("bootLoader") is None: return @@ -653,7 +655,7 @@ def install_grub(efi_directory, fw_type): shutil.copy2(efi_file_source, efi_file_target) else: libcalamares.utils.debug("Bootloader: grub (bios)") - run_grub_install(fw_type, partitions) + run_grub_install(fw_type, partitions, None) run_grub_mkconfig(partitions, libcalamares.job.configuration["grubCfg"]) From 5d23a8f69383c49e5a9077039d5071655663f938 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 17:25:40 +0100 Subject: [PATCH 167/168] Changes: post-release housekeeping --- CHANGES-3.2 | 12 ++++++++++++ CMakeLists.txt | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGES-3.2 b/CHANGES-3.2 index 4cb793b64..01da2a00e 100644 --- a/CHANGES-3.2 +++ b/CHANGES-3.2 @@ -7,6 +7,18 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. +# 3.2.52 (unreleased) # + +This release contains contributions from (alphabetically by first name): + - No external contributors yet + +## Core ## + - No core changes yet + +## Modules ## + - No module changes yet + + # 3.2.51 (2022-02-01) # This release contains contributions from (alphabetically by first name): diff --git a/CMakeLists.txt b/CMakeLists.txt index aab5ee938..dd46148d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,11 +41,11 @@ # TODO:3.3: Require CMake 3.12 cmake_minimum_required( VERSION 3.3 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.51 + VERSION 3.2.52 LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) message( FATAL_ERROR "Do not build development versions in the source-directory." ) endif() From baad8f7d2c3afd9b01748c8d0526c99537c214fe Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 1 Feb 2022 17:32:00 +0100 Subject: [PATCH 168/168] i18n: update english sources --- lang/calamares_en.ts | 785 +++++++++++++++++++++++++------------------ lang/python.pot | 324 +++++++++--------- 2 files changed, 610 insertions(+), 499 deletions(-) diff --git a/lang/calamares_en.ts b/lang/calamares_en.ts index 544fd4e71..f92210abd 100644 --- a/lang/calamares_en.ts +++ b/lang/calamares_en.ts @@ -171,7 +171,7 @@ Calamares::JobThread - + Done Done @@ -187,17 +187,17 @@ Calamares::ProcessJob - + Run command '%1' in target system. Run command '%1' in target system. - + Run command '%1'. Run command '%1'. - + Running command %1 %2 Running command %1 %2 @@ -205,32 +205,32 @@ Calamares::PythonJob - + Running %1 operation. Running %1 operation. - + Bad working directory path Bad working directory path - + Working directory %1 for python job %2 is not readable. Working directory %1 for python job %2 is not readable. - + Bad main script file Bad main script file - + Main script file %1 for python job %2 is not readable. Main script file %1 for python job %2 is not readable. - + Boost.Python error in job "%1". Boost.Python error in job "%1". @@ -285,52 +285,47 @@ Calamares::ViewManager - + Setup Failed Setup Failed - + Installation Failed Installation Failed - Would you like to paste the install log to the web? - Would you like to paste the install log to the web? - - - Error Error - + &Yes &Yes - + &No &No - + &Close &Close - + Install Log Paste URL Install Log Paste URL - + The upload was unsuccessful. No web-paste was done. The upload was unsuccessful. No web-paste was done. - + Install log posted to %1 @@ -343,124 +338,124 @@ Link copied to clipboard Link copied to clipboard - + Calamares Initialization Failed Calamares Initialization Failed - + %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. %1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution. - + <br/>The following modules could not be loaded: <br/>The following modules could not be loaded: - + Continue with setup? Continue with setup? - + Continue with installation? Continue with installation? - + The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> - + The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - + &Set up now &Set up now - + &Install now &Install now - + Go &back Go &back - + &Set up &Set up - + &Install &Install - + Setup is complete. Close the setup program. Setup is complete. Close the setup program. - + The installation is complete. Close the installer. The installation is complete. Close the installer. - + Cancel setup without changing the system. Cancel setup without changing the system. - + Cancel installation without changing the system. Cancel installation without changing the system. - + &Next &Next - + &Back &Back - + &Done &Done - + &Cancel &Cancel - + Cancel setup? Cancel setup? - + Cancel installation? Cancel installation? - + Do you really want to cancel the current setup process? The setup program will quit and all changes will be lost. Do you really want to cancel the current setup process? The setup program will quit and all changes will be lost. - + Do you really want to cancel the current install process? The installer will quit and all changes will be lost. Do you really want to cancel the current install process? @@ -470,22 +465,22 @@ The installer will quit and all changes will be lost. CalamaresPython::Helper - + Unknown exception type Unknown exception type - + unparseable Python error unparseable Python error - + unparseable Python traceback unparseable Python traceback - + Unfetchable Python error. Unfetchable Python error. @@ -537,149 +532,149 @@ The installer will quit and all changes will be lost. Form - + Select storage de&vice: Select storage de&vice: - - - - + + + + Current: Current: - + After: After: - + <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. <strong>Manual partitioning</strong><br/>You can create or resize partitions yourself. - + Reuse %1 as home partition for %2. Reuse %1 as home partition for %2. - + <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> <strong>Select a partition to shrink, then drag the bottom bar to resize</strong> - + %1 will be shrunk to %2MiB and a new %3MiB partition will be created for %4. %1 will be shrunk to %2MiB and a new %3MiB partition will be created for %4. - + Boot loader location: Boot loader location: - + <strong>Select a partition to install on</strong> <strong>Select a partition to install on</strong> - + An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - + The EFI system partition at %1 will be used for starting %2. The EFI system partition at %1 will be used for starting %2. - + EFI system partition: EFI system partition: - + This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. This storage device does not seem to have an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - - - - + + + + <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. <strong>Erase disk</strong><br/>This will <font color="red">delete</font> all data currently present on the selected storage device. - - - + + + <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. <strong>Install alongside</strong><br/>The installer will shrink a partition to make room for %1. - - - - + + + + <strong>Replace a partition</strong><br/>Replaces a partition with %1. <strong>Replace a partition</strong><br/>Replaces a partition with %1. - + This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. This storage device has %1 on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. This storage device already has an operating system on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. This storage device has multiple operating systems on it. What would you like to do?<br/>You will be able to review and confirm your choices before any change is made to the storage device. - + This storage device already has an operating system on it, but the partition table <strong>%1</strong> is different from the needed <strong>%2</strong>.<br/> This storage device already has an operating system on it, but the partition table <strong>%1</strong> is different from the needed <strong>%2</strong>.<br/> - + This storage device has one of its partitions <strong>mounted</strong>. This storage device has one of its partitions <strong>mounted</strong>. - + This storage device is a part of an <strong>inactive RAID</strong> device. This storage device is a part of an <strong>inactive RAID</strong> device. - + No Swap No Swap - + Reuse Swap Reuse Swap - + Swap (no Hibernate) Swap (no Hibernate) - + Swap (with Hibernate) Swap (with Hibernate) - + Swap to file Swap to file @@ -687,42 +682,42 @@ The installer will quit and all changes will be lost. ClearMountsJob - + Successfully unmounted %1. Successfully unmounted %1. - + Successfully disabled swap %1. Successfully disabled swap %1. - + Successfully cleared swap %1. Successfully cleared swap %1. - + Successfully closed mapper device %1. Successfully closed mapper device %1. - + Successfully disabled volume group %1. Successfully disabled volume group %1. - + Clear mounts for partitioning operations on %1 Clear mounts for partitioning operations on %1 - + Clearing mounts for partitioning operations on %1. Clearing mounts for partitioning operations on %1. - + Cleared all mounts for %1 Cleared all mounts for %1 @@ -730,22 +725,17 @@ The installer will quit and all changes will be lost. ClearTempMountsJob - + Clear all temporary mounts. Clear all temporary mounts. - + Clearing all temporary mounts. Clearing all temporary mounts. - - Cannot get list of temporary mounts. - Cannot get list of temporary mounts. - - - + Cleared all temporary mounts. Cleared all temporary mounts. @@ -782,17 +772,17 @@ The installer will quit and all changes will be lost. Set keyboard layout to %1/%2. - + Set timezone to %1/%2. Set timezone to %1/%2. - + The system language will be set to %1. The system language will be set to %1. - + The numbers and dates locale will be set to %1. The numbers and dates locale will be set to %1. @@ -962,22 +952,22 @@ The installer will quit and all changes will be lost. The installation of %1 is complete. - + Package Selection Package Selection - + Please pick a product from the list. The selected product will be installed. Please pick a product from the list. The selected product will be installed. - + Install option: <strong>%1</strong> Install option: <strong>%1</strong> - + None None @@ -1029,8 +1019,8 @@ The installer will quit and all changes will be lost. - &Primary - &Primary + Primar&y + @@ -1053,86 +1043,91 @@ The installer will quit and all changes will be lost. &Mount Point: - + Flags: Flags: - + Label for the filesystem Label for the filesystem - + FS Label: FS Label: - + En&crypt En&crypt - + Logical Logical - + Primary Primary - + GPT GPT - + Mountpoint already in use. Please select another one. Mountpoint already in use. Please select another one. + + + Mountpoint must start with a <tt>/</tt>. + + CreatePartitionJob - + Create new %1MiB partition on %3 (%2) with entries %4. Create new %1MiB partition on %3 (%2) with entries %4. - + Create new %1MiB partition on %3 (%2). Create new %1MiB partition on %3 (%2). - + Create new %2MiB partition on %4 (%3) with file system %1. Create new %2MiB partition on %4 (%3) with file system %1. - + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2) with entries <em>%4</em>. Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2) with entries <em>%4</em>. - + Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2). Create new <strong>%1MiB</strong> partition on <strong>%3</strong> (%2). - + Create new <strong>%2MiB</strong> partition on <strong>%4</strong> (%3) with file system <strong>%1</strong>. Create new <strong>%2MiB</strong> partition on <strong>%4</strong> (%3) with file system <strong>%1</strong>. - - + + Creating new %1 partition on %2. Creating new %1 partition on %2. - + The installer failed to create partition on disk '%1'. The installer failed to create partition on disk '%1'. @@ -1168,22 +1163,22 @@ The installer will quit and all changes will be lost. CreatePartitionTableJob - + Create new %1 partition table on %2. Create new %1 partition table on %2. - + Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). Create new <strong>%1</strong> partition table on <strong>%2</strong> (%3). - + Creating new %1 partition table on %2. Creating new %1 partition table on %2. - + The installer failed to create a partition table on %1. The installer failed to create a partition table on %1. @@ -1191,33 +1186,33 @@ The installer will quit and all changes will be lost. CreateUserJob - + Create user %1 Create user %1 - + Create user <strong>%1</strong>. Create user <strong>%1</strong>. - + Preserving home directory Preserving home directory - - + + Creating user %1 Creating user %1 - + Configuring user %1 Configuring user %1 - + Setting file permissions Setting file permissions @@ -1233,22 +1228,22 @@ The installer will quit and all changes will be lost. CreateVolumeGroupJob - + Create new volume group named %1. Create new volume group named %1. - + Create new volume group named <strong>%1</strong>. Create new volume group named <strong>%1</strong>. - + Creating new volume group named %1. Creating new volume group named %1. - + The installer failed to create a volume group named '%1'. The installer failed to create a volume group named '%1'. @@ -1256,18 +1251,18 @@ The installer will quit and all changes will be lost. DeactivateVolumeGroupJob - - + + Deactivate volume group named %1. Deactivate volume group named %1. - + Deactivate volume group named <strong>%1</strong>. Deactivate volume group named <strong>%1</strong>. - + The installer failed to deactivate a volume group named %1. The installer failed to deactivate a volume group named %1. @@ -1275,22 +1270,22 @@ The installer will quit and all changes will be lost. DeletePartitionJob - + Delete partition %1. Delete partition %1. - + Delete partition <strong>%1</strong>. Delete partition <strong>%1</strong>. - + Deleting partition %1. Deleting partition %1. - + The installer failed to delete partition %1. The installer failed to delete partition %1. @@ -1298,32 +1293,32 @@ The installer will quit and all changes will be lost. DeviceInfoWidget - + This device has a <strong>%1</strong> partition table. This device has a <strong>%1</strong> partition table. - + This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. This is a <strong>loop</strong> device.<br><br>It is a pseudo-device with no partition table that makes a file accessible as a block device. This kind of setup usually only contains a single filesystem. - + This installer <strong>cannot detect a partition table</strong> on the selected storage device.<br><br>The device either has no partition table, or the partition table is corrupted or of an unknown type.<br>This installer can create a new partition table for you, either automatically, or through the manual partitioning page. This installer <strong>cannot detect a partition table</strong> on the selected storage device.<br><br>The device either has no partition table, or the partition table is corrupted or of an unknown type.<br>This installer can create a new partition table for you, either automatically, or through the manual partitioning page. - + <br><br>This is the recommended partition table type for modern systems which start from an <strong>EFI</strong> boot environment. <br><br>This is the recommended partition table type for modern systems which start from an <strong>EFI</strong> boot environment. - + <br><br>This partition table type is only advisable on older systems which start from a <strong>BIOS</strong> boot environment. GPT is recommended in most other cases.<br><br><strong>Warning:</strong> the MBR partition table is an obsolete MS-DOS era standard.<br>Only 4 <em>primary</em> partitions may be created, and of those 4, one can be an <em>extended</em> partition, which may in turn contain many <em>logical</em> partitions. <br><br>This partition table type is only advisable on older systems which start from a <strong>BIOS</strong> boot environment. GPT is recommended in most other cases.<br><br><strong>Warning:</strong> the MBR partition table is an obsolete MS-DOS era standard.<br>Only 4 <em>primary</em> partitions may be created, and of those 4, one can be an <em>extended</em> partition, which may in turn contain many <em>logical</em> partitions. - + The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. The type of <strong>partition table</strong> on the selected storage device.<br><br>The only way to change the partition table type is to erase and recreate the partition table from scratch, which destroys all data on the storage device.<br>This installer will keep the current partition table unless you explicitly choose otherwise.<br>If unsure, on modern systems GPT is preferred. @@ -1331,13 +1326,13 @@ The installer will quit and all changes will be lost. DeviceModel - + %1 - %2 (%3) device[name] - size[number] (device-node[name]) %1 - %2 (%3) - + %1 - (%2) device[name] - (device-node[name]) %1 - (%2) @@ -1364,7 +1359,7 @@ The installer will quit and all changes will be lost. DummyCppJob - + Dummy C++ Job Dummy C++ Job @@ -1378,8 +1373,8 @@ The installer will quit and all changes will be lost. - Content: - Content: + Con&tent: + @@ -1402,40 +1397,35 @@ The installer will quit and all changes will be lost. &Mount Point: - + Si&ze: Si&ze: - + MiB MiB - + Fi&le System: Fi&le System: - + Flags: Flags: - + Label for the filesystem Label for the filesystem - + FS Label: FS Label: - - - Mountpoint already in use. Please select another one. - Mountpoint already in use. Please select another one. - EncryptWidget @@ -1450,76 +1440,94 @@ The installer will quit and all changes will be lost. En&crypt system - + + Your system does not seem to support encryption well enough to encrypt the entire system. You may enable encryption, but performance may suffer. + + + + Passphrase Passphrase - + Confirm passphrase Confirm passphrase - - + + Please enter the same passphrase in both boxes. Please enter the same passphrase in both boxes. + + ErrorDialog + + + Details: + + + + + Would you like to paste the install log to the web? + Would you like to paste the install log to the web? + + FillGlobalStorageJob - + Set partition information Set partition information - + Install %1 on <strong>new</strong> %2 system partition with features <em>%3</em> Install %1 on <strong>new</strong> %2 system partition with features <em>%3</em> - + Install %1 on <strong>new</strong> %2 system partition. Install %1 on <strong>new</strong> %2 system partition. - + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong> and features <em>%3</em>. Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong> and features <em>%3</em>. - + Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>%3. Set up <strong>new</strong> %2 partition with mount point <strong>%1</strong>%3. - + Install %2 on %3 system partition <strong>%1</strong> with features <em>%4</em>. Install %2 on %3 system partition <strong>%1</strong> with features <em>%4</em>. - + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong> and features <em>%4</em>. Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong> and features <em>%4</em>. - + Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>%4. Set up %3 partition <strong>%1</strong> with mount point <strong>%2</strong>%4. - + Install %2 on %3 system partition <strong>%1</strong>. Install %2 on %3 system partition <strong>%1</strong>. - + Install boot loader on <strong>%1</strong>. Install boot loader on <strong>%1</strong>. - + Setting up mount points. Setting up mount points. @@ -1586,22 +1594,22 @@ The installer will quit and all changes will be lost. FormatPartitionJob - + Format partition %1 (file system: %2, size: %3 MiB) on %4. Format partition %1 (file system: %2, size: %3 MiB) on %4. - + Format <strong>%3MiB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. Format <strong>%3MiB</strong> partition <strong>%1</strong> with file system <strong>%2</strong>. - + Formatting partition %1 with file system %2. Formatting partition %1 with file system %2. - + The installer failed to format partition %1 on disk '%2'. The installer failed to format partition %1 on disk '%2'. @@ -1716,7 +1724,7 @@ The installer will quit and all changes will be lost. InitcpioJob - + Creating initramfs with mkinitcpio. Creating initramfs with mkinitcpio. @@ -1732,17 +1740,17 @@ The installer will quit and all changes will be lost. InteractiveTerminalPage - + Konsole not installed Konsole not installed - + Please install KDE Konsole and try again! Please install KDE Konsole and try again! - + Executing script: &nbsp;<code>%1</code> Executing script: &nbsp;<code>%1</code> @@ -1794,6 +1802,29 @@ The installer will quit and all changes will be lost. &OK + + LOSHJob + + + Configuring encrypted swap. + + + + + No target system available. + + + + + No rootMountPoint is set. + + + + + No configFilePath is set. + + + LicensePage @@ -2513,12 +2544,12 @@ The installer will quit and all changes will be lost. PackageModel - + Name Name - + Description Description @@ -2641,42 +2672,42 @@ The installer will quit and all changes will be lost. PartitionLabelsView - + Root Root - + Home Home - + Boot Boot - + EFI system EFI system - + Swap Swap - + New partition for %1 New partition for %1 - + New partition New partition - + %1 %2 size[number] filesystem[name] %1 %2 @@ -2685,39 +2716,39 @@ The installer will quit and all changes will be lost. PartitionModel - - + + Free Space Free Space - - + + New partition New partition - + Name Name - + File System File System - + File System Label File System Label - + Mount Point Mount Point - + Size Size @@ -2813,82 +2844,82 @@ The installer will quit and all changes will be lost. Partitions - + Current: Current: - + After: After: - + No EFI system partition configured No EFI system partition configured - + EFI system partition configured incorrectly EFI system partition configured incorrectly - + An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem. An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem. - + The filesystem must be mounted on <strong>%1</strong>. The filesystem must be mounted on <strong>%1</strong>. - + The filesystem must have type FAT32. The filesystem must have type FAT32. - + The filesystem must be at least %1 MiB in size. The filesystem must be at least %1 MiB in size. - + The filesystem must have flag <strong>%1</strong> set. The filesystem must have flag <strong>%1</strong> set. - + You can continue without setting up an EFI system partition but your system may fail to start. You can continue without setting up an EFI system partition but your system may fail to start. - + Option to use GPT on BIOS Option to use GPT on BIOS - + A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>bios_grub</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>bios_grub</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT. - + Boot partition not encrypted Boot partition not encrypted - + A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window. A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window. - + has at least one disk device available. has at least one disk device available. - + There are no partitions to install on. There are no partitions to install on. @@ -2936,17 +2967,17 @@ The installer will quit and all changes will be lost. PreserveFiles - + Saving files for later ... Saving files for later ... - + No files configured to save for later. No files configured to save for later. - + Not all of the configured files could be preserved. Not all of the configured files could be preserved. @@ -2954,14 +2985,14 @@ The installer will quit and all changes will be lost. ProcessResult - + There was no output from the command. There was no output from the command. - + Output: @@ -2970,52 +3001,52 @@ Output: - + External command crashed. External command crashed. - + Command <i>%1</i> crashed. Command <i>%1</i> crashed. - + External command failed to start. External command failed to start. - + Command <i>%1</i> failed to start. Command <i>%1</i> failed to start. - + Internal error when starting command. Internal error when starting command. - + Bad parameters for process job call. Bad parameters for process job call. - + External command failed to finish. External command failed to finish. - + Command <i>%1</i> failed to finish in %2 seconds. Command <i>%1</i> failed to finish in %2 seconds. - + External command finished with errors. External command finished with errors. - + Command <i>%1</i> finished with exit code %2. Command <i>%1</i> finished with exit code %2. @@ -3028,22 +3059,22 @@ Output: %1 (%2) - + unknown unknown - + extended extended - + unformatted unformatted - + swap swap @@ -3078,12 +3109,12 @@ Output: Could not create new random file <pre>%1</pre>. - + No product No product - + No description provided. No description provided. @@ -3093,7 +3124,7 @@ Output: (no mount point) - + Unpartitioned space or unknown partition table Unpartitioned space or unknown partition table @@ -3119,18 +3150,18 @@ Output: RemoveVolumeGroupJob - - + + Remove Volume Group named %1. Remove Volume Group named %1. - + Remove Volume Group named <strong>%1</strong>. Remove Volume Group named <strong>%1</strong>. - + The installer failed to remove a volume group named '%1'. The installer failed to remove a volume group named '%1'. @@ -3143,69 +3174,69 @@ Output: Form - + Select where to install %1.<br/><font color="red">Warning: </font>this will delete all files on the selected partition. Select where to install %1.<br/><font color="red">Warning: </font>this will delete all files on the selected partition. - + The selected item does not appear to be a valid partition. The selected item does not appear to be a valid partition. - + %1 cannot be installed on empty space. Please select an existing partition. %1 cannot be installed on empty space. Please select an existing partition. - + %1 cannot be installed on an extended partition. Please select an existing primary or logical partition. %1 cannot be installed on an extended partition. Please select an existing primary or logical partition. - + %1 cannot be installed on this partition. %1 cannot be installed on this partition. - + Data partition (%1) Data partition (%1) - + Unknown system partition (%1) Unknown system partition (%1) - + %1 system partition (%2) %1 system partition (%2) - + <strong>%4</strong><br/><br/>The partition %1 is too small for %2. Please select a partition with capacity at least %3 GiB. <strong>%4</strong><br/><br/>The partition %1 is too small for %2. Please select a partition with capacity at least %3 GiB. - + <strong>%2</strong><br/><br/>An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. <strong>%2</strong><br/><br/>An EFI system partition cannot be found anywhere on this system. Please go back and use manual partitioning to set up %1. - - - + + + <strong>%3</strong><br/><br/>%1 will be installed on %2.<br/><font color="red">Warning: </font>all data on partition %2 will be lost. <strong>%3</strong><br/><br/>%1 will be installed on %2.<br/><font color="red">Warning: </font>all data on partition %2 will be lost. - + The EFI system partition at %1 will be used for starting %2. The EFI system partition at %1 will be used for starting %2. - + EFI system partition: EFI system partition: @@ -3230,68 +3261,68 @@ Output: ResizeFSJob - + Resize Filesystem Job Resize Filesystem Job - + Invalid configuration Invalid configuration - + The file-system resize job has an invalid configuration and will not run. The file-system resize job has an invalid configuration and will not run. - + KPMCore not Available KPMCore not Available - + Calamares cannot start KPMCore for the file-system resize job. Calamares cannot start KPMCore for the file-system resize job. - - - - - + + + + + Resize Failed Resize Failed - + The filesystem %1 could not be found in this system, and cannot be resized. The filesystem %1 could not be found in this system, and cannot be resized. - + The device %1 could not be found in this system, and cannot be resized. The device %1 could not be found in this system, and cannot be resized. - - + + The filesystem %1 cannot be resized. The filesystem %1 cannot be resized. - - + + The device %1 cannot be resized. The device %1 cannot be resized. - + The filesystem %1 must be resized, but cannot. The filesystem %1 must be resized, but cannot. - + The device %1 must be resized, but cannot The device %1 must be resized, but cannot @@ -3299,17 +3330,17 @@ Output: ResizePartitionJob - + Resize partition %1. Resize partition %1. - + Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. Resize <strong>%2MiB</strong> partition <strong>%1</strong> to <strong>%3MiB</strong>. - + Resizing %2MiB partition %1 to %3MiB. Resizing %2MiB partition %1 to %3MiB. @@ -3330,18 +3361,18 @@ Output: ResizeVolumeGroupJob - - + + Resize volume group named %1 from %2 to %3. Resize volume group named %1 from %2 to %3. - + Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. Resize volume group named <strong>%1</strong> from <strong>%2</strong> to <strong>%3</strong>. - + The installer failed to resize a volume group named '%1'. The installer failed to resize a volume group named '%1'. @@ -3362,12 +3393,12 @@ Output: ScanningDialog - + Scanning storage devices... Scanning storage devices... - + Partitioning Partitioning @@ -3435,82 +3466,82 @@ Output: SetPartFlagsJob - + Set flags on partition %1. Set flags on partition %1. - + Set flags on %1MiB %2 partition. Set flags on %1MiB %2 partition. - + Set flags on new partition. Set flags on new partition. - + Clear flags on partition <strong>%1</strong>. Clear flags on partition <strong>%1</strong>. - + Clear flags on %1MiB <strong>%2</strong> partition. Clear flags on %1MiB <strong>%2</strong> partition. - + Clear flags on new partition. Clear flags on new partition. - + Flag partition <strong>%1</strong> as <strong>%2</strong>. Flag partition <strong>%1</strong> as <strong>%2</strong>. - + Flag %1MiB <strong>%2</strong> partition as <strong>%3</strong>. Flag %1MiB <strong>%2</strong> partition as <strong>%3</strong>. - + Flag new partition as <strong>%1</strong>. Flag new partition as <strong>%1</strong>. - + Clearing flags on partition <strong>%1</strong>. Clearing flags on partition <strong>%1</strong>. - + Clearing flags on %1MiB <strong>%2</strong> partition. Clearing flags on %1MiB <strong>%2</strong> partition. - + Clearing flags on new partition. Clearing flags on new partition. - + Setting flags <strong>%2</strong> on partition <strong>%1</strong>. Setting flags <strong>%2</strong> on partition <strong>%1</strong>. - + Setting flags <strong>%3</strong> on %1MiB <strong>%2</strong> partition. Setting flags <strong>%3</strong> on %1MiB <strong>%2</strong> partition. - + Setting flags <strong>%1</strong> on new partition. Setting flags <strong>%1</strong> on new partition. - + The installer failed to set flags on partition %1. The installer failed to set flags on partition %1. @@ -3636,7 +3667,7 @@ Output: ShellProcessJob - + Shell Processes Job Shell Processes Job @@ -3653,27 +3684,27 @@ Output: StandardButtons - + &OK &OK - + &Yes &Yes - + &No &No - + &Cancel &Cancel - + &Close &Close @@ -3681,12 +3712,12 @@ Output: TrackingInstallJob - + Installation feedback Installation feedback - + Sending installation feedback. Sending installation feedback. @@ -3704,28 +3735,28 @@ Output: TrackingKUserFeedbackJob - + KDE user feedback KDE user feedback - + Configuring KDE user feedback. Configuring KDE user feedback. - + Error in KDE user feedback configuration. Error in KDE user feedback configuration. - + Could not configure KDE user feedback correctly, script error %1. Could not configure KDE user feedback correctly, script error %1. - + Could not configure KDE user feedback correctly, Calamares error %1. Could not configure KDE user feedback correctly, Calamares error %1. @@ -3744,17 +3775,17 @@ Output: - + Error in machine feedback configuration. Error in machine feedback configuration. - + Could not configure machine feedback correctly, script error %1. Could not configure machine feedback correctly, script error %1. - + Could not configure machine feedback correctly, Calamares error %1. Could not configure machine feedback correctly, Calamares error %1. @@ -3810,6 +3841,24 @@ Output: Feedback + + UmountJob + + + Unmount file systems. + + + + + No target system available. + + + + + No rootMountPoint is set. + + + UsersPage @@ -4022,6 +4071,50 @@ Output: Welcome + + ZfsJob + + + Create ZFS pools and datasets + + + + + Failed to create zpool on + + + + + Configuration Error + Configuration Error + + + + No partitions are available for Zfs. + + + + + Internal data missing + + + + + + Failed to create zpool + + + + + Failed to create dataset + + + + + The output was: + + + about @@ -4097,6 +4190,30 @@ Output: This log is copied to /var/log/installation.log of the target system.</p> + + finishedq@mobile + + + Installation Completed + Installation Completed + + + + %1 has been installed on your computer.<br/> + You may now restart your device. + + + + + Close + + + + + Restart + + + i18n diff --git a/lang/python.pot b/lang/python.pot index 63372044e..86647241b 100644 --- a/lang/python.pot +++ b/lang/python.pot @@ -2,409 +2,403 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-02 15:45+0100\n" +"POT-Creation-Date: 2022-02-01 17:27+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: src/modules/initramfscfg/main.py:32 msgid "Configuring initramfs." -msgstr "Configuring initramfs." +msgstr "" #: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 -#: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361 -#: src/modules/fstab/main.py:388 src/modules/networkcfg/main.py:105 -#: src/modules/initcpiocfg/main.py:227 src/modules/initcpiocfg/main.py:231 -#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:144 +#: src/modules/fstab/main.py:360 src/modules/fstab/main.py:366 +#: src/modules/fstab/main.py:393 src/modules/networkcfg/main.py:105 +#: src/modules/initcpiocfg/main.py:235 src/modules/initcpiocfg/main.py:239 +#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:229 #: src/modules/rawfs/main.py:164 src/modules/openrcdmcryptcfg/main.py:72 #: src/modules/openrcdmcryptcfg/main.py:76 -#: src/modules/luksopenswaphookcfg/main.py:86 -#: src/modules/luksopenswaphookcfg/main.py:90 msgid "Configuration Error" -msgstr "Configuration Error" +msgstr "" -#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356 -#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145 +#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:361 +#: src/modules/initcpiocfg/main.py:236 src/modules/mount/main.py:230 #: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73 -#: src/modules/luksopenswaphookcfg/main.py:87 msgid "No partitions are defined for
{!s}
to use." -msgstr "No partitions are defined for
{!s}
to use." +msgstr "" -#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362 -#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232 +#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:367 +#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:240 #: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77 -#: src/modules/luksopenswaphookcfg/main.py:91 msgid "No root mount point is given for
{!s}
to use." -msgstr "No root mount point is given for
{!s}
to use." +msgstr "" #: src/modules/grubcfg/main.py:28 msgid "Configure GRUB." -msgstr "Configure GRUB." +msgstr "" #: src/modules/bootloader/main.py:43 msgid "Install bootloader." -msgstr "Install bootloader." - -#: src/modules/bootloader/main.py:508 -msgid "Bootloader installation error" -msgstr "Bootloader installation error" - -#: src/modules/bootloader/main.py:509 -msgid "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." msgstr "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." + +#: src/modules/bootloader/main.py:612 +msgid "Failed to install grub, no partitions defined in global storage" +msgstr "" + +#: src/modules/bootloader/main.py:780 +msgid "Bootloader installation error" +msgstr "" + +#: src/modules/bootloader/main.py:781 +msgid "" +"The bootloader could not be installed. The installation command
{!s} returned error code {!s}."
+msgstr ""
 
 #: src/modules/fstab/main.py:29
 msgid "Writing fstab."
-msgstr "Writing fstab."
+msgstr ""
 
-#: src/modules/fstab/main.py:389
+#: src/modules/fstab/main.py:394
 msgid "No 
{!s}
configuration is given for
{!s}
to use." -msgstr "No
{!s}
configuration is given for
{!s}
to use." +msgstr "" #: src/modules/dracut/main.py:27 msgid "Creating initramfs with dracut." -msgstr "Creating initramfs with dracut." +msgstr "" #: src/modules/dracut/main.py:49 msgid "Failed to run dracut on the target" -msgstr "Failed to run dracut on the target" +msgstr "" #: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50 msgid "The exit code was {}" -msgstr "The exit code was {}" +msgstr "" -#: src/modules/displaymanager/main.py:526 +#: src/modules/displaymanager/main.py:524 msgid "Cannot write KDM configuration file" -msgstr "Cannot write KDM configuration file" +msgstr "" -#: src/modules/displaymanager/main.py:527 +#: src/modules/displaymanager/main.py:525 msgid "KDM config file {!s} does not exist" -msgstr "KDM config file {!s} does not exist" +msgstr "" -#: src/modules/displaymanager/main.py:588 +#: src/modules/displaymanager/main.py:586 msgid "Cannot write LXDM configuration file" -msgstr "Cannot write LXDM configuration file" +msgstr "" -#: src/modules/displaymanager/main.py:589 +#: src/modules/displaymanager/main.py:587 msgid "LXDM config file {!s} does not exist" -msgstr "LXDM config file {!s} does not exist" +msgstr "" -#: src/modules/displaymanager/main.py:672 +#: src/modules/displaymanager/main.py:670 msgid "Cannot write LightDM configuration file" -msgstr "Cannot write LightDM configuration file" +msgstr "" -#: src/modules/displaymanager/main.py:673 +#: src/modules/displaymanager/main.py:671 msgid "LightDM config file {!s} does not exist" -msgstr "LightDM config file {!s} does not exist" +msgstr "" -#: src/modules/displaymanager/main.py:747 +#: src/modules/displaymanager/main.py:745 msgid "Cannot configure LightDM" -msgstr "Cannot configure LightDM" +msgstr "" -#: src/modules/displaymanager/main.py:748 +#: src/modules/displaymanager/main.py:746 msgid "No LightDM greeter installed." -msgstr "No LightDM greeter installed." +msgstr "" -#: src/modules/displaymanager/main.py:779 +#: src/modules/displaymanager/main.py:777 msgid "Cannot write SLIM configuration file" -msgstr "Cannot write SLIM configuration file" +msgstr "" -#: src/modules/displaymanager/main.py:780 +#: src/modules/displaymanager/main.py:778 msgid "SLIM config file {!s} does not exist" -msgstr "SLIM config file {!s} does not exist" +msgstr "" -#: src/modules/displaymanager/main.py:906 +#: src/modules/displaymanager/main.py:991 msgid "No display managers selected for the displaymanager module." -msgstr "No display managers selected for the displaymanager module." +msgstr "" -#: src/modules/displaymanager/main.py:907 +#: src/modules/displaymanager/main.py:992 msgid "" "The displaymanagers list is empty or undefined in both globalstorage and " "displaymanager.conf." msgstr "" -"The displaymanagers list is empty or undefined in both globalstorage and " -"displaymanager.conf." -#: src/modules/displaymanager/main.py:989 +#: src/modules/displaymanager/main.py:1074 msgid "Display manager configuration was incomplete" -msgstr "Display manager configuration was incomplete" +msgstr "" #: src/modules/services-openrc/main.py:29 msgid "Configure OpenRC services" -msgstr "Configure OpenRC services" +msgstr "" #: src/modules/services-openrc/main.py:57 msgid "Cannot add service {name!s} to run-level {level!s}." -msgstr "Cannot add service {name!s} to run-level {level!s}." +msgstr "" #: src/modules/services-openrc/main.py:59 msgid "Cannot remove service {name!s} from run-level {level!s}." -msgstr "Cannot remove service {name!s} from run-level {level!s}." +msgstr "" #: src/modules/services-openrc/main.py:61 msgid "" "Unknown service-action {arg!s} for service {name!s} in run-" "level {level!s}." msgstr "" -"Unknown service-action {arg!s} for service {name!s} in run-" -"level {level!s}." #: src/modules/services-openrc/main.py:93 #: src/modules/services-systemd/main.py:59 msgid "Cannot modify service" -msgstr "Cannot modify service" +msgstr "" #: src/modules/services-openrc/main.py:94 msgid "" "rc-update {arg!s} call in chroot returned error code {num!s}." msgstr "" -"rc-update {arg!s} call in chroot returned error code {num!s}." #: src/modules/services-openrc/main.py:101 msgid "Target runlevel does not exist" -msgstr "Target runlevel does not exist" +msgstr "" #: src/modules/services-openrc/main.py:102 msgid "" "The path for runlevel {level!s} is {path!s}, which does not " "exist." msgstr "" -"The path for runlevel {level!s} is {path!s}, which does not " -"exist." #: src/modules/services-openrc/main.py:110 msgid "Target service does not exist" -msgstr "Target service does not exist" +msgstr "" #: src/modules/services-openrc/main.py:111 msgid "" -"The path for service {name!s} is {path!s}, which does not " -"exist." +"The path for service {name!s} is {path!s}, which does not exist." msgstr "" -"The path for service {name!s} is {path!s}, which does not " -"exist." #: src/modules/networkcfg/main.py:29 msgid "Saving network configuration." -msgstr "Saving network configuration." +msgstr "" -#: src/modules/packages/main.py:50 src/modules/packages/main.py:59 -#: src/modules/packages/main.py:69 +#: src/modules/packages/main.py:54 src/modules/packages/main.py:65 +#: src/modules/packages/main.py:75 msgid "Install packages." -msgstr "Install packages." +msgstr "" -#: src/modules/packages/main.py:57 +#: src/modules/packages/main.py:63 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "Processing packages (%(count)d / %(total)d)" +msgstr "" -#: src/modules/packages/main.py:62 +#: src/modules/packages/main.py:68 #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "Installing one package." -msgstr[1] "Installing %(num)d packages." +msgstr[0] "" +msgstr[1] "" -#: src/modules/packages/main.py:65 +#: src/modules/packages/main.py:71 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "Removing one package." -msgstr[1] "Removing %(num)d packages." +msgstr[0] "" +msgstr[1] "" -#: src/modules/packages/main.py:638 src/modules/packages/main.py:650 -#: src/modules/packages/main.py:678 +#: src/modules/packages/main.py:725 src/modules/packages/main.py:737 +#: src/modules/packages/main.py:765 msgid "Package Manager error" -msgstr "Package Manager error" +msgstr "" -#: src/modules/packages/main.py:639 +#: src/modules/packages/main.py:726 msgid "" "The package manager could not prepare updates. The command
{!s}
" "returned error code {!s}." msgstr "" -"The package manager could not prepare updates. The command
{!s}
" + +#: src/modules/packages/main.py:738 +msgid "" +"The package manager could not update the system. The command
{!s}
" "returned error code {!s}." - -#: src/modules/packages/main.py:651 -msgid "" -"The package manager could not update the system. The command
{!s}
" -" returned error code {!s}." msgstr "" -"The package manager could not update the system. The command
{!s}
" -" returned error code {!s}." -#: src/modules/packages/main.py:679 +#: src/modules/packages/main.py:766 msgid "" "The package manager could not make changes to the installed system. The " "command
{!s}
returned error code {!s}." msgstr "" -"The package manager could not make changes to the installed system. The " -"command
{!s}
returned error code {!s}." #: src/modules/plymouthcfg/main.py:27 msgid "Configure Plymouth theme" -msgstr "Configure Plymouth theme" +msgstr "" #: src/modules/initcpiocfg/main.py:28 msgid "Configuring mkinitcpio." -msgstr "Configuring mkinitcpio." +msgstr "" #: src/modules/localecfg/main.py:30 msgid "Configuring locales." -msgstr "Configuring locales." +msgstr "" -#: src/modules/mount/main.py:30 +#: src/modules/mount/main.py:42 msgid "Mounting partitions." -msgstr "Mounting partitions." +msgstr "" + +#: src/modules/mount/main.py:88 src/modules/mount/main.py:124 +msgid "Internal error mounting zfs datasets" +msgstr "" + +#: src/modules/mount/main.py:100 +msgid "Failed to import zpool" +msgstr "" + +#: src/modules/mount/main.py:116 +msgid "Failed to unlock zpool" +msgstr "" + +#: src/modules/mount/main.py:133 src/modules/mount/main.py:138 +msgid "Failed to set zfs mountpoint" +msgstr "" + +#: src/modules/mount/main.py:253 +msgid "zfs mounting error" +msgstr "" #: src/modules/rawfs/main.py:26 msgid "Installing data." -msgstr "Installing data." +msgstr "" #: src/modules/dummypython/main.py:35 msgid "Dummy python job." -msgstr "Dummy python job." +msgstr "" #: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 #: src/modules/dummypython/main.py:94 msgid "Dummy python step {}" -msgstr "Dummy python step {}" +msgstr "" #: src/modules/hwclock/main.py:26 msgid "Setting hardware clock." -msgstr "Setting hardware clock." - -#: src/modules/umount/main.py:31 -msgid "Unmount file systems." -msgstr "Unmount file systems." +msgstr "" #: src/modules/openrcdmcryptcfg/main.py:26 msgid "Configuring OpenRC dmcrypt service." -msgstr "Configuring OpenRC dmcrypt service." +msgstr "" #: src/modules/services-systemd/main.py:26 msgid "Configure systemd services" -msgstr "Configure systemd services" +msgstr "" #: src/modules/services-systemd/main.py:60 msgid "" "systemctl {arg!s} call in chroot returned error code {num!s}." msgstr "" -"systemctl {arg!s} call in chroot returned error code {num!s}." #: src/modules/services-systemd/main.py:63 #: src/modules/services-systemd/main.py:69 msgid "Cannot enable systemd service {name!s}." -msgstr "Cannot enable systemd service {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:65 msgid "Cannot enable systemd target {name!s}." -msgstr "Cannot enable systemd target {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:67 msgid "Cannot enable systemd timer {name!s}." -msgstr "Cannot enable systemd timer {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:71 msgid "Cannot disable systemd target {name!s}." -msgstr "Cannot disable systemd target {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:73 msgid "Cannot mask systemd unit {name!s}." -msgstr "Cannot mask systemd unit {name!s}." +msgstr "" #: src/modules/services-systemd/main.py:75 msgid "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." +"Unknown systemd commands {command!s} and {suffix!s} for unit {name!s}." msgstr "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." #: src/modules/mkinitfs/main.py:27 msgid "Creating initramfs with mkinitfs." -msgstr "Creating initramfs with mkinitfs." +msgstr "" #: src/modules/mkinitfs/main.py:49 msgid "Failed to run mkinitfs on the target" -msgstr "Failed to run mkinitfs on the target" +msgstr "" #: src/modules/unpackfs/main.py:34 msgid "Filling up filesystems." -msgstr "Filling up filesystems." +msgstr "" #: src/modules/unpackfs/main.py:254 msgid "rsync failed with error code {}." -msgstr "rsync failed with error code {}." +msgstr "" #: src/modules/unpackfs/main.py:299 msgid "Unpacking image {}/{}, file {}/{}" -msgstr "Unpacking image {}/{}, file {}/{}" +msgstr "" #: src/modules/unpackfs/main.py:314 msgid "Starting to unpack {}" -msgstr "Starting to unpack {}" +msgstr "" -#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:465 +#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:467 msgid "Failed to unpack image \"{}\"" -msgstr "Failed to unpack image \"{}\"" +msgstr "" #: src/modules/unpackfs/main.py:430 msgid "No mount point for root partition" -msgstr "No mount point for root partition" +msgstr "" #: src/modules/unpackfs/main.py:431 -msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" -msgstr "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" +msgid "globalstorage does not contain a \"rootMountPoint\" key." +msgstr "" -#: src/modules/unpackfs/main.py:436 +#: src/modules/unpackfs/main.py:434 msgid "Bad mount point for root partition" -msgstr "Bad mount point for root partition" +msgstr "" -#: src/modules/unpackfs/main.py:437 -msgid "rootMountPoint is \"{}\", which does not exist, doing nothing" -msgstr "rootMountPoint is \"{}\", which does not exist, doing nothing" +#: src/modules/unpackfs/main.py:435 +msgid "rootMountPoint is \"{}\", which does not exist." +msgstr "" -#: src/modules/unpackfs/main.py:453 src/modules/unpackfs/main.py:457 -#: src/modules/unpackfs/main.py:463 src/modules/unpackfs/main.py:478 -msgid "Bad unsquash configuration" -msgstr "Bad unsquash configuration" +#: src/modules/unpackfs/main.py:439 src/modules/unpackfs/main.py:455 +#: src/modules/unpackfs/main.py:459 src/modules/unpackfs/main.py:465 +#: src/modules/unpackfs/main.py:480 +msgid "Bad unpackfs configuration" +msgstr "" -#: src/modules/unpackfs/main.py:454 +#: src/modules/unpackfs/main.py:440 +msgid "There is no configuration information." +msgstr "" + +#: src/modules/unpackfs/main.py:456 msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel" -msgstr "The filesystem for \"{}\" ({}) is not supported by your current kernel" +msgstr "" -#: src/modules/unpackfs/main.py:458 +#: src/modules/unpackfs/main.py:460 msgid "The source filesystem \"{}\" does not exist" -msgstr "The source filesystem \"{}\" does not exist" +msgstr "" -#: src/modules/unpackfs/main.py:464 +#: src/modules/unpackfs/main.py:466 msgid "" "Failed to find unsquashfs, make sure you have the squashfs-tools package " "installed." msgstr "" -"Failed to find unsquashfs, make sure you have the squashfs-tools package " -"installed." -#: src/modules/unpackfs/main.py:479 +#: src/modules/unpackfs/main.py:481 msgid "The destination \"{}\" in the target system is not a directory" -msgstr "The destination \"{}\" in the target system is not a directory" - -#: src/modules/luksopenswaphookcfg/main.py:26 -msgid "Configuring encrypted swap." -msgstr "Configuring encrypted swap." +msgstr ""