From e27c57f8a66459c132b70236ec3053f5cd3b6a3a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 Jun 2022 14:58:11 +0200 Subject: [PATCH 01/89] [partition] Add FS-choice box when replacing (re-use the erase-fs configuration) --- src/modules/partition/gui/ChoicePage.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 2730e069f..59e2c1122 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -288,6 +288,13 @@ ChoicePage::setupChoices() m_eraseFsTypesChoiceComboBox, &QComboBox::currentTextChanged, m_config, &Config::setEraseFsTypeChoice ); connect( m_config, &Config::eraseModeFilesystemChanged, this, &ChoicePage::onActionChanged ); m_eraseButton->addOptionsComboBox( m_eraseFsTypesChoiceComboBox ); + + // Also offer it for "replace + auto* box = new QComboBox; + box->addItems( m_config->eraseFsTypes() ); + connect( box, &QComboBox::currentTextChanged, m_config, &Config : setReplaceFsChoice ); + connect( m_config, &Config::replaceModeFilesystemChanged, this, &ChoicePage::onActionChanged ); + m_replaceButton->addOptionsComboBox( box ); } m_itemsLayout->addWidget( m_alongsideButton ); From b763087e114195efdaf6b15df4121cf0bd953ba1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 Jun 2022 14:58:28 +0200 Subject: [PATCH 02/89] [partition] Partial implementation of Config-side for storing replace-FS --- src/modules/partition/Config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index 2ac44b424..1de3174b9 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -31,6 +31,8 @@ class Config : public QObject Q_PROPERTY( QString eraseModeFilesystem READ eraseFsType WRITE setEraseFsTypeChoice NOTIFY eraseModeFilesystemChanged ) + Q_PROPERTY( QString replaceModeFilesystem READ replaceModeFilesystem WRITE setReplaceFilesystem NOTIFY replaceModeFilesystemChanged ) + Q_PROPERTY( bool allowManualPartitioning READ allowManualPartitioning CONSTANT FINAL ) public: @@ -146,11 +148,13 @@ public Q_SLOTS: void setSwapChoice( int ); ///< Translates a button ID or so to SwapChoice void setSwapChoice( SwapChoice ); void setEraseFsTypeChoice( const QString& filesystemName ); ///< See property eraseModeFilesystem + void setReplaceFilesystemChoice( const QString& filesystemName ); Q_SIGNALS: void installChoiceChanged( InstallChoice ); void swapChoiceChanged( SwapChoice ); void eraseModeFilesystemChanged( const QString& ); + void replaceModeFilesystemChanged( const QString& ); private: /** @brief Handle FS-type configuration, for erase and default */ From 3b55b65a349e81f493965b41929893775729e79b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 Jun 2022 18:29:35 +0200 Subject: [PATCH 03/89] [partition] Implement config-side of a replace-filesystem choice --- src/modules/partition/Config.cpp | 13 ++++++++++++- src/modules/partition/Config.h | 7 ++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 367c4ee38..278503312 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -213,7 +213,7 @@ Config::setSwapChoice( Config::SwapChoice c ) void Config::setEraseFsTypeChoice( const QString& choice ) { - QString canonicalChoice = PartUtils::canonicalFilesystemName( choice, nullptr ); + const QString canonicalChoice = PartUtils::canonicalFilesystemName( choice, nullptr ); if ( canonicalChoice != m_eraseFsTypeChoice ) { m_eraseFsTypeChoice = canonicalChoice; @@ -221,6 +221,17 @@ Config::setEraseFsTypeChoice( const QString& choice ) } } +void +Config::setReplaceFilesystemChoice( const QString& filesystemName ) +{ + const QString canonicalChoice = PartUtils::canonicalFilesystemName( filesystemName, nullptr ); + if ( canonicalChoice != m_replaceFileSystemChoice ) + { + m_replaceFileSystemChoice = canonicalChoice; + Q_EMIT replaceModeFilesystemChanged( canonicalChoice ); + } +} + bool Config::acceptPartitionTableType( PartitionTable::TableType tableType ) const { diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index 1de3174b9..b82716fc2 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -31,7 +31,8 @@ class Config : public QObject Q_PROPERTY( QString eraseModeFilesystem READ eraseFsType WRITE setEraseFsTypeChoice NOTIFY eraseModeFilesystemChanged ) - Q_PROPERTY( QString replaceModeFilesystem READ replaceModeFilesystem WRITE setReplaceFilesystem NOTIFY replaceModeFilesystemChanged ) + Q_PROPERTY( QString replaceModeFilesystem READ replaceModeFilesystem WRITE setReplaceFilesystemChoice NOTIFY + replaceModeFilesystemChanged ) Q_PROPERTY( bool allowManualPartitioning READ allowManualPartitioning CONSTANT FINAL ) @@ -124,6 +125,9 @@ public: */ QString eraseFsType() const { return m_eraseFsTypeChoice; } + /// @brief Currently-selected FS type for *replace* mode + QString replaceModeFilesystem() const { return m_replaceFileSystemChoice; } + /** @brief Configured default FS type (for other modes than erase) * * This is not "Unknown" or "Unformatted" @@ -161,6 +165,7 @@ private: void fillConfigurationFSTypes( const QVariantMap& configurationMap ); EraseFsTypesSet m_eraseFsTypes; QString m_eraseFsTypeChoice; + QString m_replaceFileSystemChoice; FileSystem::Type m_defaultFsType; SwapChoiceSet m_swapChoices; From 425901fb98782cee340ec8e6145c9b721d79c5c5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 Jun 2022 18:32:54 +0200 Subject: [PATCH 04/89] [partition] Fix up combo-box handling for replace-fs choice --- src/modules/partition/gui/ChoicePage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 59e2c1122..2e2acd460 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -292,7 +292,7 @@ ChoicePage::setupChoices() // Also offer it for "replace auto* box = new QComboBox; box->addItems( m_config->eraseFsTypes() ); - connect( box, &QComboBox::currentTextChanged, m_config, &Config : setReplaceFsChoice ); + connect( box, &QComboBox::currentTextChanged, m_config, &Config::setReplaceFilesystemChoice ); connect( m_config, &Config::replaceModeFilesystemChanged, this, &ChoicePage::onActionChanged ); m_replaceButton->addOptionsComboBox( box ); } From 916b87e62e271067a1a1ac31461e6c75361cd331 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 Jun 2022 18:36:26 +0200 Subject: [PATCH 05/89] [partition] (unrelated) remove compatibility code for older Qt --- src/modules/partition/gui/ChoicePage.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 2e2acd460..b2a009fb1 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -310,13 +310,8 @@ ChoicePage::setupChoices() m_itemsLayout->addStretch(); -#if ( QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 ) ) - auto buttonSignal = QOverload< int, bool >::of( &QButtonGroup::buttonToggled ); -#else - auto buttonSignal = &QButtonGroup::idToggled; -#endif connect( m_grp, - buttonSignal, + &QButtonGroup::idToggled, this, [ this ]( int id, bool checked ) { From c9be4c744fa20836768f2f9da403c251648719dd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 3 Jun 2022 10:44:39 +0200 Subject: [PATCH 06/89] [partition] Use the chosen replace-filesystem type --- src/modules/partition/gui/ChoicePage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index b2a009fb1..53dd24b60 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -871,7 +871,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) selectedDevice(), selectedPartition, { gs->value( "defaultPartitionType" ).toString(), - gs->value( "defaultFileSystemType" ).toString(), + m_config->replaceModeFilesystem(), m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); From ddf65a2437637ebeb31d4d51923b30844aa4bf36 Mon Sep 17 00:00:00 2001 From: Jeremy Attali Date: Tue, 6 Sep 2022 15:57:35 -0400 Subject: [PATCH 07/89] [partition] Apply format This part was not formated properly. Fixed using clang-format --- src/modules/partition/gui/ChoicePage.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index c5e44aaec..a3ce5d7b8 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1731,10 +1731,11 @@ ChoicePage::createBootloaderPanel() return panelWidget; } -bool ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const +bool +ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const { // If there are any choices for FS, check it's not ZFS because that doesn't // support the kind of encryption we enable here. const bool suitableFS = m_eraseFsTypesChoiceComboBox ? m_eraseFsTypesChoiceComboBox->currentText() != "zfs" : true; - return (choice == InstallChoice::Erase) && m_enableEncryptionWidget && suitableFS; + return ( choice == InstallChoice::Erase ) && m_enableEncryptionWidget && suitableFS; } From 9def0cb66f1586f9aac5c8735b53a5894d15268b Mon Sep 17 00:00:00 2001 From: Jeremy Attali Date: Wed, 25 May 2022 19:27:07 +0000 Subject: [PATCH 08/89] [partition] Add support for LUKS2 This commit adds support for LUKS2 behind a new `partition.conf` key: `luksGeneration`. A bit of context, LUKS2 is the default encryption operating mode since cryptsetup >= 2.1.0 (See [Arch wiki](https://wiki.archlinux.org/title/dm-crypt/Device_encryption#Encryption_options_with_dm-crypt). It is considered more secured and allows additional extensions. It also comes with Argon2id as the default Password Based Key Derivation Function (`--pbkdf` option). So it's important to provide this as an option for Calamares in order to make Linux installs more secure, for those who wish to encrypt their system. This commit was tested on a custom Manjaro installer with: - grub bootloader with the [argon patches](https://aur.archlinux.org/packages/grub-improved-luks2-git). - [rEFInd](https://wiki.archlinux.org/title/REFInd) bootloader with unencrypted `/boot` partition because rEFInd [doesn't support booting from an encrypted volume](https://sourceforge.net/p/refind/discussion/general/thread/400418ac/) **Important consideration for distribution maintainers**: - You need to have compile flag `WITH_KPMCORE4API` on - If you are shipping with grub by default please note that you need to ship it with the Argon patches. Example on Arch Linux: [grub-improved-luks2-git](https://aur.archlinux.org/packages/grub-improved-luks2-git) - If `luksGeneration` is not found in partition.conf, it will default to luks1 - Please test this on your own distribution as this was only tested on Manjaro installer (see above). --- src/libcalamares/partition/FileSystem.cpp | 1 + src/modules/partition/Config.cpp | 39 ++++++++++++++++++- src/modules/partition/Config.h | 20 ++++++++++ src/modules/partition/PartitionViewStep.cpp | 4 +- src/modules/partition/core/ColorUtils.cpp | 4 +- src/modules/partition/core/KPMHelpers.cpp | 5 ++- src/modules/partition/core/KPMHelpers.h | 1 + .../partition/core/PartitionActions.cpp | 5 ++- src/modules/partition/core/PartitionActions.h | 14 +++++-- .../partition/core/PartitionCoreModule.cpp | 18 +++++++-- .../partition/core/PartitionCoreModule.h | 3 +- .../partition/core/PartitionLayout.cpp | 2 + src/modules/partition/core/PartitionLayout.h | 1 + src/modules/partition/gui/ChoicePage.cpp | 4 ++ .../partition/gui/CreatePartitionDialog.cpp | 22 ++++++++++- src/modules/partition/gui/ReplaceWidget.cpp | 1 + .../partition/jobs/FillGlobalStorageJob.cpp | 10 +++++ src/modules/partition/partition.conf | 14 +++++++ src/modules/partition/partition.schema.yaml | 2 + .../partition/tests/CreateLayoutsTests.cpp | 12 +++--- 20 files changed, 158 insertions(+), 24 deletions(-) diff --git a/src/libcalamares/partition/FileSystem.cpp b/src/libcalamares/partition/FileSystem.cpp index 0dcd6fd32..c6bfc5aba 100644 --- a/src/libcalamares/partition/FileSystem.cpp +++ b/src/libcalamares/partition/FileSystem.cpp @@ -46,6 +46,7 @@ prettyNameForFileSystemType( FileSystem::Type t ) case FileSystem::Ufs: case FileSystem::Hpfs: case FileSystem::Luks: + case FileSystem::Luks2: case FileSystem::Ocfs2: case FileSystem::Zfs: case FileSystem::Nilfs2: diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 367c4ee38..d1a53cfc4 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -46,6 +46,32 @@ Config::swapChoiceNames() return names; } +const NamedEnumTable< Config::LuksGeneration >& +Config::luksGenerationNames() +{ + static const NamedEnumTable< LuksGeneration > names { { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, + { QStringLiteral( "luks2" ), LuksGeneration::Luks2 } }; + + return names; +} + +const QString +Config::luksGenerationToFSName( Config::LuksGeneration luksGeneration ) +{ + // Convert luksGenerationChoice from partition.conf into its + // corresponding file system type from KPMCore. + switch ( luksGeneration ) + { + case Config::LuksGeneration::Luks2: + return QStringLiteral( "luks2" ); + case Config::LuksGeneration::Luks1: + return QStringLiteral( "luks" ); + default: + cWarning() << "luksGeneration not supported, defaulting to \"luks\""; + return QStringLiteral( "luks" ); + } +} + Config::SwapChoice pickOne( const Config::SwapChoiceSet& s ) { @@ -323,13 +349,24 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) } } + // Set LUKS file system based on luksGeneration provided, defaults to 'luks'. + bool nameFound = false; + Config::LuksGeneration luksGeneration + = luksGenerationNames().find( CalamaresUtils::getString( configurationMap, "luksGeneration" ), nameFound ); + if ( !nameFound ) + { + cWarning() << "Partition-module setting *luksGeneration* not found or invalid. Defaulting to luks1."; + luksGeneration = Config::LuksGeneration::Luks1; + } + m_luksFileSystemType = Config::luksGenerationToFSName( luksGeneration ); + gs->insert( "luksFileSystemType", m_luksFileSystemType ); + Q_ASSERT( !m_eraseFsTypes.isEmpty() ); Q_ASSERT( m_eraseFsTypes.contains( fsRealName ) ); m_eraseFsTypeChoice = fsRealName; Q_EMIT eraseModeFilesystemChanged( m_eraseFsTypeChoice ); } - void Config::setConfigurationMap( const QVariantMap& configurationMap ) { diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index 2ac44b424..c6b344d0d 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -63,6 +63,16 @@ public: using EraseFsTypesSet = QStringList; + /** @brief Choice of LUKS disk encryption generation */ + enum LuksGeneration + { + Luks1, // First generation of LUKS + Luks2, // Second generation of LUKS, default since cryptsetup >= 2.1.0 + }; + Q_ENUM( LuksGeneration ) + static const NamedEnumTable< LuksGeneration >& luksGenerationNames(); + static const QString luksGenerationToFSName( LuksGeneration choice ); + void setConfigurationMap( const QVariantMap& ); /** @brief Set GS values where other modules configuration has priority * @@ -112,6 +122,15 @@ public: */ SwapChoice swapChoice() const { return m_swapChoice; } + /** @brief The conversion of the luksGeneration into its FS type. + * + * Will convert Luks1 into "luks" and Luks2 into "luks2" for KPMCore + * partitionning functions. + * + * @return The LUKS FS type (default @c "luks" ) + */ + QString luksFileSystemType() const { return m_luksFileSystemType; } + /** @brief Get the list of configured FS types to use with *erase* mode * * This list is not empty. @@ -162,6 +181,7 @@ private: SwapChoiceSet m_swapChoices; SwapChoice m_initialSwapChoice = NoSwap; SwapChoice m_swapChoice = NoSwap; + QString m_luksFileSystemType; InstallChoice m_initialInstallChoice = NoChoice; InstallChoice m_installChoice = NoChoice; qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module diff --git a/src/modules/partition/PartitionViewStep.cpp b/src/modules/partition/PartitionViewStep.cpp index fe77bee3a..51294c8bc 100644 --- a/src/modules/partition/PartitionViewStep.cpp +++ b/src/modules/partition/PartitionViewStep.cpp @@ -616,7 +616,9 @@ PartitionViewStep::onLeave() // If the root partition is encrypted, and there's a separate boot // partition which is not encrypted - if ( root_p->fileSystem().type() == FileSystem::Luks && boot_p->fileSystem().type() != FileSystem::Luks ) + if ( ( root_p->fileSystem().type() == FileSystem::Luks && boot_p->fileSystem().type() != FileSystem::Luks ) + || ( root_p->fileSystem().type() == FileSystem::Luks2 + && boot_p->fileSystem().type() != FileSystem::Luks2 ) ) { message = tr( "Boot partition not encrypted" ); description = tr( "A separate boot partition was set up together with " diff --git a/src/modules/partition/core/ColorUtils.cpp b/src/modules/partition/core/ColorUtils.cpp index fb613e240..5368c2f86 100644 --- a/src/modules/partition/core/ColorUtils.cpp +++ b/src/modules/partition/core/ColorUtils.cpp @@ -98,7 +98,7 @@ colorForPartition( Partition* partition ) if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && !partition->fileSystem().uuid().isEmpty() ) { - if ( partition->fileSystem().type() == FileSystem::Luks ) + if ( partition->fileSystem().type() == FileSystem::Luks || partition->fileSystem().type() == FileSystem::Luks2 ) { FS::luks& luksFs = dynamic_cast< FS::luks& >( partition->fileSystem() ); if ( !luksFs.outerUuid().isEmpty() && s_partitionColorsCache.contains( luksFs.outerUuid() ) ) @@ -146,7 +146,7 @@ colorForPartition( Partition* partition ) if ( partition->fileSystem().supportGetUUID() != FileSystem::cmdSupportNone && !partition->fileSystem().uuid().isEmpty() ) { - if ( partition->fileSystem().type() == FileSystem::Luks ) + if ( partition->fileSystem().type() == FileSystem::Luks || partition->fileSystem().type() == FileSystem::Luks2 ) { FS::luks& luksFs = dynamic_cast< FS::luks& >( partition->fileSystem() ); if ( !luksFs.outerUuid().isEmpty() ) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index 102d803cb..eba4a41b6 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -84,6 +84,7 @@ createNewEncryptedPartition( PartitionNode* parent, const QString& fsLabel, qint64 firstSector, qint64 lastSector, + const QString& luksFsType, // "luks" or "luks2" const QString& passphrase, PartitionTable::Flags flags ) { @@ -93,8 +94,10 @@ createNewEncryptedPartition( PartitionNode* parent, newRoles |= PartitionRole::Luks; } + FileSystem::Type luksType = FileSystem::typeForName( luksFsType ); + FS::luks* fs = dynamic_cast< FS::luks* >( - FileSystemFactory::create( FileSystem::Luks, firstSector, lastSector, device.logicalSize() ) ); + FileSystemFactory::create( luksType, firstSector, lastSector, device.logicalSize() ) ); if ( !fs ) { cError() << "cannot create LUKS filesystem. Giving up."; diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index 2b2da6b14..7e3316cd6 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -83,6 +83,7 @@ Partition* createNewEncryptedPartition( PartitionNode* parent, const QString& fsLabel, qint64 firstSector, qint64 lastSector, + const QString& luksFsType, const QString& passphrase, PartitionTable::Flags flags ); diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 0ceff4324..80f86427c 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -169,7 +169,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO lastSectorForRoot -= suggestedSwapSizeB / sectorSize + 1; } - core->layoutApply( dev, firstFreeSector, lastSectorForRoot, o.luksPassphrase ); + core->layoutApply( dev, firstFreeSector, lastSectorForRoot, o.luksFsType, o.luksPassphrase ); if ( shouldCreateSwap ) { @@ -194,6 +194,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO QStringLiteral( "swap" ), lastSectorForRoot + 1, dev->totalLogical() - 1, + o.luksFsType, o.luksPassphrase, KPM_PARTITION_FLAG( None ) ); } @@ -244,7 +245,7 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition core->deletePartition( dev, partition ); } - core->layoutApply( dev, firstSector, lastSector, o.luksPassphrase ); + core->layoutApply( dev, firstSector, lastSector, o.luksFsType, o.luksPassphrase ); core->dumpQueue(); } diff --git a/src/modules/partition/core/PartitionActions.h b/src/modules/partition/core/PartitionActions.h index d6b86a6cd..d8663c754 100644 --- a/src/modules/partition/core/PartitionActions.h +++ b/src/modules/partition/core/PartitionActions.h @@ -31,12 +31,17 @@ struct ReplacePartitionOptions { QString defaultPartitionTableType; // e.g. "gpt" or "msdos" QString defaultFsType; // e.g. "ext4" or "btrfs" + QString luksFsType; // optional ("luks", "luks2") QString luksPassphrase; // optional - ReplacePartitionOptions( const QString& pt, const QString& fs, const QString& luks ) + ReplacePartitionOptions( const QString& pt, + const QString& fs, + const QString& luksFs, + const QString& luksPassphrase ) : defaultPartitionTableType( pt ) , defaultFsType( fs ) - , luksPassphrase( luks ) + , luksFsType( luksFs ) + , luksPassphrase( luksPassphrase ) { } }; @@ -49,11 +54,12 @@ struct AutoPartitionOptions : ReplacePartitionOptions AutoPartitionOptions( const QString& pt, const QString& fs, - const QString& luks, + const QString& luksFs, + const QString& luksPassphrase, const QString& efi, qint64 requiredBytes, Config::SwapChoice s ) - : ReplacePartitionOptions( pt, fs, luks ) + : ReplacePartitionOptions( pt, fs, luksFs, luksPassphrase ) , efiPartitionMountPoint( efi ) , requiredSpaceB( requiredBytes > 0 ? quint64( requiredBytes ) : 0U ) , swap( s ) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 78af2abf7..56d4353e8 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -952,13 +952,14 @@ void PartitionCoreModule::layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, + QString luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ) { bool isEfi = PartUtils::isEfiSystem(); QList< Partition* > partList - = m_partLayout.createPartitions( dev, firstSector, lastSector, luksPassphrase, parent, role ); + = m_partLayout.createPartitions( dev, firstSector, lastSector, luksFsType, luksPassphrase, parent, role ); // Partition::mountPoint() tells us where it is mounted **now**, while // PartitionInfo::mountPoint() says where it will be mounted in the target system. @@ -999,10 +1000,19 @@ PartitionCoreModule::layoutApply( Device* dev, } void -PartitionCoreModule::layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, QString luksPassphrase ) +PartitionCoreModule::layoutApply( Device* dev, + qint64 firstSector, + qint64 lastSector, + QString luksFsType, + QString luksPassphrase ) { - layoutApply( - dev, firstSector, lastSector, luksPassphrase, dev->partitionTable(), PartitionRole( PartitionRole::Primary ) ); + layoutApply( dev, + firstSector, + lastSector, + luksFsType, + luksPassphrase, + dev->partitionTable(), + PartitionRole( PartitionRole::Primary ) ); } void diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 1ed46fdad..2cc46d1c0 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -166,10 +166,11 @@ public: */ PartitionLayout& partitionLayout() { return m_partLayout; } - void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, QString luksPassphrase ); + void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, QString luksFsType, QString luksPassphrase ); void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, + QString luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ); diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index a8aae61ff..3ff67de7a 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -204,6 +204,7 @@ QList< Partition* > PartitionLayout::createPartitions( Device* dev, qint64 firstSector, qint64 lastSector, + QString luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ) @@ -317,6 +318,7 @@ PartitionLayout::createPartitions( Device* dev, entry.partLabel, currentSector, currentSector + sectors - 1, + luksFsType, luksPassphrase, KPM_PARTITION_FLAG( None ) ); } diff --git a/src/modules/partition/core/PartitionLayout.h b/src/modules/partition/core/PartitionLayout.h index c4c26d9f1..2af696b9f 100644 --- a/src/modules/partition/core/PartitionLayout.h +++ b/src/modules/partition/core/PartitionLayout.h @@ -116,6 +116,7 @@ public: QList< Partition* > createPartitions( Device* dev, qint64 firstSector, qint64 lastSector, + QString luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ); diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index a3ce5d7b8..a6c2831af 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -496,6 +496,7 @@ ChoicePage::applyActionChoice( InstallChoice choice ) auto gs = Calamares::JobQueue::instance()->globalStorage(); PartitionActions::Choices::AutoPartitionOptions options { gs->value( "defaultPartitionTableType" ).toString(), m_config->eraseFsType(), + gs->value( "luksFileSystemType" ).toString(), m_encryptWidget->passphrase(), gs->value( "efiSystemPartition" ).toString(), CalamaresUtils::GiBtoBytes( @@ -752,6 +753,7 @@ ChoicePage::doAlongsideApply() m_core->layoutApply( dev, newLastSector + 2, oldLastSector, + m_config->luksFileSystemType(), m_encryptWidget->passphrase(), candidate->parent(), candidate->roles() ); @@ -826,6 +828,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) m_core->layoutApply( selectedDevice(), selectedPartition->firstSector(), selectedPartition->lastSector(), + m_config->luksFileSystemType(), m_encryptWidget->passphrase(), newParent, newRoles ); @@ -858,6 +861,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) selectedPartition, { gs->value( "defaultPartitionType" ).toString(), gs->value( "defaultFileSystemType" ).toString(), + gs->value( "luksFileSystemType" ).toString(), m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index c5b17c69e..067da2c1d 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -223,6 +224,8 @@ CreatePartitionDialog::initGptPartitionTypeUi() Partition* CreatePartitionDialog::getNewlyCreatedPartition() { + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + if ( m_role.roles() == PartitionRole::None ) { m_role = PartitionRole( m_ui->extendedRadioButton->isChecked() ? PartitionRole::Extended @@ -242,12 +245,21 @@ CreatePartitionDialog::getNewlyCreatedPartition() // newFlags() and the consumer (see PartitionPage::onCreateClicked) // does so, to set up the partition for create-and-then-set-flags. Partition* partition = nullptr; + QString luksFsType = gs->value( "luksFileSystemType" ).toString(); QString luksPassphrase = m_ui->encryptWidget->passphrase(); if ( m_ui->encryptWidget->state() == EncryptWidget::Encryption::Confirmed && !luksPassphrase.isEmpty() && fsType != FileSystem::Zfs ) { - partition = KPMHelpers::createNewEncryptedPartition( - m_parent, *m_device, m_role, fsType, fsLabel, first, last, luksPassphrase, PartitionTable::Flags() ); + partition = KPMHelpers::createNewEncryptedPartition( m_parent, + *m_device, + m_role, + fsType, + fsLabel, + first, + last, + luksFsType, + luksPassphrase, + PartitionTable::Flags() ); } else { @@ -308,6 +320,12 @@ CreatePartitionDialog::updateMountPointUi() m_ui->encryptWidget->show(); m_ui->encryptWidget->reset(); } + else if ( FileSystemFactory::map()[ FileSystem::Type::Luks2 ]->supportCreate() + && FS::luks2::canEncryptType( type ) && !m_role.has( PartitionRole::Extended ) ) + { + m_ui->encryptWidget->show(); + m_ui->encryptWidget->reset(); + } else { m_ui->encryptWidget->reset(); diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 76f9ff963..ec20921a3 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -90,6 +90,7 @@ ReplaceWidget::applyChanges() partition, { gs->value( "defaultPartitionTableType" ).toString(), gs->value( "defaultFileSystemType" ).toString(), + gs->value( "luksFileSystemType" ).toString(), QString() } ); if ( m_isEfi ) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index d734485f0..eb1c027cb 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -26,6 +26,9 @@ #include #include #include +#ifdef WITH_KPMCORE42API +#include +#endif #include #include @@ -96,6 +99,13 @@ mapForPartition( Partition* partition, const QString& uuid ) { map[ "fs" ] = untranslatedFS( dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ); } +#ifdef WITH_KPMCORE42API + if ( partition->fileSystem().type() == FileSystem::Luks2 + && dynamic_cast< FS::luks2& >( partition->fileSystem() ).innerFS() ) + { + map[ "fs" ] = untranslatedFS( dynamic_cast< FS::luks2& >( partition->fileSystem() ).innerFS() ); + } +#endif map[ "uuid" ] = uuid; map[ "claimed" ] = PartitionInfo::format( partition ); // If we formatted it, it's ours diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index d1c5ba255..9973df8e8 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -64,6 +64,20 @@ userSwapChoices: # ensureSuspendToDisk: true # neverCreateSwap: false +# This setting specifies the LUKS generation (i.e LUKS1, LUKS2) used internally by +# cryptsetup when creating an encrypted partition. +# +# This option is set to luks1 by default, as grub doesn't support LUKS2 + Argon2id +# currently. On the other hand grub does support LUKS2 with PBKDF2 and could therefore be +# also set to luks2. Also there are some patches for grub and Argon2. +# See: https://aur.archlinux.org/packages/grub-improved-luks2-git +# +# Choices: luks1, luks2 +# +# The default is luks1 +# +luksGeneration: luks1 + # Correctly draw nested (e.g. logical) partitions as such. drawNestedPartitions: false diff --git a/src/modules/partition/partition.schema.yaml b/src/modules/partition/partition.schema.yaml index 6c65e8ae7..5ffaa11d4 100644 --- a/src/modules/partition/partition.schema.yaml +++ b/src/modules/partition/partition.schema.yaml @@ -20,7 +20,9 @@ properties: defaultFileSystemType: { type: string } availableFileSystemTypes: { type: array, items: { type: string } } + luksGeneration: { type: string, enum: [luks1, luks2] } enableLuksAutomatedPartitioning: { type: boolean, default: false } + allowManualPartitioning: { type: boolean, default: true } partitionLayout: { type: array } # TODO: specify items initialPartitioningChoice: { type: string, enum: [ none, erase, replace, alongside, manual ] } diff --git a/src/modules/partition/tests/CreateLayoutsTests.cpp b/src/modules/partition/tests/CreateLayoutsTests.cpp index b83f71a26..124586759 100644 --- a/src/modules/partition/tests/CreateLayoutsTests.cpp +++ b/src/modules/partition/tests/CreateLayoutsTests.cpp @@ -63,8 +63,8 @@ CreateLayoutsTests::testFixedSizePartition() QFAIL( qPrintable( "Unable to create / partition" ) ); } - partitions - = layout.createPartitions( static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, role ); + partitions = layout.createPartitions( + static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 1 ); @@ -84,8 +84,8 @@ CreateLayoutsTests::testPercentSizePartition() QFAIL( qPrintable( "Unable to create / partition" ) ); } - partitions - = layout.createPartitions( static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, role ); + partitions = layout.createPartitions( + static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 1 ); @@ -115,8 +115,8 @@ CreateLayoutsTests::testMixedSizePartition() QFAIL( qPrintable( "Unable to create /bkup partition" ) ); } - partitions - = layout.createPartitions( static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, role ); + partitions = layout.createPartitions( + static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 3 ); From b00a2ede798c823cf0846d580fc7f5abe4f087c9 Mon Sep 17 00:00:00 2001 From: Johannes Kamprad Date: Sun, 18 Sep 2022 14:43:15 +0200 Subject: [PATCH 09/89] Update services-systemd.conf removing mandatory: false from example for cups-socket as it is default same as for the other two (could confuse about may disable needs to set it? ) --- src/modules/services-systemd/services-systemd.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/services-systemd/services-systemd.conf b/src/modules/services-systemd/services-systemd.conf index d84cd1349..6e7f34451 100644 --- a/src/modules/services-systemd/services-systemd.conf +++ b/src/modules/services-systemd/services-systemd.conf @@ -37,7 +37,8 @@ # # - name: "cups.socket" # action: "disable" -# mandatory: false +# # The property "mandatory" is taken to be false by default here +# # because it is not specified # # - name: "graphical" # action: "enable" From 5c87452b67ba7bfd83912e5738929e9f57ca805b Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Sat, 24 Sep 2022 13:46:44 +0200 Subject: [PATCH 10/89] fix initcpiocfg filesystems loop Signed-off-by: Peter Jung --- src/modules/initcpiocfg/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index 96258f632..fb557a479 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -169,8 +169,6 @@ def find_initcpio_features(partitions, root_mount_point): hooks.append("plymouth") for partition in partitions: - hooks.extend(["filesystems"]) - if partition["fs"] == "linuxswap" and not partition.get("claimed", None): # Skip foreign swap continue @@ -218,9 +216,11 @@ def find_initcpio_features(partitions, root_mount_point): hooks.append("zfs") if swap_uuid != "": - hooks.extend(["resume"]) if encrypt_hook and openswap_hook: hooks.extend(["openswap"]) + hooks.extend(["resume", "filesystems"]) + else: + hooks.extend(["filesystems"]) if uses_btrfs: modules.append("crc32c-intel" if cpuinfo().is_intel else "crc32c") From f2ba0929d72b1bc4c838ee5eeba0a0ba3abf1a84 Mon Sep 17 00:00:00 2001 From: shivanandvp Date: Sat, 24 Sep 2022 21:01:38 -0500 Subject: [PATCH 11/89] feat: "Noncheckable" option for netinstall package groups The "Noncheckable" option, when true prevents a user from checking the whole group. This does not affect whether any child subgroups or packages can be selected or not No breaking changes --- src/modules/netinstall/PackageModel.cpp | 2 +- src/modules/netinstall/PackageTreeItem.cpp | 3 +++ src/modules/netinstall/PackageTreeItem.h | 8 ++++++++ src/modules/netinstall/netinstall.conf | 3 +++ src/modules/netinstall/netinstall.schema.yaml | 1 + 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/modules/netinstall/PackageModel.cpp b/src/modules/netinstall/PackageModel.cpp index d5bae1c89..4e48d3d09 100644 --- a/src/modules/netinstall/PackageModel.cpp +++ b/src/modules/netinstall/PackageModel.cpp @@ -188,7 +188,7 @@ PackageModel::flags( const QModelIndex& index ) const if ( index.column() == NameColumn ) { PackageTreeItem* item = static_cast< PackageTreeItem* >( index.internalPointer() ); - if ( item->isImmutable() ) + if ( item->isImmutable() || item->isNoncheckable() ) { return QAbstractItemModel::flags( index ); //Qt::NoItemFlags; } diff --git a/src/modules/netinstall/PackageTreeItem.cpp b/src/modules/netinstall/PackageTreeItem.cpp index 5841606c4..d5b680ea0 100644 --- a/src/modules/netinstall/PackageTreeItem.cpp +++ b/src/modules/netinstall/PackageTreeItem.cpp @@ -49,6 +49,7 @@ PackageTreeItem::PackageTreeItem( const QString& packageName, PackageTreeItem* p , m_isGroup( false ) , m_isCritical( parent ? parent->isCritical() : false ) , m_showReadOnly( parent ? parent->isImmutable() : false ) + , m_showNoncheckable( false ) { } @@ -60,6 +61,7 @@ PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, PackageTag&& par , m_isGroup( false ) , m_isCritical( parent.parent ? parent.parent->isCritical() : false ) , m_showReadOnly( parent.parent ? parent.parent->isImmutable() : false ) + , m_showNoncheckable( false ) { } @@ -75,6 +77,7 @@ PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, GroupTag&& paren , m_isCritical( parentCriticality( groupData, parent.parent ) ) , m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) ) , m_showReadOnly( CalamaresUtils::getBool( groupData, "immutable", false ) ) + , m_showNoncheckable( CalamaresUtils::getBool( groupData, "noncheckable", false ) ) , m_startExpanded( CalamaresUtils::getBool( groupData, "expanded", false ) ) { } diff --git a/src/modules/netinstall/PackageTreeItem.h b/src/modules/netinstall/PackageTreeItem.h index 2a0fca83e..074bc3dc2 100644 --- a/src/modules/netinstall/PackageTreeItem.h +++ b/src/modules/netinstall/PackageTreeItem.h @@ -109,6 +109,13 @@ public: */ bool isImmutable() const { return m_showReadOnly; } + /** @brief Is this a non-checkable item? + * + * Groups can be non-checkable: then you can't toggle the selected + * state of the group. This does not affect subgroups or packages. + */ + bool isNoncheckable() const { return m_showNoncheckable; } + /** @brief is this item selected? * * Groups may be partially selected; packages are only on or off. @@ -165,6 +172,7 @@ private: bool m_isCritical = false; bool m_isHidden = false; bool m_showReadOnly = false; + bool m_showNoncheckable = false; bool m_startExpanded = false; }; diff --git a/src/modules/netinstall/netinstall.conf b/src/modules/netinstall/netinstall.conf index d38c0b040..f185fc1b0 100644 --- a/src/modules/netinstall/netinstall.conf +++ b/src/modules/netinstall/netinstall.conf @@ -183,6 +183,9 @@ label: # really only makes sense in combination with *selected* set to true, # so that the packages will be installed. (Setting a group to immutable # can be seen as removing it from the user-interface.) +# - *noncheckable*: if true, the entire group cannot be selected or +# deselected by a single click. This does not affect any subgroups +# or child packages # - *expanded*: if true, the group is shown in an expanded form (that is, # not-collapsed) in the treeview on start. This only affects the user- # interface. Only top-level groups are show expanded-initially. diff --git a/src/modules/netinstall/netinstall.schema.yaml b/src/modules/netinstall/netinstall.schema.yaml index 3ec63daed..abc7ae117 100644 --- a/src/modules/netinstall/netinstall.schema.yaml +++ b/src/modules/netinstall/netinstall.schema.yaml @@ -33,6 +33,7 @@ definitions: selected: { type: boolean } critical: { type: boolean, default: false } immutable: { type: boolean } + noncheckable: { type: boolean } expanded: { type: boolean } subgroups: type: array From db20b79ac01340a39aae899574753af4ca39f8b1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 10 Oct 2022 21:03:50 +0200 Subject: [PATCH 12/89] Changes: credits for 3.3 work --- CHANGES-3.3 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index a31f9bbb2..74bb0718c 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -13,6 +13,11 @@ the history of the 3.2 series (2018-05 - 2022-08). This release contains contributions from (alphabetically by first name): - Adriaan de Groot - Anke Boersma + - Evan James + - Jeremy Attall + - Johannes Kamprad + - Shivanand + - Peter Jung ## Core ## - Incompatible module-configuration changes, see #1438. @@ -24,8 +29,13 @@ This release contains contributions from (alphabetically by first name): ## Modules ## - *dracut* added a configurable kernel name. (thanks Anke) + - *initcpiocfg* orders hookds slightly differently. (thanks Peter) - *localeq* moved to using Drawer instead of ComboBox in UI. (thanks Anke) - *keyboardq* moved to using Drawer instead of ComboBox in UI. (thanks Anke) + - *netinstall* now has a new *noncheckable* option for groups, which prevent + it a group from being checked/uncheckd as a whole. You can still check + individual items **in** the group though. (thanks Shivanand) +- *partition* can now pick LUKS or LUKS2. (thanks Jeremy) # 3.3.0-alpha2 (2022-08-23) From f31056faae2115361d70275217576c0fb502c448 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 10 Oct 2022 21:09:24 +0200 Subject: [PATCH 13/89] [partition] Tidy formatting of enum tables - the NamedEnumTable is one of the things that clang-format doesn't do nicely. --- src/modules/partition/Config.cpp | 45 +++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index d1a53cfc4..329530259 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -25,23 +25,36 @@ Config::Config( QObject* parent ) const NamedEnumTable< Config::InstallChoice >& Config::installChoiceNames() { - static const NamedEnumTable< InstallChoice > names { { QStringLiteral( "none" ), InstallChoice::NoChoice }, - { QStringLiteral( "nochoice" ), InstallChoice::NoChoice }, - { QStringLiteral( "alongside" ), InstallChoice::Alongside }, - { QStringLiteral( "erase" ), InstallChoice::Erase }, - { QStringLiteral( "replace" ), InstallChoice::Replace }, - { QStringLiteral( "manual" ), InstallChoice::Manual } }; + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< InstallChoice > names { + { QStringLiteral( "none" ), InstallChoice::NoChoice }, + { QStringLiteral( "nochoice" ), InstallChoice::NoChoice }, + { QStringLiteral( "alongside" ), InstallChoice::Alongside }, + { QStringLiteral( "erase" ), InstallChoice::Erase }, + { QStringLiteral( "replace" ), InstallChoice::Replace }, + { QStringLiteral( "manual" ), InstallChoice::Manual }, + }; + // clang-format on + // *INDENT-ON* + return names; } const NamedEnumTable< Config::SwapChoice >& Config::swapChoiceNames() { - static const NamedEnumTable< SwapChoice > names { { QStringLiteral( "none" ), SwapChoice::NoSwap }, - { QStringLiteral( "small" ), SwapChoice::SmallSwap }, - { QStringLiteral( "suspend" ), SwapChoice::FullSwap }, - { QStringLiteral( "reuse" ), SwapChoice::ReuseSwap }, - { QStringLiteral( "file" ), SwapChoice::SwapFile } }; + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< SwapChoice > names { + { QStringLiteral( "none" ), SwapChoice::NoSwap }, + { QStringLiteral( "small" ), SwapChoice::SmallSwap }, + { QStringLiteral( "suspend" ), SwapChoice::FullSwap }, + { QStringLiteral( "reuse" ), SwapChoice::ReuseSwap }, + { QStringLiteral( "file" ), SwapChoice::SwapFile }, + }; + // clang-format on + // *INDENT-ON* return names; } @@ -49,8 +62,14 @@ Config::swapChoiceNames() const NamedEnumTable< Config::LuksGeneration >& Config::luksGenerationNames() { - static const NamedEnumTable< LuksGeneration > names { { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, - { QStringLiteral( "luks2" ), LuksGeneration::Luks2 } }; + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< LuksGeneration > names { + { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, + { QStringLiteral( "luks2" ), LuksGeneration::Luks2 }, + }; + // clang-format on + // *INDENT-ON* return names; } From 703cbb7bf31c7b124f2ce311112550c1f30030b1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 10 Oct 2022 21:12:28 +0200 Subject: [PATCH 14/89] [partition] Allow 'luks' as alias of 'luks1' --- src/modules/partition/Config.cpp | 1 + src/modules/partition/partition.conf | 2 +- src/modules/partition/partition.schema.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 329530259..d698a5075 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -66,6 +66,7 @@ Config::luksGenerationNames() // clang-format off static const NamedEnumTable< LuksGeneration > names { { QStringLiteral( "luks1" ), LuksGeneration::Luks1 }, + { QStringLiteral( "luks" ), LuksGeneration::Luks1 }, { QStringLiteral( "luks2" ), LuksGeneration::Luks2 }, }; // clang-format on diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index 9973df8e8..ad8ab994a 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -72,7 +72,7 @@ userSwapChoices: # also set to luks2. Also there are some patches for grub and Argon2. # See: https://aur.archlinux.org/packages/grub-improved-luks2-git # -# Choices: luks1, luks2 +# Choices: luks1, luks2 (in addition, "luks" means "luks1") # # The default is luks1 # diff --git a/src/modules/partition/partition.schema.yaml b/src/modules/partition/partition.schema.yaml index 5ffaa11d4..64c261d26 100644 --- a/src/modules/partition/partition.schema.yaml +++ b/src/modules/partition/partition.schema.yaml @@ -20,7 +20,7 @@ properties: defaultFileSystemType: { type: string } availableFileSystemTypes: { type: array, items: { type: string } } - luksGeneration: { type: string, enum: [luks1, luks2] } + luksGeneration: { type: string, enum: [luks1, luks2] } # Also allows "luks" as alias of "luks1" enableLuksAutomatedPartitioning: { type: boolean, default: false } allowManualPartitioning: { type: boolean, default: true } From 596113c80fe38a487c0cac748f1e6a335bb1f84e Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 15 Oct 2022 07:06:26 -0500 Subject: [PATCH 15/89] [dracut] Change image name terminology to match dracut --- src/modules/dracut/dracut.conf | 4 ++-- src/modules/dracut/dracut.schema.yaml | 2 +- src/modules/dracut/main.py | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/dracut/dracut.conf b/src/modules/dracut/dracut.conf index 98d847d9e..ae5d85022 100644 --- a/src/modules/dracut/dracut.conf +++ b/src/modules/dracut/dracut.conf @@ -5,6 +5,6 @@ --- # Dracut defaults to setting initramfs-.img # If you want to specify another filename for the resulting image, -# set a custom kernel name, including the path +# set a custom name, including the path # -# kernelName: /boot/initramfs-linux.img +# initramfsName: /boot/initramfs-linux.img diff --git a/src/modules/dracut/dracut.schema.yaml b/src/modules/dracut/dracut.schema.yaml index 503b1a4f0..d6008e1bf 100644 --- a/src/modules/dracut/dracut.schema.yaml +++ b/src/modules/dracut/dracut.schema.yaml @@ -6,4 +6,4 @@ $id: https://calamares.io/schemas/dracut additionalProperties: false type: object properties: - kernelName: { type: string } + initramfsName: { type: string } diff --git a/src/modules/dracut/main.py b/src/modules/dracut/main.py index 071406580..dd12b92dd 100644 --- a/src/modules/dracut/main.py +++ b/src/modules/dracut/main.py @@ -34,12 +34,12 @@ def run_dracut(): :return: """ - kernelName = libcalamares.job.configuration['kernelName'] + initramfs_name = libcalamares.job.configuration['initramfsName'] - if not kernelName: + if not initramfs_name: return check_target_env_call(['dracut', '-f']) else: - return check_target_env_call(['dracut', '-f', '{}'.format(kernelName)]) + return check_target_env_call(['dracut', '-f', initramfs_name]) def run(): @@ -53,4 +53,4 @@ def run(): if return_code != 0: return (_("Failed to run dracut on the target"), - _("The exit code was {}").format(return_code)) + _(f"The exit code was {return_code}")) From 5a10c58c358ee29ea5b0d9cd87810edb86f4e46b Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 15 Oct 2022 17:31:50 -0500 Subject: [PATCH 16/89] [mount] Remove duplicate subvol option --- src/modules/mount/main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 49ffc9627..32da36dd0 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -294,13 +294,13 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun # Mount the subvolumes swap_subvol = libcalamares.job.configuration.get("btrfsSwapSubvol", "/@swap") for s in btrfs_subvolumes: - mount_option = "subvol={}".format(s['subvolume']) if s['subvolume'] == swap_subvol: - mount_option += "," + get_mount_options("btrfs_swap", mount_options, partition) + mount_option_no_subvol = get_mount_options("btrfs_swap", mount_options, partition) else: - mount_option += "," + get_mount_options(fstype, mount_options, partition) + mount_option_no_subvol = get_mount_options(fstype, mount_options, partition) + mount_option = f"subvol={s['subvolume']},{mount_option_no_subvol}" subvolume_mountpoint = mount_point[:-1] + s['mountPoint'] - mount_options_list.append({"mountpoint": s['mountPoint'], "option_string": mount_option}) + mount_options_list.append({"mountpoint": s['mountPoint'], "option_string": mount_option_no_subvol}) if libcalamares.utils.mount(device, subvolume_mountpoint, fstype, From 1b96832bf7e60a849119975adcb5fa7959e05e3e Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 16 Oct 2022 12:22:45 +0200 Subject: [PATCH 17/89] [zfs] adding hostid using ZFS in combination with dracut exposed a bug on system updates hostid from the Live session does not match hostid installed, thus zpool id no longer matches id created by dracut in the kernel img to work around this, the zfs module now uses zgenhostid to create a hostid --- src/modules/zfs/ZfsJob.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/modules/zfs/ZfsJob.cpp b/src/modules/zfs/ZfsJob.cpp index 921645f0a..c840da846 100644 --- a/src/modules/zfs/ZfsJob.cpp +++ b/src/modules/zfs/ZfsJob.cpp @@ -241,6 +241,13 @@ ZfsJob::exec() } } + // Generate the zfs hostid file + auto i = system->runCommand( { "zgenhostid" }, std::chrono::seconds( 3 ) ); + if ( i.getExitCode() != 0 ) + { + cWarning() << "Failed to create /etc/hostid"; + } + // Create the zpool ZfsResult zfsResult; if ( encrypt ) From 089d3086cc8c54a93567956d46822b9a12f3afd7 Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 16 Oct 2022 13:35:09 +0200 Subject: [PATCH 18/89] [zfshostid] adding new module module created to copy zfs generated /etc/hostid, needed to have hostid in zpool & initramfs in sync --- settings.conf | 1 + src/modules/zfshostid/main.py | 45 +++++++++++++++++++++ src/modules/zfshostid/module.desc | 8 ++++ src/modules/zfshostid/zfshostid.schema.yaml | 10 +++++ 4 files changed, 64 insertions(+) create mode 100644 src/modules/zfshostid/main.py create mode 100644 src/modules/zfshostid/module.desc create mode 100644 src/modules/zfshostid/zfshostid.schema.yaml diff --git a/settings.conf b/settings.conf index 8f4d60213..f4cbd05ca 100644 --- a/settings.conf +++ b/settings.conf @@ -140,6 +140,7 @@ sequence: # - luksopenswaphookcfg # - dracutlukscfg # - plymouthcfg +# - zfshostid - initcpiocfg - initcpio - users diff --git a/src/modules/zfshostid/main.py b/src/modules/zfshostid/main.py new file mode 100644 index 000000000..4e7960e93 --- /dev/null +++ b/src/modules/zfshostid/main.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +# === This file is part of Calamares - === +# +# SPDX-FileCopyrightText: 2022 Anke Boersma +# SPDX-License-Identifier: GPL-3.0-or-later +# +# Calamares is Free Software: see the License-Identifier above. +# + +import os +import shutil + +import libcalamares +from libcalamares.utils import gettext_path, gettext_languages + + +import gettext +_ = gettext.translation("calamares-python", + localedir=libcalamares.utils.gettext_path(), + languages=libcalamares.utils.gettext_languages(), + fallback=True).gettext + + +def pretty_name(): + return _("Copying zfs generated hostid.") + + +def run(): + + zfs = libcalamares.globalstorage.value("zfsDatasets") + root_mount_point = libcalamares.globalstorage.value("rootMountPoint") + + if zfs: + hostid_source = '/etc/hostid' + hostid_destination = '{!s}/etc/hostid'.format(root_mount_point) + + if os.path.exists(hostid_source): + try: + shutil.copy2(hostid_source, hostid_destination) + except Exception as e: + libcalamares.utils.warning("Could not copy hostid") + + return None diff --git a/src/modules/zfshostid/module.desc b/src/modules/zfshostid/module.desc new file mode 100644 index 000000000..13fec35be --- /dev/null +++ b/src/modules/zfshostid/module.desc @@ -0,0 +1,8 @@ +# SPDX-FileCopyrightText: no +# SPDX-License-Identifier: CC0-1.0 +--- +type: "job" +name: "zfshostid" +interface: "python" +script: "main.py" +noconfig: true diff --git a/src/modules/zfshostid/zfshostid.schema.yaml b/src/modules/zfshostid/zfshostid.schema.yaml new file mode 100644 index 000000000..6a7a7b753 --- /dev/null +++ b/src/modules/zfshostid/zfshostid.schema.yaml @@ -0,0 +1,10 @@ +# SPDX-FileCopyrightText: 2022 Anke Boersma +# SPDX-License-Identifier: GPL-3.0-or-later +--- +$schema: https://json-schema.org/schema# +$id: https://calamares.io/schemas/zfshostid +additionalProperties: false +type: object + +required: + - zfs From cbb01f70e7549c832b461b7e6911e5af465f9f40 Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 16 Oct 2022 13:41:54 +0200 Subject: [PATCH 19/89] Changes: add new parts for 3.3.0-aplha3 --- CHANGES-3.3 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index 74bb0718c..10abb5461 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -35,7 +35,9 @@ This release contains contributions from (alphabetically by first name): - *netinstall* now has a new *noncheckable* option for groups, which prevent it a group from being checked/uncheckd as a whole. You can still check individual items **in** the group though. (thanks Shivanand) -- *partition* can now pick LUKS or LUKS2. (thanks Jeremy) + - *partition* can now pick LUKS or LUKS2. (thanks Jeremy) + - *zfs* creates a hostid through zgenhostid. + - *zfshostid* new module to copy zfs generated /etc/hostid # 3.3.0-alpha2 (2022-08-23) From 26a9ca7a869323c680f83f73f82b9405a8bfb4fb Mon Sep 17 00:00:00 2001 From: demmm Date: Sun, 16 Oct 2022 14:12:27 +0200 Subject: [PATCH 20/89] [zfshostid] simplify run call required for schema.yaml seems to be for globalstorage entries, not modules remove section --- src/modules/zfshostid/main.py | 9 ++++----- src/modules/zfshostid/zfshostid.schema.yaml | 3 --- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/modules/zfshostid/main.py b/src/modules/zfshostid/main.py index 4e7960e93..702ba1ede 100644 --- a/src/modules/zfshostid/main.py +++ b/src/modules/zfshostid/main.py @@ -36,10 +36,9 @@ def run(): hostid_source = '/etc/hostid' hostid_destination = '{!s}/etc/hostid'.format(root_mount_point) - if os.path.exists(hostid_source): - try: - shutil.copy2(hostid_source, hostid_destination) - except Exception as e: - libcalamares.utils.warning("Could not copy hostid") + try: + shutil.copy2(hostid_source, hostid_destination) + except Exception as e: + libcalamares.utils.warning("Could not copy hostid") return None diff --git a/src/modules/zfshostid/zfshostid.schema.yaml b/src/modules/zfshostid/zfshostid.schema.yaml index 6a7a7b753..24774d01a 100644 --- a/src/modules/zfshostid/zfshostid.schema.yaml +++ b/src/modules/zfshostid/zfshostid.schema.yaml @@ -5,6 +5,3 @@ $schema: https://json-schema.org/schema# $id: https://calamares.io/schemas/zfshostid additionalProperties: false type: object - -required: - - zfs From 336a57fdf49938b04363884f2a4c39bb73280f7f Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 16 Oct 2022 09:05:30 -0500 Subject: [PATCH 21/89] [dracut] Clean up error handling --- src/modules/dracut/main.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/modules/dracut/main.py b/src/modules/dracut/main.py index dd12b92dd..6af303d64 100644 --- a/src/modules/dracut/main.py +++ b/src/modules/dracut/main.py @@ -12,9 +12,10 @@ # # Calamares is Free Software: see the License-Identifier above. # +import subprocess import libcalamares -from libcalamares.utils import check_target_env_call +from libcalamares.utils import target_env_process_output import gettext @@ -34,12 +35,18 @@ def run_dracut(): :return: """ - initramfs_name = libcalamares.job.configuration['initramfsName'] + try: + initramfs_name = libcalamares.job.configuration['initramfsName'] + target_env_process_output(['dracut', '-f', initramfs_name]) + except KeyError: + try: + target_env_process_output(['dracut', '-f']) + except subprocess.CalledProcessError as cpe: + return cpe.returncode, cpe.output + except subprocess.CalledProcessError as cpe: + return cpe.returncode, cpe.output - if not initramfs_name: - return check_target_env_call(['dracut', '-f']) - else: - return check_target_env_call(['dracut', '-f', initramfs_name]) + return 0, None def run(): @@ -49,8 +56,8 @@ def run(): :return: """ - return_code = run_dracut() - + return_code, output = run_dracut() if return_code != 0: - return (_("Failed to run dracut on the target"), - _(f"The exit code was {return_code}")) + libcalamares.utils.warning(f"Dracut failed with output: {output}") + return (_("Failed to run dracut"), + _(f"Dracut failed with on the target with return code: {return_code}")) From d13561e1c7c9169ed6738a5541ef2aa98e20e3a2 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 16 Oct 2022 09:08:42 -0500 Subject: [PATCH 22/89] [dracut] Clean up error handling more --- src/modules/dracut/main.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/modules/dracut/main.py b/src/modules/dracut/main.py index 6af303d64..85e6f3e7f 100644 --- a/src/modules/dracut/main.py +++ b/src/modules/dracut/main.py @@ -42,11 +42,13 @@ def run_dracut(): try: target_env_process_output(['dracut', '-f']) except subprocess.CalledProcessError as cpe: - return cpe.returncode, cpe.output + libcalamares.utils.warning(f"Dracut failed with output: {cpe.output}") + return cpe.returncode except subprocess.CalledProcessError as cpe: - return cpe.returncode, cpe.output + libcalamares.utils.warning(f"Dracut failed with output: {cpe.output}") + return cpe.returncode - return 0, None + return 0 def run(): @@ -56,8 +58,7 @@ def run(): :return: """ - return_code, output = run_dracut() + return_code = run_dracut() if return_code != 0: - libcalamares.utils.warning(f"Dracut failed with output: {output}") return (_("Failed to run dracut"), - _(f"Dracut failed with on the target with return code: {return_code}")) + _(f"Dracut failed to run on the target with return code: {return_code}")) From a4afddc4e1a001f51bf614a5444e309e25bd4e10 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 22 Oct 2022 08:23:55 -0500 Subject: [PATCH 23/89] [umount] Change default config for emergency to true --- src/modules/umount/umount.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 9fb922740..5842c8780 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -11,4 +11,4 @@ --- # Setting emergency to true will make it so this module is still run # when a prior module fails -emergency: false +emergency: true From 8f72d2541f241ef5a1f4bc945bdc908e7dbe9fdd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 9 Sep 2022 22:26:27 +0200 Subject: [PATCH 24/89] No more INSTALL_CONFIG --- CHANGES-3.3 | 7 +++++-- CMakeLists.txt | 6 ++---- CMakeModules/CalamaresAddModuleSubdirectory.cmake | 13 +++---------- CMakeModules/CalamaresAddPlugin.cmake | 12 ++---------- 4 files changed, 12 insertions(+), 26 deletions(-) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index 10abb5461..f187e1320 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -24,8 +24,11 @@ This release contains contributions from (alphabetically by first name): - Branding entries use ${var} instead of @{var} for substitutions, in line with all the other substitution mechanisms used from C++ core. See documentation in `branding.desc`. - - Boost::Python requires at least version 1.72 - - KDE Frameworks must be version 5.58 or later + - Boost::Python requires at least version 1.72. + - KDE Frameworks must be version 5.58 or later. + - The `INSTALL_CONFIG` option has been removed. If you are installing + the example configuration files from the Calamares repository, just + stop. That was never a good idea, and you should keep your configs elsewhere. ## Modules ## - *dracut* added a configurable kernel name. (thanks Anke) diff --git a/CMakeLists.txt b/CMakeLists.txt index 04fbf687a..289aab268 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,6 @@ set(CALAMARES_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") ### OPTIONS # -option(INSTALL_CONFIG "Install configuration files" OFF) option(INSTALL_POLKIT "Install Polkit configuration" ON) option(INSTALL_COMPLETION "Install shell completions" OFF) # When adding WITH_* that affects the ABI offered by libcalamares, @@ -542,7 +541,6 @@ add_subdirectory(src) add_feature_info(Python ${WITH_PYTHON} "Python job modules") add_feature_info(Qml ${WITH_QML} "QML UI support") -add_feature_info(Config ${INSTALL_CONFIG} "Install Calamares configuration") add_feature_info(Polkit ${INSTALL_POLKIT} "Install Polkit files") add_feature_info(KCrash ${BUILD_KF5Crash} "Crash dumps via KCrash") @@ -587,8 +585,8 @@ install( ### Miscellaneous installs # # -if(INSTALL_CONFIG) - install(FILES settings.conf DESTINATION share/calamares) +if( settings.conf IS_NEWER_THAN ${CMAKE_BINARY_DIR}/settings.conf ) + install(FILES settings.conf DESTINATION ${CMAKE_BINARY_DIR}) endif() if(INSTALL_POLKIT) diff --git a/CMakeModules/CalamaresAddModuleSubdirectory.cmake b/CMakeModules/CalamaresAddModuleSubdirectory.cmake index e0eed223e..55cf440ce 100644 --- a/CMakeModules/CalamaresAddModuleSubdirectory.cmake +++ b/CMakeModules/CalamaresAddModuleSubdirectory.cmake @@ -153,12 +153,10 @@ function( _calamares_add_module_subdirectory_impl ) get_filename_component( FLEXT ${MODULE_FILE} EXT ) if( "${FLEXT}" STREQUAL ".conf" ) - if( INSTALL_CONFIG ) - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE} - DESTINATION ${MODULE_DATA_DESTINATION} ) - endif() + message(STATUS "Config ${MODULE_FILE}") list( APPEND MODULE_CONFIG_FILES ${MODULE_FILE} ) else() + message(STATUS "Non-Config ${MODULE_FILE}") install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${SUBDIRECTORY}/${MODULE_FILE} DESTINATION ${MODULE_DESTINATION} ) endif() @@ -169,12 +167,7 @@ function( _calamares_add_module_subdirectory_impl ) message( " ${Green}TYPE:${ColorReset} jobmodule" ) message( " ${Green}MODULE_DESTINATION:${ColorReset} ${MODULE_DESTINATION}" ) if( MODULE_CONFIG_FILES ) - if ( INSTALL_CONFIG ) - set( _destination "${MODULE_DATA_DESTINATION}" ) - else() - set( _destination "[Build directory only]" ) - endif() - message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => ${_destination}" ) + message( " ${Green}CONFIGURATION_FILES:${ColorReset} ${MODULE_CONFIG_FILES} => [Build directory only]" ) endif() message( "" ) # We copy over the lang directory, if any diff --git a/CMakeModules/CalamaresAddPlugin.cmake b/CMakeModules/CalamaresAddPlugin.cmake index 7e2a3f583..a86ee6e71 100644 --- a/CMakeModules/CalamaresAddPlugin.cmake +++ b/CMakeModules/CalamaresAddPlugin.cmake @@ -104,10 +104,7 @@ function( calamares_add_plugin ) message( FATAL_ERROR "${Red}NO_CONFIG${ColorReset} is set, with configuration ${Red}${PLUGIN_CONFIG_FILES}${ColorReset}" ) endif() set( _destination "(unknown)" ) - if ( INSTALL_CONFIG AND NOT PLUGIN_NO_INSTALL ) - set( _destination "${PLUGIN_DATA_DESTINATION}" ) - elseif( NOT PLUGIN_NO_INSTALL ) - # Not INSTALL_CONFIG + if( NOT PLUGIN_NO_INSTALL ) set( _destination "[Build directory only]" ) else() set( _destination "[Skipping installation]" ) @@ -210,17 +207,12 @@ function( calamares_add_plugin ) set( _warned_config OFF ) foreach( PLUGIN_CONFIG_FILE ${PLUGIN_CONFIG_FILES} ) - if( ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN_CONFIG_FILE} IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} OR INSTALL_CONFIG ) + if( ${CMAKE_CURRENT_SOURCE_DIR}/${PLUGIN_CONFIG_FILE} IS_NEWER_THAN ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} ) configure_file( ${PLUGIN_CONFIG_FILE} ${PLUGIN_CONFIG_FILE} COPYONLY ) else() message( " ${BoldYellow}Not updating${ColorReset} ${PLUGIN_CONFIG_FILE}" ) set( _warned_config ON ) endif() - if ( INSTALL_CONFIG ) - install( - FILES ${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_CONFIG_FILE} - DESTINATION ${PLUGIN_DATA_DESTINATION} ) - endif() endforeach() if ( _warned_config ) message( "" ) From 5ef1af5aefc566d03a835ba1562d3386fd3306c2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 16:28:54 +0100 Subject: [PATCH 25/89] [partition] Introduce helpers for Cala Luks generation to KPM generations --- src/modules/partition/core/KPMHelpers.cpp | 18 ++++++++++++++++++ src/modules/partition/core/KPMHelpers.h | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index eba4a41b6..8caca3dbb 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -299,6 +299,24 @@ cryptVersion( Partition* partition ) return luksVersion; } +FileSystem::Type +luksGenerationToFSName( Config::LuksGeneration luksGeneration ) +{ + // Convert luksGenerationChoice from partition.conf into its + // corresponding file system type from KPMCore. + switch ( luksGeneration ) + { + case Config::LuksGeneration::Luks2: + return FileSystem::Type::Luks2; + case Config::LuksGeneration::Luks1: + return FileSystem::Type::Luks; + default: + cWarning() << "luksGeneration not supported, defaulting to \"luks\""; + return FileSystem::Type::Luks; + } +} + + Calamares::JobResult execute( Operation& operation, const QString& failureMessage ) { diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index 7e3316cd6..0ab33790d 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -11,6 +11,7 @@ #ifndef KPMHELPERS_H #define KPMHELPERS_H +#include "Config.h" #include "Job.h" #include @@ -120,6 +121,17 @@ bool cryptLabel( Partition* partition, const QString& label ); */ int cryptVersion( Partition* partition ); +/** @brief Convert a luksGeneration into its FS type for KPMCore. + * + * Will convert Luks1 into FileSystem::Type::luks and Luks2 into + * FileSystem::Type::luks2 for KPMCore partitioning functions. + * + * @return The LUKS FS type (default @c luks ) + */ +FileSystem::Type +luksGenerationToFSName( Config::LuksGeneration luksGeneration ); + + /** @brief Return a result for an @p operation * * Executes the operation, and if successful, returns a success result. From 2ae02bedf89d07fdcfbf975a9416ed6eb975d5b2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 16:47:26 +0100 Subject: [PATCH 26/89] [partition] Use enum values rather than strings In the innermost APIs, use the enum value rather than passing strings around. --- src/modules/partition/Config.cpp | 21 ++----------------- src/modules/partition/Config.h | 18 ++++++---------- src/modules/partition/core/KPMHelpers.cpp | 4 ++-- src/modules/partition/core/KPMHelpers.h | 2 +- .../partition/core/PartitionActions.cpp | 2 +- .../partition/core/PartitionCoreModule.cpp | 5 +++-- .../partition/core/PartitionLayout.cpp | 2 +- src/modules/partition/core/PartitionLayout.h | 6 +++--- src/modules/partition/gui/ChoicePage.cpp | 4 ++-- .../partition/gui/CreatePartitionDialog.cpp | 2 +- .../partition/tests/CreateLayoutsTests.cpp | 6 +++--- 11 files changed, 25 insertions(+), 47 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index d698a5075..8bdb4643d 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -75,23 +75,6 @@ Config::luksGenerationNames() return names; } -const QString -Config::luksGenerationToFSName( Config::LuksGeneration luksGeneration ) -{ - // Convert luksGenerationChoice from partition.conf into its - // corresponding file system type from KPMCore. - switch ( luksGeneration ) - { - case Config::LuksGeneration::Luks2: - return QStringLiteral( "luks2" ); - case Config::LuksGeneration::Luks1: - return QStringLiteral( "luks" ); - default: - cWarning() << "luksGeneration not supported, defaulting to \"luks\""; - return QStringLiteral( "luks" ); - } -} - Config::SwapChoice pickOne( const Config::SwapChoiceSet& s ) { @@ -378,8 +361,8 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) cWarning() << "Partition-module setting *luksGeneration* not found or invalid. Defaulting to luks1."; luksGeneration = Config::LuksGeneration::Luks1; } - m_luksFileSystemType = Config::luksGenerationToFSName( luksGeneration ); - gs->insert( "luksFileSystemType", m_luksFileSystemType ); + m_luksFileSystemType = luksGeneration; + gs->insert( "luksFileSystemType", luksGenerationNames().find(luksGeneration) ); Q_ASSERT( !m_eraseFsTypes.isEmpty() ); Q_ASSERT( m_eraseFsTypes.contains( fsRealName ) ); diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index c6b344d0d..9dfbf8360 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -64,14 +64,13 @@ public: using EraseFsTypesSet = QStringList; /** @brief Choice of LUKS disk encryption generation */ - enum LuksGeneration + enum class LuksGeneration { Luks1, // First generation of LUKS Luks2, // Second generation of LUKS, default since cryptsetup >= 2.1.0 }; Q_ENUM( LuksGeneration ) static const NamedEnumTable< LuksGeneration >& luksGenerationNames(); - static const QString luksGenerationToFSName( LuksGeneration choice ); void setConfigurationMap( const QVariantMap& ); /** @brief Set GS values where other modules configuration has priority @@ -122,15 +121,6 @@ public: */ SwapChoice swapChoice() const { return m_swapChoice; } - /** @brief The conversion of the luksGeneration into its FS type. - * - * Will convert Luks1 into "luks" and Luks2 into "luks2" for KPMCore - * partitionning functions. - * - * @return The LUKS FS type (default @c "luks" ) - */ - QString luksFileSystemType() const { return m_luksFileSystemType; } - /** @brief Get the list of configured FS types to use with *erase* mode * * This list is not empty. @@ -159,6 +149,10 @@ public: /// @brief Returns list of acceptable types. May be empty. QStringList partitionTableTypes() const { return m_requiredPartitionTableType; } + /** @brief The configured LUKS generation (1 or 2) + */ + LuksGeneration luksFileSystemType() const { return m_luksFileSystemType; } + public Q_SLOTS: void setInstallChoice( int ); ///< Translates a button ID or so to InstallChoice void setInstallChoice( InstallChoice ); @@ -181,7 +175,7 @@ private: SwapChoiceSet m_swapChoices; SwapChoice m_initialSwapChoice = NoSwap; SwapChoice m_swapChoice = NoSwap; - QString m_luksFileSystemType; + LuksGeneration m_luksFileSystemType = LuksGeneration::Luks1; InstallChoice m_initialInstallChoice = NoChoice; InstallChoice m_installChoice = NoChoice; qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module diff --git a/src/modules/partition/core/KPMHelpers.cpp b/src/modules/partition/core/KPMHelpers.cpp index 8caca3dbb..44da940fb 100644 --- a/src/modules/partition/core/KPMHelpers.cpp +++ b/src/modules/partition/core/KPMHelpers.cpp @@ -84,7 +84,7 @@ createNewEncryptedPartition( PartitionNode* parent, const QString& fsLabel, qint64 firstSector, qint64 lastSector, - const QString& luksFsType, // "luks" or "luks2" + Config::LuksGeneration luksFsType, const QString& passphrase, PartitionTable::Flags flags ) { @@ -94,7 +94,7 @@ createNewEncryptedPartition( PartitionNode* parent, newRoles |= PartitionRole::Luks; } - FileSystem::Type luksType = FileSystem::typeForName( luksFsType ); + FileSystem::Type luksType = luksGenerationToFSName( luksFsType ); FS::luks* fs = dynamic_cast< FS::luks* >( FileSystemFactory::create( luksType, firstSector, lastSector, device.logicalSize() ) ); diff --git a/src/modules/partition/core/KPMHelpers.h b/src/modules/partition/core/KPMHelpers.h index 0ab33790d..289520ec5 100644 --- a/src/modules/partition/core/KPMHelpers.h +++ b/src/modules/partition/core/KPMHelpers.h @@ -84,7 +84,7 @@ Partition* createNewEncryptedPartition( PartitionNode* parent, const QString& fsLabel, qint64 firstSector, qint64 lastSector, - const QString& luksFsType, + Config::LuksGeneration luksFsType, const QString& passphrase, PartitionTable::Flags flags ); diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 80f86427c..77802868b 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -194,7 +194,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO QStringLiteral( "swap" ), lastSectorForRoot + 1, dev->totalLogical() - 1, - o.luksFsType, + Config::luksGenerationNames().find(o.luksFsType, Config::LuksGeneration::Luks1), o.luksPassphrase, KPM_PARTITION_FLAG( None ) ); } diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 56d4353e8..ac2df64c6 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -957,9 +957,10 @@ PartitionCoreModule::layoutApply( Device* dev, PartitionNode* parent, const PartitionRole& role ) { - bool isEfi = PartUtils::isEfiSystem(); + const bool isEfi = PartUtils::isEfiSystem(); + const auto fsType = Config::luksGenerationNames().find(luksFsType, Config::LuksGeneration::Luks1); QList< Partition* > partList - = m_partLayout.createPartitions( dev, firstSector, lastSector, luksFsType, luksPassphrase, parent, role ); + = m_partLayout.createPartitions( dev, firstSector, lastSector, fsType, luksPassphrase, parent, role ); // Partition::mountPoint() tells us where it is mounted **now**, while // PartitionInfo::mountPoint() says where it will be mounted in the target system. diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index 3ff67de7a..61c701042 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -204,7 +204,7 @@ QList< Partition* > PartitionLayout::createPartitions( Device* dev, qint64 firstSector, qint64 lastSector, - QString luksFsType, + Config::LuksGeneration luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ) diff --git a/src/modules/partition/core/PartitionLayout.h b/src/modules/partition/core/PartitionLayout.h index 2af696b9f..6a3aad6fc 100644 --- a/src/modules/partition/core/PartitionLayout.h +++ b/src/modules/partition/core/PartitionLayout.h @@ -11,9 +11,9 @@ #ifndef PARTITIONLAYOUT_H #define PARTITIONLAYOUT_H -#include "partition/PartitionSize.h" - +#include "Config.h" #include "core/PartUtils.h" +#include "partition/PartitionSize.h" // KPMcore #include @@ -116,7 +116,7 @@ public: QList< Partition* > createPartitions( Device* dev, qint64 firstSector, qint64 lastSector, - QString luksFsType, + Config::LuksGeneration luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ); diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index a6c2831af..ac5fda8c4 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -753,7 +753,7 @@ ChoicePage::doAlongsideApply() m_core->layoutApply( dev, newLastSector + 2, oldLastSector, - m_config->luksFileSystemType(), + Config::luksGenerationNames().find(m_config->luksFileSystemType()), m_encryptWidget->passphrase(), candidate->parent(), candidate->roles() ); @@ -828,7 +828,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) m_core->layoutApply( selectedDevice(), selectedPartition->firstSector(), selectedPartition->lastSector(), - m_config->luksFileSystemType(), + Config::luksGenerationNames().find(m_config->luksFileSystemType()), m_encryptWidget->passphrase(), newParent, newRoles ); diff --git a/src/modules/partition/gui/CreatePartitionDialog.cpp b/src/modules/partition/gui/CreatePartitionDialog.cpp index 067da2c1d..8c8116b2e 100644 --- a/src/modules/partition/gui/CreatePartitionDialog.cpp +++ b/src/modules/partition/gui/CreatePartitionDialog.cpp @@ -257,7 +257,7 @@ CreatePartitionDialog::getNewlyCreatedPartition() fsLabel, first, last, - luksFsType, + Config::luksGenerationNames().find(luksFsType, Config::LuksGeneration::Luks1), luksPassphrase, PartitionTable::Flags() ); } diff --git a/src/modules/partition/tests/CreateLayoutsTests.cpp b/src/modules/partition/tests/CreateLayoutsTests.cpp index 124586759..db57f0e9d 100644 --- a/src/modules/partition/tests/CreateLayoutsTests.cpp +++ b/src/modules/partition/tests/CreateLayoutsTests.cpp @@ -64,7 +64,7 @@ CreateLayoutsTests::testFixedSizePartition() } partitions = layout.createPartitions( - static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); + static_cast< Device* >( &dev ), 0, dev.totalLogical(), Config::LuksGeneration::Luks1, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 1 ); @@ -85,7 +85,7 @@ CreateLayoutsTests::testPercentSizePartition() } partitions = layout.createPartitions( - static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); + static_cast< Device* >( &dev ), 0, dev.totalLogical(), Config::LuksGeneration::Luks1, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 1 ); @@ -116,7 +116,7 @@ CreateLayoutsTests::testMixedSizePartition() } partitions = layout.createPartitions( - static_cast< Device* >( &dev ), 0, dev.totalLogical(), nullptr, nullptr, nullptr, role ); + static_cast< Device* >( &dev ), 0, dev.totalLogical(), Config::LuksGeneration::Luks1, nullptr, nullptr, role ); QCOMPARE( partitions.count(), 3 ); From bd3a1c5e2e9f65a3781ac2003fe51496f484d534 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 16:58:00 +0100 Subject: [PATCH 27/89] [dracut] Avoid test failure When the config file is all commented-out, then it's empty, and that is not a valid configuration. --- src/modules/dracut/dracut.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/dracut/dracut.conf b/src/modules/dracut/dracut.conf index ae5d85022..ba1a7b08c 100644 --- a/src/modules/dracut/dracut.conf +++ b/src/modules/dracut/dracut.conf @@ -7,4 +7,4 @@ # If you want to specify another filename for the resulting image, # set a custom name, including the path # -# initramfsName: /boot/initramfs-linux.img +initramfsName: /boot/initramfs-freebsd.img From a45f6a316e6eafd3f01d6013d88d328b7199fef8 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 5 Nov 2022 13:24:37 -0500 Subject: [PATCH 28/89] [grubcfg] Fix bugs and add option to force defaults to update existing values --- src/modules/grubcfg/grubcfg.conf | 3 + src/modules/grubcfg/grubcfg.schema.yaml | 3 +- src/modules/grubcfg/main.py | 119 +++++++++++++----------- 3 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index 2d58e5dc2..bbc1a95c8 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -46,3 +46,6 @@ defaults: GRUB_DISABLE_SUBMENU: true GRUB_TERMINAL_OUTPUT: "console" GRUB_DISABLE_RECOVERY: true + +# Set to true to force defaults to be used even when not overwriting +always_use_defaults: false \ No newline at end of file diff --git a/src/modules/grubcfg/grubcfg.schema.yaml b/src/modules/grubcfg/grubcfg.schema.yaml index d4d8b5ddb..c04c0b79f 100644 --- a/src/modules/grubcfg/grubcfg.schema.yaml +++ b/src/modules/grubcfg/grubcfg.schema.yaml @@ -19,4 +19,5 @@ properties: GRUB_DISABLE_SUBMENU: { type: boolean, default: true } GRUB_TERMINAL_OUTPUT: { type: string } GRUB_DISABLE_RECOVERY: { type: boolean, default: true } - required: [ GRUB_TIMEOUT, GRUB_DEFAULT, GRUB_TERMINAL_OUTPUT ] + required: [ GRUB_TIMEOUT, GRUB_DEFAULT ] + always_use_defaults: { type: boolean, default: false } diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index c9a863ffd..d8431620e 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -14,6 +14,7 @@ # import libcalamares +import fileinput import os import re @@ -85,6 +86,30 @@ def get_zfs_root(): return None +def update_existing_config(default_grub, grub_config_items): + """ + Updates the existing grub configuration file with any items present in @p grub_config_items + + Items that exist in the file will be updated and new items will be appended to the end + + :param default_grub: The absolute path to the grub config file + :param grub_config_items: A dict holding the key value pairs representing the items + """ + for line in fileinput.input(default_grub, inplace=True): + line = line.strip() + if "=" in line: + # This may be a key, strip the leading comment if it has one + key = line.lstrip("#").split("=")[0].strip() + + # check if this is one of the keys we care about + if key in grub_config_items.keys(): + print(f"{key}={grub_config_items[key]}") + else: + print(line) + else: + print(line) + + def modify_grub_default(partitions, root_mount_point, distributor): """ Configures '/etc/default/grub' for hibernation and plymouth. @@ -103,7 +128,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): :return: """ default_grub = get_grub_config_path(root_mount_point) - distributor_replace = distributor.replace("'", "'\\''") + distributor = distributor.replace("'", "'\\''") dracut_bin = libcalamares.utils.target_env_call( ["sh", "-c", "which dracut"] ) @@ -125,7 +150,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): zfs_root_path = None for partition in partitions: - if partition["mountPoint"] in ("/", "/boot") and partition["fs"] in ("btrfs", "f2fs"): + if partition["mountPoint"] in ("/", "/boot") and partition["fs"] in ("btrfs", "f2fs", "zfs"): no_save_default = True break @@ -190,62 +215,45 @@ def modify_grub_default(partitions, root_mount_point, distributor): if swap_outer_mappername: kernel_params.append(f"resume=/dev/mapper/{swap_outer_mappername}") - if "overwrite" in libcalamares.job.configuration: - overwrite = libcalamares.job.configuration["overwrite"] - else: - overwrite = False + overwrite = libcalamares.job.configuration.get("overwrite", False) - distributor_line = f"GRUB_DISTRIBUTOR='{distributor_replace}'" - kernel_cmd = f'GRUB_CMDLINE_LINUX_DEFAULT="{" ".join(kernel_params)}"' - have_kernel_cmd = False - have_distributor_line = False + grub_config_items = {} + # read the lines we need from the existing config if os.path.exists(default_grub) and not overwrite: with open(default_grub, 'r') as grub_file: lines = [x.strip() for x in grub_file.readlines()] - for i in range(len(lines)): - if lines[i].startswith("#GRUB_CMDLINE_LINUX_DEFAULT"): - lines[i] = kernel_cmd - have_kernel_cmd = True - elif lines[i].startswith("GRUB_CMDLINE_LINUX_DEFAULT"): - regex = re.compile(r"^GRUB_CMDLINE_LINUX_DEFAULT\s*=\s*") - line = regex.sub("", lines[i]) - line = line.lstrip() - line = line.lstrip("\"") - line = line.lstrip("'") - line = line.rstrip() - line = line.rstrip("\"") - line = line.rstrip("'") - existing_params = line.split() + for line in lines: + if line.startswith("GRUB_CMDLINE_LINUX_DEFAULT"): + existing_params = re.sub(r"^GRUB_CMDLINE_LINUX_DEFAULT\s*=\s*", "", line).strip("\"'").split() for existing_param in existing_params: - existing_param_name = existing_param.split("=")[0] + existing_param_name = existing_param.split("=")[0].strip() - # the only ones we ever add - if existing_param_name not in [ - "quiet", "resume", "splash"]: + # Ensure we aren't adding duplicated params + param_exists = False + for param in kernel_params: + if param.split("=")[0].strip() == existing_param_name: + param_exists = True + break + if not param_exists and existing_param_name not in ["quiet", "resume", "splash"]: kernel_params.append(existing_param) - lines[i] = kernel_cmd - have_kernel_cmd = True - elif (lines[i].startswith("#GRUB_DISTRIBUTOR") - or lines[i].startswith("GRUB_DISTRIBUTOR")): - if libcalamares.job.configuration.get("keep_distributor", False): - lines[i] = distributor_line - have_distributor_line = True - else: - # We're not updating because of *keep_distributor*, but if - # this was a comment line, then it's still not been set. - have_distributor_line = have_distributor_line or not lines[i].startswith("#") - # If btrfs or f2fs is used, don't save default - if no_save_default and lines[i].startswith("GRUB_SAVEDEFAULT="): - lines[i] = "#GRUB_SAVEDEFAULT=\"true\"" - else: - lines = [] + elif line.startswith("GRUB_DISTRIBUTOR") and libcalamares.job.configuration.get("keep_distributor", False): + distributor_parts = line.split("=") + if len(distributor_parts) > 1: + distributor = distributor_parts[1].strip("'\"") + # If a filesystem grub can't write to is used, disable save default + if no_save_default and line.strip().startswith("GRUB_SAVEDEFAULT"): + grub_config_items["GRUB_SAVEDEFAULT"] = "false" + + always_use_defaults = libcalamares.job.configuration.get("always_use_defaults", False) + + # If applicable add the items from defaults to the dict containing the grub config to wirte/modify + if always_use_defaults or overwrite or not os.path.exists(default_grub): if "defaults" in libcalamares.job.configuration: - for key, value in libcalamares.job.configuration[ - "defaults"].items(): + for key, value in libcalamares.job.configuration["defaults"].items(): if value.__class__.__name__ == "bool": if value: escaped_value = "true" @@ -254,19 +262,20 @@ def modify_grub_default(partitions, root_mount_point, distributor): else: escaped_value = str(value).replace("'", "'\\''") - lines.append(f"{key}='{escaped_value}'") + grub_config_items[key] = f"'{escaped_value}'" - if not have_kernel_cmd: - lines.append(kernel_cmd) - - if not have_distributor_line: - lines.append(distributor_line) + grub_config_items['GRUB_CMDLINE_LINUX_DEFAULT'] = f"'{' '.join(kernel_params)}'" + grub_config_items["GRUB_DISTRIBUTOR"] = f"'{distributor}'" if cryptdevice_params and not unencrypted_separate_boot: - lines.append("GRUB_ENABLE_CRYPTODISK=y") + grub_config_items["GRUB_ENABLE_CRYPTODISK"] = "y" - with open(default_grub, 'w') as grub_file: - grub_file.write("\n".join(lines) + "\n") + if overwrite or not os.path.exists(default_grub) or libcalamares.job.configuration.get("prefer_grub_d", False): + with open(default_grub, 'w') as grub_file: + for key, value in grub_config_items.items(): + grub_file.write(f"{key}={value}\n") + else: + update_existing_config(default_grub, grub_config_items) return None From 9c3f576cd201743eba4ae14cb472149a557aafe9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 21:57:28 +0100 Subject: [PATCH 29/89] [partition] Convert option struct to use the enum --- src/modules/partition/core/PartitionActions.cpp | 8 +++++--- src/modules/partition/core/PartitionActions.h | 6 +++--- src/modules/partition/gui/ChoicePage.cpp | 6 ++++-- src/modules/partition/gui/ReplaceWidget.cpp | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 77802868b..035cb5b4c 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -169,7 +169,8 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO lastSectorForRoot -= suggestedSwapSizeB / sectorSize + 1; } - core->layoutApply( dev, firstFreeSector, lastSectorForRoot, o.luksFsType, o.luksPassphrase ); + // TODO: LUKS + core->layoutApply( dev, firstFreeSector, lastSectorForRoot, Config::luksGenerationNames().find(o.luksFsType), o.luksPassphrase ); if ( shouldCreateSwap ) { @@ -194,7 +195,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO QStringLiteral( "swap" ), lastSectorForRoot + 1, dev->totalLogical() - 1, - Config::luksGenerationNames().find(o.luksFsType, Config::LuksGeneration::Luks1), + o.luksFsType, o.luksPassphrase, KPM_PARTITION_FLAG( None ) ); } @@ -245,7 +246,8 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition core->deletePartition( dev, partition ); } - core->layoutApply( dev, firstSector, lastSector, o.luksFsType, o.luksPassphrase ); + // TODO: LUKS + core->layoutApply( dev, firstSector, lastSector, Config::luksGenerationNames().find(o.luksFsType), o.luksPassphrase ); core->dumpQueue(); } diff --git a/src/modules/partition/core/PartitionActions.h b/src/modules/partition/core/PartitionActions.h index d8663c754..fdf56e56e 100644 --- a/src/modules/partition/core/PartitionActions.h +++ b/src/modules/partition/core/PartitionActions.h @@ -31,12 +31,12 @@ struct ReplacePartitionOptions { QString defaultPartitionTableType; // e.g. "gpt" or "msdos" QString defaultFsType; // e.g. "ext4" or "btrfs" - QString luksFsType; // optional ("luks", "luks2") + Config::LuksGeneration luksFsType = Config::LuksGeneration::Luks1; // optional ("luks", "luks2") QString luksPassphrase; // optional ReplacePartitionOptions( const QString& pt, const QString& fs, - const QString& luksFs, + Config::LuksGeneration luksFs, const QString& luksPassphrase ) : defaultPartitionTableType( pt ) , defaultFsType( fs ) @@ -54,7 +54,7 @@ struct AutoPartitionOptions : ReplacePartitionOptions AutoPartitionOptions( const QString& pt, const QString& fs, - const QString& luksFs, + Config::LuksGeneration luksFs, const QString& luksPassphrase, const QString& efi, qint64 requiredBytes, diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index ac5fda8c4..23b65d205 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -496,7 +496,8 @@ ChoicePage::applyActionChoice( InstallChoice choice ) auto gs = Calamares::JobQueue::instance()->globalStorage(); PartitionActions::Choices::AutoPartitionOptions options { gs->value( "defaultPartitionTableType" ).toString(), m_config->eraseFsType(), - gs->value( "luksFileSystemType" ).toString(), + // TODO: LUKS + Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), m_encryptWidget->passphrase(), gs->value( "efiSystemPartition" ).toString(), CalamaresUtils::GiBtoBytes( @@ -861,7 +862,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) selectedPartition, { gs->value( "defaultPartitionType" ).toString(), gs->value( "defaultFileSystemType" ).toString(), - gs->value( "luksFileSystemType" ).toString(), + // TODO: LUKS + Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index ec20921a3..25045b8e5 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -90,7 +90,8 @@ ReplaceWidget::applyChanges() partition, { gs->value( "defaultPartitionTableType" ).toString(), gs->value( "defaultFileSystemType" ).toString(), - gs->value( "luksFileSystemType" ).toString(), + // TODO: LUKS + Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), QString() } ); if ( m_isEfi ) From 859569e1565774cbcaad0bac1ead7bcfd2cc95f6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 22:13:30 +0100 Subject: [PATCH 30/89] [partition] Convert layoutApply() --- src/modules/partition/core/PartitionActions.cpp | 6 ++---- src/modules/partition/core/PartitionCoreModule.cpp | 7 +++---- src/modules/partition/core/PartitionCoreModule.h | 5 +++-- src/modules/partition/gui/ChoicePage.cpp | 4 ++-- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 035cb5b4c..80f86427c 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -169,8 +169,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO lastSectorForRoot -= suggestedSwapSizeB / sectorSize + 1; } - // TODO: LUKS - core->layoutApply( dev, firstFreeSector, lastSectorForRoot, Config::luksGenerationNames().find(o.luksFsType), o.luksPassphrase ); + core->layoutApply( dev, firstFreeSector, lastSectorForRoot, o.luksFsType, o.luksPassphrase ); if ( shouldCreateSwap ) { @@ -246,8 +245,7 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition core->deletePartition( dev, partition ); } - // TODO: LUKS - core->layoutApply( dev, firstSector, lastSector, Config::luksGenerationNames().find(o.luksFsType), o.luksPassphrase ); + core->layoutApply( dev, firstSector, lastSector, o.luksFsType, o.luksPassphrase ); core->dumpQueue(); } diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index ac2df64c6..8eef01223 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -952,15 +952,14 @@ void PartitionCoreModule::layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, - QString luksFsType, + Config::LuksGeneration luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ) { const bool isEfi = PartUtils::isEfiSystem(); - const auto fsType = Config::luksGenerationNames().find(luksFsType, Config::LuksGeneration::Luks1); QList< Partition* > partList - = m_partLayout.createPartitions( dev, firstSector, lastSector, fsType, luksPassphrase, parent, role ); + = m_partLayout.createPartitions( dev, firstSector, lastSector, luksFsType, luksPassphrase, parent, role ); // Partition::mountPoint() tells us where it is mounted **now**, while // PartitionInfo::mountPoint() says where it will be mounted in the target system. @@ -1004,7 +1003,7 @@ void PartitionCoreModule::layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, - QString luksFsType, + Config::LuksGeneration luksFsType, QString luksPassphrase ) { layoutApply( dev, diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index 2cc46d1c0..8a7140a8c 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -12,6 +12,7 @@ #ifndef PARTITIONCOREMODULE_H #define PARTITIONCOREMODULE_H +#include "Config.h" #include "core/KPMHelpers.h" #include "core/PartitionLayout.h" #include "core/PartitionModel.h" @@ -166,11 +167,11 @@ public: */ PartitionLayout& partitionLayout() { return m_partLayout; } - void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, QString luksFsType, QString luksPassphrase ); + void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, Config::LuksGeneration luksFsType, QString luksPassphrase ); void layoutApply( Device* dev, qint64 firstSector, qint64 lastSector, - QString luksFsType, + Config::LuksGeneration luksFsType, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role ); diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 23b65d205..5e630030e 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -754,7 +754,7 @@ ChoicePage::doAlongsideApply() m_core->layoutApply( dev, newLastSector + 2, oldLastSector, - Config::luksGenerationNames().find(m_config->luksFileSystemType()), + m_config->luksFileSystemType(), m_encryptWidget->passphrase(), candidate->parent(), candidate->roles() ); @@ -829,7 +829,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) m_core->layoutApply( selectedDevice(), selectedPartition->firstSector(), selectedPartition->lastSector(), - Config::luksGenerationNames().find(m_config->luksFileSystemType()), + m_config->luksFileSystemType(), m_encryptWidget->passphrase(), newParent, newRoles ); From 8c8f2a14b6a6a042521c0aaa25dd0934552dbcbd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 22:19:24 +0100 Subject: [PATCH 31/89] [partition] Use config object in ChoicePage --- src/modules/partition/gui/ChoicePage.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 5e630030e..610be5e35 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -496,8 +496,7 @@ ChoicePage::applyActionChoice( InstallChoice choice ) auto gs = Calamares::JobQueue::instance()->globalStorage(); PartitionActions::Choices::AutoPartitionOptions options { gs->value( "defaultPartitionTableType" ).toString(), m_config->eraseFsType(), - // TODO: LUKS - Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), + m_config->luksFileSystemType(), m_encryptWidget->passphrase(), gs->value( "efiSystemPartition" ).toString(), CalamaresUtils::GiBtoBytes( @@ -862,8 +861,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) selectedPartition, { gs->value( "defaultPartitionType" ).toString(), gs->value( "defaultFileSystemType" ).toString(), - // TODO: LUKS - Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), + m_config->luksFileSystemType(), m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); From 8b29acfc595dc2a39a6277f0c3c4dd79a4371037 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 22:28:53 +0100 Subject: [PATCH 32/89] [partition] Convert ReplaceWidget to use enum Add a tag-class parameter, to demonstrate that the ReplaceWidget class is never used. --- src/modules/partition/gui/ReplaceWidget.cpp | 3 ++- src/modules/partition/gui/ReplaceWidget.h | 13 ++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 25045b8e5..dec76e413 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -32,11 +32,12 @@ using CalamaresUtils::Partition::untranslatedFS; using CalamaresUtils::Partition::userVisibleFS; -ReplaceWidget::ReplaceWidget( PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent ) +ReplaceWidget::ReplaceWidget( Nurble n, Config *config, PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent ) : QWidget( parent ) , m_ui( new Ui_ReplaceWidget ) , m_core( core ) , m_isEfi( false ) + , m_luksFsType( config->luksFileSystemType()) { m_ui->setupUi( this ); diff --git a/src/modules/partition/gui/ReplaceWidget.h b/src/modules/partition/gui/ReplaceWidget.h index fbd19b429..02fbdec4d 100644 --- a/src/modules/partition/gui/ReplaceWidget.h +++ b/src/modules/partition/gui/ReplaceWidget.h @@ -12,21 +12,27 @@ #ifndef REPLACEWIDGET_H #define REPLACEWIDGET_H +#include "Config.h" + #include "utils/CalamaresUtilsGui.h" #include #include -class Ui_ReplaceWidget; -class QComboBox; +class Config; class PartitionCoreModule; class Partition; +class Ui_ReplaceWidget; + +class QComboBox; + +struct TotallyBogus {}; class ReplaceWidget : public QWidget { Q_OBJECT public: - explicit ReplaceWidget( PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent = nullptr ); + explicit ReplaceWidget( TotallyBogus n, Config *config, PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent = nullptr ); virtual ~ReplaceWidget() override; bool isNextEnabled() const; @@ -52,6 +58,7 @@ private: bool m_nextEnabled; bool m_isEfi; + Config::LuksGeneration m_luksFsType; void updateFromCurrentDevice( QComboBox* devicesComboBox ); void onPartitionViewActivated(); From bca38907e6cfe5e0077dd2d3d553f17b03e490ef Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sat, 5 Nov 2022 22:36:05 +0100 Subject: [PATCH 33/89] [partition] Remove unused widget The ReplaceWidget was mentioned only in comments, also unused in 3.2 series. --- src/modules/partition/CMakeLists.txt | 2 - src/modules/partition/PartitionViewStep.cpp | 1 - src/modules/partition/gui/ChoicePage.cpp | 1 - src/modules/partition/gui/ReplaceWidget.cpp | 396 -------------------- src/modules/partition/gui/ReplaceWidget.h | 68 ---- src/modules/partition/gui/ReplaceWidget.ui | 135 ------- 6 files changed, 603 deletions(-) delete mode 100644 src/modules/partition/gui/ReplaceWidget.cpp delete mode 100644 src/modules/partition/gui/ReplaceWidget.h delete mode 100644 src/modules/partition/gui/ReplaceWidget.ui diff --git a/src/modules/partition/CMakeLists.txt b/src/modules/partition/CMakeLists.txt index 743d906bd..27125b030 100644 --- a/src/modules/partition/CMakeLists.txt +++ b/src/modules/partition/CMakeLists.txt @@ -88,7 +88,6 @@ if(KPMcore_FOUND) gui/PartitionSplitterWidget.cpp gui/ResizeVolumeGroupDialog.cpp gui/ScanningDialog.cpp - gui/ReplaceWidget.cpp gui/VolumeGroupBaseDialog.cpp jobs/AutoMountManagementJob.cpp jobs/ChangeFilesystemLabelJob.cpp @@ -113,7 +112,6 @@ if(KPMcore_FOUND) gui/EditExistingPartitionDialog.ui gui/EncryptWidget.ui gui/PartitionPage.ui - gui/ReplaceWidget.ui gui/VolumeGroupBaseDialog.ui LINK_PRIVATE_LIBRARIES calamares::kpmcore diff --git a/src/modules/partition/PartitionViewStep.cpp b/src/modules/partition/PartitionViewStep.cpp index 51294c8bc..a95ed0a9a 100644 --- a/src/modules/partition/PartitionViewStep.cpp +++ b/src/modules/partition/PartitionViewStep.cpp @@ -447,7 +447,6 @@ PartitionViewStep::onActivate() { m_choicePage->applyActionChoice( Config::InstallChoice::Alongside ); // m_choicePage->reset(); - //FIXME: ReplaceWidget should be reset maybe? } } diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 610be5e35..b81a8bf66 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -28,7 +28,6 @@ #include "gui/PartitionBarsView.h" #include "gui/PartitionLabelsView.h" #include "gui/PartitionSplitterWidget.h" -#include "gui/ReplaceWidget.h" #include "gui/ScanningDialog.h" #include "Branding.h" diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp deleted file mode 100644 index dec76e413..000000000 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* === This file is part of Calamares - === - * - * SPDX-FileCopyrightText: 2014-2015 Teo Mrnjavac - * SPDX-FileCopyrightText: 2014 Aurélien Gâteau - * SPDX-FileCopyrightText: 2019-2020 Adriaan de Groot - * SPDX-License-Identifier: GPL-3.0-or-later - * - * Calamares is Free Software: see the License-Identifier above. - * - */ - -#include "ReplaceWidget.h" -#include "ui_ReplaceWidget.h" - -#include "core/DeviceModel.h" -#include "core/PartitionActions.h" -#include "core/PartitionCoreModule.h" -#include "core/PartitionInfo.h" - -#include "Branding.h" -#include "GlobalStorage.h" -#include "JobQueue.h" -#include "partition/FileSystem.h" -#include "utils/CalamaresUtilsGui.h" -#include "utils/Retranslator.h" - -#include -#include - -#include - -using CalamaresUtils::Partition::untranslatedFS; -using CalamaresUtils::Partition::userVisibleFS; - -ReplaceWidget::ReplaceWidget( Nurble n, Config *config, PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent ) - : QWidget( parent ) - , m_ui( new Ui_ReplaceWidget ) - , m_core( core ) - , m_isEfi( false ) - , m_luksFsType( config->luksFileSystemType()) -{ - m_ui->setupUi( this ); - - m_ui->bootComboBox->hide(); - m_ui->bootComboBox->clear(); - m_ui->bootStatusLabel->hide(); - m_ui->bootStatusLabel->clear(); - - updateFromCurrentDevice( devicesComboBox ); - connect( devicesComboBox, - &QComboBox::currentTextChanged, - this, - [ = ]( const QString& /* text */ ) { updateFromCurrentDevice( devicesComboBox ); } ); - - CALAMARES_RETRANSLATE( onPartitionSelected(); ); -} - - -ReplaceWidget::~ReplaceWidget() {} - - -bool -ReplaceWidget::isNextEnabled() const -{ - return m_nextEnabled; -} - - -void -ReplaceWidget::reset() -{ - //moo; -} - - -void -ReplaceWidget::applyChanges() -{ - auto gs = Calamares::JobQueue::instance()->globalStorage(); - - PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); - if ( model ) - { - Partition* partition = model->partitionForIndex( m_ui->partitionTreeView->currentIndex() ); - if ( partition ) - { - Device* dev = model->device(); - - PartitionActions::doReplacePartition( m_core, - dev, - partition, - { gs->value( "defaultPartitionTableType" ).toString(), - gs->value( "defaultFileSystemType" ).toString(), - // TODO: LUKS - Config::luksGenerationNames().find(gs->value( "luksFileSystemType" ).toString(), Config::LuksGeneration::Luks1), - QString() } ); - - if ( m_isEfi ) - { - QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); - if ( efiSystemPartitions.count() == 1 ) - { - PartitionInfo::setMountPoint( efiSystemPartitions.first(), - gs->value( "efiSystemPartition" ).toString() ); - } - else if ( efiSystemPartitions.count() > 1 ) - { - PartitionInfo::setMountPoint( efiSystemPartitions.at( m_ui->bootComboBox->currentIndex() ), - gs->value( "efiSystemPartition" ).toString() ); - } - } - - m_core->dumpQueue(); - } - } -} - - -void -ReplaceWidget::onPartitionSelected() -{ - if ( Calamares::JobQueue::instance()->globalStorage()->value( "firmwareType" ) == "efi" ) - { - m_isEfi = true; - } - - const auto* branding = Calamares::Branding::instance(); - if ( m_ui->partitionTreeView->currentIndex() == QModelIndex() ) - { - updateStatus( CalamaresUtils::PartitionPartition, - tr( "Select where to install %1.
" - "Warning: this will delete all files " - "on the selected partition." ) - .arg( branding->versionedName() ) ); - setNextEnabled( false ); - return; - } - - bool ok = false; - double requiredSpaceB - = Calamares::JobQueue::instance()->globalStorage()->value( "requiredStorageGiB" ).toDouble( &ok ) * 1024 * 1024 - * 1024; - - PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); - if ( model && ok ) - { - const QStringList osproberLines - = Calamares::JobQueue::instance()->globalStorage()->value( "osproberLines" ).toStringList(); - - Partition* partition = model->partitionForIndex( m_ui->partitionTreeView->currentIndex() ); - if ( !partition || partition->state() != KPM_PARTITION_STATE( None ) ) - { - updateStatus( CalamaresUtils::Fail, tr( "The selected item does not appear to be a valid partition." ) ); - setNextEnabled( false ); - return; - } - - if ( partition->roles().has( PartitionRole::Unallocated ) ) - { - updateStatus( CalamaresUtils::Fail, - tr( "%1 cannot be installed on empty space. Please select an " - "existing partition." ) - .arg( branding->versionedName() ) ); - setNextEnabled( false ); - return; - } - - if ( partition->roles().has( PartitionRole::Extended ) ) - { - updateStatus( CalamaresUtils::Fail, - tr( "%1 cannot be installed on an extended partition. Please select an " - "existing primary or logical partition." ) - .arg( branding->versionedName() ) ); - setNextEnabled( false ); - return; - } - - if ( partition->partitionPath().isEmpty() ) - { - updateStatus( CalamaresUtils::Fail, - tr( "%1 cannot be installed on this partition." ).arg( branding->versionedName() ) ); - setNextEnabled( false ); - return; - } - - QString fsNameForUser = userVisibleFS( partition->fileSystem() ); - QString prettyName = tr( "Data partition (%1)" ).arg( fsNameForUser ); - for ( const auto& line : osproberLines ) - { - QStringList lineColumns = line.split( ':' ); - - QString path = lineColumns.value( 0 ).simplified(); - if ( path == partition->partitionPath() ) - { - QString osName; - if ( !lineColumns.value( 1 ).simplified().isEmpty() ) - { - osName = lineColumns.value( 1 ).simplified(); - } - else if ( !lineColumns.value( 2 ).simplified().isEmpty() ) - { - osName = lineColumns.value( 2 ).simplified(); - } - - if ( osName.isEmpty() ) - { - prettyName = tr( "Unknown system partition (%1)" ).arg( fsNameForUser ); - } - else - { - prettyName = tr( "%1 system partition (%2)" ) - .arg( osName.replace( 0, 1, osName.at( 0 ).toUpper() ) ) - .arg( fsNameForUser ); - } - break; - } - } - - // 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

" - "The partition %1 is too small for %2. Please select a partition " - "with capacity at least %3 GiB." ) - .arg( partition->partitionPath() ) - .arg( branding->versionedName() ) - .arg( requiredSpaceB / ( 1024. * 1024. * 1024. ), 0, 'f', 1 ) - .arg( prettyName ) ); - setNextEnabled( false ); - return; - } - - m_ui->bootComboBox->hide(); - m_ui->bootComboBox->clear(); - m_ui->bootStatusLabel->hide(); - m_ui->bootStatusLabel->clear(); - - if ( m_isEfi ) - { - QList< Partition* > efiSystemPartitions = m_core->efiSystemPartitions(); - if ( efiSystemPartitions.count() == 0 ) - { - updateStatus( CalamaresUtils::Fail, - tr( "%2

" - "An EFI system partition cannot be found anywhere " - "on this system. Please go back and use manual " - "partitioning to set up %1." ) - .arg( branding->shortProductName() ) - .arg( prettyName ) ); - setNextEnabled( false ); - } - else if ( efiSystemPartitions.count() == 1 ) - { - updateStatus( CalamaresUtils::PartitionPartition, - tr( "%3

" - "%1 will be installed on %2.
" - "Warning: all data on partition " - "%2 will be lost." ) - .arg( branding->versionedName() ) - .arg( partition->partitionPath() ) - .arg( prettyName ) ); - m_ui->bootStatusLabel->show(); - m_ui->bootStatusLabel->setText( tr( "The EFI system partition at %1 will be used for starting %2." ) - .arg( efiSystemPartitions.first()->partitionPath() ) - .arg( branding->shortProductName() ) ); - setNextEnabled( true ); - } - else - { - updateStatus( CalamaresUtils::PartitionPartition, - tr( "%3

" - "%1 will be installed on %2.
" - "Warning: all data on partition " - "%2 will be lost." ) - .arg( branding->versionedName() ) - .arg( partition->partitionPath() ) - .arg( prettyName ) ); - m_ui->bootStatusLabel->show(); - m_ui->bootStatusLabel->setText( tr( "EFI system partition:" ) ); - m_ui->bootComboBox->show(); - for ( int i = 0; i < efiSystemPartitions.count(); ++i ) - { - Partition* efiPartition = efiSystemPartitions.at( i ); - m_ui->bootComboBox->addItem( efiPartition->partitionPath(), i ); - if ( efiPartition->devicePath() == partition->devicePath() && efiPartition->number() == 1 ) - { - m_ui->bootComboBox->setCurrentIndex( i ); - } - } - setNextEnabled( true ); - } - } - else - { - updateStatus( CalamaresUtils::PartitionPartition, - tr( "%3

" - "%1 will be installed on %2.
" - "Warning: all data on partition " - "%2 will be lost." ) - .arg( branding->versionedName() ) - .arg( partition->partitionPath() ) - .arg( prettyName ) ); - setNextEnabled( true ); - } - } -} - - -void -ReplaceWidget::setNextEnabled( bool enabled ) -{ - if ( enabled == m_nextEnabled ) - { - return; - } - - m_nextEnabled = enabled; - Q_EMIT nextStatusChanged( enabled ); -} - - -void -ReplaceWidget::updateStatus( CalamaresUtils::ImageType imageType, const QString& text ) -{ - int iconSize = CalamaresUtils::defaultFontHeight() * 6; - m_ui->selectedIconLabel->setPixmap( - CalamaresUtils::defaultPixmap( imageType, CalamaresUtils::Original, QSize( iconSize, iconSize ) ) ); - m_ui->selectedIconLabel->setFixedHeight( iconSize ); - m_ui->selectedStatusLabel->setText( text ); -} - - -void -ReplaceWidget::updateFromCurrentDevice( QComboBox* devicesComboBox ) -{ - QModelIndex index = m_core->deviceModel()->index( devicesComboBox->currentIndex(), 0 ); - if ( !index.isValid() ) - { - return; - } - - Device* device = m_core->deviceModel()->deviceForIndex( index ); - - QAbstractItemModel* oldModel = m_ui->partitionTreeView->model(); - if ( oldModel ) - { - disconnect( oldModel, nullptr, this, nullptr ); - } - - PartitionModel* model = m_core->partitionModelForDevice( device ); - m_ui->partitionTreeView->setModel( model ); - m_ui->partitionTreeView->expandAll(); - - // Must be done here because we need to have a model set to define - // individual column resize mode - QHeaderView* header = m_ui->partitionTreeView->header(); - header->setSectionResizeMode( QHeaderView::ResizeToContents ); - header->setSectionResizeMode( 0, QHeaderView::Stretch ); - - //updateButtons(); - // Establish connection here because selection model is destroyed when - // model changes - connect( m_ui->partitionTreeView->selectionModel(), - &QItemSelectionModel::currentRowChanged, - this, - &ReplaceWidget::onPartitionViewActivated ); - - connect( model, &QAbstractItemModel::modelReset, this, &ReplaceWidget::onPartitionModelReset ); -} - - -void -ReplaceWidget::onPartitionViewActivated() -{ - QModelIndex index = m_ui->partitionTreeView->currentIndex(); - if ( !index.isValid() ) - { - return; - } - - const PartitionModel* model = static_cast< const PartitionModel* >( index.model() ); - Q_ASSERT( model ); - Partition* partition = model->partitionForIndex( index ); - Q_ASSERT( partition ); - - onPartitionSelected(); -} - - -void -ReplaceWidget::onPartitionModelReset() -{ - m_ui->partitionTreeView->expandAll(); - onPartitionSelected(); -} diff --git a/src/modules/partition/gui/ReplaceWidget.h b/src/modules/partition/gui/ReplaceWidget.h deleted file mode 100644 index 02fbdec4d..000000000 --- a/src/modules/partition/gui/ReplaceWidget.h +++ /dev/null @@ -1,68 +0,0 @@ -/* === This file is part of Calamares - === - * - * SPDX-FileCopyrightText: 2014-2015 Teo Mrnjavac - * SPDX-FileCopyrightText: 2014 Aurélien Gâteau - * SPDX-FileCopyrightText: 2018 Adriaan de Groot - * SPDX-License-Identifier: GPL-3.0-or-later - * - * Calamares is Free Software: see the License-Identifier above. - * - */ - -#ifndef REPLACEWIDGET_H -#define REPLACEWIDGET_H - -#include "Config.h" - -#include "utils/CalamaresUtilsGui.h" - -#include -#include - -class Config; -class PartitionCoreModule; -class Partition; -class Ui_ReplaceWidget; - -class QComboBox; - -struct TotallyBogus {}; - -class ReplaceWidget : public QWidget -{ - Q_OBJECT -public: - explicit ReplaceWidget( TotallyBogus n, Config *config, PartitionCoreModule* core, QComboBox* devicesComboBox, QWidget* parent = nullptr ); - virtual ~ReplaceWidget() override; - - bool isNextEnabled() const; - - void reset(); - - void applyChanges(); - -signals: - void nextStatusChanged( bool ); - -private slots: - void onPartitionSelected(); - -private: - QScopedPointer< Ui_ReplaceWidget > m_ui; - void setNextEnabled( bool enabled ); - - void updateStatus( CalamaresUtils::ImageType imageType, const QString& text ); - - PartitionCoreModule* m_core; - - bool m_nextEnabled; - - bool m_isEfi; - Config::LuksGeneration m_luksFsType; - - void updateFromCurrentDevice( QComboBox* devicesComboBox ); - void onPartitionViewActivated(); - void onPartitionModelReset(); -}; - -#endif // REPLACEWIDGET_H diff --git a/src/modules/partition/gui/ReplaceWidget.ui b/src/modules/partition/gui/ReplaceWidget.ui deleted file mode 100644 index 14f520f49..000000000 --- a/src/modules/partition/gui/ReplaceWidget.ui +++ /dev/null @@ -1,135 +0,0 @@ - - - -SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org> -SPDX-License-Identifier: GPL-3.0-or-later - - ReplaceWidget - - - - 0 - 0 - 643 - 187 - - - - Form - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - QAbstractItemView::NoEditTriggers - - - false - - - true - - - false - - - false - - - - - - - - - - - - - - - Qt::AlignCenter - - - true - - - - - - - - 0 - 0 - - - - - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - true - - - - - - - - - - - - - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - From 152895b48cada1074644d4e09e33684e6f802993 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 5 Nov 2022 16:50:05 -0500 Subject: [PATCH 34/89] [grubcfg] Add newline to config --- src/modules/grubcfg/grubcfg.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/grubcfg/grubcfg.conf b/src/modules/grubcfg/grubcfg.conf index bbc1a95c8..189d4c2a9 100644 --- a/src/modules/grubcfg/grubcfg.conf +++ b/src/modules/grubcfg/grubcfg.conf @@ -48,4 +48,4 @@ defaults: GRUB_DISABLE_RECOVERY: true # Set to true to force defaults to be used even when not overwriting -always_use_defaults: false \ No newline at end of file +always_use_defaults: false From 2ea11d4d63d47c23036f4262ee0b36fe67398482 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 5 Nov 2022 16:52:50 -0500 Subject: [PATCH 35/89] [grubcfg] Minor update from PR feedback --- src/modules/grubcfg/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/grubcfg/main.py b/src/modules/grubcfg/main.py index d8431620e..d325766f6 100644 --- a/src/modules/grubcfg/main.py +++ b/src/modules/grubcfg/main.py @@ -254,7 +254,7 @@ def modify_grub_default(partitions, root_mount_point, distributor): if always_use_defaults or overwrite or not os.path.exists(default_grub): if "defaults" in libcalamares.job.configuration: for key, value in libcalamares.job.configuration["defaults"].items(): - if value.__class__.__name__ == "bool": + if isinstance(value, bool): if value: escaped_value = "true" else: From b02255519893ff5aec8df8f95fd4f0a3f575b829 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 18 Dec 2022 00:58:44 +0100 Subject: [PATCH 36/89] [partition] Assign the replace-mode FS when reading the configuration --- src/modules/partition/Config.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 278503312..3212bf645 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -337,7 +337,9 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) Q_ASSERT( !m_eraseFsTypes.isEmpty() ); Q_ASSERT( m_eraseFsTypes.contains( fsRealName ) ); m_eraseFsTypeChoice = fsRealName; + m_replaceFileSystemChoice = fsRealName; Q_EMIT eraseModeFilesystemChanged( m_eraseFsTypeChoice ); + Q_EMIT replaceModeFilesystemChanged( m_replaceFileSystemChoice ); } From 93a24b65a974b9fe9187d8ba58470cf7a3240897 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 18 Dec 2022 01:02:08 +0100 Subject: [PATCH 37/89] [partition] (unrelated) switch types *again* to avoid compile warning --- src/modules/partition/Config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 3212bf645..b3c5ba021 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -263,8 +263,8 @@ fillGSConfigurationEFI( Calamares::GlobalStorage* gs, const QVariantMap& configu gs->insert( "efiSystemPartitionSize_i", part_size.toBytes() ); // Assign long long int to long unsigned int to prevent compilation warning - size_t unsigned_part_size = part_size.toBytes(); - if ( unsigned_part_size != PartUtils::efiFilesystemMinimumSize() ) + auto byte_part_size = part_size.toBytes(); + if ( byte_part_size != PartUtils::efiFilesystemMinimumSize() ) { cWarning() << "EFI partition size" << sizeString << "has been adjusted to" << PartUtils::efiFilesystemMinimumSize() << "bytes"; From 40b7274c85899fdaf71b17177ed97cf2cd54a19a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 18 Dec 2022 01:18:33 +0100 Subject: [PATCH 38/89] CMake: copy settings.conf into the build directory Having an up-to-date settings.conf in the build directory makes `calamares -d` in that directory much more predicatable. This should not have used CMake command `install()`. FIXES #2075 CLOSEs #2079 --- CMakeLists.txt | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 289aab268..86e8175f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -585,10 +585,6 @@ install( ### Miscellaneous installs # # -if( settings.conf IS_NEWER_THAN ${CMAKE_BINARY_DIR}/settings.conf ) - install(FILES settings.conf DESTINATION ${CMAKE_BINARY_DIR}) -endif() - if(INSTALL_POLKIT) install(FILES com.github.calamares.calamares.policy DESTINATION "${POLKITQT-1_POLICY_FILES_INSTALL_DIR}") endif() @@ -605,7 +601,9 @@ install(FILES calamares.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/application install(FILES man/calamares.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8/) -# uninstall target +### Uninstall +# +# configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" @@ -615,6 +613,17 @@ configure_file( add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake) +### Developer convenience +# +# The module support files -- .desc files, .conf files -- are copied into the build +# directory so that it is possible to run `calamares -d` from there. Copy the +# top-level settings.conf as well, into the build directory. +if( settings.conf IS_NEWER_THAN ${CMAKE_BINARY_DIR}/settings.conf ) + configure_file(settings.conf ${CMAKE_BINARY_DIR}/settings.conf COPYONLY) +endif() + + + ### CMAKE SUMMARY REPORT # get_directory_property(SKIPPED_MODULES DIRECTORY src/modules DEFINITION LIST_SKIPPED_MODULES) From 56fafb87693f6703be6c72ff6da3b1b4eefbd391 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Sun, 18 Dec 2022 14:22:10 +0100 Subject: [PATCH 39/89] Add "kms" hook to initcpiocfg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "kms" hook got added with commit¹ to the default hooks array. Follow the archlinux defaults and add it also. 1. https://gitlab.archlinux.org/archlinux/mkinitcpio/mkinitcpio/-/commit/b99eb1c0d5704ed0a0d220d0abcbbbeec10a3b76 Signed-off-by: Peter Jung --- src/modules/initcpiocfg/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index fb557a479..500bb135e 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -146,6 +146,7 @@ def find_initcpio_features(partitions, root_mount_point): hooks = [ "base", "udev", + "kms", "autodetect", "modconf", "block", From a3518e88d38c50ce1042159639a8df6eb1e5e323 Mon Sep 17 00:00:00 2001 From: dalto Date: Thu, 22 Dec 2022 17:13:43 -0600 Subject: [PATCH 40/89] [bootloader] Add refind, bootloader selection and general improvements --- src/modules/bootloader/bootloader.conf | 30 +- src/modules/bootloader/bootloader.schema.yaml | 21 +- src/modules/bootloader/main.py | 343 +++++++++++------- 3 files changed, 232 insertions(+), 162 deletions(-) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index c5b94bbc7..22e2689e7 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -9,25 +9,31 @@ # should specifically set *efiBootloaderId* to "debian" because that is # hard-coded in `grubx64.efi`. --- +# A variable from global storage which overrides the value of efiBootLoader +#efiBootLoaderVar: "packagechooser_bootloader" + # Define which bootloader you want to use for EFI installations # Possible options are 'grub', 'sb-shim' and 'systemd-boot'. efiBootLoader: "grub" -# systemd-boot configuration files settings, set kernel search path, kernel name -# and amount of time before default selection boots +# systemd-boot configuration files settings + +# kernelSearchPath is the path relative to the root of the install to search for kernels +# A kernel is identified by finding files which match regular expression, kernelPattern kernelSearchPath: "/usr/lib/modules" -kernelName: "vmlinuz" -timeout: "10" +kernelPattern: "^vmlinuz.*" -# additionalInitrdFiles is a comma seperated list of file names -additionalInitrdFiles: - - "/boot/amd-ucode" - - "/boot/intel-ucode" +# loaderEntries is an array of options to add to loader.conf for systemd-boot +# please note that the "default" option is added programmatically +loaderEntries: + - "timeout 5" + - "console-mode keep" -# Optionally set the menu entry name to use in systemd-boot. -# If not specified here, these settings will be taken from branding.desc. -# -# bootloaderEntryName: "Generic GNU/Linux" +# systemd-boot and refind support custom kernel params +kernelParams: [ "quiet" ] + +# A list of kernel names that refind should accept as kernels +#refindKernelList: [ "linux","linux-lts","linux-zen","linux-hardened" ] # GRUB 2 binary names and boot directory # Some distributions (e.g. Fedora) use grub2-* (resp. /boot/grub2/) names. diff --git a/src/modules/bootloader/bootloader.schema.yaml b/src/modules/bootloader/bootloader.schema.yaml index ef61721c0..2505dc73e 100644 --- a/src/modules/bootloader/bootloader.schema.yaml +++ b/src/modules/bootloader/bootloader.schema.yaml @@ -6,17 +6,13 @@ $id: https://calamares.io/schemas/bootloader additionalProperties: false type: object properties: + efiBootLoaderVar: { type: string } efiBootLoader: { type: string } kernelSearchPath: { type: string } kernelName: { type: string } - timeout: { type: string } # Inserted verbatim - additionalInitrdFiles: - type: array - items: - type: string - bootloaderEntryName: { type: string } - kernelLine: { type: string } - fallbackKernelLine: { type: string } + kernelParams: { type: array, items: { type: string } } + loaderEntries: { type: array, items: { type: string } } + refindKernelList: { type: array, items: { type: string } } # Programs grubInstall: { type: string } @@ -27,12 +23,3 @@ properties: efiBootloaderId: { type: string } installEFIFallback: { type: boolean } - -required: - - efiBootLoader - - kernelSearchPath - - kernelName - - grubInstall - - grubMkconfig - - grubCfg - - grubProbe diff --git a/src/modules/bootloader/main.py b/src/modules/bootloader/main.py index c10d8bf2e..4a5a93f60 100644 --- a/src/modules/bootloader/main.py +++ b/src/modules/bootloader/main.py @@ -20,7 +20,9 @@ # Calamares is Free Software: see the License-Identifier above. # +import fileinput import os +import re import shutil import subprocess @@ -28,8 +30,8 @@ import libcalamares from libcalamares.utils import check_target_env_call - import gettext + _ = gettext.translation("calamares-python", localedir=libcalamares.utils.gettext_path(), languages=libcalamares.utils.gettext_languages(), @@ -39,6 +41,7 @@ _ = gettext.translation("calamares-python", # to make identifiers (or to clean up names to make filenames). file_name_sanitizer = str.maketrans(" /()", "_-__") + def pretty_name(): return _("Install bootloader.") @@ -59,20 +62,6 @@ def get_uuid(): return "" -def get_bootloader_entry_name(): - """ - Passes 'bootloader_entry_name' to other routine based - on configuration file. - - :return: - """ - if "bootloaderEntryName" in libcalamares.job.configuration: - return libcalamares.job.configuration["bootloaderEntryName"] - else: - branding = libcalamares.globalstorage.value("branding") - return branding["bootloaderEntryName"] - - def get_kernel_line(kernel_type): """ Passes 'kernel_line' to other routine based on configuration file. @@ -136,49 +125,43 @@ def is_zfs_root(partition): return partition["mountPoint"] == "/" and partition["fs"] == "zfs" -def create_systemd_boot_conf(installation_root_path, efi_dir, uuid, entry, kernel, kernel_type, kernel_version): - """ - Creates systemd-boot configuration files based on given parameters. - - :param installation_root_path: A string containing the absolute path to the root of the installation - :param efi_dir: A string containing the path to the efi dir relative to the root of the installation - :param uuid: A string containing the UUID of the root volume - :param entry: A string containing the name of the entry as it will be displayed on boot - :param kernel: A string containing the path to the kernel relative to the root of the installation - :param kernel_type: A string which should be set if there is a special version of the entry, for example "fallback" - :param kernel_version: The kernel version string - """ - kernel_params = ["quiet"] +def get_kernel_params(uuid): + kernel_params = libcalamares.job.configuration.get("kernelParams", ["quiet"]) + kernel_params.append("rw") partitions = libcalamares.globalstorage.value("partitions") swap_uuid = "" swap_outer_mappername = None + swap_outer_uuid = None cryptdevice_params = [] + have_dracut = libcalamares.utils.target_env_call(["sh", "-c", "which dracut"]) == 0 + # Take over swap settings: # - unencrypted swap partition sets swap_uuid # - encrypted root sets cryptdevice_params for partition in partitions: if partition["fs"] == "linuxswap" and not partition.get("claimed", None): + # Skip foreign swap continue has_luks = "luksMapperName" in partition if partition["fs"] == "linuxswap" and not has_luks: swap_uuid = partition["uuid"] - if (partition["fs"] == "linuxswap" and has_luks): + if partition["fs"] == "linuxswap" and has_luks: swap_outer_mappername = partition["luksMapperName"] + swap_outer_uuid = partition["luksUuid"] if partition["mountPoint"] == "/" and has_luks: - cryptdevice_params = ["cryptdevice=UUID=" - + partition["luksUuid"] - + ":" - + partition["luksMapperName"], - "root=/dev/mapper/" - + partition["luksMapperName"]] + if have_dracut: + cryptdevice_params = [f"rd.luks.uuid={partition['luksUuid']}"] + else: + cryptdevice_params = [f"cryptdevice=UUID={partition['luksUuid']}:{partition['luksMapperName']}"] + cryptdevice_params.append(f"root=/dev/mapper/{partition['luksMapperName']}") + # btrfs and zfs handling for partition in partitions: - # systemd-boot with a BTRFS root filesystem needs to be told abouut the root subvolume. # If a btrfs root subvolume wasn't set, it means the root is directly on the partition # and this option isn't needed if is_btrfs_root(partition): @@ -190,7 +173,7 @@ def create_systemd_boot_conf(installation_root_path, efi_dir, uuid, entry, kerne if is_zfs_root(partition): zfs_root_path = get_zfs_root() if zfs_root_path is not None: - kernel_params.append("zfs=" + zfs_root_path) + kernel_params.append("root=ZFS=" + zfs_root_path) else: # Something is really broken if we get to this point libcalamares.utils.warning("Internal error handling zfs dataset") @@ -204,93 +187,86 @@ def create_systemd_boot_conf(installation_root_path, efi_dir, uuid, entry, kerne if swap_uuid: kernel_params.append("resume=UUID={!s}".format(swap_uuid)) + if have_dracut and swap_outer_uuid: + kernel_params.append(f"rd.luks.uuid={swap_outer_uuid}") + if swap_outer_mappername: - kernel_params.append("resume=/dev/mapper/{!s}".format( - swap_outer_mappername)) + kernel_params.append(f"resume=/dev/mapper/{swap_outer_mappername}") - libcalamares.utils.debug("Configure: \"{!s}\"".format(f"{entry} {kernel_version}")) + return kernel_params - if kernel_type == "fallback": - version_string = kernel_version + "-fallback" - initrd = "initrd-fallback" - else: - version_string = kernel_version - initrd = "initrd" + +def create_systemd_boot_conf(installation_root_path, efi_dir, uuid, kernel, kernel_version): + """ + Creates systemd-boot configuration files based on given parameters. + + :param installation_root_path: A string containing the absolute path to the root of the installation + :param efi_dir: A string containing the path to the efi dir relative to the root of the installation + :param uuid: A string containing the UUID of the root volume + :param kernel: A string containing the path to the kernel relative to the root of the installation + :param kernel_version: The kernel version string + """ + + # Get the kernel params and write them to /etc/kernel/cmdline + # This file is used by kernel-install + kernel_params = " ".join(get_kernel_params(uuid)) + kernel_cmdline_path = os.path.join(installation_root_path, "etc", "kernel") + os.makedirs(kernel_cmdline_path, exist_ok=True) + with open(os.path.join(kernel_cmdline_path, "cmdline"), "w") as cmdline_file: + cmdline_file.write(kernel_params) + + libcalamares.utils.debug(f"Configuring kernel version {kernel_version}") # get the machine-id with open(os.path.join(installation_root_path, "etc", "machine-id"), 'r') as machineid_file: machine_id = machineid_file.read().rstrip('\n') - # Copy kernel to a subdirectory of /efi partition + # Ensure the directory exists machine_dir = os.path.join(installation_root_path + efi_dir, machine_id) os.makedirs(machine_dir, exist_ok=True) - target_efi_files_dir = os.path.join(machine_dir, kernel_version) - os.makedirs(target_efi_files_dir, exist_ok=True) - - kernel_path = os.path.join(installation_root_path, kernel) - kernel_name = os.path.basename(kernel_path) - shutil.copyfile(kernel_path, os.path.join(target_efi_files_dir, "linux")) - - # write the entry - lines = [ - '## Generated by Calamares\n', - '\n', - "title {!s}\n".format(entry), - "version {!s}\n".format(version_string), - "machine-id {!s}\n".format(machine_id), - "linux {!s}\n".format(os.path.join("/", machine_id, kernel_version, "linux")), - ] - - try: - additional_initrd_files = libcalamares.job.configuration["additionalInitrdFiles"] - for initrd_file in additional_initrd_files: - libcalamares.utils.debug("Attempting to handle initrd image " + initrd_file) - if os.path.isfile(os.path.join(installation_root_path, initrd_file.lstrip('/'))): - libcalamares.utils.debug("Found image " + initrd_file) - shutil.copyfile(os.path.join(installation_root_path, initrd_file.lstrip('/')), os.path.join(target_efi_files_dir, os.path.basename(initrd_file))) - lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, os.path.basename(initrd_file)))) - except KeyError: # If the configuration option isn't set, we can just move on - libcalamares.utils.debug("Failed to find key additionalInitrdFiles") - pass - - lines.append("initrd {!s}\n".format(os.path.join("/", machine_id, kernel_version, initrd))) - lines.append("options {!s} rw\n".format(" ".join(kernel_params))) - - conf_path = os.path.join(installation_root_path + efi_dir, - "loader", - "entries", - machine_id + "-" + version_string + ".conf") - - with open(conf_path, 'w') as conf_file: - for line in lines: - conf_file.write(line) + # Call kernel-install for each kernel + libcalamares.utils.target_env_process_output(["kernel-install", + "add", + kernel_version, + os.path.join("/", kernel)]) -def create_loader(loader_path, entry): +def create_loader(loader_path, installation_root_path): """ Writes configuration for loader. - :param loader_path: - :param entry: + :param loader_path: The absolute path to the loader.conf file + :param installation_root_path: The path to the root of the target installation """ - timeout = libcalamares.job.configuration["timeout"] - lines = [ - "timeout {!s}\n".format(timeout), - "default {!s}\n".format(entry), - ] + + # get the machine-id + with open(os.path.join(installation_root_path, "etc", "machine-id"), 'r') as machineid_file: + machine_id = machineid_file.read().rstrip('\n') + + try: + loader_entries = libcalamares.job.configuration["loaderEntries"] + except KeyError: + libcalamares.utils.debug("No aditional loader entries found in config") + loader_entries = [] + pass + + lines = [f"default {machine_id}*"] + + lines.extend(loader_entries) with open(loader_path, 'w') as loader_file: for line in lines: - loader_file.write(line) + loader_file.write(line + "\n") -class suffix_iterator(object): +class SuffixIterator(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 @@ -310,6 +286,7 @@ 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 @@ -354,6 +331,7 @@ 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 @@ -427,7 +405,7 @@ def change_efi_suffix(efi_directory, bootloader_id): """ if bootloader_id.endswith("}") and "${" in bootloader_id: # Do 10 attempts with any suffix generator - g = suffix_iterator(10, get_efi_suffix_generator(bootloader_id)) + g = SuffixIterator(10, get_efi_suffix_generator(bootloader_id)) else: # Just one attempt g = [bootloader_id] @@ -444,7 +422,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, libcalamares.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"] @@ -482,6 +460,7 @@ def efi_boot_next(): if boot_entry: subprocess.call([boot_mgr, "-n", boot_entry]) + def get_kernels(installation_root_path): """ Gets a list of kernels and associated values for each kernel. This will work as is for many distros. @@ -493,20 +472,32 @@ def get_kernels(installation_root_path): Each 3-tuple contains the kernel, kernel_type and kernel_version """ - kernel_search_path = libcalamares.job.configuration["kernelSearchPath"] - source_kernel_name = libcalamares.job.configuration["kernelName"] + try: + kernel_search_path = libcalamares.job.configuration["kernelSearchPath"] + except KeyError: + libcalamares.utils.warning("No kernel pattern found in configuration, using '/usr/lib/modules'") + kernel_search_path = "/usr/lib/modules" + pass + kernel_list = [] - # find all the installed kernels and generate default and fallback entries for each + try: + kernel_pattern = libcalamares.job.configuration["kernelPattern"] + except KeyError: + libcalamares.utils.warning("No kernel pattern found in configuration, using 'vmlinuz'") + kernel_pattern = "vmlinuz" + pass + + # find all the installed kernels for root, dirs, files in os.walk(os.path.join(installation_root_path, kernel_search_path.lstrip('/'))): for file in files: - if file == source_kernel_name: + if re.search(kernel_pattern, file): rel_root = os.path.relpath(root, installation_root_path) - kernel_list.append((os.path.join(rel_root, file),"default",os.path.basename(root))) - kernel_list.append((os.path.join(rel_root, file),"fallback",os.path.basename(root))) + kernel_list.append((os.path.join(rel_root, file), "default", os.path.basename(root))) return kernel_list + def install_systemd_boot(efi_directory): """ Installs systemd-boot as bootloader for EFI setups. @@ -517,8 +508,6 @@ def install_systemd_boot(efi_directory): installation_root_path = libcalamares.globalstorage.value("rootMountPoint") install_efi_directory = installation_root_path + efi_directory uuid = get_uuid() - distribution = get_bootloader_entry_name() - distribution_translated = distribution.translate(file_name_sanitizer) loader_path = os.path.join(install_efi_directory, "loader", "loader.conf") @@ -528,14 +517,13 @@ def install_systemd_boot(efi_directory): for (kernel, kernel_type, kernel_version) in get_kernels(installation_root_path): create_systemd_boot_conf(installation_root_path, - efi_directory, - uuid, - distribution, - kernel, - kernel_type, - kernel_version) + efi_directory, + uuid, + kernel, + kernel_version) + + create_loader(loader_path, installation_root_path) - create_loader(loader_path, distribution_translated) def get_grub_efi_parameters(): """ @@ -554,15 +542,16 @@ def get_grub_efi_parameters(): if efi_bitness == "32": # Assume all 32-bitters are legacy x86 - return ("i386-efi", "grubia32.efi", "bootia32.efi") + return "i386-efi", "grubia32.efi", "bootia32.efi" elif efi_bitness == "64" and cpu_type == "aarch64": - return ("arm64-efi", "grubaa64.efi", "bootaa64.efi") + return "arm64-efi", "grubaa64.efi", "bootaa64.efi" elif efi_bitness == "64" and cpu_type == "loongarch64": - return ("loongarch64-efi", "grubloongarch64.efi", "bootloongarch64.efi") + return "loongarch64-efi", "grubloongarch64.efi", "bootloongarch64.efi" elif efi_bitness == "64": # If it's not ARM, must by AMD64 - return ("x86_64-efi", "grubx64.efi", "bootx64.efi") - libcalamares.utils.warning("Could not find GRUB parameters for bits {b} and cpu {c}".format(b=repr(efi_bitness), c=repr(cpu_type))) + return "x86_64-efi", "grubx64.efi", "bootx64.efi" + libcalamares.utils.warning( + "Could not find GRUB parameters for bits {b} and cpu {c}".format(b=repr(efi_bitness), c=repr(cpu_type))) return None @@ -667,8 +656,8 @@ def install_grub(efi_directory, fw_type): # VFAT is weird, see issue CAL-385 install_efi_directory_firmware = (vfat_correct_case( - install_efi_directory, - "EFI")) + install_efi_directory, + "EFI")) if not os.path.exists(install_efi_directory_firmware): os.makedirs(install_efi_directory_firmware) @@ -676,8 +665,8 @@ def install_grub(efi_directory, fw_type): # most usual they are boot, Boot, BOOT install_efi_boot_directory = (vfat_correct_case( - install_efi_directory_firmware, - "boot")) + install_efi_directory_firmware, + "boot")) if not os.path.exists(install_efi_boot_directory): os.makedirs(install_efi_boot_directory) @@ -712,6 +701,9 @@ def install_secureboot(efi_directory): install_efi_bin = "shimx64.efi" elif efi_word_size() == "32": install_efi_bin = "shimia32.efi" + else: + libcalamares.utils.warning(f"Unknown efi word size of {efi_word_size()} found") + return None # Copied, roughly, from openSUSE's install script, # and pythonified. *disk* is something like /dev/sda, @@ -725,7 +717,7 @@ def install_secureboot(efi_directory): libcalamares.job.configuration["grubProbe"], "-t", "disk", "--device-map=", install_efi_directory]).decode("ascii") - efi_drive_partition = efi_drive.replace("(","").replace(")","").split(",")[1] + efi_drive_partition = efi_drive.replace("(", "").replace(")", "").split(",")[1] # Get the first run of digits from the partition efi_partition_number = None c = 0 @@ -765,6 +757,62 @@ def vfat_correct_case(parent, name): return os.path.join(parent, name) +def efi_partitions(efi_boot_path): + """ + The (one) partition mounted on @p efi_boot_path, or an empty list. + """ + return [p for p in libcalamares.globalstorage.value("partitions") if p["mountPoint"] == efi_boot_path] + + +def update_refind_config(efi_directory, installation_root_path): + """ + :param efi_directory: The path to the efi directory relative to the root + :param installation_root_path: The path to the root of the installation + """ + try: + kernel_list = libcalamares.job.configuration["refindKernelList"] + except KeyError: + libcalamares.utils.warning('refindKernelList not set. Skipping updating refind.conf') + return + + # Update the config in the file + for line in fileinput.input(installation_root_path + efi_directory + "/EFI/refind/refind.conf", inplace=True): + line = line.strip() + if line.startswith("#extra_kernel_version_strings") or line.startswith("extra_kernel_version_strings"): + line = line.lstrip("#") + for kernel in kernel_list: + if kernel not in line: + line += "," + kernel + print(line) + + +def install_refind(efi_directory): + try: + installation_root_path = libcalamares.globalstorage.value("rootMountPoint") + except KeyError: + libcalamares.utils.warning('Global storage value "rootMountPoint" missing') + + install_efi_directory = installation_root_path + efi_directory + uuid = get_uuid() + kernel_params = " ".join(get_kernel_params(uuid)) + conf_path = os.path.join(installation_root_path, "boot/refind_linux.conf") + + check_target_env_call(["refind-install"]) + + with open(conf_path, "r") as refind_file: + filedata = [x.strip() for x in refind_file.readlines()] + + with open(conf_path, 'w') as refind_file: + for line in filedata: + if line.startswith('"Boot with standard options"'): + line = f'"Boot with standard options" "{kernel_params}"' + elif line.startswith('"Boot to single-user mode"'): + line = f'"Boot to single-user mode" "{kernel_params}" single' + refind_file.write(line + "\n") + + update_refind_config(efi_directory, installation_root_path) + + def prepare_bootloader(fw_type): """ Prepares bootloader. @@ -774,19 +822,47 @@ def prepare_bootloader(fw_type): :param fw_type: :return: """ - efi_boot_loader = libcalamares.job.configuration["efiBootLoader"] + + # Get the boot loader selection from global storage if it is set in the config file + try: + gs_name = libcalamares.job.configuration["efiBootLoaderVar"] + if libcalamares.globalstorage.contains(gs_name): + efi_boot_loader = libcalamares.globalstorage.value(gs_name) + else: + libcalamares.utils.warning( + f"Specified global storage value not found in global storage") + return None + except KeyError: + # If the conf value for using global storage is not set, use the setting from the config file. + try: + efi_boot_loader = libcalamares.job.configuration["efiBootLoader"] + except KeyError: + if fw_type == "efi": + libcalamares.utils.warning("Configuration missing both efiBootLoader and efiBootLoaderVar on an EFI " + "system, bootloader not installed") + return + else: + pass + + # If the user has selected not to install bootloader, bail out here + if efi_boot_loader.casefold() == "none": + libcalamares.utils.debug("Skipping bootloader installation since no bootloader was selected") + return None + efi_directory = libcalamares.globalstorage.value("efiSystemPartition") if efi_boot_loader == "systemd-boot" and fw_type == "efi": install_systemd_boot(efi_directory) elif efi_boot_loader == "sb-shim" and fw_type == "efi": install_secureboot(efi_directory) + elif efi_boot_loader == "refind" and fw_type == "efi": + install_refind(efi_directory) elif efi_boot_loader == "grub" or fw_type != "efi": install_grub(efi_directory, fw_type) else: - libcalamares.utils.debug( "WARNING: the combination of " - "boot-loader '{!s}' and firmware '{!s}' " - "is not supported.".format(efi_boot_loader, fw_type) ) + libcalamares.utils.debug("WARNING: the combination of " + "boot-loader '{!s}' and firmware '{!s}' " + "is not supported.".format(efi_boot_loader, fw_type)) def run(): @@ -798,16 +874,16 @@ def run(): fw_type = libcalamares.globalstorage.value("firmwareType") - if (libcalamares.globalstorage.value("bootLoader") is None and fw_type != "efi"): - libcalamares.utils.warning( "Non-EFI system, and no bootloader is set." ) + if libcalamares.globalstorage.value("bootLoader") is None and fw_type != "efi": + libcalamares.utils.warning("Non-EFI system, and no bootloader is set.") return None partitions = libcalamares.globalstorage.value("partitions") if fw_type == "efi": efi_system_partition = libcalamares.globalstorage.value("efiSystemPartition") - esp_found = [ p for p in partitions if p["mountPoint"] == efi_system_partition ] + esp_found = [p for p in partitions if p["mountPoint"] == efi_system_partition] if not esp_found: - libcalamares.utils.warning( "EFI system, but nothing mounted on {!s}".format(efi_system_partition) ) + libcalamares.utils.warning("EFI system, but nothing mounted on {!s}".format(efi_system_partition)) return None try: @@ -817,7 +893,8 @@ def run(): libcalamares.utils.debug("stdout:" + str(e.stdout)) libcalamares.utils.debug("stderr:" + str(e.stderr)) return (_("Bootloader installation error"), - _("The bootloader could not be installed. The installation command
{!s}
returned error code {!s}.") + _("The bootloader could not be installed. The installation command
{!s}
returned error " + "code {!s}.") .format(e.cmd, e.returncode)) return None From 672cbc3d1ad3b80226c1a902d4a7447ed4ab7f96 Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Fri, 23 Dec 2022 11:47:19 +0100 Subject: [PATCH 41/89] Use kms hook after autodetect Signed-off-by: Peter Jung --- src/modules/initcpiocfg/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index 500bb135e..5fd9d93ae 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -146,8 +146,8 @@ def find_initcpio_features(partitions, root_mount_point): hooks = [ "base", "udev", - "kms", "autodetect", + "kms", "modconf", "block", "keyboard", From bf77a94721e226ba30dc10a92c9cb4482773dfb3 Mon Sep 17 00:00:00 2001 From: wiz64 <67432394+wiz64@users.noreply.github.com> Date: Mon, 2 Jan 2023 19:19:57 +0530 Subject: [PATCH 42/89] Update actions shields.io image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 570adf575..66475c6d3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,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 Build Status](https://img.shields.io/github/actions/workflow/status/calamares/calamares/push.yml)](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/GPL-3.0-or-later.txt) From a307d7d5c11aa9155607c757795ee7f1f00bcdec Mon Sep 17 00:00:00 2001 From: wiz64 <67432394+wiz64@users.noreply.github.com> Date: Fri, 13 Jan 2023 21:11:42 +0530 Subject: [PATCH 43/89] Update license shields --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 66475c6d3..d3d1cdd61 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/actions/workflow/status/calamares/calamares/push.yml)](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/GPL-3.0-or-later.txt) +[![GitHub license](https://img.shields.io/badge/license-GPL-green)](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 117e2fecf9e090ecdb04945dc6d31052cbb7aa51 Mon Sep 17 00:00:00 2001 From: wiz64 <67432394+wiz64@users.noreply.github.com> Date: Sat, 14 Jan 2023 21:17:10 +0530 Subject: [PATCH 44/89] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d3d1cdd61..35a75453b 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/actions/workflow/status/calamares/calamares/push.yml)](https://github.com/calamares/calamares/actions?query=workflow%3Aci) -[![GitHub license](https://img.shields.io/badge/license-GPL-green)](https://github.com/calamares/calamares/blob/calamares/LICENSES/GPL-3.0-or-later.txt) +[![GitHub license](https://img.shields.io/badge/license-Multiple-green)](https://github.com/calamares/calamares/tree/calamares/LICENSES) | [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 871651c0c16300dc95b0430a6a9432dd83705905 Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 22 Jan 2023 10:40:58 -0600 Subject: [PATCH 45/89] [partition] Restore encryption option to alongside and replace partition options --- src/modules/partition/gui/ChoicePage.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index a6c2831af..b2dd685f0 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1741,5 +1741,7 @@ ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const // If there are any choices for FS, check it's not ZFS because that doesn't // support the kind of encryption we enable here. const bool suitableFS = m_eraseFsTypesChoiceComboBox ? m_eraseFsTypesChoiceComboBox->currentText() != "zfs" : true; - return ( choice == InstallChoice::Erase ) && m_enableEncryptionWidget && suitableFS; + const bool suitableChoice + = choice == InstallChoice::Erase || choice == InstallChoice::Alongside || choice == InstallChoice::Replace; + return suitableChoice && m_enableEncryptionWidget && suitableFS; } From f1f903ef9fd34aecc68aa4dce526dfb1dedbd796 Mon Sep 17 00:00:00 2001 From: dalto8 <57767042+dalto8@users.noreply.github.com> Date: Sun, 5 Feb 2023 16:28:05 +0000 Subject: [PATCH 46/89] [bootloader] Add refind to the comments for efiBootLoader --- src/modules/bootloader/bootloader.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/bootloader/bootloader.conf b/src/modules/bootloader/bootloader.conf index 22e2689e7..9679f6696 100644 --- a/src/modules/bootloader/bootloader.conf +++ b/src/modules/bootloader/bootloader.conf @@ -13,7 +13,7 @@ #efiBootLoaderVar: "packagechooser_bootloader" # Define which bootloader you want to use for EFI installations -# Possible options are 'grub', 'sb-shim' and 'systemd-boot'. +# Possible options are 'grub', 'sb-shim', 'refind` and 'systemd-boot'. efiBootLoader: "grub" # systemd-boot configuration files settings From f142710feee559ee3d7075a38883fa3b7957eb02 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Feb 2023 10:52:25 +0100 Subject: [PATCH 47/89] [displaymanager] Overwrite DM-instance settings with config-settings If there are settings in the config-file, they can overwrite settings in the DM-instance in code. --- src/modules/displaymanager/main.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index f908bc441..6f80751f2 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -983,6 +983,11 @@ def run(): # Do the actual configuration and collect messages dm_setup_message = [] for dm in dm_impl: + dm_specific_configuration = libcalamares.job.configuration.get(dm.name, None) + if dm_specific_configuration and isinstance(dm_specific_configuration, dict): + for k, v in dm_specific_configuration.items(): + if hasattr(dm, k): + setattr(dm, k, v) dm_message = None if enable_basic_setup: dm_message = dm.basic_setup() From 46a28543b9cee725989e5517aeebd20d450ec3e9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 6 Feb 2023 11:03:28 +0100 Subject: [PATCH 48/89] [displaymanager] Add configuration items + schema for greetd user --- src/modules/displaymanager/displaymanager.conf | 8 ++++++++ src/modules/displaymanager/displaymanager.schema.yaml | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/src/modules/displaymanager/displaymanager.conf b/src/modules/displaymanager/displaymanager.conf index c5c0e0b78..18e956f27 100644 --- a/src/modules/displaymanager/displaymanager.conf +++ b/src/modules/displaymanager/displaymanager.conf @@ -59,3 +59,11 @@ basicSetup: false # *displaymanagers* list (as the only one). # sysconfigSetup: false + +# Some DMs have specific settings. These can be customized here. +# +# greetd has configurable user and group; the user and group is created if it +# does not exist, and the user is set as default-session user. +greetd: + greeter_user: "tom_bombadil" + greeter_group: "wheel" diff --git a/src/modules/displaymanager/displaymanager.schema.yaml b/src/modules/displaymanager/displaymanager.schema.yaml index 7e4c5f54c..2f1da9d56 100644 --- a/src/modules/displaymanager/displaymanager.schema.yaml +++ b/src/modules/displaymanager/displaymanager.schema.yaml @@ -20,3 +20,10 @@ properties: required: [ executable, desktopFile ] basicSetup: { type: boolean, default: false } sysconfigSetup: { type: boolean, default: false } + greetd: + type: object + properties: + greeter_user: { type: string } + greeter_group: { type: string } + additionalProperties: false + From 81c316efd1894606c3ff53daae98f39dbde5db8c Mon Sep 17 00:00:00 2001 From: Sunderland93 Date: Mon, 6 Feb 2023 17:12:21 +0400 Subject: [PATCH 49/89] gtkgreet: disable window decoration in Cage --- src/modules/displaymanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index f908bc441..c21f21a66 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -828,7 +828,7 @@ class DMgreetd(DisplayManager): de_command = default_desktop_environment.executable if os.path.exists(self.os_path("usr/bin/gtkgreet")) and os.path.exists(self.os_path("usr/bin/cage")): - self.config_data['default_session']['command'] = "cage -s -- gtkgreet" + self.config_data['default_session']['command'] = "cage -d -s -- gtkgreet" elif os.path.exists(self.os_path("usr/bin/tuigreet")): tuigreet_base_cmd = "tuigreet --remember --time --issue --asterisks --cmd " self.config_data['default_session']['command'] = tuigreet_base_cmd + de_command From 77e1407c5110b32259230c33f46912c87a834579 Mon Sep 17 00:00:00 2001 From: Masato Toyoshima Date: Tue, 14 Feb 2023 04:30:24 +0900 Subject: [PATCH 50/89] During installation, if a swap partition exists, enable swap. If there is no swap at all when the partition of the installation destination device is mounted, if a Swap partition exists, enable swap. --- src/modules/mount/main.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index cb36120d8..ddf46d8e9 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -307,7 +307,7 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun mount_option) != 0: libcalamares.utils.warning("Cannot mount {}".format(device)) -def enable_swap_partition(swap_partitions): +def enable_swap_partitions(swap_partitions): try: for swap_device in swap_partitions: libcalamares.utils.host_env_process_output(["swapon", swap_device]) @@ -328,9 +328,8 @@ def run(): _("No partitions are defined for
{!s}
to use.").format("mount")) # swap - swap_partitions = [p['device'] for p in partitions if p['fs'] == 'linuxswap' and p['claimed'] == False ] - if ( swap_partitions != [] ): - enable_swap_partition(swap_partitions) + swap_partitions = [p['device'] for p in partitions if p['fs'] == 'linuxswap' ] + enable_swap_partitions(swap_partitions) root_mount_point = tempfile.mkdtemp(prefix="calamares-root-") From 8080adbce2300e4b188fdae71479848573b38a5f Mon Sep 17 00:00:00 2001 From: dalto Date: Fri, 17 Feb 2023 15:33:37 -0600 Subject: [PATCH 51/89] [partition] Fix issues with replace partition --- src/modules/partition/gui/ChoicePage.cpp | 31 ++++++++++++++++++------ src/modules/partition/gui/ChoicePage.h | 2 +- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index e782a0299..ef26fc7e5 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -290,11 +290,14 @@ ChoicePage::setupChoices() m_eraseButton->addOptionsComboBox( m_eraseFsTypesChoiceComboBox ); // Also offer it for "replace - auto* box = new QComboBox; - box->addItems( m_config->eraseFsTypes() ); - connect( box, &QComboBox::currentTextChanged, m_config, &Config::setReplaceFilesystemChoice ); + m_replaceFsTypesChoiceComboBox = new QComboBox; + m_replaceFsTypesChoiceComboBox->addItems( m_config->eraseFsTypes() ); + connect( m_replaceFsTypesChoiceComboBox, + &QComboBox::currentTextChanged, + m_config, + &Config::setReplaceFilesystemChoice ); connect( m_config, &Config::replaceModeFilesystemChanged, this, &ChoicePage::onActionChanged ); - m_replaceButton->addOptionsComboBox( box ); + m_replaceButton->addOptionsComboBox( m_replaceFsTypesChoiceComboBox ); } m_itemsLayout->addWidget( m_alongsideButton ); @@ -451,7 +454,6 @@ ChoicePage::continueApplyDeviceChoice() if ( m_lastSelectedDeviceIndex != m_drivesCombo->currentIndex() ) { m_lastSelectedDeviceIndex = m_drivesCombo->currentIndex(); - m_lastSelectedActionIndex = -1; m_config->setInstallChoice( m_config->initialInstallChoice() ); checkInstallChoiceRadioButton( m_config->installChoice() ); } @@ -485,9 +487,9 @@ ChoicePage::onEraseSwapChoiceChanged() void ChoicePage::applyActionChoice( InstallChoice choice ) { - cDebug() << "Prev" << m_lastSelectedActionIndex << "InstallChoice" << choice - << Config::installChoiceNames().find( choice ); + cDebug() << "InstallChoice" << choice << Config::installChoiceNames().find( choice ); m_beforePartitionBarsView->selectionModel()->disconnect( SIGNAL( currentRowChanged( QModelIndex, QModelIndex ) ) ); + auto priorSelection = m_beforePartitionBarsView->selectionModel()->currentIndex(); m_beforePartitionBarsView->selectionModel()->clearSelection(); m_beforePartitionBarsView->selectionModel()->clearCurrentIndex(); @@ -546,6 +548,12 @@ ChoicePage::applyActionChoice( InstallChoice choice ) this, SLOT( onPartitionToReplaceSelected( QModelIndex, QModelIndex ) ), Qt::UniqueConnection ); + + // Maintain the selection for replace + if ( priorSelection.isValid() ) + { + m_beforePartitionBarsView->selectionModel()->setCurrentIndex( priorSelection, QItemSelectionModel::Select ); + } break; case InstallChoice::Alongside: @@ -1742,7 +1750,14 @@ ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const { // If there are any choices for FS, check it's not ZFS because that doesn't // support the kind of encryption we enable here. - const bool suitableFS = m_eraseFsTypesChoiceComboBox ? m_eraseFsTypesChoiceComboBox->currentText() != "zfs" : true; + bool suitableFS = true; + if ( ( m_eraseFsTypesChoiceComboBox && m_eraseFsTypesChoiceComboBox->isVisible() + && m_eraseFsTypesChoiceComboBox->currentText() == "zfs" ) + || ( m_replaceFsTypesChoiceComboBox && m_replaceFsTypesChoiceComboBox->isVisible() + && m_replaceFsTypesChoiceComboBox->currentText() == "zfs" ) ) + { + suitableFS = false; + } const bool suitableChoice = choice == InstallChoice::Erase || choice == InstallChoice::Alongside || choice == InstallChoice::Replace; return suitableChoice && m_enableEncryptionWidget && suitableFS; diff --git a/src/modules/partition/gui/ChoicePage.h b/src/modules/partition/gui/ChoicePage.h index 6d77629d4..684a55018 100644 --- a/src/modules/partition/gui/ChoicePage.h +++ b/src/modules/partition/gui/ChoicePage.h @@ -152,6 +152,7 @@ private: Calamares::Widgets::PrettyRadioButton* m_somethingElseButton; QComboBox* m_eraseSwapChoiceComboBox = nullptr; // UI, see also Config's swap choice QComboBox* m_eraseFsTypesChoiceComboBox = nullptr; // UI, see also Config's erase-mode FS + QComboBox* m_replaceFsTypesChoiceComboBox = nullptr; // UI, see also Config's erase-mode FS DeviceInfoWidget* m_deviceInfoWidget; @@ -166,7 +167,6 @@ private: QPointer< QComboBox > m_efiComboBox; int m_lastSelectedDeviceIndex = -1; - int m_lastSelectedActionIndex = -1; bool m_enableEncryptionWidget = false; From a1c9dedc37aab1d964ab702b58e7acba589ac0c4 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 18 Feb 2023 09:43:03 -0600 Subject: [PATCH 52/89] [partition] Make replace partition call setDefaultFsType() so the FS is updated --- src/modules/partition/core/PartitionActions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 80f86427c..2287c57bd 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -217,6 +217,12 @@ doReplacePartition( PartitionCoreModule* core, Device* dev, Partition* partition cDebug() << "doReplacePartition for device" << partition->partitionPath(); + // Looking up the defaultFsType (which should name a filesystem type) + // will log an error and set the type to Unknown if there's something wrong. + FileSystem::Type type = FileSystem::Unknown; + PartUtils::canonicalFilesystemName( o.defaultFsType, &type ); + core->partitionLayout().setDefaultFsType( type == FileSystem::Unknown ? FileSystem::Ext4 : type ); + PartitionRole newRoles( partition->roles() ); if ( partition->roles().has( PartitionRole::Extended ) ) { From c54ce69e67316cb3baad20455a3a26243fb01ef0 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 18 Feb 2023 15:36:35 -0600 Subject: [PATCH 53/89] [partition] Fix merge error --- src/modules/partition/gui/ChoicePage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 739310354..8a76a7ade 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -862,7 +862,7 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current ) selectedPartition, { gs->value( "defaultPartitionType" ).toString(), m_config->replaceModeFilesystem(), - gs->value( "luksFileSystemType" ).toString(), + m_config->luksFileSystemType(), m_encryptWidget->passphrase() } ); Partition* homePartition = findPartitionByPath( { selectedDevice() }, *homePartitionPath ); From cea2b1e8d8d1f89b79f133d0af6e1fbe48272462 Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 18 Feb 2023 16:15:59 -0600 Subject: [PATCH 54/89] [partition] Enable zfs encryption for erase disk --- src/modules/partition/gui/ChoicePage.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 7832196db..222f686a0 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1750,10 +1750,8 @@ ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const // If there are any choices for FS, check it's not ZFS because that doesn't // support the kind of encryption we enable here. bool suitableFS = true; - if ( ( m_eraseFsTypesChoiceComboBox && m_eraseFsTypesChoiceComboBox->isVisible() - && m_eraseFsTypesChoiceComboBox->currentText() == "zfs" ) - || ( m_replaceFsTypesChoiceComboBox && m_replaceFsTypesChoiceComboBox->isVisible() - && m_replaceFsTypesChoiceComboBox->currentText() == "zfs" ) ) + if ( m_replaceFsTypesChoiceComboBox && m_replaceFsTypesChoiceComboBox->isVisible() + && m_replaceFsTypesChoiceComboBox->currentText() == "zfs" ) { suitableFS = false; } From f156fc356248f6ea4eec8b48afe2152c827748ed Mon Sep 17 00:00:00 2001 From: dalto Date: Tue, 21 Feb 2023 17:24:01 -0600 Subject: [PATCH 55/89] [partition] Enable encryption for zfs with replace partition --- src/modules/partition/gui/ChoicePage.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 222f686a0..171df4a57 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1747,15 +1747,7 @@ ChoicePage::createBootloaderPanel() bool ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const { - // If there are any choices for FS, check it's not ZFS because that doesn't - // support the kind of encryption we enable here. - bool suitableFS = true; - if ( m_replaceFsTypesChoiceComboBox && m_replaceFsTypesChoiceComboBox->isVisible() - && m_replaceFsTypesChoiceComboBox->currentText() == "zfs" ) - { - suitableFS = false; - } const bool suitableChoice = choice == InstallChoice::Erase || choice == InstallChoice::Alongside || choice == InstallChoice::Replace; - return suitableChoice && m_enableEncryptionWidget && suitableFS; + return suitableChoice && m_enableEncryptionWidget; } From d45819d552473a6491f21be387dfd83b2011359b Mon Sep 17 00:00:00 2001 From: dalto Date: Tue, 21 Feb 2023 18:56:04 -0600 Subject: [PATCH 56/89] [partition] Check minimum password length for zfs encryption --- src/modules/partition/gui/ChoicePage.cpp | 12 ++++++++++++ src/modules/partition/gui/EncryptWidget.cpp | 16 ++++++++++++++++ src/modules/partition/gui/EncryptWidget.h | 8 ++++++++ 3 files changed, 36 insertions(+) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 171df4a57..817580bbf 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -464,6 +464,18 @@ ChoicePage::continueApplyDeviceChoice() void ChoicePage::onActionChanged() { + if ( m_enableEncryptionWidget ) + { + if ( m_config->installChoice() == InstallChoice::Erase && m_eraseFsTypesChoiceComboBox ) + { + m_encryptWidget->setFilesystem( m_eraseFsTypesChoiceComboBox->currentText() ); + } + else if ( m_config->installChoice() == InstallChoice::Replace && m_replaceFsTypesChoiceComboBox ) + { + m_encryptWidget->setFilesystem( m_replaceFsTypesChoiceComboBox->currentText() ); + } + } + Device* currd = selectedDevice(); if ( currd ) { diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index 7c17de7af..e540fd2d0 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -16,6 +16,9 @@ #include "Branding.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Retranslator.h" +#include + +constexpr uint ZFS_MIN_LENGTH = 8; /** @brief Does this system support whole-disk encryption? * @@ -150,11 +153,17 @@ EncryptWidget::updateState() QString p1 = m_ui->m_passphraseLineEdit->text(); QString p2 = m_ui->m_confirmLineEdit->text(); + if ( p1.isEmpty() && p2.isEmpty() ) { applyPixmap( m_ui->m_iconLabel, CalamaresUtils::StatusWarning ); m_ui->m_iconLabel->setToolTip( tr( "Please enter the same passphrase in both boxes." ) ); } + else if ( FileSystem::typeForName( m_filesystem ) == FileSystem::Zfs && p1.length() < ZFS_MIN_LENGTH ) + { + applyPixmap( m_ui->m_iconLabel, CalamaresUtils::StatusError ); + m_ui->m_iconLabel->setToolTip( tr( "Password must be a minimum of %1 characters" ).arg( ZFS_MIN_LENGTH ) ); + } else if ( p1 == p2 ) { applyPixmap( m_ui->m_iconLabel, CalamaresUtils::StatusOk ); @@ -201,3 +210,10 @@ EncryptWidget::onCheckBoxStateChanged( int checked ) updateState(); } + +void +EncryptWidget::setFilesystem( const QString& fs ) +{ + m_filesystem = fs; + updateState(); +} diff --git a/src/modules/partition/gui/EncryptWidget.h b/src/modules/partition/gui/EncryptWidget.h index 9a3b8ab1f..1e4805850 100644 --- a/src/modules/partition/gui/EncryptWidget.h +++ b/src/modules/partition/gui/EncryptWidget.h @@ -38,6 +38,12 @@ public: Encryption state() const; void setText( const QString& text ); + /** + * @brief setFilesystem sets the filesystem name used for password validation + * @param fs A QString containing the name of the filesystem + */ + void setFilesystem( const QString& fs ); + QString passphrase() const; void retranslate(); @@ -52,6 +58,8 @@ private: Ui::EncryptWidget* m_ui; Encryption m_state; + + QString m_filesystem; }; #endif // ENCRYPTWIDGET_H From 2f8ef8fdf3a1912c33778cf0b8544a6d52ef6818 Mon Sep 17 00:00:00 2001 From: dalto Date: Wed, 22 Feb 2023 16:42:32 -0600 Subject: [PATCH 57/89] [partition] Fix crash caused by notification storm --- src/modules/partition/gui/EncryptWidget.cpp | 14 ++++++++++---- src/modules/partition/gui/EncryptWidget.h | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index e540fd2d0..a9adbc5ac 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -18,7 +18,7 @@ #include "utils/Retranslator.h" #include -constexpr uint ZFS_MIN_LENGTH = 8; +constexpr int ZFS_MIN_LENGTH = 8; /** @brief Does this system support whole-disk encryption? * @@ -146,7 +146,7 @@ applyPixmap( QLabel* label, CalamaresUtils::ImageType pixmap ) } void -EncryptWidget::updateState() +EncryptWidget::updateState( const bool notify ) { if ( m_ui->m_passphraseLineEdit->isVisible() ) { @@ -181,7 +181,10 @@ EncryptWidget::updateState() if ( newState != m_state ) { m_state = newState; - Q_EMIT stateChanged( m_state ); + if ( notify ) + { + Q_EMIT stateChanged( m_state ); + } } } @@ -215,5 +218,8 @@ void EncryptWidget::setFilesystem( const QString& fs ) { m_filesystem = fs; - updateState(); + if ( m_state != Encryption::Disabled ) + { + updateState( false ); + } } diff --git a/src/modules/partition/gui/EncryptWidget.h b/src/modules/partition/gui/EncryptWidget.h index 1e4805850..fa9a0397a 100644 --- a/src/modules/partition/gui/EncryptWidget.h +++ b/src/modules/partition/gui/EncryptWidget.h @@ -52,7 +52,7 @@ signals: void stateChanged( Encryption ); private: - void updateState(); + void updateState( const bool notify = true ); void onPassphraseEdited(); void onCheckBoxStateChanged( int checked ); From d88d2ce92eea56e1e498fde2e535b5a847f0a2ac Mon Sep 17 00:00:00 2001 From: dalto Date: Thu, 23 Feb 2023 16:47:39 -0600 Subject: [PATCH 58/89] [partition] Make EncryptWidget::setFilesystem take a FileSystem::Type --- src/modules/partition/gui/ChoicePage.cpp | 4 ++-- src/modules/partition/gui/EncryptWidget.cpp | 6 ++---- src/modules/partition/gui/EncryptWidget.h | 6 ++++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 817580bbf..db877e3b8 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -468,11 +468,11 @@ ChoicePage::onActionChanged() { if ( m_config->installChoice() == InstallChoice::Erase && m_eraseFsTypesChoiceComboBox ) { - m_encryptWidget->setFilesystem( m_eraseFsTypesChoiceComboBox->currentText() ); + m_encryptWidget->setFilesystem( FileSystem::typeForName( m_eraseFsTypesChoiceComboBox->currentText() ) ); } else if ( m_config->installChoice() == InstallChoice::Replace && m_replaceFsTypesChoiceComboBox ) { - m_encryptWidget->setFilesystem( m_replaceFsTypesChoiceComboBox->currentText() ); + m_encryptWidget->setFilesystem( FileSystem::typeForName( m_replaceFsTypesChoiceComboBox->currentText() ) ); } } diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index a9adbc5ac..53cae0880 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -16,7 +16,6 @@ #include "Branding.h" #include "utils/CalamaresUtilsGui.h" #include "utils/Retranslator.h" -#include constexpr int ZFS_MIN_LENGTH = 8; @@ -153,13 +152,12 @@ EncryptWidget::updateState( const bool notify ) QString p1 = m_ui->m_passphraseLineEdit->text(); QString p2 = m_ui->m_confirmLineEdit->text(); - if ( p1.isEmpty() && p2.isEmpty() ) { applyPixmap( m_ui->m_iconLabel, CalamaresUtils::StatusWarning ); m_ui->m_iconLabel->setToolTip( tr( "Please enter the same passphrase in both boxes." ) ); } - else if ( FileSystem::typeForName( m_filesystem ) == FileSystem::Zfs && p1.length() < ZFS_MIN_LENGTH ) + else if ( m_filesystem == FileSystem::Zfs && p1.length() < ZFS_MIN_LENGTH ) { applyPixmap( m_ui->m_iconLabel, CalamaresUtils::StatusError ); m_ui->m_iconLabel->setToolTip( tr( "Password must be a minimum of %1 characters" ).arg( ZFS_MIN_LENGTH ) ); @@ -215,7 +213,7 @@ EncryptWidget::onCheckBoxStateChanged( int checked ) } void -EncryptWidget::setFilesystem( const QString& fs ) +EncryptWidget::setFilesystem( const FileSystem::Type fs ) { m_filesystem = fs; if ( m_state != Encryption::Disabled ) diff --git a/src/modules/partition/gui/EncryptWidget.h b/src/modules/partition/gui/EncryptWidget.h index fa9a0397a..6292fd379 100644 --- a/src/modules/partition/gui/EncryptWidget.h +++ b/src/modules/partition/gui/EncryptWidget.h @@ -14,6 +14,8 @@ #include +#include + namespace Ui { class EncryptWidget; @@ -42,7 +44,7 @@ public: * @brief setFilesystem sets the filesystem name used for password validation * @param fs A QString containing the name of the filesystem */ - void setFilesystem( const QString& fs ); + void setFilesystem( const FileSystem::Type fs ); QString passphrase() const; @@ -59,7 +61,7 @@ private: Ui::EncryptWidget* m_ui; Encryption m_state; - QString m_filesystem; + FileSystem::Type m_filesystem; }; #endif // ENCRYPTWIDGET_H From b7af2dd77d5135b481332165c67443a2c221b121 Mon Sep 17 00:00:00 2001 From: dalto Date: Thu, 23 Feb 2023 17:17:37 -0600 Subject: [PATCH 59/89] [partition] Add a config option for allowing zfs encryption --- src/modules/partition/Config.cpp | 4 +++- src/modules/partition/Config.h | 5 ++++- src/modules/partition/gui/ChoicePage.cpp | 13 ++++++++++++- src/modules/partition/gui/ChoicePage.h | 1 + src/modules/partition/gui/EncryptWidget.cpp | 1 + src/modules/partition/gui/EncryptWidget.h | 1 + src/modules/partition/partition.conf | 10 ++++++++++ src/modules/partition/partition.schema.yaml | 2 ++ 8 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/modules/partition/Config.cpp b/src/modules/partition/Config.cpp index 3a5e80a7c..4519bd278 100644 --- a/src/modules/partition/Config.cpp +++ b/src/modules/partition/Config.cpp @@ -373,7 +373,7 @@ Config::fillConfigurationFSTypes( const QVariantMap& configurationMap ) luksGeneration = Config::LuksGeneration::Luks1; } m_luksFileSystemType = luksGeneration; - gs->insert( "luksFileSystemType", luksGenerationNames().find(luksGeneration) ); + gs->insert( "luksFileSystemType", luksGenerationNames().find( luksGeneration ) ); Q_ASSERT( !m_eraseFsTypes.isEmpty() ); Q_ASSERT( m_eraseFsTypes.contains( fsRealName ) ); @@ -409,6 +409,8 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) } setSwapChoice( m_initialSwapChoice ); + m_allowZfsEncryption = CalamaresUtils::getBool( configurationMap, "allowZfsEncryption", true ); + m_allowManualPartitioning = CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ); m_requiredPartitionTableType = CalamaresUtils::getStringList( configurationMap, "requiredPartitionTableType" ); diff --git a/src/modules/partition/Config.h b/src/modules/partition/Config.h index e59ee6887..0146d1a3e 100644 --- a/src/modules/partition/Config.h +++ b/src/modules/partition/Config.h @@ -159,6 +159,9 @@ public: */ LuksGeneration luksFileSystemType() const { return m_luksFileSystemType; } + /// @brief If zfs encryption should be allowed + bool allowZfsEncryption() const { return m_allowZfsEncryption; } + public Q_SLOTS: void setInstallChoice( int ); ///< Translates a button ID or so to InstallChoice void setInstallChoice( InstallChoice ); @@ -189,7 +192,7 @@ private: InstallChoice m_installChoice = NoChoice; qreal m_requiredStorageGiB = 0.0; // May duplicate setting in the welcome module QStringList m_requiredPartitionTableType; - + bool m_allowZfsEncryption = true; bool m_allowManualPartitioning = true; }; diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index db877e3b8..b31d042fd 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -4,6 +4,7 @@ * SPDX-FileCopyrightText: 2017-2019 Adriaan de Groot * SPDX-FileCopyrightText: 2019 Collabora Ltd * SPDX-FileCopyrightText: 2021 Anubhav Choudhary + * SPDX-FileCopyrightText: 2023 Evan James * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. @@ -1759,7 +1760,17 @@ ChoicePage::createBootloaderPanel() bool ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const { + bool suitableFS = true; + if ( !m_config->allowZfsEncryption() + && ( ( m_eraseFsTypesChoiceComboBox && m_eraseFsTypesChoiceComboBox->isVisible() + && m_eraseFsTypesChoiceComboBox->currentText() == "zfs" ) + || ( m_replaceFsTypesChoiceComboBox && m_replaceFsTypesChoiceComboBox->isVisible() + && m_replaceFsTypesChoiceComboBox->currentText() == "zfs" ) ) ) + { + suitableFS = false; + } + const bool suitableChoice = choice == InstallChoice::Erase || choice == InstallChoice::Alongside || choice == InstallChoice::Replace; - return suitableChoice && m_enableEncryptionWidget; + return suitableChoice && m_enableEncryptionWidget && suitableFS; } diff --git a/src/modules/partition/gui/ChoicePage.h b/src/modules/partition/gui/ChoicePage.h index 684a55018..7deb4dec6 100644 --- a/src/modules/partition/gui/ChoicePage.h +++ b/src/modules/partition/gui/ChoicePage.h @@ -3,6 +3,7 @@ * SPDX-FileCopyrightText: 2014-2016 Teo Mrnjavac * SPDX-FileCopyrightText: 2018-2019 Adriaan de Groot * SPDX-FileCopyrightText: 2019 Collabora Ltd + * SPDX-FileCopyrightText: 2023 Evan James * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. diff --git a/src/modules/partition/gui/EncryptWidget.cpp b/src/modules/partition/gui/EncryptWidget.cpp index 53cae0880..f2ed1d17e 100644 --- a/src/modules/partition/gui/EncryptWidget.cpp +++ b/src/modules/partition/gui/EncryptWidget.cpp @@ -2,6 +2,7 @@ * * SPDX-FileCopyrightText: 2016 Teo Mrnjavac * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-FileCopyrightText: 2023 Evan James * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. diff --git a/src/modules/partition/gui/EncryptWidget.h b/src/modules/partition/gui/EncryptWidget.h index 6292fd379..9669b4d21 100644 --- a/src/modules/partition/gui/EncryptWidget.h +++ b/src/modules/partition/gui/EncryptWidget.h @@ -2,6 +2,7 @@ * * SPDX-FileCopyrightText: 2016 Teo Mrnjavac * SPDX-FileCopyrightText: 2020 Adriaan de Groot + * SPDX-FileCopyrightText: 2023 Evan James * SPDX-License-Identifier: GPL-3.0-or-later * * Calamares is Free Software: see the License-Identifier above. diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf index ad8ab994a..ecd183ca1 100644 --- a/src/modules/partition/partition.conf +++ b/src/modules/partition/partition.conf @@ -78,6 +78,16 @@ userSwapChoices: # luksGeneration: luks1 +# This setting determines if encryption should be allowed when using zfs. This +# setting has no effect unless zfs support is provided. +# +# This setting is to handle the fact that some bootloaders(such as grub) do not +# support zfs encryption. +# +# The default is true +# +# allowZfsEncryption: true + # Correctly draw nested (e.g. logical) partitions as such. drawNestedPartitions: false diff --git a/src/modules/partition/partition.schema.yaml b/src/modules/partition/partition.schema.yaml index 64c261d26..dafdc5851 100644 --- a/src/modules/partition/partition.schema.yaml +++ b/src/modules/partition/partition.schema.yaml @@ -1,4 +1,5 @@ # SPDX-FileCopyrightText: 2020 Adriaan de Groot +# SPDX-FileCopyrightText: 2023 Evan James # SPDX-License-Identifier: GPL-3.0-or-later --- $schema: https://json-schema.org/schema# @@ -14,6 +15,7 @@ properties: # ensureSuspendToDisk: { type: boolean, default: true } # Legacy # neverCreateSwap: { type: boolean, default: false } # Legacy + allowZfsEncryption: { type: boolean, default: true } drawNestedPartitions: { type: boolean, default: false } alwaysShowPartitionLabels: { type: boolean, default: true } From 8ca6b56f56798497888213792ae0ad1a7c2ef62d Mon Sep 17 00:00:00 2001 From: Paolo Dongilli Date: Wed, 10 Aug 2022 20:08:48 +0200 Subject: [PATCH 60/89] Add detection of default lightdm-greeter --- src/modules/displaymanager/main.py | 51 ++++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 608b443ad..f458b3596 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -640,34 +640,37 @@ class DMlightdm(DisplayManager): # configure lightdm-greeter greeter_path = os.path.join( - self.root_mount_point, "usr/share/xgreeters" + self.root_mount_point, "usr/share/xgreeters/lightdm-greeter.desktop" + # lightdm-greeter.desktop is typically a symlink managed + # by update-alternatives pointing to + # /etc/alternatives/lightdm-greeter which is also a + # symlink to a real .desktop file back in + # /usr/share/xgreeters/ ) if (os.path.exists(greeter_path)): - # configure first found lightdm-greeter - for entry in os.listdir(greeter_path): - if entry.endswith('.desktop'): - greeter = entry.split('.')[0] - libcalamares.utils.debug( - "found greeter {!s}".format(greeter) - ) - os.system( - "sed -i -e \"s/^.*greeter-session=.*" - "/greeter-session={!s}/\" {!s}".format( - greeter, - lightdm_conf_path - ) - ) - libcalamares.utils.debug( - "{!s} configured as greeter.".format(greeter) - ) - break - else: - return ( - _("Cannot configure LightDM"), - _("No LightDM greeter installed.") + # find the default lightdm-greeter + entry = os.path.basename(os.path.realpath(greeter_path)) + if entry.endswith('.desktop'): + greeter = entry.split('.')[0] + libcalamares.utils.debug( + "found greeter {!s}".format(greeter) + ) + os.system( + "sed -i -e \"s/^.*greeter-session=.*" + "/greeter-session={!s}/\" {!s}".format( + greeter, + lightdm_conf_path ) - + ) + libcalamares.utils.debug( + "{!s} configured as greeter.".format(greeter) + ) + else: + return ( + _("Cannot configure LightDM"), + _("No LightDM greeter installed.") + ) class DMslim(DisplayManager): name = "slim" From 48f61be73aab4355985f4a35da7178a62149ea76 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Feb 2023 20:18:19 +0100 Subject: [PATCH 61/89] [displaymanager] Factor out the find-a-greeter part --- src/modules/displaymanager/main.py | 58 +++++++++++++++--------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index f458b3596..fbb5e93ce 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -633,39 +633,39 @@ class DMlightdm(DisplayManager): ) ) + def find_preferred_greeter(self, greeters_dir): + """ + On Debian, lightdm-greeter.desktop is typically a symlink managed + by update-alternatives pointing to /etc/alternatives/lightdm-greeter + which is also a symlink to a real .desktop file back in /usr/share/xgreeters/ + + Returns a path *into the mounted target* of the preferred greeter -- usually + a .desktop file that specifies where the actual executable is. May return + None to indicate nothing-was-found. + """ + greeters_dir = "usr/share/xgreeters" + greeter_path = os.path.join(self.root_mount_point, greeters_dir, "lightdm-greeter.desktop") + return greeter_path + + def greeter_setup(self): - lightdm_conf_path = os.path.join( - self.root_mount_point, "etc/lightdm/lightdm.conf" - ) + lightdm_conf_path = os.path.join(self.root_mount_point, "etc/lightdm/lightdm.conf") + greeter_path = self.find_preferred_greeter() - # configure lightdm-greeter - greeter_path = os.path.join( - self.root_mount_point, "usr/share/xgreeters/lightdm-greeter.desktop" - # lightdm-greeter.desktop is typically a symlink managed - # by update-alternatives pointing to - # /etc/alternatives/lightdm-greeter which is also a - # symlink to a real .desktop file back in - # /usr/share/xgreeters/ - ) + if greeter_path is not None and os.path.exists(greeter_path): + greeter = os.path.basename(os.path.realpath(greeter_path)) # Follow symlinks, hope they are not absolute + if greeter.endswith('.desktop'): + greeter = greeter[:-8] # Remove ".desktop" from end - if (os.path.exists(greeter_path)): - # find the default lightdm-greeter - entry = os.path.basename(os.path.realpath(greeter_path)) - if entry.endswith('.desktop'): - greeter = entry.split('.')[0] - libcalamares.utils.debug( - "found greeter {!s}".format(greeter) - ) - os.system( - "sed -i -e \"s/^.*greeter-session=.*" - "/greeter-session={!s}/\" {!s}".format( - greeter, - lightdm_conf_path - ) - ) - libcalamares.utils.debug( - "{!s} configured as greeter.".format(greeter) + libcalamares.utils.debug("found greeter {!s}".format(greeter)) + os.system( + "sed -i -e \"s/^.*greeter-session=.*" + "/greeter-session={!s}/\" {!s}".format( + greeter, + lightdm_conf_path ) + ) + libcalamares.utils.debug("{!s} configured as greeter.".format(greeter)) else: return ( _("Cannot configure LightDM"), From d448be1077ce5a5c03ca83daadfe96552f74bac2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Feb 2023 20:25:48 +0100 Subject: [PATCH 62/89] [displaymanager] Handle preferred / deterministic greeter --- src/modules/displaymanager/main.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index fbb5e93ce..9947a5cce 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -644,8 +644,22 @@ class DMlightdm(DisplayManager): None to indicate nothing-was-found. """ greeters_dir = "usr/share/xgreeters" - greeter_path = os.path.join(self.root_mount_point, greeters_dir, "lightdm-greeter.desktop") - return greeter_path + greeters_target_path = os.path.join(self.root_mount_point, greeters_dir) + preferred_names = ("lightdm-greeter.desktop", ) + available_names = os.listdir(greeters_target_path) + available_names.sort() + desktop_names = [n for n in preferred_names if n in available_names] # Preferred ones + if desktop_names: + return desktop_names[0] + desktop_names = [n for n in available_names if n.endswith(".desktop")] # .. otherwise any .desktop + if desktop_names: + return desktop_names[0] + desktop_names = [n for n in available_names if not n.startswith(".")] # .. otherwise any non-dot-file + if desktop_names: + return desktop_names[0] + if available_names: # Anything? + return available_names[0] + return None def greeter_setup(self): From bbc9d908880db003f5707d0f079cec6021e5b716 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 20 Feb 2023 20:54:34 +0100 Subject: [PATCH 63/89] [displaymanager] Allow configuring the preferred-greeter-list --- src/modules/displaymanager/displaymanager.conf | 6 ++++++ src/modules/displaymanager/displaymanager.schema.yaml | 5 ++++- src/modules/displaymanager/main.py | 6 ++++-- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/modules/displaymanager/displaymanager.conf b/src/modules/displaymanager/displaymanager.conf index 18e956f27..81469bd58 100644 --- a/src/modules/displaymanager/displaymanager.conf +++ b/src/modules/displaymanager/displaymanager.conf @@ -64,6 +64,12 @@ sysconfigSetup: false # # greetd has configurable user and group; the user and group is created if it # does not exist, and the user is set as default-session user. +# +# lightdm has a list of greeters to look for, preferring them in order if +# they are installed (if not, picks the alphabetically first greeter that is installed). +# greetd: greeter_user: "tom_bombadil" greeter_group: "wheel" +lightdm: + preferred_greeters: ["lightdm-greeter.desktop", "slick-greeter.desktop"] diff --git a/src/modules/displaymanager/displaymanager.schema.yaml b/src/modules/displaymanager/displaymanager.schema.yaml index 2f1da9d56..ab89c0ada 100644 --- a/src/modules/displaymanager/displaymanager.schema.yaml +++ b/src/modules/displaymanager/displaymanager.schema.yaml @@ -26,4 +26,7 @@ properties: greeter_user: { type: string } greeter_group: { type: string } additionalProperties: false - + lightdm: + type: object + properties: + preferred_greeters: { type: array, items: { type: string } } diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 9947a5cce..11b707ece 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -544,6 +544,9 @@ class DMlightdm(DisplayManager): name = "lightdm" executable = "lightdm" + # Can be overridden in the .conf file + preferred_greeters = ["lightdm-greeter.desktop"] + def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with LightDM as Desktop Manager # Ideally, we should use configparser for the ini conf file, @@ -645,10 +648,9 @@ class DMlightdm(DisplayManager): """ greeters_dir = "usr/share/xgreeters" greeters_target_path = os.path.join(self.root_mount_point, greeters_dir) - preferred_names = ("lightdm-greeter.desktop", ) available_names = os.listdir(greeters_target_path) available_names.sort() - desktop_names = [n for n in preferred_names if n in available_names] # Preferred ones + desktop_names = [n for n in self.preferred_greeters if n in available_names] # Preferred ones if desktop_names: return desktop_names[0] desktop_names = [n for n in available_names if n.endswith(".desktop")] # .. otherwise any .desktop From 59fd4ee0823bd520a57b8f205cb9ea80a99fc2e2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 23 Feb 2023 20:38:29 +0100 Subject: [PATCH 64/89] [displaymanager] lightdm: logging errors Don't just use *any* file found in the xgreeters directory, and log when no greeter was found (outside of the translated error message). --- src/modules/displaymanager/main.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 11b707ece..8c1a44e1c 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -659,8 +659,6 @@ class DMlightdm(DisplayManager): desktop_names = [n for n in available_names if not n.startswith(".")] # .. otherwise any non-dot-file if desktop_names: return desktop_names[0] - if available_names: # Anything? - return available_names[0] return None @@ -683,6 +681,10 @@ class DMlightdm(DisplayManager): ) libcalamares.utils.debug("{!s} configured as greeter.".format(greeter)) else: + if greeter_path is None: + libcalamares.utils.error("No greeter found at all, preferred {!s}".format(self.preferred_greeters)) + else: + libcalamares.utils.error("Greeter {!s} selected but file does not exist".format(greeter_path)) return ( _("Cannot configure LightDM"), _("No LightDM greeter installed.") From 92a208104bf1da2d96aa82696f8643dee6d4b498 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 23 Feb 2023 20:36:00 +0100 Subject: [PATCH 65/89] [displaymanager] lightdm: default to no-preferred-greeter While here, drop nonsensical alternatives: if it's not a .desktop file, it's not going to work anyway. --- src/modules/displaymanager/main.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index 8c1a44e1c..b403a382a 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -544,8 +544,10 @@ class DMlightdm(DisplayManager): name = "lightdm" executable = "lightdm" - # Can be overridden in the .conf file - preferred_greeters = ["lightdm-greeter.desktop"] + # Can be overridden in the .conf file. With no value it won't match any + # desktop file in the xgreeters directory and instead we end up picking + # the alphabetically first file there. + preferred_greeters = [] def set_autologin(self, username, do_autologin, default_desktop_environment): # Systems with LightDM as Desktop Manager @@ -654,9 +656,6 @@ class DMlightdm(DisplayManager): if desktop_names: return desktop_names[0] desktop_names = [n for n in available_names if n.endswith(".desktop")] # .. otherwise any .desktop - if desktop_names: - return desktop_names[0] - desktop_names = [n for n in available_names if not n.startswith(".")] # .. otherwise any non-dot-file if desktop_names: return desktop_names[0] return None From 6c25be670da9e96ac7d662d8fb38d391e3448df9 Mon Sep 17 00:00:00 2001 From: Masato Toyoshima Date: Tue, 21 Feb 2023 22:24:11 +0900 Subject: [PATCH 66/89] Added automatic enabling of swap partition before installation starts. Mainly to suppress installer stoppages caused by oom killer. --- src/modules/mount/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index ddf46d8e9..9d5d89bef 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -329,7 +329,8 @@ def run(): # swap swap_partitions = [p['device'] for p in partitions if p['fs'] == 'linuxswap' ] - enable_swap_partitions(swap_partitions) + if ( swap_partitions != [] ): + enable_swap_partition(swap_partitions) root_mount_point = tempfile.mkdtemp(prefix="calamares-root-") From 00387511060949b8d32bae6e0c978ccf222d8577 Mon Sep 17 00:00:00 2001 From: Masato TOYOSHIMA <77603626+phoepsilonix@users.noreply.github.com> Date: Sun, 26 Feb 2023 02:04:37 +0900 Subject: [PATCH 67/89] UAdded automatic enabling of swap partition before installation starts. Mainly to suppress installer stoppages caused by oom killer. --- src/modules/mount/main.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 9d5d89bef..f38935578 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -307,12 +307,23 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun mount_option) != 0: libcalamares.utils.warning("Cannot mount {}".format(device)) +<<<<<<< ours def enable_swap_partitions(swap_partitions): try: for swap_device in swap_partitions: libcalamares.utils.host_env_process_output(["swapon", swap_device]) except subprocess.CalledProcessError: libcalamares.utils.warning("Failed to swapon " + swap_device) +||||||| base +======= +def enable_swap_partition(swap_device): + try: + for d in swap_device: + subprocess.check_call(["swapon", d]) + except subprocess.CalledProcessError: + raise Exception(_("Failed to swapon " + swap_device)) + +>>>>>>> theirs def run(): """ @@ -327,11 +338,19 @@ def run(): return (_("Configuration Error"), _("No partitions are defined for
{!s}
to use.").format("mount")) +<<<<<<< ours # swap - swap_partitions = [p['device'] for p in partitions if p['fs'] == 'linuxswap' ] + swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p.get("claimed", None) )] if ( swap_partitions != [] ): enable_swap_partition(swap_partitions) +||||||| base +======= + swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p['claimed'] == True ) ] + if swap_partitions != [] : + enable_swap_partition(swap_partitions) + +>>>>>>> theirs root_mount_point = tempfile.mkdtemp(prefix="calamares-root-") # Get the mountOptions, if this is None, that is OK and will be handled later From 5513ffcd1cefd8be12cfe1a3ed2a71b2a7428870 Mon Sep 17 00:00:00 2001 From: Masato TOYOSHIMA <77603626+phoepsilonix@users.noreply.github.com> Date: Sun, 26 Feb 2023 07:24:12 +0900 Subject: [PATCH 68/89] Update main.py --- src/modules/mount/main.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index f38935578..40ab731ed 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -307,15 +307,6 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun mount_option) != 0: libcalamares.utils.warning("Cannot mount {}".format(device)) -<<<<<<< ours -def enable_swap_partitions(swap_partitions): - try: - for swap_device in swap_partitions: - libcalamares.utils.host_env_process_output(["swapon", swap_device]) - except subprocess.CalledProcessError: - libcalamares.utils.warning("Failed to swapon " + swap_device) -||||||| base -======= def enable_swap_partition(swap_device): try: for d in swap_device: @@ -323,8 +314,6 @@ def enable_swap_partition(swap_device): except subprocess.CalledProcessError: raise Exception(_("Failed to swapon " + swap_device)) ->>>>>>> theirs - def run(): """ Mount all the partitions from GlobalStorage and from the job configuration. @@ -338,19 +327,10 @@ def run(): return (_("Configuration Error"), _("No partitions are defined for
{!s}
to use.").format("mount")) -<<<<<<< ours - # swap - swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p.get("claimed", None) )] - if ( swap_partitions != [] ): - enable_swap_partition(swap_partitions) - -||||||| base -======= swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p['claimed'] == True ) ] if swap_partitions != [] : enable_swap_partition(swap_partitions) ->>>>>>> theirs root_mount_point = tempfile.mkdtemp(prefix="calamares-root-") # Get the mountOptions, if this is None, that is OK and will be handled later From c296f67356678c8182f5cd6c43364b372c9fc86c Mon Sep 17 00:00:00 2001 From: Masato TOYOSHIMA <77603626+phoepsilonix@users.noreply.github.com> Date: Sun, 26 Feb 2023 07:48:51 +0900 Subject: [PATCH 69/89] Update main.py --- src/modules/mount/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 40ab731ed..2847f4909 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -310,7 +310,7 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun def enable_swap_partition(swap_device): try: for d in swap_device: - subprocess.check_call(["swapon", d]) + libcalamares.utils.host_env_process_output(["swapon", d]) except subprocess.CalledProcessError: raise Exception(_("Failed to swapon " + swap_device)) @@ -327,7 +327,7 @@ def run(): return (_("Configuration Error"), _("No partitions are defined for
{!s}
to use.").format("mount")) - swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p['claimed'] == True ) ] + swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p['claimed'] ) ] if swap_partitions != [] : enable_swap_partition(swap_partitions) From ce6f4983580841e2e652238bb723032704960d1a Mon Sep 17 00:00:00 2001 From: dalto Date: Tue, 28 Feb 2023 18:35:18 -0600 Subject: [PATCH 70/89] [mount] Post-merge cleanup of swap enablement --- src/modules/mount/main.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index 2847f4909..e22cf0f31 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -307,12 +307,14 @@ def mount_partition(root_mount_point, partition, partitions, mount_options, moun mount_option) != 0: libcalamares.utils.warning("Cannot mount {}".format(device)) -def enable_swap_partition(swap_device): + +def enable_swap_partition(devices): try: - for d in swap_device: + for d in devices: libcalamares.utils.host_env_process_output(["swapon", d]) except subprocess.CalledProcessError: - raise Exception(_("Failed to swapon " + swap_device)) + raise Exception(_(f"Failed to enable swap for devices: {devices}")) + def run(): """ @@ -327,9 +329,10 @@ def run(): return (_("Configuration Error"), _("No partitions are defined for
{!s}
to use.").format("mount")) - swap_partitions = [p['device'] for p in partitions if ( p['fs'] == 'linuxswap' and p['claimed'] ) ] - if swap_partitions != [] : - enable_swap_partition(swap_partitions) + # Find existing swap partitions that are part of the installation and enable them now + swap_devices = [p['device'] for p in partitions if (p['fs'] == 'linuxswap' and p['claimed'])] + + enable_swap_partition(swap_devices) root_mount_point = tempfile.mkdtemp(prefix="calamares-root-") From f5b974984cc15da8486c15f9862a49df40072351 Mon Sep 17 00:00:00 2001 From: dalto Date: Fri, 3 Mar 2023 19:05:06 -0600 Subject: [PATCH 71/89] [partition] Remove WITH_KPMCORE42 to fix luks2 support --- src/modules/partition/jobs/FillGlobalStorageJob.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index eb1c027cb..f6ea8c772 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -26,9 +26,7 @@ #include #include #include -#ifdef WITH_KPMCORE42API #include -#endif #include #include @@ -94,18 +92,18 @@ mapForPartition( Partition* partition, const QString& uuid ) map[ "parttype" ] = partition->type(); map[ "partattrs" ] = partition->attributes(); map[ "features" ] = partition->fileSystem().features(); + if ( partition->fileSystem().type() == FileSystem::Luks && dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ) { map[ "fs" ] = untranslatedFS( dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ); } -#ifdef WITH_KPMCORE42API if ( partition->fileSystem().type() == FileSystem::Luks2 && dynamic_cast< FS::luks2& >( partition->fileSystem() ).innerFS() ) { map[ "fs" ] = untranslatedFS( dynamic_cast< FS::luks2& >( partition->fileSystem() ).innerFS() ); } -#endif + map[ "uuid" ] = uuid; map[ "claimed" ] = PartitionInfo::format( partition ); // If we formatted it, it's ours From 3a0cb8d1fdd8a9e78d09017f5532521eda3a944f Mon Sep 17 00:00:00 2001 From: Sunderland93 Date: Sun, 5 Mar 2023 10:40:17 +0400 Subject: [PATCH 72/89] change environments entry from desktopFile to desktopExecutable --- src/modules/displaymanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index b403a382a..776db080a 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -837,7 +837,7 @@ class DMgreetd(DisplayManager): def desktop_environment_setup(self, default_desktop_environment): with open(self.environments_path(), 'w') as envs_file: - envs_file.write(default_desktop_environment.desktop_file) + envs_file.write(default_desktop_environment.executable) envs_file.write("\n") def greeter_setup(self): From 079f608700085a476ffca9ba281d89f2f429c71a Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 5 Mar 2023 13:58:13 -0600 Subject: [PATCH 73/89] [displaymanager] Fix bug with find_preferred_greeters() --- src/modules/displaymanager/main.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index b403a382a..c8edb149a 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -444,7 +444,6 @@ class DMgdm(DisplayManager): userfile.write("Icon=\n") - def basic_setup(self): if libcalamares.utils.target_env_call( ['getent', 'group', 'gdm'] @@ -598,7 +597,6 @@ class DMlightdm(DisplayManager): _("LightDM config file {!s} does not exist").format(lightdm_conf_path) ) - def basic_setup(self): libcalamares.utils.target_env_call( ['mkdir', '-p', '/run/lightdm'] @@ -638,7 +636,7 @@ class DMlightdm(DisplayManager): ) ) - def find_preferred_greeter(self, greeters_dir): + def find_preferred_greeter(self): """ On Debian, lightdm-greeter.desktop is typically a symlink managed by update-alternatives pointing to /etc/alternatives/lightdm-greeter @@ -660,7 +658,6 @@ class DMlightdm(DisplayManager): return desktop_names[0] return None - def greeter_setup(self): lightdm_conf_path = os.path.join(self.root_mount_point, "etc/lightdm/lightdm.conf") greeter_path = self.find_preferred_greeter() @@ -689,6 +686,7 @@ class DMlightdm(DisplayManager): _("No LightDM greeter installed.") ) + class DMslim(DisplayManager): name = "slim" executable = "slim" From da295e00f90a8eaa2ebf6465e302df99476ff47a Mon Sep 17 00:00:00 2001 From: dalto Date: Sun, 5 Mar 2023 19:37:33 -0600 Subject: [PATCH 74/89] [displaymanager] Fix bug in lightdm preferred greeter implementation --- src/modules/displaymanager/main.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index c8edb149a..9e2cfea2d 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -660,12 +660,12 @@ class DMlightdm(DisplayManager): def greeter_setup(self): lightdm_conf_path = os.path.join(self.root_mount_point, "etc/lightdm/lightdm.conf") - greeter_path = self.find_preferred_greeter() + greeter_name = self.find_preferred_greeter() - if greeter_path is not None and os.path.exists(greeter_path): - greeter = os.path.basename(os.path.realpath(greeter_path)) # Follow symlinks, hope they are not absolute + if greeter_name is not None: + greeter = os.path.basename(greeter_name) # Follow symlinks, hope they are not absolute if greeter.endswith('.desktop'): - greeter = greeter[:-8] # Remove ".desktop" from end + greeter = greeter[:-8] # Remove ".desktop" from end libcalamares.utils.debug("found greeter {!s}".format(greeter)) os.system( @@ -677,10 +677,7 @@ class DMlightdm(DisplayManager): ) libcalamares.utils.debug("{!s} configured as greeter.".format(greeter)) else: - if greeter_path is None: - libcalamares.utils.error("No greeter found at all, preferred {!s}".format(self.preferred_greeters)) - else: - libcalamares.utils.error("Greeter {!s} selected but file does not exist".format(greeter_path)) + libcalamares.utils.error("No greeter found at all, preferred {!s}".format(self.preferred_greeters)) return ( _("Cannot configure LightDM"), _("No LightDM greeter installed.") From d35e69c8a9d3b10c06277d79e4a65294c8340f7d Mon Sep 17 00:00:00 2001 From: dalto Date: Sat, 11 Mar 2023 10:16:20 -0600 Subject: [PATCH 75/89] [mount] Warn on failure to activate swap partition --- src/modules/mount/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index e22cf0f31..235b67060 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -313,7 +313,7 @@ def enable_swap_partition(devices): for d in devices: libcalamares.utils.host_env_process_output(["swapon", d]) except subprocess.CalledProcessError: - raise Exception(_(f"Failed to enable swap for devices: {devices}")) + libcalamares.utils.warning(f"Failed to enable swap for devices: {devices}") def run(): From 4844534d7dd7c2c1af0418ab8dff872f6b3a8c00 Mon Sep 17 00:00:00 2001 From: Mario Haustein Date: Sat, 18 Mar 2023 21:15:31 +0100 Subject: [PATCH 76/89] respect LDFLAGS from environment during build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 86e8175f8..9c75c3210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -216,7 +216,7 @@ set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG") set(CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g") -set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings") +set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings ${CMAKE_SHARED_LINKER_FLAGS}") # If no build type is set, pick a reasonable one if(NOT CMAKE_BUILD_TYPE) From 4f2ab856a320c840ec3fc492faf1f3de32769398 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Mar 2023 12:05:14 +0100 Subject: [PATCH 77/89] Changes: credit for PRs merged into calamares branch --- CHANGES-3.3 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index f187e1320..44215416a 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -12,12 +12,17 @@ the history of the 3.2 series (2018-05 - 2022-08). This release contains contributions from (alphabetically by first name): - Adriaan de Groot + - Aleksey Samoilov - Anke Boersma - Evan James - Jeremy Attall - Johannes Kamprad - - Shivanand + - Mario Haustein + - Masato TOYOSHIMA + - Paolo Dongilli - Peter Jung + - Shivanand + - wiz64 ## Core ## - Incompatible module-configuration changes, see #1438. From 81c87dc5aca0bc4c41591713a850fd376669385f Mon Sep 17 00:00:00 2001 From: Peter Jung Date: Wed, 22 Mar 2023 19:49:30 +0100 Subject: [PATCH 78/89] cmake: Change Release build from -O4 to -O3 Signed-off-by: Peter Jung --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9c75c3210..d6edad5be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") set(CMAKE_C_FLAGS_DEBUG "-Og -g") set(CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG") -set(CMAKE_C_FLAGS_RELEASE "-O4 -DNDEBUG") +set(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG") set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g") set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -Wl,--fatal-warnings ${CMAKE_SHARED_LINKER_FLAGS}") From 2d118c70576eaa688092be11e4f91528fdb60293 Mon Sep 17 00:00:00 2001 From: Emir SARI Date: Tue, 18 Apr 2023 04:21:08 +0300 Subject: [PATCH 79/89] Add i18n support for percent value --- src/libcalamaresui/viewpages/ExecutionViewStep.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index 998d9f38b..8e845a34f 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -73,6 +73,7 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) { m_widget->setObjectName( "slideshow" ); m_progressBar->setObjectName( "exec-progress" ); + m_progressBar->setFormat(tr("%p%")); m_label->setObjectName( "exec-message" ); QVBoxLayout* layout = new QVBoxLayout( m_widget ); From 3ceee01713497efdffb448b431b664149296aff4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Mar 2023 12:42:33 +0100 Subject: [PATCH 80/89] CI: bail out when Transifex script fails --- ci/txpull.sh | 2 +- ci/txpush.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ci/txpull.sh b/ci/txpull.sh index 0f4a2aa47..d7e8a07c1 100755 --- a/ci/txpull.sh +++ b/ci/txpull.sh @@ -55,7 +55,7 @@ done # .tx/config file to locate files, and overwrites them in the # filesystem with new (merged) translations. export QT_SELECT=5 -tx pull --force --source --all +tx pull --force --source --all || exit 1 ### CLEANUP TRANSLATIONS diff --git a/ci/txpush.sh b/ci/txpush.sh index 1a0a7249b..f262eaeec 100755 --- a/ci/txpush.sh +++ b/ci/txpush.sh @@ -108,8 +108,8 @@ if test -n "$XMLLINT" ; then $XMLLINT --c14n11 "$TS_FILE" | { echo "" ; cat - ; } | $XMLLINT --format --encode utf-8 -o "$TS_FILE".new - && mv "$TS_FILE".new "$TS_FILE" fi -tx push --source --no-interactive -r calamares.calamares -tx push --source --no-interactive -r calamares.fdo +tx push --source --no-interactive -r calamares.calamares || exit 1 +tx push --source --no-interactive -r calamares.fdo || exit 1 ### PYTHON MODULES From b07f0c285784d79c04ea15dc918ad09a78e769c0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 23 Apr 2023 11:35:48 +0200 Subject: [PATCH 81/89] Changes: add credit for %p While here, add a disambiguation to help translators. --- CHANGES-3.3 | 2 ++ src/libcalamaresui/viewpages/ExecutionViewStep.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES-3.3 b/CHANGES-3.3 index 44215416a..28c7bdaca 100644 --- a/CHANGES-3.3 +++ b/CHANGES-3.3 @@ -14,6 +14,7 @@ This release contains contributions from (alphabetically by first name): - Adriaan de Groot - Aleksey Samoilov - Anke Boersma + - Emir Sari - Evan James - Jeremy Attall - Johannes Kamprad @@ -34,6 +35,7 @@ This release contains contributions from (alphabetically by first name): - The `INSTALL_CONFIG` option has been removed. If you are installing the example configuration files from the Calamares repository, just stop. That was never a good idea, and you should keep your configs elsewhere. + - Progress percentage during install can now be localized. (thanks Emir) ## Modules ## - *dracut* added a configurable kernel name. (thanks Anke) diff --git a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp index 8e845a34f..7eae78cbc 100644 --- a/src/libcalamaresui/viewpages/ExecutionViewStep.cpp +++ b/src/libcalamaresui/viewpages/ExecutionViewStep.cpp @@ -73,7 +73,7 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) { m_widget->setObjectName( "slideshow" ); m_progressBar->setObjectName( "exec-progress" ); - m_progressBar->setFormat(tr("%p%")); + m_progressBar->setFormat(tr("%p%", "Progress percentage indicator: %p is where the number 0..100 is placed")); m_label->setObjectName( "exec-message" ); QVBoxLayout* layout = new QVBoxLayout( m_widget ); From 25b9e23330889646d5b342978b39a6bc57bdeb0d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 22:02:15 +0200 Subject: [PATCH 82/89] i18n: update Transifex configuration Use the new (go-based, APIv3) Transifex cli tool. --- .tx/config | 14 +++++++------- ci/txpull.sh | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.tx/config b/.tx/config index 65a8521b5..12d56dd73 100644 --- a/.tx/config +++ b/.tx/config @@ -2,23 +2,23 @@ # SPDX-License-Identifier: CC0-1.0 [main] -host = https://www.transifex.com +host = https://app.transifex.com -[calamares.calamares] +[o:calamares:p:calamares:r:calamares] file_filter = lang/calamares_.ts source_file = lang/calamares_en.ts source_lang = en -type = QT +type = QT -[calamares.fdo] +[o:calamares:p:calamares:r:fdo] file_filter = lang/desktop_.desktop source_file = calamares.desktop source_lang = en -type = DESKTOP +type = DESKTOP -[calamares.python] +[o:calamares:p:calamares:r:python] file_filter = lang/python//LC_MESSAGES/python.po source_file = lang/python.pot source_lang = en -type = PO +type = PO diff --git a/ci/txpull.sh b/ci/txpull.sh index d7e8a07c1..31ebcedd8 100755 --- a/ci/txpull.sh +++ b/ci/txpull.sh @@ -55,7 +55,7 @@ done # .tx/config file to locate files, and overwrites them in the # filesystem with new (merged) translations. export QT_SELECT=5 -tx pull --force --source --all || exit 1 +transifex-client pull --force --all || exit 1 ### CLEANUP TRANSLATIONS From 9c2cbf758886993519da6c5dcbce906c1bb4cac1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 23:32:24 +0200 Subject: [PATCH 83/89] [libcalamares] Repair link to Translations --- src/libcalamares/CalamaresAbout.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/CalamaresAbout.cpp b/src/libcalamares/CalamaresAbout.cpp index 86e597b4b..a90866846 100644 --- a/src/libcalamares/CalamaresAbout.cpp +++ b/src/libcalamares/CalamaresAbout.cpp @@ -19,7 +19,7 @@ static const char s_header[] static const char s_footer[] = QT_TRANSLATE_NOOP( "AboutData", "Thanks to the Calamares team " - "and the Calamares " + "and the Calamares " "translators team.

" "Calamares " "development is sponsored by
" From 69d771ae777098598072a9dcb7b0e4cd14653f2c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 23:32:35 +0200 Subject: [PATCH 84/89] docs: Update Transifex links --- CMakeLists.txt | 2 +- README.md | 2 +- ci/txstats.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d6edad5be..ffe61077b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,7 +135,7 @@ set(CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framew # # Language en (source language) is added later. It isn't listed in # Transifex either. Get the list of languages and their status -# from https://transifex.com/calamares/calamares/ , or (preferably) +# from https://app.transifex.com/calamares/calamares/ , or (preferably) # use ci/txstats.py to automatically check. # # When adding a new language, take care that it is properly loaded diff --git a/README.md b/README.md index 35a75453b..43a336de1 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [![GitHub license](https://img.shields.io/badge/license-Multiple-green)](https://github.com/calamares/calamares/tree/calamares/LICENSES) -| [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) | +| [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://app.transifex.com/calamares/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) | |:--:|:--:|:--:|:--:|:--:|:--:| diff --git a/ci/txstats.py b/ci/txstats.py index 5fddc6bd6..f4aa8e196 100755 --- a/ci/txstats.py +++ b/ci/txstats.py @@ -53,7 +53,7 @@ class TransifexGetter(object): parser = configparser.ConfigParser() parser.read_file(f) - return parser.get("https://www.transifex.com", "password") + return parser.get("https://app.transifex.com", "password") except IOError as e: return None From 9dfd83ab7c5391fd81c67ebd58cae501a486cd27 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 23:37:33 +0200 Subject: [PATCH 85/89] i18n: update to newer transifex client --- ci/txpush.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/ci/txpush.sh b/ci/txpush.sh index f262eaeec..449135790 100755 --- a/ci/txpush.sh +++ b/ci/txpush.sh @@ -53,6 +53,10 @@ if test "x$1" = "x--no-tx" ; then } else # tx is the regular transifex command + tx() { + transifex-client "$@" + } + # txtag is used to tag in git to measure changes txtag() { git tag -f translation @@ -108,8 +112,8 @@ if test -n "$XMLLINT" ; then $XMLLINT --c14n11 "$TS_FILE" | { echo "" ; cat - ; } | $XMLLINT --format --encode utf-8 -o "$TS_FILE".new - && mv "$TS_FILE".new "$TS_FILE" fi -tx push --source --no-interactive -r calamares.calamares || exit 1 -tx push --source --no-interactive -r calamares.fdo || exit 1 +tx push --source -r calamares.calamares || exit 1 +tx push --source -r calamares.fdo || exit 1 ### PYTHON MODULES @@ -133,8 +137,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d | sort) ; d POTFILE="${MODULE_DIR}/lang/${MODULE_NAME}.pot" if [ -f "$POTFILE" ]; then sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" - tx set -r calamares.${MODULE_NAME} --source -l en "$POTFILE" - tx push --source --no-interactive -r calamares.${MODULE_NAME} + tx push --source -r calamares.${MODULE_NAME} fi else SHARED_PYTHON="$SHARED_PYTHON $FILES" @@ -146,8 +149,7 @@ if test -n "$SHARED_PYTHON" ; then ${PYGETTEXT} -p lang -d python -o python.pot $SHARED_PYTHON POTFILE="lang/python.pot" sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" - tx set -r calamares.python --source -l en "$POTFILE" - tx push --source --no-interactive -r calamares.python + tx push --source -r calamares.python fi txtag From 5f51d84887eb1d26acd3125bb943b30c389d666b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 23:49:23 +0200 Subject: [PATCH 86/89] i18n: support BSD sed in the txpush script --- ci/txpush.sh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/ci/txpush.sh b/ci/txpush.sh index 449135790..666cddc4a 100755 --- a/ci/txpush.sh +++ b/ci/txpush.sh @@ -86,6 +86,15 @@ do done # XMLLINT is optional +if sed --version 2>&1 | grep -q GNU ; then + reinplace() { + sed -i'' "$@" + } +else + reinplace() { + sed -i '' "$@" + } +fi ### CREATE TRANSLATIONS # @@ -136,7 +145,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d | sort) ; d ${PYGETTEXT} -p ${MODULE_DIR}/lang -d ${MODULE_NAME} -o ${MODULE_NAME}.pot ${MODULE_DIR}/*.py POTFILE="${MODULE_DIR}/lang/${MODULE_NAME}.pot" if [ -f "$POTFILE" ]; then - sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" + reinplace '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" tx push --source -r calamares.${MODULE_NAME} fi else @@ -148,7 +157,7 @@ done if test -n "$SHARED_PYTHON" ; then ${PYGETTEXT} -p lang -d python -o python.pot $SHARED_PYTHON POTFILE="lang/python.pot" - sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" + reinplace '/^"Content-Type/s/CHARSET/UTF-8/' "$POTFILE" tx push --source -r calamares.python fi From 29ef9e909df58e025868e1f0eea1c4f0fc30cf3a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 24 Apr 2023 23:49:46 +0200 Subject: [PATCH 87/89] i18n: update source language --- lang/calamares_en.ts | 625 +++++++++++++++++++++---------------------- lang/python.pot | 593 +++++++++++++++++++--------------------- 2 files changed, 585 insertions(+), 633 deletions(-) diff --git a/lang/calamares_en.ts b/lang/calamares_en.ts index 19c979644..7a92656b3 100644 --- a/lang/calamares_en.ts +++ b/lang/calamares_en.ts @@ -10,8 +10,8 @@ - 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. - 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. + Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://app.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. + @@ -49,27 +49,27 @@ BootLoaderModel - + Master Boot Record of %1 Master Boot Record of %1 - + Boot Partition Boot Partition - + System Partition System Partition - + Do not install a boot loader Do not install a boot loader - + %1 (%2) %1 (%2) @@ -156,7 +156,7 @@ Widget Tree - + Debug information Debug information @@ -164,12 +164,18 @@ Calamares::ExecutionViewStep - + + %p% + Progress percentage indicator: %p is where the number 0..100 is placed + + + + Set up Set up - + Install Install @@ -276,8 +282,8 @@ Calamares::RequirementsChecker - Requirements checking for module <i>%1</i> is complete. - Requirements checking for module <i>%1</i> is complete. + Requirements checking for module '%1' is complete. + @@ -507,12 +513,12 @@ The installer will quit and all changes will be lost. CalamaresWindow - + %1 Setup Program %1 Setup Program - + %1 Installer %1 Installer @@ -520,17 +526,18 @@ The installer will quit and all changes will be lost. ChangeFilesystemLabelJob - + Set filesystem label on %1. Set filesystem label on %1. - + Set filesystem label <strong>%1</strong> to partition <strong>%2</strong>. Set filesystem label <strong>%1</strong> to partition <strong>%2</strong>. - + + The installer failed to update partition table on disk '%1'. The installer failed to update partition table on disk '%1'. @@ -551,149 +558,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 @@ -762,46 +769,40 @@ The installer will quit and all changes will be lost. CommandList - - + Could not run command. 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 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. - The command needs to know the user's name, but no username is defined. + + The commands use variables that are not defined. Missing variables are: %1. + Config - + Set keyboard model to %1.<br/> Set keyboard model to %1.<br/> - + Set keyboard layout to %1/%2. 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. @@ -837,96 +838,96 @@ The installer will quit and all changes will be lost. - 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 setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> + This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. + - - 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 the minimum requirements for installing %1.<br/>Installation cannot continue. <a href="#details">Details...</a> + + This computer does not satisfy the minimum requirements for installing %1.<br/>Installation cannot continue. + - + 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 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 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. 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 the Calamares setup program for %1</h1> - + <h1>Welcome to %1 setup</h1> <h1>Welcome to %1 setup</h1> - + <h1>Welcome to the Calamares installer for %1</h1> <h1>Welcome to the Calamares installer for %1</h1> - + <h1>Welcome to the %1 installer</h1> <h1>Welcome to the %1 installer</h1> - + Your username is too long. Your username is too long. - + '%1' is not allowed as username. '%1' is not allowed as username. - + Your username must start with a lowercase letter or underscore. Your username must start with a lowercase letter or underscore. - + Only lowercase letters, numbers, underscore and hyphen are allowed. Only lowercase letters, numbers, underscore and hyphen are allowed. - + Your hostname is too short. Your hostname is too short. - + Your hostname is too long. Your hostname is too long. - + '%1' is not allowed as hostname. '%1' is not allowed as hostname. - + Only letters, numbers, underscore and hyphen are allowed. Only letters, numbers, underscore and hyphen are allowed. - + Your passwords do not match! Your passwords do not match! - + OK! OK! @@ -1082,22 +1083,22 @@ The installer will quit and all changes will be lost. FS Label: - + En&crypt En&crypt - + Logical Logical - + Primary Primary - + GPT GPT @@ -1115,43 +1116,43 @@ The installer will quit and all changes will be lost. 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'. @@ -1317,7 +1318,7 @@ 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. @@ -1327,7 +1328,7 @@ The installer will quit and all changes will be lost. 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. @@ -1342,7 +1343,7 @@ The installer will quit and all changes will be lost. <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. @@ -1489,11 +1490,16 @@ The installer will quit and all changes will be lost. Confirm passphrase - - + + Please enter the same passphrase in both boxes. Please enter the same passphrase in both boxes. + + + Password must be a minimum of %1 characters + + ErrorDialog @@ -1511,57 +1517,57 @@ The installer will quit and all changes will be lost. 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. @@ -1657,75 +1663,131 @@ The installer will quit and all changes will be lost. GeneralRequirements - - has at least %1 GiB available drive space - has at least %1 GiB available drive space + + Please ensure the system has at least %1 GiB available drive space. + - + + Available drive space is all of the hard disks and SSDs connected to the system. + + + + There is not enough drive space. At least %1 GiB is required. There is not enough drive space. At least %1 GiB is required. - + has at least %1 GiB working memory has at least %1 GiB working memory - + The system does not have enough working memory. At least %1 GiB is required. The system does not have enough working memory. At least %1 GiB is required. - + is plugged in to a power source is plugged in to a power source - + The system is not plugged in to a power source. The system is not plugged in to a power source. - + is connected to the Internet is connected to the Internet - + The system is not connected to the Internet. The system is not connected to the Internet. - + is running the installer as an administrator (root) is running the installer as an administrator (root) - + The setup program is not running with administrator rights. The setup program is not running with administrator rights. - + The installer is not running with administrator rights. The installer is not running with administrator rights. - + has a screen large enough to show the whole installer 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 setup program. - + The screen is too small to display the installer. The screen is too small to display the installer. + + + is always false + + + + + The computer says no. + + + + + is always false (slowly) + + + + + The computer says no (slowly). + + + + + is always true + + + + + The computer says yes. + + + + + is always true (slowly) + + + + + The computer says yes (slowly). + + + + + is checked three times. + + + + + The snark has not been checked three times. + The (some mythological beast) has not been checked three times. + + HostInfoJob @@ -1878,32 +1940,32 @@ The installer will quit and all changes will be lost. <h1>License Agreement</h1> - + I accept the terms and conditions above. I accept the terms and conditions above. - + Please review the End User License Agreements (EULAs). Please review the End User License Agreements (EULAs). - + This setup procedure will install proprietary software that is subject to licensing terms. 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. 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. 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. If you do not agree with the terms, proprietary software will not be installed, and open source alternatives will be used instead. @@ -2006,7 +2068,7 @@ The installer will quit and all changes will be lost. LocaleTests - + Quit Quit @@ -2014,7 +2076,7 @@ The installer will quit and all changes will be lost. LocaleViewStep - + Location Location @@ -2229,12 +2291,12 @@ The installer will quit and all changes will be lost. OEMViewStep - + OEM Configuration OEM Configuration - + Set the OEM Batch Identifier to <code>%1</code>. Set the OEM Batch Identifier to <code>%1</code>. @@ -2242,29 +2304,29 @@ The installer will quit and all changes will be lost. Offline - + Select your preferred Region, or use the default settings. Select your preferred Region, or use the default settings. - - - + + + Timezone: %1 Timezone: %1 - + Select your preferred Zone within your Region. Select your preferred Zone within your Region. - + Zones Zones - + You can fine-tune Language and Locale settings below. You can fine-tune Language and Locale settings below. @@ -2539,7 +2601,7 @@ The installer will quit and all changes will be lost. Unknown error - + Password is empty Password is empty @@ -2852,17 +2914,17 @@ The installer will quit and all changes will be lost. I&nstall boot loader on: - + Are you sure you want to create a new partition table on %1? Are you sure you want to create a new partition table on %1? - + Can not create new partition 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. 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. @@ -2905,72 +2967,72 @@ The installer will quit and all changes will be lost. 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>%2</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>%2</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. @@ -3018,17 +3080,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. @@ -3105,7 +3167,7 @@ Output: QObject - + %1 (%2) %1 (%2) @@ -3217,92 +3279,17 @@ Output: The installer failed to remove a volume group named '%1'. - - ReplaceWidget - - - Form - 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: - - Requirements - + <p>This computer does not satisfy the minimum requirements for installing %1.<br/> Installation cannot continue.</p> <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> <p>This computer does not satisfy some of the recommended requirements for setting up %1.<br/> @@ -3317,63 +3304,63 @@ Output: 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 @@ -3429,16 +3416,11 @@ Output: - ResultsListDialog + ResultsListWidget - - For best results, please ensure that this computer: - For best results, please ensure that this computer: - - - - System requirements - System requirements + + Checking requirements again in a few seconds ... + @@ -4066,12 +4048,12 @@ Output: %1 support - + About %1 setup About %1 setup - + About %1 installer About %1 installer @@ -4121,17 +4103,17 @@ Output: - + Failed to create zpool Failed to create zpool - + Failed to create dataset Failed to create dataset - + The output was: The output was: @@ -4140,14 +4122,26 @@ Output: calamares-sidebar + About About + Debug Debug + + + Show information about Calamares + + + + + Show debug information + + finishedq @@ -4206,63 +4200,54 @@ Output: Restart - - 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>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>. - <h1>Locales</h1> </br> - The system locale setting affects the numbers and dates format. The current setting is <strong>%1</strong>. - - - - Back - Back - - keyboardq - + To activate keyboard preview, select a layout. To activate keyboard preview, select a layout. - - Keyboard Model: - Keyboard Model: + + <b>Keyboard Model:&nbsp;&nbsp;</b> + - - Layouts - Layouts + + Layout + - + + Variant + + + + Type here to test your keyboard Type here to test your keyboard - - - Variants - Variants - localeq - + + Change Change + + + <h3>Languages</h3> </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>. + + + + + <h3>Locales</h3> </br> + The system locale setting affects the numbers and dates format. The current setting is <strong>%1</strong>. + + notesqml diff --git a/lang/python.pot b/lang/python.pot index 7321113a2..386a07071 100644 --- a/lang/python.pot +++ b/lang/python.pot @@ -2,426 +2,393 @@ # 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: 2022-05-29 16:17+0200\n" +"POT-Creation-Date: 2023-04-24 23:48+0200\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=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Language: \n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: src/modules/grubcfg/main.py:28 -msgid "Configure GRUB." -msgstr "Configure GRUB." - -#: src/modules/mount/main.py:42 -msgid "Mounting partitions." -msgstr "Mounting partitions." - -#: src/modules/mount/main.py:88 src/modules/mount/main.py:124 -msgid "Internal error mounting zfs datasets" -msgstr "Internal error mounting zfs datasets" - -#: src/modules/mount/main.py:100 -msgid "Failed to import zpool" -msgstr "Failed to import zpool" - -#: src/modules/mount/main.py:116 -msgid "Failed to unlock zpool" -msgstr "Failed to unlock zpool" - -#: src/modules/mount/main.py:133 src/modules/mount/main.py:138 -msgid "Failed to set zfs mountpoint" -msgstr "Failed to set zfs mountpoint" - -#: src/modules/mount/main.py:229 src/modules/initcpiocfg/main.py:235 -#: src/modules/initcpiocfg/main.py:239 src/modules/rawfs/main.py:164 -#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 -#: src/modules/openrcdmcryptcfg/main.py:72 -#: src/modules/openrcdmcryptcfg/main.py:76 src/modules/fstab/main.py:394 -#: src/modules/fstab/main.py:400 src/modules/fstab/main.py:428 -#: src/modules/localecfg/main.py:140 src/modules/networkcfg/main.py:105 -msgid "Configuration Error" -msgstr "Configuration Error" - -#: src/modules/mount/main.py:230 src/modules/initcpiocfg/main.py:236 -#: src/modules/rawfs/main.py:165 src/modules/initramfscfg/main.py:86 -#: src/modules/openrcdmcryptcfg/main.py:73 src/modules/fstab/main.py:395 -msgid "No partitions are defined for
{!s}
to use." -msgstr "No partitions are defined for
{!s}
to use." - -#: src/modules/mount/main.py:253 -msgid "zfs mounting error" -msgstr "zfs mounting error" - -#: src/modules/services-systemd/main.py:26 -msgid "Configure systemd services" -msgstr "Configure systemd services" - -#: src/modules/services-systemd/main.py:59 -#: src/modules/services-openrc/main.py:93 -msgid "Cannot modify service" -msgstr "Cannot modify service" - -#: src/modules/services-systemd/main.py:60 -msgid "" -"systemctl {arg!s} call in chroot returned error code {num!s}." +#: src/modules/bootloader/main.py:46 +msgid "Install bootloader." 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}." - -#: src/modules/services-systemd/main.py:65 -msgid "Cannot enable systemd target {name!s}." -msgstr "Cannot enable systemd target {name!s}." - -#: src/modules/services-systemd/main.py:67 -msgid "Cannot enable systemd timer {name!s}." -msgstr "Cannot enable systemd timer {name!s}." - -#: src/modules/services-systemd/main.py:71 -msgid "Cannot disable systemd target {name!s}." -msgstr "Cannot disable systemd target {name!s}." - -#: src/modules/services-systemd/main.py:73 -msgid "Cannot mask systemd unit {name!s}." -msgstr "Cannot mask systemd unit {name!s}." - -#: src/modules/services-systemd/main.py:75 -msgid "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." +#: src/modules/bootloader/main.py:640 +msgid "Failed to install grub, no partitions defined in global storage" msgstr "" -"Unknown systemd commands {command!s} and " -"{suffix!s} for unit {name!s}." -#: src/modules/unpackfs/main.py:34 -msgid "Filling up filesystems." -msgstr "Filling up filesystems." - -#: src/modules/unpackfs/main.py:254 -msgid "rsync failed with error code {}." -msgstr "rsync failed with error code {}." - -#: src/modules/unpackfs/main.py:299 -msgid "Unpacking image {}/{}, file {}/{}" -msgstr "Unpacking image {}/{}, file {}/{}" - -#: src/modules/unpackfs/main.py:314 -msgid "Starting to unpack {}" -msgstr "Starting to unpack {}" - -#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:467 -msgid "Failed to unpack image \"{}\"" -msgstr "Failed to unpack image \"{}\"" - -#: src/modules/unpackfs/main.py:430 -msgid "No mount point for root partition" -msgstr "No mount point for root partition" - -#: src/modules/unpackfs/main.py:431 -msgid "globalstorage does not contain a \"rootMountPoint\" key." -msgstr "globalstorage does not contain a \"rootMountPoint\" key." - -#: src/modules/unpackfs/main.py:434 -msgid "Bad mount point for root partition" -msgstr "Bad mount point for root partition" - -#: src/modules/unpackfs/main.py:435 -msgid "rootMountPoint is \"{}\", which does not exist." -msgstr "rootMountPoint is \"{}\", which does not exist." - -#: 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 "Bad unpackfs configuration" - -#: src/modules/unpackfs/main.py:440 -msgid "There is no configuration information." -msgstr "There is no configuration information." - -#: 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" - -#: src/modules/unpackfs/main.py:460 -msgid "The source filesystem \"{}\" does not exist" -msgstr "The source filesystem \"{}\" does not exist" - -#: src/modules/unpackfs/main.py:466 -msgid "" -"Failed to find unsquashfs, make sure you have the squashfs-tools package " -"installed." +#: src/modules/bootloader/main.py:895 +msgid "Bootloader installation error" msgstr "" -"Failed to find unsquashfs, make sure you have the squashfs-tools package " -"installed." -#: 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/bootloader/main.py:896 +msgid "" +"The bootloader could not be installed. The installation command
{!s} returned error code {!s}."
+msgstr ""
 
-#: src/modules/displaymanager/main.py:524
-msgid "Cannot write KDM configuration file"
-msgstr "Cannot write KDM configuration file"
-
-#: src/modules/displaymanager/main.py:525
-msgid "KDM config file {!s} does not exist"
-msgstr "KDM config file {!s} does not exist"
-
-#: src/modules/displaymanager/main.py:586
+#: src/modules/displaymanager/main.py:507
 msgid "Cannot write LXDM configuration file"
-msgstr "Cannot write LXDM configuration file"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:587
+#: src/modules/displaymanager/main.py:508
 msgid "LXDM config file {!s} does not exist"
-msgstr "LXDM config file {!s} does not exist"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:670
+#: src/modules/displaymanager/main.py:596
 msgid "Cannot write LightDM configuration file"
-msgstr "Cannot write LightDM configuration file"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:671
+#: src/modules/displaymanager/main.py:597
 msgid "LightDM config file {!s} does not exist"
-msgstr "LightDM config file {!s} does not exist"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:745
+#: src/modules/displaymanager/main.py:682
 msgid "Cannot configure LightDM"
-msgstr "Cannot configure LightDM"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:746
+#: src/modules/displaymanager/main.py:683
 msgid "No LightDM greeter installed."
-msgstr "No LightDM greeter installed."
+msgstr ""
 
-#: src/modules/displaymanager/main.py:777
+#: src/modules/displaymanager/main.py:714
 msgid "Cannot write SLIM configuration file"
-msgstr "Cannot write SLIM configuration file"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:778
+#: src/modules/displaymanager/main.py:715
 msgid "SLIM config file {!s} does not exist"
-msgstr "SLIM config file {!s} does not exist"
+msgstr ""
 
-#: src/modules/displaymanager/main.py:992
+#: src/modules/displaymanager/main.py:933
 msgid "No display managers selected for the displaymanager module."
-msgstr "No display managers selected for the displaymanager module."
+msgstr ""
 
-#: src/modules/displaymanager/main.py:993
+#: src/modules/displaymanager/main.py:934
 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:1075
+#: src/modules/displaymanager/main.py:1021
 msgid "Display manager configuration was incomplete"
-msgstr "Display manager configuration was incomplete"
+msgstr ""
 
-#: src/modules/initcpiocfg/main.py:28
-msgid "Configuring mkinitcpio."
-msgstr "Configuring mkinitcpio."
+#: src/modules/dracut/main.py:29
+msgid "Creating initramfs with dracut."
+msgstr ""
 
-#: src/modules/initcpiocfg/main.py:240 src/modules/initramfscfg/main.py:90
-#: src/modules/openrcdmcryptcfg/main.py:77 src/modules/fstab/main.py:401
+#: src/modules/dracut/main.py:63
+msgid "Failed to run dracut"
+msgstr ""
+
+#: src/modules/dracut/main.py:64
+#, python-brace-format
+msgid "Dracut failed to run on the target with return code: {return_code}"
+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/fstab/main.py:28
+msgid "Writing fstab."
+msgstr ""
+
+#: src/modules/fstab/main.py:377 src/modules/fstab/main.py:383
+#: src/modules/fstab/main.py:411 src/modules/initcpiocfg/main.py:245
+#: src/modules/initcpiocfg/main.py:249 src/modules/initramfscfg/main.py:85
+#: src/modules/initramfscfg/main.py:89 src/modules/localecfg/main.py:140
+#: src/modules/mount/main.py:329 src/modules/networkcfg/main.py:105
+#: src/modules/openrcdmcryptcfg/main.py:72
+#: src/modules/openrcdmcryptcfg/main.py:76 src/modules/rawfs/main.py:164
+msgid "Configuration Error"
+msgstr ""
+
+#: src/modules/fstab/main.py:378 src/modules/initramfscfg/main.py:86
+#: src/modules/mount/main.py:330 src/modules/openrcdmcryptcfg/main.py:73
+#: src/modules/rawfs/main.py:165
+msgid "No partitions are defined for 
{!s}
to use." +msgstr "" + +#: src/modules/fstab/main.py:384 src/modules/initramfscfg/main.py:90 #: src/modules/localecfg/main.py:141 src/modules/networkcfg/main.py:106 +#: src/modules/openrcdmcryptcfg/main.py:77 msgid "No root mount point is given for
{!s}
to use." -msgstr "No root mount point is given for
{!s}
to use." - -#: src/modules/rawfs/main.py:26 -msgid "Installing data." -msgstr "Installing data." - -#: src/modules/services-openrc/main.py:29 -msgid "Configure OpenRC services" -msgstr "Configure OpenRC services" - -#: 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}." - -#: 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}." - -#: 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:94 -msgid "" -"rc-update {arg!s} call in chroot returned error code {num!s}." +#: src/modules/fstab/main.py:412 +msgid "No
{!s}
configuration is given for
{!s}
to use." 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" - -#: src/modules/services-openrc/main.py:102 -msgid "" -"The path for runlevel {level!s} is {path!s}, which does not " -"exist." +#: src/modules/grubcfg/main.py:29 +msgid "Configure GRUB." 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" - -#: src/modules/services-openrc/main.py:111 -msgid "" -"The path for service {name!s} is {path!s}, which does not " -"exist." +#: src/modules/hwclock/main.py:26 +msgid "Setting hardware clock." msgstr "" -"The path for service {name!s} is {path!s}, which does not " -"exist." -#: src/modules/plymouthcfg/main.py:27 -msgid "Configure Plymouth theme" -msgstr "Configure Plymouth theme" +#: src/modules/initcpiocfg/main.py:27 +msgid "Configuring mkinitcpio." +msgstr "" + +#: src/modules/initcpiocfg/main.py:246 +msgid "No partitions are defined for
initcpiocfg
." +msgstr "" + +#: src/modules/initcpiocfg/main.py:250 +msgid "No root mount point for
initcpiocfg
." +msgstr "" + +#: src/modules/initramfscfg/main.py:32 +msgid "Configuring initramfs." +msgstr "" + +#: src/modules/localecfg/main.py:31 +msgid "Configuring locales." +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/mkinitfs/main.py:50 +msgid "The exit code was {}" +msgstr "" + +#: src/modules/mount/main.py:43 +msgid "Mounting partitions." +msgstr "" + +#: src/modules/mount/main.py:164 src/modules/mount/main.py:200 +msgid "Internal error mounting zfs datasets" +msgstr "" + +#: src/modules/mount/main.py:176 +msgid "Failed to import zpool" +msgstr "" + +#: src/modules/mount/main.py:192 +msgid "Failed to unlock zpool" +msgstr "" + +#: src/modules/mount/main.py:209 src/modules/mount/main.py:214 +msgid "Failed to set zfs mountpoint" +msgstr "" + +#: src/modules/mount/main.py:365 +msgid "zfs mounting error" +msgstr "" + +#: src/modules/networkcfg/main.py:29 +msgid "Saving network configuration." +msgstr "" + +#: src/modules/openrcdmcryptcfg/main.py:26 +msgid "Configuring OpenRC dmcrypt service." +msgstr "" #: 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:63 #, python-format msgid "Processing packages (%(count)d / %(total)d)" -msgstr "Processing packages (%(count)d / %(total)d)" +msgstr "" #: 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: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: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: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}
" -"returned error code {!s}." #: src/modules/packages/main.py:738 msgid "" -"The package manager could not update the system. The command
{!s}
" -" returned error code {!s}." +"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: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/bootloader/main.py:43 -msgid "Install bootloader." -msgstr "Install bootloader." - -#: src/modules/bootloader/main.py:614 -msgid "Failed to install grub, no partitions defined in global storage" -msgstr "Failed to install grub, no partitions defined in global storage" - -#: src/modules/bootloader/main.py:782 -msgid "Bootloader installation error" -msgstr "Bootloader installation error" - -#: src/modules/bootloader/main.py:783 -msgid "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." +#: src/modules/plymouthcfg/main.py:27 +msgid "Configure Plymouth theme" msgstr "" -"The bootloader could not be installed. The installation command " -"
{!s}
returned error code {!s}." -#: src/modules/hwclock/main.py:26 -msgid "Setting hardware clock." -msgstr "Setting hardware clock." +#: src/modules/rawfs/main.py:26 +msgid "Installing data." +msgstr "" -#: src/modules/mkinitfs/main.py:27 -msgid "Creating initramfs with mkinitfs." -msgstr "Creating initramfs with mkinitfs." +#: src/modules/services-openrc/main.py:29 +msgid "Configure OpenRC services" +msgstr "" -#: src/modules/mkinitfs/main.py:49 -msgid "Failed to run mkinitfs on the target" -msgstr "Failed to run mkinitfs on the target" +#: src/modules/services-openrc/main.py:57 +msgid "Cannot add service {name!s} to run-level {level!s}." +msgstr "" -#: src/modules/mkinitfs/main.py:50 src/modules/dracut/main.py:50 -msgid "The exit code was {}" -msgstr "The exit code was {}" +#: src/modules/services-openrc/main.py:59 +msgid "Cannot remove service {name!s} from run-level {level!s}." +msgstr "" -#: src/modules/dracut/main.py:27 -msgid "Creating initramfs with dracut." -msgstr "Creating initramfs with dracut." +#: 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/dracut/main.py:49 -msgid "Failed to run dracut on the target" -msgstr "Failed to run dracut on the target" +#: src/modules/services-openrc/main.py:93 +msgid "Cannot modify service" +msgstr "" -#: src/modules/initramfscfg/main.py:32 -msgid "Configuring initramfs." -msgstr "Configuring initramfs." +#: src/modules/services-openrc/main.py:94 +msgid "" +"rc-update {arg!s} call in chroot returned error code {num!s}." +msgstr "" -#: src/modules/openrcdmcryptcfg/main.py:26 -msgid "Configuring OpenRC dmcrypt service." -msgstr "Configuring OpenRC dmcrypt service." +#: src/modules/services-openrc/main.py:101 +msgid "Target runlevel does not exist" +msgstr "" -#: src/modules/fstab/main.py:28 -msgid "Writing fstab." -msgstr "Writing fstab." +#: src/modules/services-openrc/main.py:102 +msgid "" +"The path for runlevel {level!s} is {path!s}, which does not " +"exist." +msgstr "" -#: src/modules/fstab/main.py:429 -msgid "No
{!s}
configuration is given for
{!s}
to use." -msgstr "No
{!s}
configuration is given for
{!s}
to use." +#: src/modules/services-openrc/main.py:110 +msgid "Target service does not exist" +msgstr "" -#: src/modules/dummypython/main.py:35 -msgid "Dummy python job." -msgstr "Dummy python job." +#: src/modules/services-openrc/main.py:111 +msgid "" +"The path for service {name!s} is {path!s}, which does not exist." +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 {}" +#: src/modules/services-systemd/main.py:26 +msgid "Configure systemd units" +msgstr "" -#: src/modules/localecfg/main.py:31 -msgid "Configuring locales." -msgstr "Configuring locales." +#: src/modules/services-systemd/main.py:64 +msgid "Cannot modify unit" +msgstr "" -#: src/modules/networkcfg/main.py:29 -msgid "Saving network configuration." -msgstr "Saving network configuration." +#: src/modules/services-systemd/main.py:65 +msgid "" +"systemctl {_action!s} call in chroot returned error code " +"{_exit_code!s}." +msgstr "" + +#: src/modules/services-systemd/main.py:66 +msgid "Cannot {_action!s} systemd unit {_name!s}." +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:467 +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." +msgstr "" + +#: src/modules/unpackfs/main.py:434 +msgid "Bad mount point for root partition" +msgstr "" + +#: src/modules/unpackfs/main.py:435 +msgid "rootMountPoint is \"{}\", which does not exist." +msgstr "" + +#: 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: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 "" + +#: src/modules/unpackfs/main.py:460 +msgid "The source filesystem \"{}\" does not exist" +msgstr "" + +#: src/modules/unpackfs/main.py:466 +msgid "" +"Failed to find unsquashfs, make sure you have the squashfs-tools package " +"installed." +msgstr "" + +#: src/modules/unpackfs/main.py:481 +msgid "The destination \"{}\" in the target system is not a directory" +msgstr "" + +#: src/modules/zfshostid/main.py:27 +msgid "Copying zfs generated hostid." +msgstr "" From 4bf1b0fa7e73a038c3fa5948d5e67698630ca5ab Mon Sep 17 00:00:00 2001 From: Sunderland93 Date: Wed, 17 May 2023 16:25:57 +0400 Subject: [PATCH 88/89] Add River and Hyprland to desktop list --- src/modules/displaymanager/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/displaymanager/main.py b/src/modules/displaymanager/main.py index d7533e122..2a1448e51 100644 --- a/src/modules/displaymanager/main.py +++ b/src/modules/displaymanager/main.py @@ -197,6 +197,8 @@ desktop_environments = [ DesktopEnvironment('/usr/bin/sway', 'sway'), DesktopEnvironment('/usr/bin/ukui-session', 'ukui'), DesktopEnvironment('/usr/bin/cutefish-session', 'cutefish-xsession'), + DesktopEnvironment('/usr/bin/river', 'river'), + DesktopEnvironment('/usr/bin/Hyprland', 'hyprland'), ] From 7a67840c9bdd5d8c955aba436848a197859a9b25 Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Mon, 22 May 2023 12:03:22 -0400 Subject: [PATCH 89/89] [packages] Call dnf-3 binary, not dnf DNF is being replaced by a new package manager, DNF 5, in Fedora 39+. The `dnf` binary will soon symlink to DNF 5 instead of DNF 5. The old DNF 4 binary will still be (and always has been) available as /usr/bin/dnf-3. Until Calamares adds support for DNF 5, it should explicitly call the old dnf-3 binary. --- src/modules/packages/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index e373a3443..26ed30a19 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -282,12 +282,12 @@ class PMDnf(PackageManager): backend = "dnf" def install(self, pkgs, from_local=False): - check_target_env_call(["dnf", "-y", "install"] + pkgs) + check_target_env_call(["dnf-3", "-y", "install"] + pkgs) def remove(self, pkgs): # ignore the error code for now because dnf thinks removing a # nonexistent package is an error - target_env_call(["dnf", "--disablerepo=*", "-C", "-y", + target_env_call(["dnf-3", "--disablerepo=*", "-C", "-y", "remove"] + pkgs) def update_db(self): @@ -295,7 +295,7 @@ class PMDnf(PackageManager): pass def update_system(self): - check_target_env_call(["dnf", "-y", "upgrade"]) + check_target_env_call(["dnf-3", "-y", "upgrade"]) class PMDummy(PackageManager):