From 45daebd989cb64d299c2be2feaa36927455392d3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 12:42:58 +0200 Subject: [PATCH 01/30] [initcpiocfg] Refactor CPU-characteristics determination The code is still over-wrought, but the API for cpuinfo now exposes the interesting thing (is it Intel?) in a useful -- more readable -- way. --- src/modules/initcpiocfg/main.py | 71 +++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index 4fb0923cd..d5cb101a1 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -28,35 +28,57 @@ def pretty_name(): return _("Configuring mkinitcpio.") -def cpuinfo(): +class cpuinfo(object): """ - Return the information in /proc/cpuinfo as a dictionary in the following - format: + Object describing the current CPU's characteristics. It may be + be considered a named tuple, there's no behavior here. - cpu_info['proc0']={...} - cpu_info['proc1']={...} + Fields in the object: + - is_intel (if it's definitely an Intel CPU) + - is_amd (if it's definitely an AMD CPU) + - number_of_cores + It is possible for both is_* fields to be False. """ - cpu_info = OrderedDict() - procinfo = OrderedDict() + def __init__(self): + self.is_intel = False + self.is_amd = False + self.number_of_cores = 0 - nprocs = 0 + cpu = self._cpuinfo() + self.is_intel = cpu['proc0']['vendor_id'].lower() == "genuineintel" + self.is_amd = cpu['proc0']['vendor_id'].lower() == "authenticamd" + self.number_of_cores = len(cpu) - with open('/proc/cpuinfo') as cpuinfo_file: - for line in cpuinfo_file: - if not line.strip(): - # end of one processor - cpu_info["proc{!s}".format(nprocs)] = procinfo - nprocs += 1 - # Reset - procinfo = OrderedDict() - else: - if len(line.split(':')) == 2: - splitted_line = line.split(':')[1].strip() - procinfo[line.split(':')[0].strip()] = splitted_line + @staticmethod + def _cpuinfo(): + """ + Return the information in /proc/cpuinfo as a dictionary in the following + format: + + cpu_info['proc0']={...} + cpu_info['proc1']={...} + """ + cpu_info = OrderedDict() + procinfo = OrderedDict() + + nprocs = 0 + + with open('/proc/cpuinfo') as cpuinfo_file: + for line in cpuinfo_file: + if not line.strip(): + # end of one processor + cpu_info["proc{!s}".format(nprocs)] = procinfo + nprocs += 1 + # Reset + procinfo = OrderedDict() else: - procinfo[line.split(':')[0].strip()] = '' + if len(line.split(':')) == 2: + splitted_line = line.split(':')[1].strip() + procinfo[line.split(':')[0].strip()] = splitted_line + else: + procinfo[line.split(':')[0].strip()] = '' - return cpu_info + return cpu_info def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): @@ -172,10 +194,9 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): else: hooks.extend(["filesystems"]) - if btrfs == "yes" and cpu['proc0']['vendor_id'].lower() != "genuineintel": + if btrfs == "yes" and not cpu.is_intel: modules.append("crc32c") - elif (btrfs == "yes" - and cpu['proc0']['vendor_id'].lower() == "genuineintel"): + elif (btrfs == "yes" and cpu.is_intel): modules.append("crc32c-intel") else: hooks.append("fsck") From 7f7dc04e8dda8add2454a9b88ad175d56e871aa7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 12:52:16 +0200 Subject: [PATCH 02/30] [initcpiocfg] Use bools for boolean values Having "" and "yes" as values is a bit shell-script-ish. Use a regular boolean value instead; simplify code while we're at it. --- src/modules/initcpiocfg/main.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index d5cb101a1..bdc3f9cde 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -132,9 +132,8 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): :param partitions: :param root_mount_point: """ - cpu = cpuinfo() swap_uuid = "" - btrfs = "" + uses_btrfs = False lvm2 = "" hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] @@ -159,7 +158,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): openswap_hook = True if partition["fs"] == "btrfs": - btrfs = "yes" + uses_btrfs = True if "lvm2" in partition["fs"]: lvm2 = "yes" @@ -194,10 +193,8 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): else: hooks.extend(["filesystems"]) - if btrfs == "yes" and not cpu.is_intel: - modules.append("crc32c") - elif (btrfs == "yes" and cpu.is_intel): - modules.append("crc32c-intel") + if uses_btrfs: + modules.append("crc32c-intel" if cpuinfo().is_intel else "crc32c") else: hooks.append("fsck") From 7c3c7c4ff79a66bdb6e3253d0ea4d86a988405b2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 12:54:18 +0200 Subject: [PATCH 03/30] [initcpiocfg] Use booleans for boolean values (as previous) Use False/True rather than ""/"yes" for keeping track of does-the-system-use-lvm2. --- 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 bdc3f9cde..fe0712a9a 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -134,7 +134,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): """ swap_uuid = "" uses_btrfs = False - lvm2 = "" + uses_lvm2 = False hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] modules = [] @@ -161,7 +161,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): uses_btrfs = True if "lvm2" in partition["fs"]: - lvm2 = "yes" + uses_lvm2 = True if partition["mountPoint"] == "/" and "luksMapperName" in partition: encrypt_hook = True @@ -183,7 +183,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): ): files.append("/crypto_keyfile.bin") - if lvm2: + if uses_lvm2: hooks.append("lvm2") if swap_uuid != "": From 118e18ac6060c5df285f808023b64d5ade4fa9bf Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 13:03:13 +0200 Subject: [PATCH 04/30] [initcpiocfg] Code-shuffle - put the system-information and -detection functions at top and the "do the actual work" things below - don't mix the boolean do-we-use-this flags with the lists of files and modules which are the important parts of modify_mkinitcpio_conf --- src/modules/initcpiocfg/main.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index fe0712a9a..b91a46086 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -28,6 +28,16 @@ def pretty_name(): return _("Configuring mkinitcpio.") +def detect_plymouth(): + """ + Checks existence (runnability) of plymouth in the target system. + + @return True if plymouth exists in the target, False otherwise + """ + # Used to only check existence of path /usr/bin/plymouth in target + return target_env_call(["sh", "-c", "which plymouth"]) == 0 + + class cpuinfo(object): """ Object describing the current CPU's characteristics. It may be @@ -115,16 +125,6 @@ def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): mkinitcpio_file.write("\n".join(mklins) + "\n") -def detect_plymouth(): - """ - Checks existence (runnability) of plymouth in the target system. - - @return True if plymouth exists in the target, False otherwise - """ - # Used to only check existence of path /usr/bin/plymouth in target - return target_env_call(["sh", "-c", "which plymouth"]) == 0 - - def modify_mkinitcpio_conf(partitions, root_mount_point): """ Modifies mkinitcpio.conf @@ -132,13 +132,13 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): :param partitions: :param root_mount_point: """ + hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] + modules = [] + files = [] + swap_uuid = "" uses_btrfs = False uses_lvm2 = False - hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", - "keymap"] - modules = [] - files = [] encrypt_hook = False openswap_hook = False unencrypted_separate_boot = False From 60e495bd8c7645f2368ffa9215e0118a750ce635 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 13:13:21 +0200 Subject: [PATCH 05/30] [initcpiocfg] Refactor, improve testability - don't chain directly from modify_mkinitcpio_conf() to the function that writes the file write_mkinitcpio_lines(); split into "figure out what needs to be written" and calling that writing-function, so that we can test / check / log if needed between the two. --- src/modules/initcpiocfg/main.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index b91a46086..d89c0f94f 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -125,12 +125,16 @@ def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): mkinitcpio_file.write("\n".join(mklins) + "\n") -def modify_mkinitcpio_conf(partitions, root_mount_point): +def find_initcpio_features(partitions, root_mount_point): """ - Modifies mkinitcpio.conf + Returns a tuple (hooks, modules, files) needed to support + the given @p partitions (filesystems types, encryption, etc) + in the target. - :param partitions: - :param root_mount_point: + :param partitions: (from GS) + :param root_mount_point: (from GS) + + :return 3-tuple of lists """ hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] modules = [] @@ -198,7 +202,7 @@ def modify_mkinitcpio_conf(partitions, root_mount_point): else: hooks.append("fsck") - write_mkinitcpio_lines(hooks, modules, files, root_mount_point) + return (hooks, modules, files) def run(): @@ -219,6 +223,7 @@ def run(): return (_("Configuration Error"), _("No root mount point is given for
{!s}
to use." ).format("initcpiocfg")) - modify_mkinitcpio_conf(partitions, root_mount_point) + hooks, modules, files = find_initcpio_features(partitions, root_mount_point) + write_mkinitcpio_lines(hooks, modules, files, root_mount_point) return None From 12cd9dd5b22a9274a2486df656b81232b973ae3c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 13:18:01 +0200 Subject: [PATCH 06/30] [initcpiocfg] Refactor - Read the host /etc/mkinitcpio.cfg in one function rather than hiding it inside the writer --- src/modules/initcpiocfg/main.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index d89c0f94f..f209a7376 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -91,6 +91,23 @@ class cpuinfo(object): return cpu_info +def get_host_initcpio(): + """ + Reads the host system mkinitcpio.conf and returns all + the lines from that file, or an empty list if it does + not exist. + """ + hostfile = "/etc/mkinitcpio.conf" + try: + with open(hostfile, "r") as mkinitcpio_file: + mklins = [x.strip() for x in mkinitcpio_file.readlines()] + except FileNotFoundError: + libcalamares.utils.debug("Could not open host file '%s'" % hostfile) + mklins = [] + + return mklins + + def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): """ Set up mkinitcpio.conf. @@ -100,13 +117,7 @@ def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): :param files: :param root_mount_point: """ - hostfile = "/etc/mkinitcpio.conf" - try: - with open(hostfile, "r") as mkinitcpio_file: - mklins = [x.strip() for x in mkinitcpio_file.readlines()] - except FileNotFoundError: - libcalamares.utils.debug("Could not open host file '%s'" % hostfile) - mklins = [] + mklins = get_host_initcpio() for i in range(len(mklins)): if mklins[i].startswith("HOOKS"): From a4c714238fe1666814309efee861ed1564acb1a3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 13:39:29 +0200 Subject: [PATCH 07/30] [initcpio] Refactor file-writing - iterate over the lines of the source file, rather than over indexes, and make clear that the hooks, modules and files lines are replaced, rather than merged. - this calls write() more often, but it's only a few lines --- src/modules/initcpiocfg/main.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/modules/initcpiocfg/main.py b/src/modules/initcpiocfg/main.py index f209a7376..903ef635f 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -119,21 +119,18 @@ def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): """ mklins = get_host_initcpio() - for i in range(len(mklins)): - if mklins[i].startswith("HOOKS"): - joined_hooks = ' '.join(hooks) - mklins[i] = "HOOKS=\"{!s}\"".format(joined_hooks) - elif mklins[i].startswith("MODULES"): - joined_modules = ' '.join(modules) - mklins[i] = "MODULES=\"{!s}\"".format(joined_modules) - elif mklins[i].startswith("FILES"): - joined_files = ' '.join(files) - mklins[i] = "FILES=\"{!s}\"".format(joined_files) - - path = os.path.join(root_mount_point, "etc/mkinitcpio.conf") - - with open(path, "w") as mkinitcpio_file: - mkinitcpio_file.write("\n".join(mklins) + "\n") + target_path = os.path.join(root_mount_point, "etc/mkinitcpio.conf") + with open(target_path, "w") as mkinitcpio_file: + for line in mklins: + # Replace HOOKS, MODULES and FILES lines with what we + # have found via find_initcpio_features() + if line.startswith("HOOKS"): + line = "HOOKS=\"{!s}\"".format(' '.join(hooks)) + elif line.startswith("MODULES"): + line = "MODULES=\"{!s}\"".format(' '.join(modules)) + elif lines.startswith("FILES"): + line = "FILES=\"{!s}\"".format(' '.join(files)) + mkinitcpio_file.write(line + "\n") def find_initcpio_features(partitions, root_mount_point): From cb92e49363a3dbb58cb5da7a693d8521ead86ab2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 15:16:08 +0200 Subject: [PATCH 08/30] [initcpiocfg] Document this module --- src/modules/initcpiocfg/module.desc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/initcpiocfg/module.desc b/src/modules/initcpiocfg/module.desc index a4476121b..a64fdf173 100644 --- a/src/modules/initcpiocfg/module.desc +++ b/src/modules/initcpiocfg/module.desc @@ -1,7 +1,13 @@ # SPDX-FileCopyrightText: no # SPDX-License-Identifier: CC0-1.0 +# +# Writes a mkinitcpio.conf into the target system. It copies +# the host system's /etc/mkinitcpio.conf, and replaces any +# HOOKS, MODULES, and FILES lines with calculated values +# based on what the installation (seems to) need. --- type: "job" name: "initcpiocfg" interface: "python" script: "main.py" +noconfig: true From 54385b760630fec1b982f1a57fddc635712feb45 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 21 Sep 2021 16:53:09 +0200 Subject: [PATCH 09/30] [libcalamares] Cut down config-file-loading log spam --- src/libcalamares/modulesystem/Module.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/modulesystem/Module.cpp b/src/libcalamares/modulesystem/Module.cpp index ff0b20f78..8fbb05300 100644 --- a/src/libcalamares/modulesystem/Module.cpp +++ b/src/libcalamares/modulesystem/Module.cpp @@ -101,7 +101,7 @@ Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::E YAML::Node doc = YAML::Load( ba.constData() ); if ( doc.IsNull() ) { - cDebug() << "Found empty module configuration" << path; + cWarning() << "Found empty module configuration" << path; // Special case: empty config files are valid, // but aren't a map. return; @@ -112,14 +112,13 @@ Module::loadConfigurationFile( const QString& configFileName ) //throws YAML::E return; } - cDebug() << "Loaded module configuration" << path; m_configurationMap = CalamaresUtils::yamlMapToVariant( doc ); m_emergency = m_maybe_emergency && m_configurationMap.contains( EMERGENCY ) && m_configurationMap[ EMERGENCY ].toBool(); return; } } - cDebug() << "No config file for" << name() << "found anywhere at" << Logger::DebugList( configCandidates ); + cWarning() << "No config file for" << name() << "found anywhere at" << Logger::DebugList( configCandidates ); } From 39915db988eb10157c0f551b71020b9431723037 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 00:58:31 +0200 Subject: [PATCH 10/30] [libcalamares] Reduce log spam when running commands --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index df578a862..d2c0a6cf1 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -169,7 +169,7 @@ System::runCommand( System::RunLocation location, } } - cDebug() << "Running" << program << RedactedList( arguments ); + cDebug() << Logger::SubEntry << "Running" << program << RedactedList( arguments ); process.start(); if ( !process.waitForStarted() ) { @@ -208,10 +208,6 @@ System::runCommand( System::RunLocation location, { cDebug() << Logger::SubEntry << "Finished. Exit code:" << r << "output:\n" << Logger::NoQuote << output; } - else - { - cDebug() << Logger::SubEntry << "Finished. Exit code:" << r; - } } else // if ( r != 0 ) { From 857aaa6ca4319023e286a6b426cd66ca87abe434 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 01:05:13 +0200 Subject: [PATCH 11/30] [partition] Cut down log spam about /etc/fstab --- src/modules/partition/core/PartUtils.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 54f971f4e..58e2fdf0d 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -250,8 +250,6 @@ lookForFstabEntries( const QString& partitionPath ) { QFile fstabFile( mount.path() + "/etc/fstab" ); - cDebug() << Logger::SubEntry << "reading" << fstabFile.fileName(); - if ( fstabFile.open( QIODevice::ReadOnly | QIODevice::Text ) ) { const QStringList fstabLines = QString::fromLocal8Bit( fstabFile.readAll() ).split( '\n' ); @@ -261,10 +259,10 @@ lookForFstabEntries( const QString& partitionPath ) fstabEntries.append( FstabEntry::fromEtcFstab( rawLine ) ); } fstabFile.close(); - cDebug() << Logger::SubEntry << "got" << fstabEntries.count() << "lines."; + const int lineCount = fstabEntries.count(); std::remove_if( fstabEntries.begin(), fstabEntries.end(), []( const FstabEntry& x ) { return !x.isValid(); } ); - cDebug() << Logger::SubEntry << "got" << fstabEntries.count() << "fstab entries."; + cDebug() << Logger::SubEntry << "got" << fstabEntries.count() << "fstab entries from" << lineCount << "lines in" << fstabFile.fileName(); } else { From cf1128b719dcb66c5b91bedac6f46fca1f15f46b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 01:27:33 +0200 Subject: [PATCH 12/30] [partition] Cut down log-spam while checking for resize --- src/modules/partition/core/PartUtils.cpp | 38 +++++++++++++----------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 58e2fdf0d..c99884ce6 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -126,23 +126,22 @@ canBeResized( Partition* candidate, const Logger::Once& o ) return false; } - cDebug() << o << "Checking if" << convenienceName( candidate ) << "can be resized."; if ( !candidate->fileSystem().supportGrow() || !candidate->fileSystem().supportShrink() ) { - cDebug() << Logger::SubEntry << "NO, filesystem" << candidate->fileSystem().name() - << "does not support resize."; + cDebug() << o << "Can not resize" << convenienceName( candidate ) << ", filesystem" + << candidate->fileSystem().name() << "does not support resize."; return false; } if ( isPartitionFreeSpace( candidate ) ) { - cDebug() << Logger::SubEntry << "NO, partition is free space"; + cDebug() << o << "Can not resize" << convenienceName( candidate ) << ", partition is free space"; return false; } if ( candidate->isMounted() ) { - cDebug() << Logger::SubEntry << "NO, partition is mounted"; + cDebug() << o << "Can not resize" << convenienceName( candidate ) << ", partition is mounted"; return false; } @@ -151,14 +150,14 @@ canBeResized( Partition* candidate, const Logger::Once& o ) PartitionTable* table = dynamic_cast< PartitionTable* >( candidate->parent() ); if ( !table ) { - cDebug() << Logger::SubEntry << "NO, no partition table found"; + cDebug() << o << "Can not resize" << convenienceName( candidate ) << ", no partition table found"; return false; } if ( table->numPrimaries() >= table->maxPrimaries() ) { - cDebug() << Logger::SubEntry << "NO, partition table already has" << table->maxPrimaries() - << "primary partitions."; + cDebug() << o << "Can not resize" << convenienceName( candidate ) << ", partition table already has" + << table->maxPrimaries() << "primary partitions."; return false; } } @@ -167,7 +166,8 @@ canBeResized( Partition* candidate, const Logger::Once& o ) double requiredStorageGiB = getRequiredStorageGiB( ok ); if ( !ok ) { - cDebug() << Logger::SubEntry << "NO, requiredStorageGiB is not set correctly."; + cDebug() << o << "Can not resize" << convenienceName( candidate ) + << ", requiredStorageGiB is not set correctly."; return false; } @@ -200,24 +200,25 @@ canBeResized( Partition* candidate, const Logger::Once& o ) bool canBeResized( DeviceModel* dm, const QString& partitionPath, const Logger::Once& o ) { - cDebug() << o << "Checking if" << partitionPath << "can be resized."; - QString partitionWithOs = partitionPath; - if ( partitionWithOs.startsWith( "/dev/" ) ) + if ( partitionPath.startsWith( "/dev/" ) ) { for ( int i = 0; i < dm->rowCount(); ++i ) { Device* dev = dm->deviceForIndex( dm->index( i ) ); - Partition* candidate = CalamaresUtils::Partition::findPartitionByPath( { dev }, partitionWithOs ); + Partition* candidate = CalamaresUtils::Partition::findPartitionByPath( { dev }, partitionPath ); if ( candidate ) { return canBeResized( candidate, o ); } } - cDebug() << Logger::SubEntry << "no Partition* found for" << partitionWithOs; + cWarning() << "Can not resize" << partitionPath << ", no Partition* found."; + return false; + } + else + { + cWarning() << "Can not resize" << partitionPath << ", does not start with /dev"; + return false; } - - cDebug() << Logger::SubEntry << "Partition" << partitionWithOs << "CANNOT BE RESIZED FOR AUTOINSTALL."; - return false; } @@ -262,7 +263,8 @@ lookForFstabEntries( const QString& partitionPath ) const int lineCount = fstabEntries.count(); std::remove_if( fstabEntries.begin(), fstabEntries.end(), []( const FstabEntry& x ) { return !x.isValid(); } ); - cDebug() << Logger::SubEntry << "got" << fstabEntries.count() << "fstab entries from" << lineCount << "lines in" << fstabFile.fileName(); + cDebug() << Logger::SubEntry << "got" << fstabEntries.count() << "fstab entries from" << lineCount + << "lines in" << fstabFile.fileName(); } else { From 049bccbdd82ce6559a04fe67f94edbfd0f273a23 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 01:28:40 +0200 Subject: [PATCH 13/30] [libcalamares] Cut down log-spam from KPMManager --- src/libcalamares/partition/KPMManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libcalamares/partition/KPMManager.cpp b/src/libcalamares/partition/KPMManager.cpp index 5f6b87589..ff7701703 100644 --- a/src/libcalamares/partition/KPMManager.cpp +++ b/src/libcalamares/partition/KPMManager.cpp @@ -100,12 +100,10 @@ getInternal() KPMManager::KPMManager() : m_d( getInternal() ) { - cDebug() << "KPMManager" << s_backend.use_count() << "created."; } KPMManager::~KPMManager() { - cDebug() << "KPMManager" << s_backend.use_count() << "being destroyed."; } KPMManager::operator bool() const From 9be9431970d83822d06f0a4e4edbe621bea102a3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 01:41:28 +0200 Subject: [PATCH 14/30] [libcalamares] Give Logger::Once more flexibility --- src/libcalamares/utils/Logger.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h index 871cc6fb3..1fd534d04 100644 --- a/src/libcalamares/utils/Logger.h +++ b/src/libcalamares/utils/Logger.h @@ -310,6 +310,14 @@ public: } friend CDebug& operator<<( CDebug&&, const Once& ); + /** @brief Restore the object to "fresh" state + * + * It may be necessary to allow the Once object to stream the + * function header again -- for instance, after logging an error, + * any following debug log might want to re-introduce the header. + */ + void refresh() { m = true; } + private: mutable bool m = false; }; From db26df311d93b47a7cc98fc08feaf504ccfe9ff0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 01:44:00 +0200 Subject: [PATCH 15/30] [libcalamares] Reduce log-spam in emergencies - when an emergency strikes, log the modules that are skipped with a Once, but if an emergency module runs, refresh that Once so that the function header is printed again -- to distinguish JobQueue debugging from the logging from the emergency module. --- src/libcalamares/JobQueue.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index 00b30f318..039a28e26 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -112,17 +112,19 @@ public: QString message; ///< Filled in with errors QString details; + Logger::Once o; m_jobIndex = 0; for ( const auto& jobitem : *m_runningJobs ) { if ( failureEncountered && !jobitem.job->isEmergency() ) { - cDebug() << "Skipping non-emergency job" << jobitem.job->prettyName(); + cDebug() << o << "Skipping non-emergency job" << jobitem.job->prettyName(); } else { - cDebug() << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" ) << jobitem.job->prettyName() + cDebug() << o << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" ) << jobitem.job->prettyName() << '(' << ( m_jobIndex + 1 ) << '/' << m_runningJobs->count() << ')'; + o.refresh(); // So next time it shows the function header again emitProgress( 0.0 ); // 0% for *this job* connect( jobitem.job.data(), &Job::progress, this, &JobThread::emitProgress ); auto result = jobitem.job->exec(); From cce8b73554584d73942a5313e41463a4b4696983 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 21 Sep 2021 15:25:51 +0200 Subject: [PATCH 16/30] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_cs_CZ.ts | 74 ++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/lang/calamares_cs_CZ.ts b/lang/calamares_cs_CZ.ts index 1c2ed1755..5714c4e31 100644 --- a/lang/calamares_cs_CZ.ts +++ b/lang/calamares_cs_CZ.ts @@ -134,7 +134,7 @@ Widget Tree - Strom widgetu + Strom ovládacích prvků @@ -217,7 +217,7 @@ Working directory %1 for python job %2 is not readable. - Pracovní složku %1 pro Python skript %2 se nedaří otevřít pro čtení. + Pracovní složka %1 pro Python skript %2 není přístupná pro čtení. @@ -227,7 +227,7 @@ Main script file %1 for python job %2 is not readable. - Hlavní soubor s python skriptem %1 pro úlohu %2 se nedaří otevřít pro čtení.. + Hlavní soubor Python skriptu %1 pro úlohu %2 není přístupný pro čtení. @@ -504,7 +504,7 @@ Instalační program bude ukončen a všechny změny ztraceny. %1 Installer - %1 instalátor + Instalátor %1 @@ -660,7 +660,7 @@ Instalační program bude ukončen a všechny změny ztraceny. This storage device is a part of an <strong>inactive RAID</strong> device. - Toto úložné zařízení je součástí <strong>Neaktivního RAID</strong> zařízení. + Toto úložné zařízení je součástí <strong>neaktivního RAID</strong> zařízení. @@ -758,7 +758,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Set keyboard layout to %1/%2. - Nastavit rozložení klávesnice na %1/%2. + Nastavit rozvržení klávesnice na %1/%2. @@ -808,7 +808,7 @@ Instalační program bude ukončen a všechny změny ztraceny. This computer does not satisfy the minimum requirements for setting up %1.<br/>Setup cannot continue. <a href="#details">Details...</a> - Počítač nesplňuje minimální požadavky pro instalaci %1.<br/>Instalace nemůže pokračovat <a href="#details">Podrobnosti…</a> + Počítač nesplňuje minimální požadavky pro instalaci %1.<br/>Nastavování nemůže pokračovat <a href="#details">Podrobnosti…</a> @@ -953,7 +953,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Install option: <strong>%1</strong> - Možnost instalace: <strong>%1</strong> + Volba instalace: <strong>%1</strong> @@ -1182,7 +1182,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Preserving home directory - Zachování domovské složky + Zachovává se domovská složka @@ -1198,7 +1198,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Setting file permissions - Nastavení oprávnění souboru + Nastavují se přístupová práva k souboru @@ -1755,7 +1755,7 @@ Instalační program bude ukončen a všechny změny ztraceny. System locale setting - Místní a jazykové nastavení systému + Místní a jazyková nastavení systému @@ -1986,7 +1986,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Timezone: %1 - Časová zóna: %1 + Časové pásmo: %1 @@ -2152,12 +2152,12 @@ Instalační program bude ukončen a všechny změny ztraceny. Select your preferred Zone within your Region. - Vyberte preferovanou zónu ve vašem regionu. + Vyberte upřednostňované pásmo ve svém regionu. Zones - Zóny + Pásma @@ -2283,7 +2283,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Heslo obsahuje méně než %1 číslici Heslo obsahuje méně než %1 číslice - Heslo obsahuje méně než %1 číslice + Heslo obsahuje méně než %1 číslic Heslo obsahuje méně než %1 číslice @@ -2463,7 +2463,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Form - Form + Formulář @@ -2724,7 +2724,7 @@ Instalační program bude ukončen a všechny změny ztraceny. Form - Form + Formulář @@ -3609,7 +3609,7 @@ Výstup: These groups are missing in the target system: %1 - Tyto skupiny chybí v cílovém systému chybí: %1 + Tyto skupiny v cílovém systému chybí: %1 @@ -3703,7 +3703,7 @@ Výstup: KDE user feedback - Zpětná vazba uživatele KDE + Zpětná vazba od uživatele pro KDE @@ -3719,12 +3719,12 @@ Výstup: Could not configure KDE user feedback correctly, script error %1. - Nepodařilo se správně nastavit zpětnou vazbu KDE uživatele, chyba ve skriptu %1. + Nepodařilo se správně nastavit zpětnou vazbu od uživatele pro KDE, chyba ve skriptu %1. Could not configure KDE user feedback correctly, Calamares error %1. - Nepodařilo se správně nastavit zpětnou vazbu KDE uživatele, chyba Calamares %1. + Nepodařilo se správně nastavit zpětnou vazbu od uživatel pro KDE, chyba Calamares %1. @@ -3732,28 +3732,28 @@ Výstup: Machine feedback - Zpětná vazba stroje + Zpětná vazba ze stroje Configuring machine feedback. - Nastavování zpětné vazby stroje + Nastavování zpětné vazby ze stroje Error in machine feedback configuration. - Chyba v nastavení zpětné vazby stroje. + Chyba v nastavení zpětné vazby ze stroje. Could not configure machine feedback correctly, script error %1. - Nepodařilo se správně nastavit zpětnou vazbu stroje, chyba skriptu %1. + Nepodařilo se správně nastavit zpětnou vazbu ze stroje, chyba skriptu %1. Could not configure machine feedback correctly, Calamares error %1. - Nepodařilo se správně nastavit zpětnou vazbu stroje, chyba Calamares %1. + Nepodařilo se správně nastavit zpětnou vazbu ze stroje, chyba Calamares %1. @@ -3786,7 +3786,7 @@ Výstup: By selecting this you will send information about your installation and hardware. This information will only be sent <b>once</b> after the installation finishes. - Výběrem tohoto pošlete informace o své instalaci a hardware. Tyto údaje budou poslány <b>pouze jednorázově</b> po dokončení instalace. + Výběrem tohoto pošlete informace o své instalaci a hardware. Tyto údaje budou odeslány <b>pouze jednorázově</b> po dokončení instalace. @@ -3975,7 +3975,7 @@ Výstup: <h1>Welcome to the Calamares installer for %1.</h1> - <h1>Vítejte v Calamares, instalačním programu (nejen) pro %1.</h1> + <h1>Vítejte v Calamares, instalačním programu (nejen) pro %1.</h1> @@ -4121,7 +4121,7 @@ Výstup: To activate keyboard preview, select a layout. - + Pokud chcete aktivovat náhled klávesnice, vyberte rozvržení. @@ -4131,7 +4131,7 @@ Výstup: Layouts - Rovzržení + Rozvržení @@ -4179,7 +4179,7 @@ Výstup: If you don't want to install an office suite, just select No Office Suite. You can always add one (or more) later on your installed system as the need arrives. - Pokud nechcete nainstalovat žádnou sadu kancelářských aplikací, stačí jen zvolit Žádná sada kancelářských aplikací. V případě potřeby je možné kdykoli nějakou přidat na už nainstalovaný systém. + Pokud nechcete nainstalovat žádnou sadu kancelářských aplikací, stačí jen zvolit Žádná sada kancelářských aplikací. V případě potřeby je možné kdykoli nějakou přidat do už nainstalovaného systému. @@ -4310,7 +4310,7 @@ Výstup: This name will be used if you make the computer visible to others on a network. - Tento název se použije, pokud počítač zviditelníte ostatním v síti. + Pod tímto názvem se bude počítač případně zobrazovat ostatním počítačům v síti. @@ -4335,7 +4335,7 @@ Výstup: Enter the same password twice, so that it can be checked for typing errors. A good password will contain a mixture of letters, numbers and punctuation, should be at least eight characters long, and should be changed at regular intervals. - Zadejte dvakrát stejné heslo, aby bylo možné zkontrolovat chyby při psaní. Dobré heslo by mělo obsahovat směs písmen, čísel a interpunkce a mělo by mít alespoň osm znaků. Zvažte také jeho pravidelnou změnu. + Zadání hesla zopakujte i do kontrolní kolonky, abyste měli jistotu, že jste napsali, co zamýšleli (že nedošlo k překlepu). Dobré heslo se bude skládat z písmen, číslic a interpunkce a mělo by být alespoň osm znaků dlouhé. Heslo byste také měli pravidelně měnit (prevence škod z jeho případného prozrazení). @@ -4350,7 +4350,7 @@ Výstup: Log in automatically without asking for the password - Přihlaste se automaticky bez zadávání hesla + Přihlašovat se automaticky bez zadávání hesla @@ -4360,7 +4360,7 @@ Výstup: Reuse user password as root password - Použijte uživatelské heslo zároveň jako heslo root + Použijte heslo uživatele i pro účet správce (root) @@ -4380,12 +4380,12 @@ Výstup: Repeat Root Password - Opakujte root heslo + Zopakujte zadání hesla pro správce systému (root) Enter the same password twice, so that it can be checked for typing errors. - Zadejte dvakrát stejné heslo, aby bylo možné zkontrolovat chyby při psaní. + Zadání hesla zopakujte i do kontrolní kolonky, abyste měli jistotu, že jste napsali, co zamýšleli (že nedošlo k překlepu). From 7bdccd0ea7320a9badad1b43f88f3caff77de516 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Tue, 21 Sep 2021 15:25:51 +0200 Subject: [PATCH 17/30] i18n: [python] Automatic merge of Transifex translations --- lang/python/az/LC_MESSAGES/python.po | 4 ++-- lang/python/az_AZ/LC_MESSAGES/python.po | 4 ++-- lang/python/cs_CZ/LC_MESSAGES/python.po | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lang/python/az/LC_MESSAGES/python.po b/lang/python/az/LC_MESSAGES/python.po index f4c40e5ab..8ac8172d8 100644 --- a/lang/python/az/LC_MESSAGES/python.po +++ b/lang/python/az/LC_MESSAGES/python.po @@ -4,7 +4,7 @@ # FIRST AUTHOR , YEAR. # # Translators: -# xxmn77 , 2021 +# Xəyyam Qocayev , 2021 # #, fuzzy msgid "" @@ -13,7 +13,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-09-08 13:31+0200\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: xxmn77 , 2021\n" +"Last-Translator: Xəyyam Qocayev , 2021\n" "Language-Team: Azerbaijani (https://www.transifex.com/calamares/teams/20061/az/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/lang/python/az_AZ/LC_MESSAGES/python.po b/lang/python/az_AZ/LC_MESSAGES/python.po index 2d57f0d4b..0df66e711 100644 --- a/lang/python/az_AZ/LC_MESSAGES/python.po +++ b/lang/python/az_AZ/LC_MESSAGES/python.po @@ -4,7 +4,7 @@ # FIRST AUTHOR , YEAR. # # Translators: -# xxmn77 , 2021 +# Xəyyam Qocayev , 2021 # #, fuzzy msgid "" @@ -13,7 +13,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-09-08 13:31+0200\n" "PO-Revision-Date: 2017-08-09 10:34+0000\n" -"Last-Translator: xxmn77 , 2021\n" +"Last-Translator: Xəyyam Qocayev , 2021\n" "Language-Team: Azerbaijani (Azerbaijan) (https://www.transifex.com/calamares/teams/20061/az_AZ/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" diff --git a/lang/python/cs_CZ/LC_MESSAGES/python.po b/lang/python/cs_CZ/LC_MESSAGES/python.po index 6305ba7fb..993ed0b3f 100644 --- a/lang/python/cs_CZ/LC_MESSAGES/python.po +++ b/lang/python/cs_CZ/LC_MESSAGES/python.po @@ -206,8 +206,8 @@ msgid "" "The displaymanagers list is empty or undefined in both globalstorage and " "displaymanager.conf." msgstr "" -"Seznam správců displejů je prázdný nebo není definován v jak " -"bothglobalstorage, tak v displaymanager.conf." +"Seznam správců displejů je prázdný nebo není definován v jak globalstorage, " +"tak v displaymanager.conf." #: src/modules/displaymanager/main.py:989 msgid "Display manager configuration was incomplete" @@ -343,7 +343,7 @@ msgid "" "The package manager could not make changes to the installed system. The " "command
{!s}
returned error code {!s}." msgstr "" -"Nástroji pro správu balíčků se nepodařilo udělat změny v nainstalovaném " +"Nástroji pro správu balíčků se nepodařilo udělat změny v instalovaném " "systému. Příkaz
{!s}
vrátil chybový kód {!s}." #: src/modules/bootloader/main.py:43 From b0149c271257e216a4d5a5d501f07962b6f4c6d2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 11:03:56 +0200 Subject: [PATCH 18/30] [libcalamares] Log the Python language-search process just once - log the list of search paths once - log the found-language as if from Python - warn always if none are found --- src/libcalamares/PythonJobApi.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index d61cfc223..3f908b98d 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -16,6 +16,7 @@ #include "partition/Mount.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" +#include "utils/RAII.h" #include "utils/String.h" #include @@ -147,7 +148,7 @@ debug( const std::string& s ) void warning( const std::string& s ) { - Logger::CDebug( Logger::LOGWARNING ) << output_prefix << QString::fromStdString( s ); + Logger::CDebug( Logger::LOGWARNING ) << output_prefix << QString::fromStdString( s ); } PythonJobInterface::PythonJobInterface( Calamares::PythonJob* parent ) @@ -241,6 +242,10 @@ _add_localedirs( QStringList& pathList, const QString& candidate ) bp::object gettext_path() { + // Going to log informatively just once + static bool first_time = true; + cPointerSetter( &first_time, false ); + // TODO: distinguish between -d runs and normal runs // TODO: can we detect DESTDIR-installs? QStringList candidatePaths @@ -257,21 +262,26 @@ gettext_path() } _add_localedirs( candidatePaths, QDir().canonicalPath() ); // . - cDebug() << "Determining gettext path from" << candidatePaths; + if ( first_time ) + { + cDebug() << "Determining gettext path from" << candidatePaths; + } QStringList candidateLanguages = _gettext_languages(); - for ( const auto& lang : candidateLanguages ) + { for ( auto localedir : candidatePaths ) { QDir ldir( localedir ); if ( ldir.cd( lang ) ) { - cDebug() << Logger::SubEntry << "Found" << lang << "in" << ldir.canonicalPath(); + Logger::CDebug( Logger::LOGDEBUG ) + << output_prefix << "Found gettext" << lang << "in" << ldir.canonicalPath(); return bp::object( localedir.toStdString() ); } } - cDebug() << Logger::SubEntry << "No translation found for languages" << candidateLanguages; + } + cWarning() << "No translation found for languages" << candidateLanguages; return bp::object(); // None } From bba5b21873969587edabc6b8c18c16a834754d4b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 11:17:41 +0200 Subject: [PATCH 19/30] [libcalamares] Remove cBoolSetter This class was used only once, and is confusing because the assignment happens always, but to the opposite value as what was visible. It can be replaced with other scoped assignment, instead. Removes the tests for it, too. --- src/libcalamares/utils/RAII.h | 14 -------------- src/libcalamares/utils/Tests.cpp | 28 ++-------------------------- src/modules/locale/LocalePage.cpp | 3 ++- 3 files changed, 4 insertions(+), 41 deletions(-) diff --git a/src/libcalamares/utils/RAII.h b/src/libcalamares/utils/RAII.h index 00e276ec6..186775676 100644 --- a/src/libcalamares/utils/RAII.h +++ b/src/libcalamares/utils/RAII.h @@ -42,20 +42,6 @@ struct cqDeleter } }; -/// @brief Sets a bool to @p value and resets to !value on destruction -template < bool value > -struct cBoolSetter -{ - bool& m_b; - - cBoolSetter( bool& b ) - : m_b( b ) - { - m_b = value; - } - ~cBoolSetter() { m_b = !value; } -}; - /// @brief Blocks signals on a QObject until destruction using cSignalBlocker = QSignalBlocker; diff --git a/src/libcalamares/utils/Tests.cpp b/src/libcalamares/utils/Tests.cpp index a689505e9..bb1bf9520 100644 --- a/src/libcalamares/utils/Tests.cpp +++ b/src/libcalamares/utils/Tests.cpp @@ -55,7 +55,6 @@ private Q_SLOTS: void testOddSizedPrintable(); /** @section Tests the RAII bits. */ - void testBoolSetter(); void testPointerSetter(); /** @section Tests the Traits bits. */ @@ -340,28 +339,6 @@ LibCalamaresTests::testOddSizedPrintable() } } -void -LibCalamaresTests::testBoolSetter() -{ - bool b = false; - - QVERIFY( !b ); - { - QVERIFY( !b ); - cBoolSetter< true > x( b ); - QVERIFY( b ); - } - QVERIFY( !b ); - - QVERIFY( !b ); - { - QVERIFY( !b ); - cBoolSetter< false > x( b ); - QVERIFY( !b ); // Still! - } - QVERIFY( b ); -} - void LibCalamaresTests::testPointerSetter() { @@ -384,7 +361,7 @@ LibCalamaresTests::testPointerSetter() } QCOMPARE( special, 3 ); { - cPointerSetter p( nullptr ); + cPointerSetter< int > p( nullptr ); } QCOMPARE( special, 3 ); { @@ -490,8 +467,7 @@ LibCalamaresTests::testVariantStringListCode() QStringList { "astring" } ); // A single string **can** be considered a stringlist! m.insert( key, QString( "more strings" ) ); QCOMPARE( getStringList( m, key ).count(), 1 ); - QCOMPARE( getStringList( m, key ), - QStringList { "more strings" } ); + QCOMPARE( getStringList( m, key ), QStringList { "more strings" } ); m.insert( key, QString() ); QCOMPARE( getStringList( m, key ).count(), 1 ); QCOMPARE( getStringList( m, key ), QStringList { QString() } ); diff --git a/src/modules/locale/LocalePage.cpp b/src/modules/locale/LocalePage.cpp index f63aed10d..027d50a38 100644 --- a/src/modules/locale/LocalePage.cpp +++ b/src/modules/locale/LocalePage.cpp @@ -174,7 +174,8 @@ LocalePage::locationChanged( const CalamaresUtils::Locale::TimeZoneData* locatio { return; } - cBoolSetter< true > b( m_blockTzWidgetSet ); + m_blockTzWidgetSet = true; // Blocked until we go out of scope + cPointerSetter b( &m_blockTzWidgetSet, false ); // Set region index int index = m_regionCombo->findData( location->region() ); From 8f65a644a9fe67a8d387f73e18a7627e8895fafe Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 22 Sep 2021 11:26:28 +0200 Subject: [PATCH 20/30] [libcalamares] Rename cPointerSetter This class doesn't really set a pointer -- it is a scoped assignment through a pointer, which **can** set a value on destruction (when it leaves scope). Rename it. While here, extend the API so that it can do an assignment to the underlying object **now**, while also doing a scoped assignment later when it leaves scope. This makes some code a bit easier to read ("in this scope, X is now and then it becomes ") --- src/libcalamares/PythonJobApi.cpp | 2 +- src/libcalamares/utils/RAII.h | 37 +++++++++++++++++------- src/libcalamares/utils/Tests.cpp | 16 +++++----- src/modules/keyboard/Config.cpp | 4 +-- src/modules/locale/LocalePage.cpp | 3 +- src/modules/partition/core/PartUtils.cpp | 2 +- 6 files changed, 39 insertions(+), 25 deletions(-) diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index 3f908b98d..480a115ae 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -244,7 +244,7 @@ gettext_path() { // Going to log informatively just once static bool first_time = true; - cPointerSetter( &first_time, false ); + cScopedAssignment( &first_time, false ); // TODO: distinguish between -d runs and normal runs // TODO: can we detect DESTDIR-installs? diff --git a/src/libcalamares/utils/RAII.h b/src/libcalamares/utils/RAII.h index 186775676..957e4fe42 100644 --- a/src/libcalamares/utils/RAII.h +++ b/src/libcalamares/utils/RAII.h @@ -48,10 +48,11 @@ using cSignalBlocker = QSignalBlocker; /** @brief Writes a value on destruction to a pointed-to location. * * If the pointer is non-null, write the last-given-value if there - * is one to the pointed-to object. + * is one to the pointed-to object. This is called the "then-value". + * */ template < typename T > -struct cPointerSetter +struct cScopedAssignment { std::optional< T > m_value; T* m_pointer; @@ -62,22 +63,36 @@ struct cPointerSetter * will do nothing on destruction, leaving the pointed-to * value unchanged. */ - cPointerSetter( T* p ) + cScopedAssignment( T* p ) : m_pointer( p ) { } - /** @brief Create a setter with a value already set + /** @brief Create a setter with a then-value already set * * This ensures that on destruction, the value @p v will be written; * it is equivalent to assigning @p v immediately. The pointed-to * value is **not** changed (until destruction). */ - cPointerSetter( T* p, T v ) - : m_value( v ) + cScopedAssignment( T* p, T then ) + : m_value( then ) , m_pointer( p ) { } - ~cPointerSetter() + /** @brief Create a setter with a then-value and assign a new value now + * + * As above, but also assign @p now to the thing pointed-to. + */ + cScopedAssignment( T* p, T now, T then ) + : m_value( then ) + , m_pointer( p ) + { + if ( p ) + { + *p = now; + } + } + + ~cScopedAssignment() { if ( m_pointer && m_value.has_value() ) { @@ -85,13 +100,13 @@ struct cPointerSetter } } - const T& operator=( const T& v ) + const T& operator=( const T& then ) { - m_value = v; - return v; + m_value = then; + return then; } }; template < typename T > -cPointerSetter( T p )->cPointerSetter< decltype( *p ) >; +cScopedAssignment( T p )->cScopedAssignment< decltype( *p ) >; #endif diff --git a/src/libcalamares/utils/Tests.cpp b/src/libcalamares/utils/Tests.cpp index bb1bf9520..c652571b4 100644 --- a/src/libcalamares/utils/Tests.cpp +++ b/src/libcalamares/utils/Tests.cpp @@ -346,35 +346,35 @@ LibCalamaresTests::testPointerSetter() QCOMPARE( special, 17 ); { - cPointerSetter p( &special ); + cScopedAssignment p( &special ); } QCOMPARE( special, 17 ); { - cPointerSetter p( &special ); + cScopedAssignment p( &special ); p = 18; } QCOMPARE( special, 18 ); { - cPointerSetter p( &special ); + cScopedAssignment p( &special ); p = 20; p = 3; } QCOMPARE( special, 3 ); { - cPointerSetter< int > p( nullptr ); + cScopedAssignment< int > p( nullptr ); } QCOMPARE( special, 3 ); { // "don't do this" .. order of destructors is important - cPointerSetter p( &special ); - cPointerSetter q( &special ); + cScopedAssignment p( &special ); + cScopedAssignment q( &special ); p = 17; } QCOMPARE( special, 17 ); { // "don't do this" .. order of destructors is important - cPointerSetter p( &special ); - cPointerSetter q( &special ); + cScopedAssignment p( &special ); + cScopedAssignment q( &special ); p = 34; q = 2; // q destroyed first, then p diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index 7140bd790..f1b6efeba 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -275,7 +275,7 @@ Config::detectCurrentKeyboardLayout() { return; } - cPointerSetter returnToIntial( &m_state, State::Initial ); + cScopedAssignment returnToIntial( &m_state, State::Initial ); m_state = State::Guessing; //### Detect current keyboard layout and variant @@ -427,7 +427,7 @@ Config::guessLocaleKeyboardLayout() { return; } - cPointerSetter returnToIntial( &m_state, State::Initial ); + cScopedAssignment returnToIntial( &m_state, State::Initial ); m_state = State::Guessing; /* Guessing a keyboard layout based on the locale means diff --git a/src/modules/locale/LocalePage.cpp b/src/modules/locale/LocalePage.cpp index 027d50a38..236f63ec3 100644 --- a/src/modules/locale/LocalePage.cpp +++ b/src/modules/locale/LocalePage.cpp @@ -174,8 +174,7 @@ LocalePage::locationChanged( const CalamaresUtils::Locale::TimeZoneData* locatio { return; } - m_blockTzWidgetSet = true; // Blocked until we go out of scope - cPointerSetter b( &m_blockTzWidgetSet, false ); + cScopedAssignment b( &m_blockTzWidgetSet, true, false ); // Set region index int index = m_regionCombo->findData( location->region() ); diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index c99884ce6..806c0ceb3 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -529,7 +529,7 @@ efiFilesystemMinimumSize() QString canonicalFilesystemName( const QString& fsName, FileSystem::Type* fsType ) { - cPointerSetter type( fsType ); + cScopedAssignment type( fsType ); if ( fsName.isEmpty() ) { type = FileSystem::Ext4; From 9b57f402da97aada820054a168c144e17fd6d767 Mon Sep 17 00:00:00 2001 From: Shrinivas Vishnu Kumbhar Date: Thu, 23 Sep 2021 11:07:43 +0200 Subject: [PATCH 21/30] [keyboard] Use US-English for India --- src/modules/keyboard/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/keyboard/Config.cpp b/src/modules/keyboard/Config.cpp index f1b6efeba..720588810 100644 --- a/src/modules/keyboard/Config.cpp +++ b/src/modules/keyboard/Config.cpp @@ -472,7 +472,7 @@ Config::guessLocaleKeyboardLayout() { "el_GR", "gr" }, /* Greek in Greece */ { "ig_NG", "igbo_NG" }, /* Igbo in Nigeria */ { "ha_NG", "hausa_NG" }, /* Hausa */ - { "en_IN", "eng_in" }, /* India, English with Rupee */ + { "en_IN", "us" }, /* India, US English keyboards are common in India */ } ); // Try to preselect a layout, depending on language and locale From 528a8153072dfb7892089abdb8206779ec5cfc34 Mon Sep 17 00:00:00 2001 From: Shrinivas Vishnu Kumbhar Date: Thu, 23 Sep 2021 11:08:11 +0200 Subject: [PATCH 22/30] [locale] Default to English in India --- CHANGES | 3 +++ src/modules/locale/LocaleConfiguration.cpp | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/CHANGES b/CHANGES index 1bdb681f0..a5a1b1fe1 100644 --- a/CHANGES +++ b/CHANGES @@ -10,12 +10,15 @@ website will have to do for older versions. # 3.2.44 (unreleased) # This release contains contributions from (alphabetically by first name): + - Shrinivas Vishnu Kumbhar (new contributor, welcome!) - whorfin (new contributor, welcome!) ## Core ## - No core changes yet ## Modules ## + - Both *locale* and *keyboard* have received some tweaks for configurations + in India; unless the user selects otherwise, English is preferred. - The *luksbootkeyfile* module was reported to be too quick to declare a timeout when applying the keyfile. The timeout has been increased to one minute. (Thanks whorfin) diff --git a/src/modules/locale/LocaleConfiguration.cpp b/src/modules/locale/LocaleConfiguration.cpp index c208dc02d..b7b895290 100644 --- a/src/modules/locale/LocaleConfiguration.cpp +++ b/src/modules/locale/LocaleConfiguration.cpp @@ -201,6 +201,10 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale, // but nearly all its native speakers also speak English, // and migrants are likely to use English. { "IE", "en" }, + // India has many languages even though Hindi is known as + // national language but English is used in all computer + // and mobile devices. + { "IN", "en" }, { "IT", "it" }, { "MA", "ar" }, { "MK", "mk" }, From 3f890dfb8e51f9f4e9dea55b426c8b574156452f Mon Sep 17 00:00:00 2001 From: librewish Date: Fri, 24 Sep 2021 12:24:58 +0530 Subject: [PATCH 23/30] [fstab] Improve btrfs mount options --- src/modules/fstab/fstab.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/fstab/fstab.conf b/src/modules/fstab/fstab.conf index 21f6ffce3..fdf0d41ec 100644 --- a/src/modules/fstab/fstab.conf +++ b/src/modules/fstab/fstab.conf @@ -13,7 +13,7 @@ # options from this mapping. mountOptions: default: defaults,noatime - btrfs: defaults,noatime,space_cache,autodefrag + btrfs: defaults,noatime,space_cache,autodefrag,compress=zstd # Mount options to use for the EFI System Partition. If not defined, the # *mountOptions* for *vfat* are used, or if that is not set either, @@ -38,10 +38,10 @@ efiMountOptions: umask=0077 # swap: discard # btrfs: discard,compress=lzo # -# The standard configuration applies only lzo compression to btrfs +# The standard configuration applies asynchronous discard support and ssd optimizations to btrfs # and does nothing for other filesystems. ssdExtraMountOptions: - btrfs: compress=lzo + btrfs: discard=async,ssd # Additional options added to each line in /etc/crypttab crypttabOptions: luks From e5e9e14a9f053de20eed42c3baf74c823526bfd5 Mon Sep 17 00:00:00 2001 From: librewish Date: Fri, 24 Sep 2021 12:30:42 +0530 Subject: [PATCH 24/30] [initcpiocfg] add consolefont to hooks --- 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 903ef635f..ba43984d2 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -144,7 +144,7 @@ def find_initcpio_features(partitions, root_mount_point): :return 3-tuple of lists """ - hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap"] + hooks = ["base", "udev", "autodetect", "modconf", "block", "keyboard", "keymap", "consolefont"] modules = [] files = [] From 678e6f6d7444d116e3224fdaa4c63ee2f7ab81f4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 24 Sep 2021 12:15:16 +0200 Subject: [PATCH 25/30] [networkcfg] Be more forgiving when getting the live username - This function is intended to do whatever it takes to get the live username. --- src/modules/networkcfg/main.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/modules/networkcfg/main.py b/src/modules/networkcfg/main.py index 35bf67d63..75b5a3abe 100644 --- a/src/modules/networkcfg/main.py +++ b/src/modules/networkcfg/main.py @@ -29,6 +29,34 @@ def pretty_name(): return _("Saving network configuration.") +def live_user(): + """ + Gets the "live user" login. This might be "live", or "nitrux", + or something similar: it is the login name used *right now*, + and network configurations saved for that user, should be applied + also for the installed user (which probably has a different name). + """ + # getlogin() is a thin-wrapper, and depends on getlogin(3), + # which reads utmp -- and utmp isn't always set up right. + try: + return os.getlogin() + except OSError: + pass + # getpass will return the **current** user, which is generally root. + # That isn't very useful, because the network settings have been + # made outside of Calamares-running-as-root, as a different user. + # + # If Calamares is running as non-root, though, this is fine. + import getpass + name = getpass.getuser() + if name != "root": + return name + + # TODO: other mechanisms, e.g. guessing that "live" is the name + # TODO: support a what-is-the-live-user setting + return None + + def run(): """ Setup network configuration From bf60d0576b5796f4646ea817253ecf5b38bf5819 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 24 Sep 2021 12:25:33 +0200 Subject: [PATCH 26/30] [networkcfg] Refactor username-replacement Read, then write, the NM file. Add a note about how we might handle this better. Rename live_user() function to give it a verb (and avoid UnboundLocal when using a variable of the same name). --- src/modules/networkcfg/main.py | 43 ++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/modules/networkcfg/main.py b/src/modules/networkcfg/main.py index 75b5a3abe..f2970af24 100644 --- a/src/modules/networkcfg/main.py +++ b/src/modules/networkcfg/main.py @@ -29,7 +29,7 @@ def pretty_name(): return _("Saving network configuration.") -def live_user(): +def get_live_user(): """ Gets the "live user" login. This might be "live", or "nitrux", or something similar: it is the login name used *right now*, @@ -57,13 +57,41 @@ def live_user(): return None +def replace_username(nm_config_filename, live_user, target_user): + """ + If @p live_user isn't None, then go through the given + file and replace @p live_user by the @p target_user. + + Reads the file, then (re-)writes it with new permissions lives. + """ + # FIXME: Perhaps if live_user is None, we should just replace **all** + # permissions lines? After all, this is supposed to be a live + # system so **whatever** NM networks are configured, should be + # available to the new user. + if live_user is None: + return + if not os.path.exists(nm_config_filename): + return + + with open(target_network, "r") as network_conf: + text = network_conf.readlines() + + live_permissions = 'permissions=user:{}:;'.format(live_user) + target_permissions = 'permissions=user:{}:;\n'.format(user) + with open(target_network, "w") as network_conf: + for line in text: + if live_permissions in line: + line = target_permissions + network_conf.write(line) + + def run(): """ Setup network configuration """ root_mount_point = libcalamares.globalstorage.value("rootMountPoint") user = libcalamares.globalstorage.value("username") - live_user = os.getlogin() + live_user = get_live_user() if root_mount_point is None: libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point)) @@ -91,16 +119,7 @@ def run(): try: shutil.copy(source_network, target_network, follow_symlinks=False) - if live_user in open(target_network).read(): - text = [] - with open(target_network, "r") as network_conf: - text = network_conf.readlines() - with open(target_network, "w") as network_conf: - for line in text: - if 'permissions=user:{}:;'.format(live_user) in line: - line = 'permissions=user:{}:;\n'.format(user) - network_conf.write(line) - network_conf.close() + replace_username(target_network, live_user, user) except FileNotFoundError: libcalamares.utils.debug( "Can't copy network configuration files in " From 13d69cb81352e60dc5b4ad34ec99c93f68b5870f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 24 Sep 2021 12:30:11 +0200 Subject: [PATCH 27/30] [networkcfg] Don't mindlessly PEP8 --- src/modules/networkcfg/main.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/modules/networkcfg/main.py b/src/modules/networkcfg/main.py index f2970af24..6dab71fd9 100644 --- a/src/modules/networkcfg/main.py +++ b/src/modules/networkcfg/main.py @@ -98,10 +98,9 @@ def run(): return (_("Configuration Error"), _("No root mount point is given for
{!s}
to use." ).format("networkcfg")) - source_nm = "/etc/NetworkManager/system-connections/" - target_nm = os.path.join( - root_mount_point, "etc/NetworkManager/system-connections/" - ) + nm_connections = "etc/NetworkManager/system-connections/" + source_nm = "/" + nm_connections + target_nm = os.path.join(root_mount_point, nm_connections) # Sanity checks. We don't want to do anything if a network # configuration already exists on the target @@ -122,8 +121,7 @@ def run(): replace_username(target_network, live_user, user) except FileNotFoundError: libcalamares.utils.debug( - "Can't copy network configuration files in " - + "{}".format(source_network) + "Can't copy network configuration files in {}".format(source_network) ) except FileExistsError: pass From ce5d42ce0f1b352f5f7a1215ad82cbf1370f73aa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 24 Sep 2021 12:33:00 +0200 Subject: [PATCH 28/30] [networkcfg] Refactor getting source-and-target paths of a file --- src/modules/networkcfg/main.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/modules/networkcfg/main.py b/src/modules/networkcfg/main.py index 6dab71fd9..4dc6cbbf7 100644 --- a/src/modules/networkcfg/main.py +++ b/src/modules/networkcfg/main.py @@ -85,6 +85,13 @@ def replace_username(nm_config_filename, live_user, target_user): network_conf.write(line) +def path_pair(root_mount_point, relative_path): + """ + Returns /relative_path and the relative path in the target system. + """ + return ("/" + relative_path, os.path.join(root_mount_point, relative_path)) + + def run(): """ Setup network configuration @@ -98,9 +105,7 @@ def run(): return (_("Configuration Error"), _("No root mount point is given for
{!s}
to use." ).format("networkcfg")) - nm_connections = "etc/NetworkManager/system-connections/" - source_nm = "/" + nm_connections - target_nm = os.path.join(root_mount_point, nm_connections) + source_nm, target_nm = path_pair(root_mount_point, "etc/NetworkManager/system-connections/") # Sanity checks. We don't want to do anything if a network # configuration already exists on the target @@ -127,8 +132,7 @@ def run(): pass # We need to overwrite the default resolv.conf in the chroot. - source_resolv = "/etc/resolv.conf" - target_resolv = os.path.join(root_mount_point, "etc/resolv.conf") + source_resolv, target_resolv = path_pair(root_mount_point, "etc/resolv.conf") if source_resolv != target_resolv and os.path.exists(source_resolv): try: os.remove(target_resolv) From 0403749bf105020f273aff1fe4d4faa091b407c5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 24 Sep 2021 12:40:38 +0200 Subject: [PATCH 29/30] Changes: pre-release housekeeping --- CHANGES | 10 ++++++++-- CMakeLists.txt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index a5a1b1fe1..c91e99299 100644 --- a/CHANGES +++ b/CHANGES @@ -7,21 +7,27 @@ contributors are listed. Note that Calamares does not have a historical changelog -- this log starts with version 3.2.0. The release notes on the website will have to do for older versions. -# 3.2.44 (unreleased) # +# 3.2.44 (2021-09-24) # This release contains contributions from (alphabetically by first name): + - Anke Boersma - Shrinivas Vishnu Kumbhar (new contributor, welcome!) - whorfin (new contributor, welcome!) ## Core ## - - No core changes yet + - "Log spam" has been reduced a little in the partitioning module. ## Modules ## + - *initcpiocfg* has had a number of internal code-fixes, and now adds + the `consolefont` hook by default as well. (Thanks Shrinivas) - Both *locale* and *keyboard* have received some tweaks for configurations in India; unless the user selects otherwise, English is preferred. - The *luksbootkeyfile* module was reported to be too quick to declare a timeout when applying the keyfile. The timeout has been increased to one minute. (Thanks whorfin) + - *networkcfg* tries harder to find the live-user login for re-working + networking settings. This fixes a regression on FerenOS, where the + installer was crashing because it could not find the live-user login. # 3.2.43 (2021-09-17) # diff --git a/CMakeLists.txt b/CMakeLists.txt index 807cdfabf..b391cfeb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ project( CALAMARES LANGUAGES C CXX ) -set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development +set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development ### OPTIONS # From 65c1ef7cb5fcab2bc80268aebc15de072ffab0f2 Mon Sep 17 00:00:00 2001 From: demmm Date: Fri, 24 Sep 2021 16:27:35 +0200 Subject: [PATCH 30/30] [initcpiocfg] fix install failure due to extra s --- 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 ba43984d2..99168dcde 100644 --- a/src/modules/initcpiocfg/main.py +++ b/src/modules/initcpiocfg/main.py @@ -128,7 +128,7 @@ def write_mkinitcpio_lines(hooks, modules, files, root_mount_point): line = "HOOKS=\"{!s}\"".format(' '.join(hooks)) elif line.startswith("MODULES"): line = "MODULES=\"{!s}\"".format(' '.join(modules)) - elif lines.startswith("FILES"): + elif line.startswith("FILES"): line = "FILES=\"{!s}\"".format(' '.join(files)) mkinitcpio_file.write(line + "\n")