Merge branch 'calamares' into work-3.3

This commit is contained in:
Adriaan de Groot 2021-09-28 23:37:38 +02:00
commit c1e1e6c3a4
22 changed files with 396 additions and 216 deletions

View File

@ -42,6 +42,18 @@ include( CalamaresCheckModuleSelection )
set( MODULE_DATA_DESTINATION share/calamares/modules ) set( MODULE_DATA_DESTINATION share/calamares/modules )
# We look for Pylint (just once) so that unittests can be added that
# check the syntax / variables of Python modules. This should help
# avoid more typo's-in-releases.
if(BUILD_TESTING AND NOT PYLINT_COMMAND_SEARCHED)
set(PYLINT_COMMAND_SEARCHED TRUE)
find_program(
PYLINT_COMMAND
NAMES pylint3 pylint
PATHS $ENV{HOME}/.local/bin
)
endif()
function( _calamares_add_module_subdirectory_impl ) function( _calamares_add_module_subdirectory_impl )
set( SUBDIRECTORY ${ARGV0} ) set( SUBDIRECTORY ${ARGV0} )
@ -241,6 +253,19 @@ function( _calamares_add_module_subdirectory_impl )
if ( EXISTS ${_testdir}/CMakeTests.txt AND NOT EXISTS ${_mod_dir}/CMakeLists.txt ) if ( EXISTS ${_testdir}/CMakeTests.txt AND NOT EXISTS ${_mod_dir}/CMakeLists.txt )
include( ${_testdir}/CMakeTests.txt ) include( ${_testdir}/CMakeTests.txt )
endif() endif()
if ( PYLINT_COMMAND AND MODULE_INTERFACE MATCHES "python" )
# Python modules get an additional test via pylint; this
# needs to run at top-level because the ci/libcalamares directory
# contains API stubs.
#
# TODO: the entry point is assumed to be `main.py`, but that is
# configurable through module.desc
add_test(
NAME lint-${SUBDIRECTORY}
COMMAND env PYTHONPATH=ci: ${PYLINT_COMMAND} -E ${_mod_dir}/main.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
endif()
endif() endif()
endfunction() endfunction()

View File

@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Stubs for part of the Python API from libcalamares
# (although the **actual** API is presented through
# Boost::Python, not as a bare C-extension) so that
# pylint doesn't complain about libcalamares internals.
VERSION_SHORT="1.0"

View File

@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Stubs for part of the Python API from libcalamares
# (although the **actual** API is presented through
# Boost::Python, not as a bare C-extension) so that
# pylint doesn't complain about libcalamares internals.
def count(): return 1
def keys(): return []
def contains(_): return True
def value(key):
if key in ("branding",):
return dict()
if key in ("partitions",):
return list()
return ""
def insert(key, value): pass
def remove(_): pass

15
ci/libcalamares/job.py Normal file
View File

@ -0,0 +1,15 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Stubs for part of the Python API from libcalamares
# (although the **actual** API is presented through
# Boost::Python, not as a bare C-extension) so that
# pylint doesn't complain about libcalamares internals.
configuration = dict()
def setprogress(_): pass
def pretty_name(): return ""
def working_path(): return ""

23
ci/libcalamares/utils.py Normal file
View File

@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Stubs for part of the Python API from libcalamares
# (although the **actual** API is presented through
# Boost::Python, not as a bare C-extension) so that
# pylint doesn't complain about libcalamares internals.
def debug(_): pass
def warning(_): pass
def error(_): pass
def gettext_path(): pass
def gettext_languages(): pass
def target_env_call(_): return 0
def check_target_env_call(_): pass
def mount(device, mountpoint, fstype, options): return 0

View File

@ -171,7 +171,7 @@
<context> <context>
<name>Calamares::JobThread</name> <name>Calamares::JobThread</name>
<message> <message>
<location filename="../src/libcalamares/JobQueue.cpp" line="199"/> <location filename="../src/libcalamares/JobQueue.cpp" line="201"/>
<source>Done</source> <source>Done</source>
<translation>Done</translation> <translation>Done</translation>
</message> </message>
@ -320,17 +320,17 @@
<translation>&amp;Close</translation> <translation>&amp;Close</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/utils/Paste.cpp" line="171"/> <location filename="../src/libcalamaresui/utils/Paste.cpp" line="183"/>
<source>Install Log Paste URL</source> <source>Install Log Paste URL</source>
<translation>Install Log Paste URL</translation> <translation>Install Log Paste URL</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/utils/Paste.cpp" line="153"/> <location filename="../src/libcalamaresui/utils/Paste.cpp" line="165"/>
<source>The upload was unsuccessful. No web-paste was done.</source> <source>The upload was unsuccessful. No web-paste was done.</source>
<translation>The upload was unsuccessful. No web-paste was done.</translation> <translation>The upload was unsuccessful. No web-paste was done.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/utils/Paste.cpp" line="165"/> <location filename="../src/libcalamaresui/utils/Paste.cpp" line="177"/>
<source>Install log posted to <source>Install log posted to
%1 %1
@ -1926,35 +1926,35 @@ The installer will quit and all changes will be lost.</translation>
<context> <context>
<name>LuksBootKeyFileJob</name> <name>LuksBootKeyFileJob</name>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="28"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="30"/>
<source>Configuring LUKS key file.</source> <source>Configuring LUKS key file.</source>
<translation>Configuring LUKS key file.</translation> <translation>Configuring LUKS key file.</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="168"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="186"/>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="176"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="194"/>
<source>No partitions are defined.</source> <source>No partitions are defined.</source>
<translation>No partitions are defined.</translation> <translation>No partitions are defined.</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="211"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="229"/>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="218"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="236"/>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="226"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="244"/>
<source>Encrypted rootfs setup error</source> <source>Encrypted rootfs setup error</source>
<translation>Encrypted rootfs setup error</translation> <translation>Encrypted rootfs setup error</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="212"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="230"/>
<source>Root partition %1 is LUKS but no passphrase has been set.</source> <source>Root partition %1 is LUKS but no passphrase has been set.</source>
<translation>Root partition %1 is LUKS but no passphrase has been set.</translation> <translation>Root partition %1 is LUKS but no passphrase has been set.</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="219"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="237"/>
<source>Could not create LUKS key file for root partition %1.</source> <source>Could not create LUKS key file for root partition %1.</source>
<translation>Could not create LUKS key file for root partition %1.</translation> <translation>Could not create LUKS key file for root partition %1.</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="227"/> <location filename="../src/modules/luksbootkeyfile/LuksBootKeyFileJob.cpp" line="245"/>
<source>Could not configure LUKS key file on partition %1.</source> <source>Could not configure LUKS key file on partition %1.</source>
<translation>Could not configure LUKS key file on partition %1.</translation> <translation>Could not configure LUKS key file on partition %1.</translation>
</message> </message>
@ -2929,14 +2929,14 @@ The installer will quit and all changes will be lost.</translation>
<context> <context>
<name>ProcessResult</name> <name>ProcessResult</name>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="429"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="425"/>
<source> <source>
There was no output from the command.</source> There was no output from the command.</source>
<translation> <translation>
There was no output from the command.</translation> There was no output from the command.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="430"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="426"/>
<source> <source>
Output: Output:
</source> </source>
@ -2945,52 +2945,52 @@ Output:
</translation> </translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="434"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="430"/>
<source>External command crashed.</source> <source>External command crashed.</source>
<translation>External command crashed.</translation> <translation>External command crashed.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="435"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="431"/>
<source>Command &lt;i&gt;%1&lt;/i&gt; crashed.</source> <source>Command &lt;i&gt;%1&lt;/i&gt; crashed.</source>
<translation>Command &lt;i&gt;%1&lt;/i&gt; crashed.</translation> <translation>Command &lt;i&gt;%1&lt;/i&gt; crashed.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="440"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="436"/>
<source>External command failed to start.</source> <source>External command failed to start.</source>
<translation>External command failed to start.</translation> <translation>External command failed to start.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="441"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="437"/>
<source>Command &lt;i&gt;%1&lt;/i&gt; failed to start.</source> <source>Command &lt;i&gt;%1&lt;/i&gt; failed to start.</source>
<translation>Command &lt;i&gt;%1&lt;/i&gt; failed to start.</translation> <translation>Command &lt;i&gt;%1&lt;/i&gt; failed to start.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="445"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="441"/>
<source>Internal error when starting command.</source> <source>Internal error when starting command.</source>
<translation>Internal error when starting command.</translation> <translation>Internal error when starting command.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="446"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="442"/>
<source>Bad parameters for process job call.</source> <source>Bad parameters for process job call.</source>
<translation>Bad parameters for process job call.</translation> <translation>Bad parameters for process job call.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="450"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="446"/>
<source>External command failed to finish.</source> <source>External command failed to finish.</source>
<translation>External command failed to finish.</translation> <translation>External command failed to finish.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="451"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="447"/>
<source>Command &lt;i&gt;%1&lt;/i&gt; failed to finish in %2 seconds.</source> <source>Command &lt;i&gt;%1&lt;/i&gt; failed to finish in %2 seconds.</source>
<translation>Command &lt;i&gt;%1&lt;/i&gt; failed to finish in %2 seconds.</translation> <translation>Command &lt;i&gt;%1&lt;/i&gt; failed to finish in %2 seconds.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="458"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="454"/>
<source>External command finished with errors.</source> <source>External command finished with errors.</source>
<translation>External command finished with errors.</translation> <translation>External command finished with errors.</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="459"/> <location filename="../src/libcalamares/utils/CalamaresUtilsSystem.cpp" line="455"/>
<source>Command &lt;i&gt;%1&lt;/i&gt; finished with exit code %2.</source> <source>Command &lt;i&gt;%1&lt;/i&gt; finished with exit code %2.</source>
<translation>Command &lt;i&gt;%1&lt;/i&gt; finished with exit code %2.</translation> <translation>Command &lt;i&gt;%1&lt;/i&gt; finished with exit code %2.</translation>
</message> </message>

View File

@ -2,32 +2,32 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package. # This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-09-08 13:31+0200\n" "POT-Creation-Date: 2021-09-22 11:02+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Language: \n"
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
#: src/modules/grubcfg/main.py:28 #: src/modules/grubcfg/main.py:28
msgid "Configure GRUB." msgid "Configure GRUB."
msgstr "Configure GRUB." msgstr ""
#: src/modules/mount/main.py:30 #: src/modules/mount/main.py:30
msgid "Mounting partitions." msgid "Mounting partitions."
msgstr "Mounting partitions." msgstr ""
#: src/modules/mount/main.py:144 src/modules/initcpiocfg/main.py:197 #: src/modules/mount/main.py:144 src/modules/initcpiocfg/main.py:227
#: src/modules/initcpiocfg/main.py:201 #: src/modules/initcpiocfg/main.py:231
#: src/modules/luksopenswaphookcfg/main.py:86 #: src/modules/luksopenswaphookcfg/main.py:86
#: src/modules/luksopenswaphookcfg/main.py:90 src/modules/rawfs/main.py:164 #: src/modules/luksopenswaphookcfg/main.py:90 src/modules/rawfs/main.py:164
#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89 #: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89
@ -36,372 +36,349 @@ msgstr "Mounting partitions."
#: src/modules/fstab/main.py:361 src/modules/fstab/main.py:388 #: src/modules/fstab/main.py:361 src/modules/fstab/main.py:388
#: src/modules/localecfg/main.py:135 src/modules/networkcfg/main.py:42 #: src/modules/localecfg/main.py:135 src/modules/networkcfg/main.py:42
msgid "Configuration Error" msgid "Configuration Error"
msgstr "Configuration Error" msgstr ""
#: src/modules/mount/main.py:145 src/modules/initcpiocfg/main.py:198 #: src/modules/mount/main.py:145 src/modules/initcpiocfg/main.py:228
#: src/modules/luksopenswaphookcfg/main.py:87 src/modules/rawfs/main.py:165 #: src/modules/luksopenswaphookcfg/main.py:87 src/modules/rawfs/main.py:165
#: src/modules/initramfscfg/main.py:86 src/modules/openrcdmcryptcfg/main.py:73 #: src/modules/initramfscfg/main.py:86 src/modules/openrcdmcryptcfg/main.py:73
#: src/modules/fstab/main.py:356 #: src/modules/fstab/main.py:356
msgid "No partitions are defined for <pre>{!s}</pre> to use." msgid "No partitions are defined for <pre>{!s}</pre> to use."
msgstr "No partitions are defined for <pre>{!s}</pre> to use." msgstr ""
#: src/modules/services-systemd/main.py:26 #: src/modules/services-systemd/main.py:26
msgid "Configure systemd services" msgid "Configure systemd services"
msgstr "Configure systemd services" msgstr ""
#: src/modules/services-systemd/main.py:59 #: src/modules/services-systemd/main.py:59
#: src/modules/services-openrc/main.py:93 #: src/modules/services-openrc/main.py:93
msgid "Cannot modify service" msgid "Cannot modify service"
msgstr "Cannot modify service" msgstr ""
#: src/modules/services-systemd/main.py:60 #: src/modules/services-systemd/main.py:60
msgid "" msgid ""
"<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}." "<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}."
msgstr "" msgstr ""
"<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}."
#: src/modules/services-systemd/main.py:63 #: src/modules/services-systemd/main.py:63
#: src/modules/services-systemd/main.py:67 #: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd service <code>{name!s}</code>." msgid "Cannot enable systemd service <code>{name!s}</code>."
msgstr "Cannot enable systemd service <code>{name!s}</code>." msgstr ""
#: src/modules/services-systemd/main.py:65 #: src/modules/services-systemd/main.py:65
msgid "Cannot enable systemd target <code>{name!s}</code>." msgid "Cannot enable systemd target <code>{name!s}</code>."
msgstr "Cannot enable systemd target <code>{name!s}</code>." msgstr ""
#: src/modules/services-systemd/main.py:69 #: src/modules/services-systemd/main.py:69
msgid "Cannot disable systemd target <code>{name!s}</code>." msgid "Cannot disable systemd target <code>{name!s}</code>."
msgstr "Cannot disable systemd target <code>{name!s}</code>." msgstr ""
#: src/modules/services-systemd/main.py:71 #: src/modules/services-systemd/main.py:71
msgid "Cannot mask systemd unit <code>{name!s}</code>." msgid "Cannot mask systemd unit <code>{name!s}</code>."
msgstr "Cannot mask systemd unit <code>{name!s}</code>." msgstr ""
#: src/modules/services-systemd/main.py:73 #: src/modules/services-systemd/main.py:73
msgid "" msgid ""
"Unknown systemd commands <code>{command!s}</code> and " "Unknown systemd commands <code>{command!s}</code> and <code>{suffix!s}</"
"<code>{suffix!s}</code> for unit {name!s}." "code> for unit {name!s}."
msgstr "" msgstr ""
"Unknown systemd commands <code>{command!s}</code> and "
"<code>{suffix!s}</code> for unit {name!s}."
#: src/modules/umount/main.py:31 #: src/modules/umount/main.py:31
msgid "Unmount file systems." msgid "Unmount file systems."
msgstr "Unmount file systems." msgstr ""
#: src/modules/unpackfs/main.py:35 #: src/modules/unpackfs/main.py:35
msgid "Filling up filesystems." msgid "Filling up filesystems."
msgstr "Filling up filesystems." msgstr ""
#: src/modules/unpackfs/main.py:255 #: src/modules/unpackfs/main.py:255
msgid "rsync failed with error code {}." msgid "rsync failed with error code {}."
msgstr "rsync failed with error code {}." msgstr ""
#: src/modules/unpackfs/main.py:300 #: src/modules/unpackfs/main.py:300
msgid "Unpacking image {}/{}, file {}/{}" msgid "Unpacking image {}/{}, file {}/{}"
msgstr "Unpacking image {}/{}, file {}/{}" msgstr ""
#: src/modules/unpackfs/main.py:315 #: src/modules/unpackfs/main.py:315
msgid "Starting to unpack {}" msgid "Starting to unpack {}"
msgstr "Starting to unpack {}" msgstr ""
#: src/modules/unpackfs/main.py:324 src/modules/unpackfs/main.py:464 #: src/modules/unpackfs/main.py:324 src/modules/unpackfs/main.py:464
msgid "Failed to unpack image \"{}\"" msgid "Failed to unpack image \"{}\""
msgstr "Failed to unpack image \"{}\"" msgstr ""
#: src/modules/unpackfs/main.py:431 #: src/modules/unpackfs/main.py:431
msgid "No mount point for root partition" msgid "No mount point for root partition"
msgstr "No mount point for root partition" msgstr ""
#: src/modules/unpackfs/main.py:432 #: src/modules/unpackfs/main.py:432
msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing"
msgstr "globalstorage does not contain a \"rootMountPoint\" key, doing nothing" msgstr ""
#: src/modules/unpackfs/main.py:437 #: src/modules/unpackfs/main.py:437
msgid "Bad mount point for root partition" msgid "Bad mount point for root partition"
msgstr "Bad mount point for root partition" msgstr ""
#: src/modules/unpackfs/main.py:438 #: src/modules/unpackfs/main.py:438
msgid "rootMountPoint is \"{}\", which does not exist, doing nothing" msgid "rootMountPoint is \"{}\", which does not exist, doing nothing"
msgstr "rootMountPoint is \"{}\", which does not exist, doing nothing" msgstr ""
#: src/modules/unpackfs/main.py:454 src/modules/unpackfs/main.py:458 #: src/modules/unpackfs/main.py:454 src/modules/unpackfs/main.py:458
#: src/modules/unpackfs/main.py:478 #: src/modules/unpackfs/main.py:478
msgid "Bad unsquash configuration" msgid "Bad unsquash configuration"
msgstr "Bad unsquash configuration" msgstr ""
#: src/modules/unpackfs/main.py:455 #: src/modules/unpackfs/main.py:455
msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel" msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel"
msgstr "The filesystem for \"{}\" ({}) is not supported by your current kernel" msgstr ""
#: src/modules/unpackfs/main.py:459 #: src/modules/unpackfs/main.py:459
msgid "The source filesystem \"{}\" does not exist" msgid "The source filesystem \"{}\" does not exist"
msgstr "The source filesystem \"{}\" does not exist" msgstr ""
#: src/modules/unpackfs/main.py:465 #: src/modules/unpackfs/main.py:465
msgid "" msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package " "Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed" "installed"
msgstr "" msgstr ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed"
#: src/modules/unpackfs/main.py:479 #: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory" msgid "The destination \"{}\" in the target system is not a directory"
msgstr "The destination \"{}\" in the target system is not a directory" msgstr ""
#: src/modules/displaymanager/main.py:526 #: src/modules/displaymanager/main.py:526
msgid "Cannot write KDM configuration file" msgid "Cannot write KDM configuration file"
msgstr "Cannot write KDM configuration file" msgstr ""
#: src/modules/displaymanager/main.py:527 #: src/modules/displaymanager/main.py:527
msgid "KDM config file {!s} does not exist" msgid "KDM config file {!s} does not exist"
msgstr "KDM config file {!s} does not exist" msgstr ""
#: src/modules/displaymanager/main.py:588 #: src/modules/displaymanager/main.py:588
msgid "Cannot write LXDM configuration file" msgid "Cannot write LXDM configuration file"
msgstr "Cannot write LXDM configuration file" msgstr ""
#: src/modules/displaymanager/main.py:589 #: src/modules/displaymanager/main.py:589
msgid "LXDM config file {!s} does not exist" msgid "LXDM config file {!s} does not exist"
msgstr "LXDM config file {!s} does not exist" msgstr ""
#: src/modules/displaymanager/main.py:672 #: src/modules/displaymanager/main.py:672
msgid "Cannot write LightDM configuration file" msgid "Cannot write LightDM configuration file"
msgstr "Cannot write LightDM configuration file" msgstr ""
#: src/modules/displaymanager/main.py:673 #: src/modules/displaymanager/main.py:673
msgid "LightDM config file {!s} does not exist" msgid "LightDM config file {!s} does not exist"
msgstr "LightDM config file {!s} does not exist" msgstr ""
#: src/modules/displaymanager/main.py:747 #: src/modules/displaymanager/main.py:747
msgid "Cannot configure LightDM" msgid "Cannot configure LightDM"
msgstr "Cannot configure LightDM" msgstr ""
#: src/modules/displaymanager/main.py:748 #: src/modules/displaymanager/main.py:748
msgid "No LightDM greeter installed." msgid "No LightDM greeter installed."
msgstr "No LightDM greeter installed." msgstr ""
#: src/modules/displaymanager/main.py:779 #: src/modules/displaymanager/main.py:779
msgid "Cannot write SLIM configuration file" msgid "Cannot write SLIM configuration file"
msgstr "Cannot write SLIM configuration file" msgstr ""
#: src/modules/displaymanager/main.py:780 #: src/modules/displaymanager/main.py:780
msgid "SLIM config file {!s} does not exist" msgid "SLIM config file {!s} does not exist"
msgstr "SLIM config file {!s} does not exist" msgstr ""
#: src/modules/displaymanager/main.py:906 #: src/modules/displaymanager/main.py:906
msgid "No display managers selected for the displaymanager module." msgid "No display managers selected for the displaymanager module."
msgstr "No display managers selected for the displaymanager module." msgstr ""
#: src/modules/displaymanager/main.py:907 #: src/modules/displaymanager/main.py:907
msgid "" msgid ""
"The displaymanagers list is empty or undefined in both globalstorage and " "The displaymanagers list is empty or undefined in both globalstorage and "
"displaymanager.conf." "displaymanager.conf."
msgstr "" msgstr ""
"The displaymanagers list is empty or undefined in both globalstorage and "
"displaymanager.conf."
#: src/modules/displaymanager/main.py:989 #: src/modules/displaymanager/main.py:989
msgid "Display manager configuration was incomplete" msgid "Display manager configuration was incomplete"
msgstr "Display manager configuration was incomplete" msgstr ""
#: src/modules/initcpiocfg/main.py:28 #: src/modules/initcpiocfg/main.py:28
msgid "Configuring mkinitcpio." msgid "Configuring mkinitcpio."
msgstr "Configuring mkinitcpio." msgstr ""
#: src/modules/initcpiocfg/main.py:202 #: src/modules/initcpiocfg/main.py:232
#: src/modules/luksopenswaphookcfg/main.py:91 #: src/modules/luksopenswaphookcfg/main.py:91
#: src/modules/initramfscfg/main.py:90 src/modules/openrcdmcryptcfg/main.py:77 #: src/modules/initramfscfg/main.py:90 src/modules/openrcdmcryptcfg/main.py:77
#: src/modules/fstab/main.py:362 src/modules/localecfg/main.py:136 #: src/modules/fstab/main.py:362 src/modules/localecfg/main.py:136
#: src/modules/networkcfg/main.py:43 #: src/modules/networkcfg/main.py:43
msgid "No root mount point is given for <pre>{!s}</pre> to use." msgid "No root mount point is given for <pre>{!s}</pre> to use."
msgstr "No root mount point is given for <pre>{!s}</pre> to use." msgstr ""
#: src/modules/luksopenswaphookcfg/main.py:26 #: src/modules/luksopenswaphookcfg/main.py:26
msgid "Configuring encrypted swap." msgid "Configuring encrypted swap."
msgstr "Configuring encrypted swap." msgstr ""
#: src/modules/rawfs/main.py:26 #: src/modules/rawfs/main.py:26
msgid "Installing data." msgid "Installing data."
msgstr "Installing data." msgstr ""
#: src/modules/services-openrc/main.py:29 #: src/modules/services-openrc/main.py:29
msgid "Configure OpenRC services" msgid "Configure OpenRC services"
msgstr "Configure OpenRC services" msgstr ""
#: src/modules/services-openrc/main.py:57 #: src/modules/services-openrc/main.py:57
msgid "Cannot add service {name!s} to run-level {level!s}." msgid "Cannot add service {name!s} to run-level {level!s}."
msgstr "Cannot add service {name!s} to run-level {level!s}." msgstr ""
#: src/modules/services-openrc/main.py:59 #: src/modules/services-openrc/main.py:59
msgid "Cannot remove service {name!s} from run-level {level!s}." msgid "Cannot remove service {name!s} from run-level {level!s}."
msgstr "Cannot remove service {name!s} from run-level {level!s}." msgstr ""
#: src/modules/services-openrc/main.py:61 #: src/modules/services-openrc/main.py:61
msgid "" msgid ""
"Unknown service-action <code>{arg!s}</code> for service {name!s} in run-" "Unknown service-action <code>{arg!s}</code> for service {name!s} in run-"
"level {level!s}." "level {level!s}."
msgstr "" msgstr ""
"Unknown service-action <code>{arg!s}</code> for service {name!s} in run-"
"level {level!s}."
#: src/modules/services-openrc/main.py:94 #: src/modules/services-openrc/main.py:94
msgid "" msgid ""
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}." "<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
msgstr "" msgstr ""
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
#: src/modules/services-openrc/main.py:101 #: src/modules/services-openrc/main.py:101
msgid "Target runlevel does not exist" msgid "Target runlevel does not exist"
msgstr "Target runlevel does not exist" msgstr ""
#: src/modules/services-openrc/main.py:102 #: src/modules/services-openrc/main.py:102
msgid "" msgid ""
"The path for runlevel {level!s} is <code>{path!s}</code>, which does not " "The path for runlevel {level!s} is <code>{path!s}</code>, which does not "
"exist." "exist."
msgstr "" msgstr ""
"The path for runlevel {level!s} is <code>{path!s}</code>, which does not "
"exist."
#: src/modules/services-openrc/main.py:110 #: src/modules/services-openrc/main.py:110
msgid "Target service does not exist" msgid "Target service does not exist"
msgstr "Target service does not exist" msgstr ""
#: src/modules/services-openrc/main.py:111 #: src/modules/services-openrc/main.py:111
msgid "" msgid ""
"The path for service {name!s} is <code>{path!s}</code>, which does not " "The path for service {name!s} is <code>{path!s}</code>, which does not exist."
"exist."
msgstr "" msgstr ""
"The path for service {name!s} is <code>{path!s}</code>, which does not "
"exist."
#: src/modules/plymouthcfg/main.py:27 #: src/modules/plymouthcfg/main.py:27
msgid "Configure Plymouth theme" msgid "Configure Plymouth theme"
msgstr "Configure Plymouth theme" msgstr ""
#: src/modules/packages/main.py:50 src/modules/packages/main.py:59 #: src/modules/packages/main.py:50 src/modules/packages/main.py:59
#: src/modules/packages/main.py:69 #: src/modules/packages/main.py:69
msgid "Install packages." msgid "Install packages."
msgstr "Install packages." msgstr ""
#: src/modules/packages/main.py:57 #: src/modules/packages/main.py:57
#, python-format #, python-format
msgid "Processing packages (%(count)d / %(total)d)" msgid "Processing packages (%(count)d / %(total)d)"
msgstr "Processing packages (%(count)d / %(total)d)" msgstr ""
#: src/modules/packages/main.py:62 #: src/modules/packages/main.py:62
#, python-format #, python-format
msgid "Installing one package." msgid "Installing one package."
msgid_plural "Installing %(num)d packages." msgid_plural "Installing %(num)d packages."
msgstr[0] "Installing one package." msgstr[0] ""
msgstr[1] "Installing %(num)d packages." msgstr[1] ""
#: src/modules/packages/main.py:65 #: src/modules/packages/main.py:65
#, python-format #, python-format
msgid "Removing one package." msgid "Removing one package."
msgid_plural "Removing %(num)d packages." msgid_plural "Removing %(num)d packages."
msgstr[0] "Removing one package." msgstr[0] ""
msgstr[1] "Removing %(num)d packages." msgstr[1] ""
#: src/modules/packages/main.py:638 src/modules/packages/main.py:650 #: src/modules/packages/main.py:638 src/modules/packages/main.py:650
#: src/modules/packages/main.py:678 #: src/modules/packages/main.py:678
msgid "Package Manager error" msgid "Package Manager error"
msgstr "Package Manager error" msgstr ""
#: src/modules/packages/main.py:639 #: src/modules/packages/main.py:639
msgid "" msgid ""
"The package manager could not prepare updates. The command <pre>{!s}</pre> " "The package manager could not prepare updates. The command <pre>{!s}</pre> "
"returned error code {!s}." "returned error code {!s}."
msgstr "" msgstr ""
"The package manager could not prepare updates. The command <pre>{!s}</pre> "
"returned error code {!s}."
#: src/modules/packages/main.py:651 #: src/modules/packages/main.py:651
msgid "" msgid ""
"The package manager could not update the system. The command <pre>{!s}</pre>" "The package manager could not update the system. The command <pre>{!s}</pre> "
" returned error code {!s}." "returned error code {!s}."
msgstr "" msgstr ""
"The package manager could not update the system. The command <pre>{!s}</pre>"
" returned error code {!s}."
#: src/modules/packages/main.py:679 #: src/modules/packages/main.py:679
msgid "" msgid ""
"The package manager could not make changes to the installed system. The " "The package manager could not make changes to the installed system. The "
"command <pre>{!s}</pre> returned error code {!s}." "command <pre>{!s}</pre> returned error code {!s}."
msgstr "" msgstr ""
"The package manager could not make changes to the installed system. The "
"command <pre>{!s}</pre> returned error code {!s}."
#: src/modules/bootloader/main.py:43 #: src/modules/bootloader/main.py:43
msgid "Install bootloader." msgid "Install bootloader."
msgstr "Install bootloader." msgstr ""
#: src/modules/bootloader/main.py:508 #: src/modules/bootloader/main.py:508
msgid "Bootloader installation error" msgid "Bootloader installation error"
msgstr "Bootloader installation error" msgstr ""
#: src/modules/bootloader/main.py:509 #: src/modules/bootloader/main.py:509
msgid "" msgid ""
"The bootloader could not be installed. The installation command " "The bootloader could not be installed. The installation command <pre>{!s}</"
"<pre>{!s}</pre> returned error code {!s}." "pre> returned error code {!s}."
msgstr "" msgstr ""
"The bootloader could not be installed. The installation command "
"<pre>{!s}</pre> returned error code {!s}."
#: src/modules/hwclock/main.py:26 #: src/modules/hwclock/main.py:26
msgid "Setting hardware clock." msgid "Setting hardware clock."
msgstr "Setting hardware clock." msgstr ""
#: src/modules/mkinitfs/main.py:27 #: src/modules/mkinitfs/main.py:27
msgid "Creating initramfs with mkinitfs." msgid "Creating initramfs with mkinitfs."
msgstr "Creating initramfs with mkinitfs." msgstr ""
#: src/modules/mkinitfs/main.py:49 #: src/modules/mkinitfs/main.py:49
msgid "Failed to run mkinitfs on the target" msgid "Failed to run mkinitfs on the target"
msgstr "Failed to run mkinitfs on the target" msgstr ""
#: src/modules/mkinitfs/main.py:50 src/modules/dracut/main.py:50 #: src/modules/mkinitfs/main.py:50 src/modules/dracut/main.py:50
msgid "The exit code was {}" msgid "The exit code was {}"
msgstr "The exit code was {}" msgstr ""
#: src/modules/dracut/main.py:27 #: src/modules/dracut/main.py:27
msgid "Creating initramfs with dracut." msgid "Creating initramfs with dracut."
msgstr "Creating initramfs with dracut." msgstr ""
#: src/modules/dracut/main.py:49 #: src/modules/dracut/main.py:49
msgid "Failed to run dracut on the target" msgid "Failed to run dracut on the target"
msgstr "Failed to run dracut on the target" msgstr ""
#: src/modules/initramfscfg/main.py:32 #: src/modules/initramfscfg/main.py:32
msgid "Configuring initramfs." msgid "Configuring initramfs."
msgstr "Configuring initramfs." msgstr ""
#: src/modules/openrcdmcryptcfg/main.py:26 #: src/modules/openrcdmcryptcfg/main.py:26
msgid "Configuring OpenRC dmcrypt service." msgid "Configuring OpenRC dmcrypt service."
msgstr "Configuring OpenRC dmcrypt service." msgstr ""
#: src/modules/fstab/main.py:29 #: src/modules/fstab/main.py:29
msgid "Writing fstab." msgid "Writing fstab."
msgstr "Writing fstab." msgstr ""
#: src/modules/fstab/main.py:389 #: src/modules/fstab/main.py:389
msgid "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use." msgid "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use."
msgstr "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use." msgstr ""
#: src/modules/dummypython/main.py:35 #: src/modules/dummypython/main.py:35
msgid "Dummy python job." msgid "Dummy python job."
msgstr "Dummy python job." msgstr ""
#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93 #: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93
#: src/modules/dummypython/main.py:94 #: src/modules/dummypython/main.py:94
msgid "Dummy python step {}" msgid "Dummy python step {}"
msgstr "Dummy python step {}" msgstr ""
#: src/modules/localecfg/main.py:30 #: src/modules/localecfg/main.py:30
msgid "Configuring locales." msgid "Configuring locales."
msgstr "Configuring locales." msgstr ""
#: src/modules/networkcfg/main.py:29 #: src/modules/networkcfg/main.py:29
msgid "Saving network configuration." msgid "Saving network configuration."
msgstr "Saving network configuration." msgstr ""

View File

@ -71,22 +71,20 @@ handle_args( QCoreApplication& a )
{ {
QCommandLineOption debugLevelOption( QCommandLineOption debugLevelOption(
QStringLiteral( "D" ), "Verbose output for debugging purposes (0-8), ignored.", "level" ); QStringLiteral( "D" ), "Verbose output for debugging purposes (0-8), ignored.", "level" );
QCommandLineOption globalOption( QStringList() << QStringLiteral( "g" ) << QStringLiteral( "global " ), QCommandLineOption globalOption( { QStringLiteral( "g" ), QStringLiteral( "global" ) },
QStringLiteral( "Global settings document" ), QStringLiteral( "Global settings document" ),
"global.yaml" ); "global.yaml" );
QCommandLineOption jobOption( QStringList() << QStringLiteral( "j" ) << QStringLiteral( "job" ), QCommandLineOption jobOption(
QStringLiteral( "Job settings document" ), { QStringLiteral( "j" ), QStringLiteral( "job" ) }, QStringLiteral( "Job settings document" ), "job.yaml" );
"job.yaml" ); QCommandLineOption langOption( { QStringLiteral( "l" ), QStringLiteral( "language" ) },
QCommandLineOption langOption( QStringList() << QStringLiteral( "l" ) << QStringLiteral( "language" ),
QStringLiteral( "Language (global)" ), QStringLiteral( "Language (global)" ),
"languagecode" ); "languagecode" );
QCommandLineOption brandOption( QStringList() << QStringLiteral( "b" ) << QStringLiteral( "branding" ), QCommandLineOption brandOption( { QStringLiteral( "b" ), QStringLiteral( "branding" ) },
QStringLiteral( "Branding directory" ), QStringLiteral( "Branding directory" ),
"path/to/branding.desc", "path/to/branding.desc",
"src/branding/default/branding.desc" ); "src/branding/default/branding.desc" );
QCommandLineOption uiOption( QStringList() << QStringLiteral( "U" ) << QStringLiteral( "ui" ), QCommandLineOption uiOption( { QStringLiteral( "U" ), QStringLiteral( "ui" ) }, QStringLiteral( "Enable UI" ) );
QStringLiteral( "Enable UI" ) ); QCommandLineOption slideshowOption( { QStringLiteral( "s" ), QStringLiteral( "slideshow" ) },
QCommandLineOption slideshowOption( QStringList() << QStringLiteral( "s" ) << QStringLiteral( "slideshow" ),
QStringLiteral( "Run slideshow module" ) ); QStringLiteral( "Run slideshow module" ) );
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription( "Calamares module tester" ); parser.setApplicationDescription( "Calamares module tester" );
@ -101,7 +99,7 @@ handle_args( QCoreApplication& a )
parser.addOption( uiOption ); parser.addOption( uiOption );
parser.addOption( slideshowOption ); parser.addOption( slideshowOption );
#ifdef WITH_PYTHON #ifdef WITH_PYTHON
QCommandLineOption pythonOption( QStringList() << QStringLiteral( "P" ) << QStringLiteral( "no-injected-python" ), QCommandLineOption pythonOption( { QStringLiteral( "P" ), QStringLiteral( "no-injected-python" ) },
QStringLiteral( "Do not disable potentially-harmful Python commands" ) ); QStringLiteral( "Do not disable potentially-harmful Python commands" ) );
parser.addOption( pythonOption ); parser.addOption( pythonOption );
#endif #endif
@ -143,8 +141,7 @@ handle_args( QCoreApplication& a )
parser.value( langOption ), parser.value( langOption ),
parser.value( brandOption ), parser.value( brandOption ),
parser.isSet( slideshowOption ) || parser.isSet( uiOption ), parser.isSet( slideshowOption ) || parser.isSet( uiOption ),
pythonInjection pythonInjection };
};
} }
} }
@ -299,7 +296,8 @@ load_module( const ModuleConfig& moduleConfig )
bool ok = false; bool ok = false;
QVariantMap descriptor; QVariantMap descriptor;
for ( const QString& prefix : QStringList { "./", "src/modules/", "modules/" } ) QStringList moduleDirectories { "./", "src/modules/", "modules/", CMAKE_INSTALL_FULL_LIBDIR "/calamares/modules/" };
for ( const QString& prefix : qAsConst( moduleDirectories ) )
{ {
// Could be a complete path, eg. src/modules/dummycpp/module.desc // Could be a complete path, eg. src/modules/dummycpp/module.desc
fi = QFileInfo( prefix + moduleName ); fi = QFileInfo( prefix + moduleName );
@ -325,12 +323,23 @@ load_module( const ModuleConfig& moduleConfig )
{ {
break; break;
} }
else
{
if ( !fi.exists() )
{
cDebug() << "Expected a descriptor file" << fi.path();
}
else
{
cDebug() << "Read descriptor" << fi.path() << "and it was empty.";
}
}
} }
} }
if ( !ok ) if ( !ok )
{ {
cWarning() << "No suitable module descriptor found."; cWarning() << "No suitable module descriptor found in" << Logger::DebugList( moduleDirectories );
return nullptr; return nullptr;
} }
@ -461,7 +470,7 @@ main( int argc, char* argv[] )
#ifdef WITH_PYTHON #ifdef WITH_PYTHON
if ( module.m_pythonInjection ) if ( module.m_pythonInjection )
{ {
Calamares::PythonJob::setInjectedPreScript(pythonPreScript); Calamares::PythonJob::setInjectedPreScript( pythonPreScript );
} }
#endif #endif
#ifdef WITH_QML #ifdef WITH_QML

View File

@ -330,7 +330,8 @@ void
PythonJob::setInjectedPreScript( const char* preScript ) PythonJob::setInjectedPreScript( const char* preScript )
{ {
s_preScript = preScript; s_preScript = preScript;
cDebug() << "Python pre-script set to" << Logger::Pointer( preScript ); cDebug() << "Python pre-script set to string" << Logger::Pointer( preScript ) << "length"
<< ( preScript ? strlen( preScript ) : 0 );
} }
} // namespace Calamares } // namespace Calamares

View File

@ -198,7 +198,7 @@ desktop_environments = [
DesktopEnvironment('/usr/bin/fvwm3', 'fvwm3'), DesktopEnvironment('/usr/bin/fvwm3', 'fvwm3'),
DesktopEnvironment('/usr/bin/sway', 'sway'), DesktopEnvironment('/usr/bin/sway', 'sway'),
DesktopEnvironment('/usr/bin/ukui-session', 'ukui'), DesktopEnvironment('/usr/bin/ukui-session', 'ukui'),
DesktopEnvironment('/usr/bin/cutefish-session', 'cutefish-xsession'), DesktopEnvironment('/usr/bin/cutefish-session', 'cutefish-xsession'),
] ]
@ -923,7 +923,7 @@ def run():
else: else:
dm_instance = None dm_instance = None
else: else:
libcalamares.utils.debug("{!s} has {!d} implementation classes.".format(dm).format(len(impl))) libcalamares.utils.debug("{!s} has {!s} implementation classes.".format(dm, len(impl)))
if dm_instance is None: if dm_instance is None:
libcalamares.utils.debug("{!s} selected but not installed".format(dm)) libcalamares.utils.debug("{!s} selected but not installed".format(dm))

View File

@ -13,7 +13,7 @@
# options from this mapping. # options from this mapping.
mountOptions: mountOptions:
default: defaults,noatime 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 # 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, # *mountOptions* for *vfat* are used, or if that is not set either,
@ -38,10 +38,10 @@ efiMountOptions: umask=0077
# swap: discard # swap: discard
# btrfs: discard,compress=lzo # 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. # and does nothing for other filesystems.
ssdExtraMountOptions: ssdExtraMountOptions:
btrfs: compress=lzo btrfs: discard=async,ssd
# Additional options added to each line in /etc/crypttab # Additional options added to each line in /etc/crypttab
crypttabOptions: luks crypttabOptions: luks

View File

@ -150,7 +150,8 @@ def find_initcpio_features(partitions, root_mount_point):
"modconf", "modconf",
"block", "block",
"keyboard", "keyboard",
"keymap" "keymap",
"consolefont",
] ]
modules = [] modules = []
files = [] files = []

View File

@ -472,7 +472,7 @@ Config::guessLocaleKeyboardLayout()
{ "el_GR", "gr" }, /* Greek in Greece */ { "el_GR", "gr" }, /* Greek in Greece */
{ "ig_NG", "igbo_NG" }, /* Igbo in Nigeria */ { "ig_NG", "igbo_NG" }, /* Igbo in Nigeria */
{ "ha_NG", "hausa_NG" }, /* Hausa */ { "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 // Try to preselect a layout, depending on language and locale

View File

@ -201,6 +201,10 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
// but nearly all its native speakers also speak English, // but nearly all its native speakers also speak English,
// and migrants are likely to use English. // and migrants are likely to use English.
{ "IE", "en" }, { "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" }, { "IT", "it" },
{ "MA", "ar" }, { "MA", "ar" },
{ "MK", "mk" }, { "MK", "mk" },

View File

@ -29,23 +29,83 @@ def pretty_name():
return _("Saving network configuration.") return _("Saving network configuration.")
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*,
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 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(nm_config_filename, "r") as network_conf:
text = network_conf.readlines()
live_permissions = 'permissions=user:{}:;'.format(live_user)
target_permissions = 'permissions=user:{}:;\n'.format(target_user)
with open(nm_config_filename, "w") as network_conf:
for line in text:
if live_permissions in line:
line = target_permissions
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(): def run():
""" """
Setup network configuration Setup network configuration
""" """
root_mount_point = libcalamares.globalstorage.value("rootMountPoint") root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
user = libcalamares.globalstorage.value("username") user = libcalamares.globalstorage.value("username")
live_user = os.getlogin() live_user = get_live_user()
if root_mount_point is None: if root_mount_point is None:
libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point)) libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point))
return (_("Configuration Error"), return (_("Configuration Error"),
_("No root mount point is given for <pre>{!s}</pre> to use." ).format("networkcfg")) _("No root mount point is given for <pre>{!s}</pre> to use." ).format("networkcfg"))
source_nm = "/etc/NetworkManager/system-connections/" source_nm, target_nm = path_pair(root_mount_point, "etc/NetworkManager/system-connections/")
target_nm = os.path.join(
root_mount_point, "etc/NetworkManager/system-connections/"
)
# Sanity checks. We don't want to do anything if a network # Sanity checks. We don't want to do anything if a network
# configuration already exists on the target # configuration already exists on the target
@ -63,27 +123,16 @@ def run():
try: try:
shutil.copy(source_network, target_network, follow_symlinks=False) shutil.copy(source_network, target_network, follow_symlinks=False)
if live_user in open(target_network).read(): replace_username(target_network, live_user, user)
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()
except FileNotFoundError: except FileNotFoundError:
libcalamares.utils.debug( libcalamares.utils.debug(
"Can't copy network configuration files in " "Can't copy network configuration files in {}".format(source_network)
+ "{}".format(source_network)
) )
except FileExistsError: except FileExistsError:
pass pass
# We need to overwrite the default resolv.conf in the chroot. # We need to overwrite the default resolv.conf in the chroot.
source_resolv = "/etc/resolv.conf" source_resolv, target_resolv = path_pair(root_mount_point, "etc/resolv.conf")
target_resolv = os.path.join(root_mount_point, "etc/resolv.conf")
if source_resolv != target_resolv and os.path.exists(source_resolv): if source_resolv != target_resolv and os.path.exists(source_resolv):
try: try:
os.remove(target_resolv) os.remove(target_resolv)

View File

@ -13,6 +13,7 @@
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "partition/PartitionSize.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/Variant.h" #include "utils/Variant.h"
@ -233,7 +234,25 @@ fillGSConfigurationEFI( Calamares::GlobalStorage* gs, const QVariantMap& configu
// Read and parse key efiSystemPartitionSize // Read and parse key efiSystemPartitionSize
if ( configurationMap.contains( "efiSystemPartitionSize" ) ) if ( configurationMap.contains( "efiSystemPartitionSize" ) )
{ {
gs->insert( "efiSystemPartitionSize", CalamaresUtils::getString( configurationMap, "efiSystemPartitionSize" ) ); const QString sizeString = CalamaresUtils::getString( configurationMap, "efiSystemPartitionSize" );
CalamaresUtils::Partition::PartitionSize part_size
= CalamaresUtils::Partition::PartitionSize( sizeString );
if (part_size.isValid())
{
// Insert once as string, once as a size-in-bytes;
// changes to these keys should be synchronized with PartUtils.cpp
gs->insert( "efiSystemPartitionSize", sizeString );
gs->insert( "efiSystemPartitionSize_i", part_size.toBytes());
if (part_size.toBytes() != PartUtils::efiFilesystemMinimumSize())
{
cWarning() << "EFI partition size" << sizeString << "has been adjusted to" << PartUtils::efiFilesystemMinimumSize() << "bytes";
}
}
else
{
cWarning() << "EFI partition size" << sizeString << "is invalid, ignored";
}
} }
// Read and parse key efiSystemPartitionName // Read and parse key efiSystemPartitionName

View File

@ -558,9 +558,10 @@ PartitionViewStep::onLeave()
if ( !okSize ) if ( !okSize )
{ {
cDebug() << o << "ESP too small"; cDebug() << o << "ESP too small";
const auto atLeastBytes = PartUtils::efiFilesystemMinimumSize();
const auto atLeastMiB = CalamaresUtils::BytesToMiB( atLeastBytes );
description.append( ' ' ); description.append( ' ' );
description.append( tr( "The filesystem must be at least %1 MiB in size." ) description.append( tr( "The filesystem must be at least %1 MiB in size." ).arg( atLeastMiB ) );
.arg( PartUtils::efiFilesystemMinimumSize() ) );
} }
if ( !okFlag ) if ( !okFlag )
{ {

View File

@ -471,9 +471,12 @@ bool
isEfiFilesystemSuitableSize( const Partition* candidate ) isEfiFilesystemSuitableSize( const Partition* candidate )
{ {
auto size = candidate->capacity(); // bytes auto size = candidate->capacity(); // bytes
if ( size <= 0 )
{
return false;
}
using CalamaresUtils::Units::operator""_MiB; if ( size_t( size ) >= efiFilesystemMinimumSize() )
if ( size >= 300_MiB )
{ {
return true; return true;
} }
@ -522,7 +525,22 @@ size_t
efiFilesystemMinimumSize() efiFilesystemMinimumSize()
{ {
using CalamaresUtils::Units::operator""_MiB; using CalamaresUtils::Units::operator""_MiB;
return 300_MiB;
auto uefisys_part_sizeB = 300_MiB;
// The default can be overridden; the key used here comes
// from the partition module Config.cpp
auto* gs = Calamares::JobQueue::instance()->globalStorage();
if ( gs->contains( "efiSystemPartitionSize_i" ) )
{
uefisys_part_sizeB = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
}
// There is a lower limit of what can be configured
if ( uefisys_part_sizeB < 32_MiB )
{
uefisys_part_sizeB = 32_MiB;
}
return uefisys_part_sizeB;
} }

View File

@ -94,12 +94,18 @@ bool isEfiFilesystemSuitableType( const Partition* candidate );
*/ */
bool isEfiFilesystemSuitableSize( const Partition* candidate ); bool isEfiFilesystemSuitableSize( const Partition* candidate );
/** @brief Returns the minimum size of an EFI boot partition. /** @brief Returns the minimum size of an EFI boot partition in bytes.
* *
* This is determined as 300MiB, based on the FAT32 standard * This is determined as 300MiB, based on the FAT32 standard
* and EFI documentation (and not a little discussion in Calamares * and EFI documentation (and not a little discussion in Calamares
* issues about what works, what is effective, and what is mandated * issues about what works, what is effective, and what is mandated
* by the standard and how all of those are different). * by the standard and how all of those are different).
*
* This can be configured through the `partition.conf` file,
* key *efiSystemPartitionSize*, which will then apply to both
* automatic partitioning **and** the warning for manual partitioning.
*
* A minimum of 32MiB (which is bonkers-small) is enforced.
*/ */
size_t efiFilesystemMinimumSize(); size_t efiFilesystemMinimumSize();

View File

@ -118,14 +118,7 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO
if ( isEfi ) if ( isEfi )
{ {
int uefisys_part_sizeB = 300_MiB; size_t uefisys_part_sizeB = PartUtils::efiFilesystemMinimumSize();
if ( gs->contains( "efiSystemPartitionSize" ) )
{
CalamaresUtils::Partition::PartitionSize part_size
= CalamaresUtils::Partition::PartitionSize( gs->value( "efiSystemPartitionSize" ).toString() );
uefisys_part_sizeB = part_size.toBytes( dev->capacity() );
}
qint64 efiSectorCount = CalamaresUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); qint64 efiSectorCount = CalamaresUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() );
Q_ASSERT( efiSectorCount > 0 ); Q_ASSERT( efiSectorCount > 0 );

View File

@ -10,6 +10,12 @@ efiSystemPartition: "/boot/efi"
# This optional setting specifies the size of the EFI system partition. # This optional setting specifies the size of the EFI system partition.
# If nothing is specified, the default size of 300MiB will be used. # If nothing is specified, the default size of 300MiB will be used.
#
# This size applies both to automatic partitioning and the checks
# during manual partitioning. A minimum of 32MiB is enforced,
# 300MiB is the default, M is treated as MiB, and if you really want
# one-million (10^6) bytes, use MB.
#
# efiSystemPartitionSize: 300M # efiSystemPartitionSize: 300M
# This optional setting specifies the name of the EFI system partition (see # This optional setting specifies the name of the EFI system partition (see

View File

@ -22,13 +22,12 @@ import subprocess
import sys import sys
import tempfile import tempfile
from libcalamares import * import libcalamares
from libcalamares.utils import mount
import gettext import gettext
_ = gettext.translation("calamares-python", _ = gettext.translation("calamares-python",
localedir=utils.gettext_path(), localedir=libcalamares.utils.gettext_path(),
languages=utils.gettext_languages(), languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext fallback=True).gettext
def pretty_name(): def pretty_name():
@ -123,14 +122,14 @@ class UnpackEntry:
return return
if os.path.isdir(self.source): if os.path.isdir(self.source):
r = mount(self.source, imgmountdir, "", "--bind") r = libcalamares.utils.mount(self.source, imgmountdir, "", "--bind")
elif os.path.isfile(self.source): elif os.path.isfile(self.source):
r = mount(self.source, imgmountdir, self.sourcefs, "loop") r = libcalamares.utils.mount(self.source, imgmountdir, self.sourcefs, "loop")
else: # self.source is a device else: # self.source is a device
r = mount(self.source, imgmountdir, self.sourcefs, "") r = libcalamares.utils.mount(self.source, imgmountdir, self.sourcefs, "")
if r != 0: if r != 0:
utils.debug("Failed to mount '{}' (fs={}) (target={})".format(self.source, self.sourcefs, imgmountdir)) libcalamares.utils.debug("Failed to mount '{}' (fs={}) (target={})".format(self.source, self.sourcefs, imgmountdir))
raise subprocess.CalledProcessError(r, "mount") raise subprocess.CalledProcessError(r, "mount")
@ -142,7 +141,7 @@ def global_excludes():
List excludes for rsync. List excludes for rsync.
""" """
lst = [] lst = []
extra_mounts = globalstorage.value("extraMounts") extra_mounts = libcalamares.globalstorage.value("extraMounts")
if extra_mounts is None: if extra_mounts is None:
extra_mounts = [] extra_mounts = []
@ -251,7 +250,7 @@ def file_copy(source, entry, progress_cb):
# https://bugzilla.redhat.com/show_bug.cgi?id=868755#c50 # https://bugzilla.redhat.com/show_bug.cgi?id=868755#c50
# for the same issue in Anaconda, which uses a similar workaround. # for the same issue in Anaconda, which uses a similar workaround.
if process.returncode != 0 and process.returncode != 23: if process.returncode != 0 and process.returncode != 23:
utils.warning("rsync failed with error code {}.".format(process.returncode)) libcalamares.utils.warning("rsync failed with error code {}.".format(process.returncode))
return _("rsync failed with error code {}.").format(process.returncode) return _("rsync failed with error code {}.").format(process.returncode)
return None return None
@ -298,7 +297,7 @@ class UnpackOperation:
global status global status
status = _("Unpacking image {}/{}, file {}/{}").format((complete_count+1), len(self.entries), current_done, current_total) status = _("Unpacking image {}/{}, file {}/{}").format((complete_count+1), len(self.entries), current_done, current_total)
job.setprogress(progress) libcalamares.job.setprogress(progress)
def run(self): def run(self):
""" """
@ -313,7 +312,7 @@ class UnpackOperation:
complete = 0 complete = 0
for entry in self.entries: for entry in self.entries:
status = _("Starting to unpack {}").format(entry.source) status = _("Starting to unpack {}").format(entry.source)
job.setprogress( ( 1.0 * complete ) / len(self.entries) ) libcalamares.job.setprogress( ( 1.0 * complete ) / len(self.entries) )
entry.do_mount(source_mount_path) entry.do_mount(source_mount_path)
entry.do_count() # Fill in the entry.total entry.do_count() # Fill in the entry.total
@ -398,7 +397,7 @@ def repair_root_permissions(root_mount_point):
try: try:
os.chmod(root_mount_point, 0o755) # Want / to be rwxr-xr-x os.chmod(root_mount_point, 0o755) # Want / to be rwxr-xr-x
except OSError as e: except OSError as e:
utils.warning("Could not set / to safe permissions: {}".format(e)) libcalamares.utils.warning("Could not set / to safe permissions: {}".format(e))
# But ignore it # But ignore it
@ -414,9 +413,9 @@ def extract_weight(entry):
wi = int(w) wi = int(w)
return wi if wi > 0 else 1 return wi if wi > 0 else 1
except ValueError: except ValueError:
utils.warning("*weight* setting {!r} is not valid.".format(w)) libcalamares.utils.warning("*weight* setting {!r} is not valid.".format(w))
except TypeError: except TypeError:
utils.warning("*weight* setting {!r} must be number.".format(w)) libcalamares.utils.warning("*weight* setting {!r} must be number.".format(w))
return 1 return 1
@ -424,16 +423,16 @@ def run():
""" """
Unsquash filesystem. Unsquash filesystem.
""" """
root_mount_point = globalstorage.value("rootMountPoint") root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
if not root_mount_point: if not root_mount_point:
utils.warning("No mount point for root partition") libcalamares.utils.warning("No mount point for root partition")
return (_("No mount point for root partition"), return (_("No mount point for root partition"),
_("globalstorage does not contain a \"rootMountPoint\" key, " _("globalstorage does not contain a \"rootMountPoint\" key, "
"doing nothing")) "doing nothing"))
if not os.path.exists(root_mount_point): if not os.path.exists(root_mount_point):
utils.warning("Bad root mount point \"{}\"".format(root_mount_point)) libcalamares.utils.warning("Bad root mount point \"{}\"".format(root_mount_point))
return (_("Bad mount point for root partition"), return (_("Bad mount point for root partition"),
_("rootMountPoint is \"{}\", which does not " _("rootMountPoint is \"{}\", which does not "
"exist, doing nothing").format(root_mount_point)) "exist, doing nothing").format(root_mount_point))
@ -444,41 +443,42 @@ def run():
# - unsupported filesystems # - unsupported filesystems
# - non-existent sources # - non-existent sources
# - missing tools for specific FS # - missing tools for specific FS
for entry in job.configuration["unpack"]: for entry in libcalamares.job.configuration["unpack"]:
source = os.path.abspath(entry["source"]) source = os.path.abspath(entry["source"])
sourcefs = entry["sourcefs"] sourcefs = entry["sourcefs"]
if sourcefs not in supported_filesystems: if sourcefs not in supported_filesystems:
utils.warning("The filesystem for \"{}\" ({}) is not supported by your current kernel".format(source, sourcefs)) libcalamares.utils.warning("The filesystem for \"{}\" ({}) is not supported by your current kernel".format(source, sourcefs))
utils.warning(" ... modprobe {} may solve the problem".format(sourcefs)) libcalamares.utils.warning(" ... modprobe {} may solve the problem".format(sourcefs))
return (_("Bad unsquash configuration"), return (_("Bad unsquash configuration"),
_("The filesystem for \"{}\" ({}) is not supported by your current kernel").format(source, sourcefs)) _("The filesystem for \"{}\" ({}) is not supported by your current kernel").format(source, sourcefs))
if not os.path.exists(source): if not os.path.exists(source):
utils.warning("The source filesystem \"{}\" does not exist".format(source)) libcalamares.utils.warning("The source filesystem \"{}\" does not exist".format(source))
return (_("Bad unsquash configuration"), return (_("Bad unsquash configuration"),
_("The source filesystem \"{}\" does not exist").format(source)) _("The source filesystem \"{}\" does not exist").format(source))
if sourcefs == "squashfs": if sourcefs == "squashfs":
if shutil.which("unsquashfs") is None: if shutil.which("unsquashfs") is None:
utils.warning("Failed to find unsquashfs") libcalamares.utils.warning("Failed to find unsquashfs")
return (_("Failed to unpack image \"{}\"").format(self.source), return (_("Bad unsquash configuration"),
_("Failed to find unsquashfs, make sure you have the squashfs-tools package installed")) _("Failed to find unsquashfs, make sure you have the squashfs-tools package installed.") +
" " + _("Failed to unpack image \"{}\"").format(source))
unpack = list() unpack = list()
is_first = True is_first = True
for entry in job.configuration["unpack"]: for entry in libcalamares.job.configuration["unpack"]:
source = os.path.abspath(entry["source"]) source = os.path.abspath(entry["source"])
sourcefs = entry["sourcefs"] sourcefs = entry["sourcefs"]
destination = os.path.abspath(root_mount_point + entry["destination"]) destination = os.path.abspath(root_mount_point + entry["destination"])
if not os.path.isdir(destination) and sourcefs != "file": if not os.path.isdir(destination) and sourcefs != "file":
utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination)) libcalamares.utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination))
if is_first: if is_first:
return (_("Bad unsquash configuration"), return (_("Bad unsquash configuration"),
_("The destination \"{}\" in the target system is not a directory").format(destination)) _("The destination \"{}\" in the target system is not a directory").format(destination))
else: else:
utils.debug(".. assuming that the previous targets will create that directory.") libcalamares.utils.debug(".. assuming that the previous targets will create that directory.")
unpack.append(UnpackEntry(source, sourcefs, destination)) unpack.append(UnpackEntry(source, sourcefs, destination))
# Optional settings # Optional settings