Merge branch 'calamares' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
df37ae610b
12
CHANGES-3.3
12
CHANGES-3.3
@ -10,13 +10,21 @@ the history of the 3.2 series (2018-05 - 2022-08).
|
|||||||
# 3.3.10 (unreleased)
|
# 3.3.10 (unreleased)
|
||||||
|
|
||||||
This release contains contributions from (alphabetically by given name):
|
This release contains contributions from (alphabetically by given name):
|
||||||
- Nobody yet
|
- Adriaan de Groot
|
||||||
|
- Evan James
|
||||||
|
- Neal Gompa
|
||||||
|
|
||||||
## Core ##
|
## Core ##
|
||||||
- Nothing yet
|
- Nothing yet
|
||||||
|
|
||||||
## Modules ##
|
## Modules ##
|
||||||
- Nothing yet
|
- *keyboard* Repaired summary messages with strange formatting. (#2364)
|
||||||
|
- *keyboard* Can update KDE Plasma configuration in Wayland. (thanks Neal, #2264)
|
||||||
|
- *locale* Repaired summary messages with strange formatting. (#2364)
|
||||||
|
- *umount* Correctly unmounts the root filesystem of the target. (thanks Evan)
|
||||||
|
- *users* Supports a new `home_permissions` setting to override the
|
||||||
|
distro's `useradd` configuration of the umask. (#2362)
|
||||||
|
- *welcome* Follows system styling colors (e.g. Dark Mode).
|
||||||
|
|
||||||
|
|
||||||
# 3.3.9 (2024-08-12)
|
# 3.3.9 (2024-08-12)
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
# There is no docker image for EndeavoudOS, and the live ISO
|
# There is no docker image for EndeavoudOS, and the live ISO
|
||||||
# for Cassini Nova is KF5 / Qt5 based, but we can build there.
|
# for Cassini Nova is KF5 / Qt5 based, but we can build there.
|
||||||
# It even has most of the build-deps already installed.
|
# It even has most of the build-deps already installed.
|
||||||
pacman -Syu --noconfirm git cmake ninja jq
|
pacman -Syu --noconfirm jq
|
||||||
pacman -S --noconfirm gcc yaml-cpp icu
|
pacman -S --noconfirm git cmake ninja jq || exit 1
|
||||||
pacman -S --noconfirm extra-cmake-modules
|
pacman -S --noconfirm gcc yaml-cpp icu || exit 1
|
||||||
|
pacman -S --noconfirm extra-cmake-modules || exit 1
|
||||||
|
pacman -S --noconfirm python-jsonschema || exit 1
|
||||||
|
|
||||||
|
@ -378,18 +378,18 @@
|
|||||||
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="124"/>
|
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="124"/>
|
||||||
<source>Waiting for %n module(s)…</source>
|
<source>Waiting for %n module(s)…</source>
|
||||||
<comment>@status</comment>
|
<comment>@status</comment>
|
||||||
<translation type="unfinished">
|
<translation>
|
||||||
<numerusform/>
|
<numerusform>Waiting for %n module<EFBFBD>~@<EFBFBD></numerusform>
|
||||||
<numerusform/>
|
<numerusform>Waiting for %n modules<EFBFBD>~@<EFBFBD></numerusform>
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="125"/>
|
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="125"/>
|
||||||
<source>(%n second(s))</source>
|
<source>(%n second(s))</source>
|
||||||
<comment>@status</comment>
|
<comment>@status</comment>
|
||||||
<translation type="unfinished">
|
<translation type="unfinished">
|
||||||
<numerusform/>
|
<numerusform>(%n second)</numerusform>
|
||||||
<numerusform/>
|
<numerusform>(%n seconds)</numerusform>
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
@ -965,31 +965,31 @@ The installer will quit and all changes will be lost.</source>
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/keyboard/Config.cpp" line="506"/>
|
<location filename="../src/modules/keyboard/Config.cpp" line="504"/>
|
||||||
<source>Keyboard model has been set to %1<br/>.</source>
|
<source>Keyboard model has been set to %1.</source>
|
||||||
<comment>@label, %1 is keyboard model, as in Apple Magic Keyboard</comment>
|
<comment>@label, %1 is keyboard model, as in Apple Magic Keyboard</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/keyboard/Config.cpp" line="513"/>
|
<location filename="../src/modules/keyboard/Config.cpp" line="512"/>
|
||||||
<source>Keyboard layout has been set to %1/%2.</source>
|
<source>Keyboard layout has been set to %1/%2.</source>
|
||||||
<comment>@label, %1 is layout, %2 is layout variant</comment>
|
<comment>@label, %1 is layout, %2 is layout variant</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/locale/Config.cpp" line="379"/>
|
<location filename="../src/modules/locale/Config.cpp" line="381"/>
|
||||||
<source>Set timezone to %1/%2</source>
|
<source>Set timezone to %1.</source>
|
||||||
<comment>@action</comment>
|
<comment>@action</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/locale/Config.cpp" line="416"/>
|
<location filename="../src/modules/locale/Config.cpp" line="418"/>
|
||||||
<source>The system language will be set to %1.</source>
|
<source>The system language will be set to %1.</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/locale/Config.cpp" line="423"/>
|
<location filename="../src/modules/locale/Config.cpp" line="425"/>
|
||||||
<source>The numbers and dates locale will be set to %1.</source>
|
<source>The numbers and dates locale will be set to %1.</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
@ -2281,7 +2281,7 @@ The installer will quit and all changes will be lost.</source>
|
|||||||
<context>
|
<context>
|
||||||
<name>LocaleTests</name>
|
<name>LocaleTests</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/libcalamares/locale/Tests.cpp" line="266"/>
|
<location filename="../src/libcalamares/locale/Tests.cpp" line="272"/>
|
||||||
<source>Quit</source>
|
<source>Quit</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
@ -3246,174 +3246,179 @@ The installer will quit and all changes will be lost.</source>
|
|||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="143"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="144"/>
|
||||||
<source>Install %1 <strong>alongside</strong> another operating system</source>
|
<source>Install %1 <strong>alongside</strong> another operating system</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="147"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="148"/>
|
||||||
<source><strong>Erase</strong> disk and install %1</source>
|
<source><strong>Erase</strong> disk and install %1</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="151"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="152"/>
|
||||||
<source><strong>Replace</strong> a partition with %1</source>
|
<source><strong>Replace</strong> a partition with %1</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="156"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="157"/>
|
||||||
<source><strong>Manual</strong> partitioning</source>
|
<source><strong>Manual</strong> partitioning</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="178"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="179"/>
|
||||||
<source>Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3)</source>
|
<source>Install %1 <strong>alongside</strong> another operating system on disk <strong>%2</strong> (%3)</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="187"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="188"/>
|
||||||
<source><strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1</source>
|
<source><strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="194"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="195"/>
|
||||||
<source><strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1</source>
|
<source><strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="203"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="204"/>
|
||||||
<source><strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2)</source>
|
<source><strong>Manual</strong> partitioning on disk <strong>%1</strong> (%2)</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="213"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="214"/>
|
||||||
<source>Disk <strong>%1</strong> (%2)</source>
|
<source>Disk <strong>%1</strong> (%2)</source>
|
||||||
<comment>@info</comment>
|
<comment>@info</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="263"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="239"/>
|
||||||
|
<source>Create a swap file.</source>
|
||||||
|
<translation type="unfinished"/>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="268"/>
|
||||||
<source>Unsafe partition actions are enabled.</source>
|
<source>Unsafe partition actions are enabled.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="266"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="271"/>
|
||||||
<source>Partitioning is configured to <b>always</b> fail.</source>
|
<source>Partitioning is configured to <b>always</b> fail.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="269"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="274"/>
|
||||||
<source>No partitions will be changed.</source>
|
<source>No partitions will be changed.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="309"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="314"/>
|
||||||
<source>Current:</source>
|
<source>Current:</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="327"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="332"/>
|
||||||
<source>After:</source>
|
<source>After:</source>
|
||||||
<comment>@label</comment>
|
<comment>@label</comment>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="550"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="555"/>
|
||||||
<source>An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem.</source>
|
<source>An EFI system partition is necessary to start %1.<br/><br/>To configure an EFI system partition, go back and select or create a suitable filesystem.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="556"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="561"/>
|
||||||
<source>An EFI system partition is necessary to start %1.<br/><br/>The EFI system partition does not meet recommendations. It is recommended to go back and select or create a suitable filesystem.</source>
|
<source>An EFI system partition is necessary to start %1.<br/><br/>The EFI system partition does not meet recommendations. It is recommended to go back and select or create a suitable filesystem.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="564"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="569"/>
|
||||||
<source>The filesystem must be mounted on <strong>%1</strong>.</source>
|
<source>The filesystem must be mounted on <strong>%1</strong>.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="565"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="570"/>
|
||||||
<source>The filesystem must have type FAT32.</source>
|
<source>The filesystem must have type FAT32.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="566"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="571"/>
|
||||||
<source>The filesystem must have flag <strong>%1</strong> set.</source>
|
<source>The filesystem must have flag <strong>%1</strong> set.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="574"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="579"/>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="576"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="581"/>
|
||||||
<source>The filesystem must be at least %1 MiB in size.</source>
|
<source>The filesystem must be at least %1 MiB in size.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="578"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="583"/>
|
||||||
<source>The minimum recommended size for the filesystem is %1 MiB.</source>
|
<source>The minimum recommended size for the filesystem is %1 MiB.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="580"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="585"/>
|
||||||
<source>You can continue without setting up an EFI system partition but your system may fail to start.</source>
|
<source>You can continue without setting up an EFI system partition but your system may fail to start.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="582"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="587"/>
|
||||||
<source>You can continue with this EFI system partition configuration but your system may fail to start.</source>
|
<source>You can continue with this EFI system partition configuration but your system may fail to start.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="594"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="599"/>
|
||||||
<source>No EFI system partition configured</source>
|
<source>No EFI system partition configured</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="602"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="607"/>
|
||||||
<source>EFI system partition configured incorrectly</source>
|
<source>EFI system partition configured incorrectly</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="622"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="627"/>
|
||||||
<source>EFI system partition recommendation</source>
|
<source>EFI system partition recommendation</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="641"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="646"/>
|
||||||
<source>Option to use GPT on BIOS</source>
|
<source>Option to use GPT on BIOS</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="642"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="647"/>
|
||||||
<source>A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>%2</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT.</source>
|
<source>A GPT partition table is the best option for all systems. This installer supports such a setup for BIOS systems too.<br/><br/>To configure a GPT partition table on BIOS, (if not done so already) go back and set the partition table to GPT, next create a 8 MB unformatted partition with the <strong>%2</strong> flag enabled.<br/><br/>An unformatted 8 MB partition is necessary to start %1 on a BIOS system with GPT.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="664"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="669"/>
|
||||||
<source>Boot partition not encrypted</source>
|
<source>Boot partition not encrypted</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="665"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="670"/>
|
||||||
<source>A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window.</source>
|
<source>A separate boot partition was set up together with an encrypted root partition, but the boot partition is not encrypted.<br/><br/>There are security concerns with this kind of setup, because important system files are kept on an unencrypted partition.<br/>You may continue if you wish, but filesystem unlocking will happen later during system startup.<br/>To encrypt the boot partition, go back and recreate it, selecting <strong>Encrypt</strong> in the partition creation window.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="757"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="762"/>
|
||||||
<source>has at least one disk device available.</source>
|
<source>has at least one disk device available.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="758"/>
|
<location filename="../src/modules/partition/PartitionViewStep.cpp" line="763"/>
|
||||||
<source>There are no partitions to install on.</source>
|
<source>There are no partitions to install on.</source>
|
||||||
<translation type="unfinished"/>
|
<translation type="unfinished"/>
|
||||||
</message>
|
</message>
|
||||||
|
@ -8,7 +8,7 @@ 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: 2024-07-03 22:44+0200\n"
|
"POT-Creation-Date: 2024-09-06 14:34+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"
|
||||||
@ -230,24 +230,24 @@ msgid_plural "Removing %(num)d packages."
|
|||||||
msgstr[0] ""
|
msgstr[0] ""
|
||||||
msgstr[1] ""
|
msgstr[1] ""
|
||||||
|
|
||||||
#: src/modules/packages/main.py:769 src/modules/packages/main.py:781
|
#: src/modules/packages/main.py:775 src/modules/packages/main.py:787
|
||||||
#: src/modules/packages/main.py:809
|
#: src/modules/packages/main.py:815
|
||||||
msgid "Package Manager error"
|
msgid "Package Manager error"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/modules/packages/main.py:770
|
#: src/modules/packages/main.py:776
|
||||||
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 ""
|
||||||
|
|
||||||
#: src/modules/packages/main.py:782
|
#: src/modules/packages/main.py:788
|
||||||
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 ""
|
||||||
|
|
||||||
#: src/modules/packages/main.py:810
|
#: src/modules/packages/main.py:816
|
||||||
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}."
|
||||||
|
@ -236,7 +236,7 @@ if(KPMcore_FOUND)
|
|||||||
calamares_add_test(libcalamarespartitionkpmtest SOURCES partition/KPMTests.cpp LIBRARIES calamares::kpmcore)
|
calamares_add_test(libcalamarespartitionkpmtest SOURCES partition/KPMTests.cpp LIBRARIES calamares::kpmcore)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
calamares_add_test(libcalamaresutilstest SOURCES utils/Tests.cpp utils/Runner.cpp)
|
calamares_add_test(libcalamaresutilstest SOURCES utils/Tests.cpp utils/Permissions.cpp utils/Runner.cpp)
|
||||||
|
|
||||||
calamares_add_test(libcalamaresutilspathstest SOURCES utils/TestPaths.cpp)
|
calamares_add_test(libcalamaresutilspathstest SOURCES utils/TestPaths.cpp)
|
||||||
|
|
||||||
|
@ -60,9 +60,12 @@ public:
|
|||||||
TimeZoneData( const TimeZoneData& ) = delete;
|
TimeZoneData( const TimeZoneData& ) = delete;
|
||||||
TimeZoneData( TimeZoneData&& ) = delete;
|
TimeZoneData( TimeZoneData&& ) = delete;
|
||||||
|
|
||||||
|
///@brief Returns a translated, human-readable form of region/zone (e.g. "America/New York")
|
||||||
QString translated() const override;
|
QString translated() const override;
|
||||||
|
|
||||||
|
///@brief Returns the region key (e.g. "Europe") with no translation and no human-readable tweaks
|
||||||
QString region() const { return m_region; }
|
QString region() const { return m_region; }
|
||||||
|
///@brief Returns the zone key (e.g. "New_York") with no translation and no human-readable tweaks
|
||||||
QString zone() const { return key(); }
|
QString zone() const { return key(); }
|
||||||
|
|
||||||
QString country() const { return m_country; }
|
QString country() const { return m_country; }
|
||||||
|
@ -50,9 +50,8 @@ Permissions::parsePermissions( QString const& p )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok;
|
const auto octal = parseFileMode( segments[ 2 ] );
|
||||||
int octal = segments[ 2 ].toInt( &ok, 8 );
|
if ( octal <= 0 )
|
||||||
if ( !ok || octal == 0 )
|
|
||||||
{
|
{
|
||||||
m_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
@ -120,4 +119,24 @@ Permissions::apply( const QString& path, const Calamares::Permissions& p )
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parseFileMode( const QString& mode )
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
int octal = mode.toInt( &ok, 8 );
|
||||||
|
if ( !ok )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( 0777 < octal )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( octal < 0 )
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return octal;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -16,8 +16,10 @@ namespace Calamares
|
|||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The Permissions class takes a QString @p in the form of
|
* @brief Represents a <user>:<group>:<file-mode>
|
||||||
* <user>:<group>:<permissions>, checks it for validity, and makes the three
|
*
|
||||||
|
* The Permissions class takes a QString @p in the form of
|
||||||
|
* <user>:<group>:<file-mode>, checks it for validity, and makes the three
|
||||||
* components available indivdually.
|
* components available indivdually.
|
||||||
*/
|
*/
|
||||||
class DLLEXPORT Permissions
|
class DLLEXPORT Permissions
|
||||||
@ -27,8 +29,9 @@ public:
|
|||||||
/** @brief Constructor
|
/** @brief Constructor
|
||||||
*
|
*
|
||||||
* Splits the string @p at the colon (":") into separate elements for
|
* Splits the string @p at the colon (":") into separate elements for
|
||||||
* <user>, <group>, and <value> (permissions), where <value> is interpreted
|
* <user>, <group>, and <file-mode> (permissions), where <file-mode> is any
|
||||||
* as an **octal** integer. That is, "root:wheel:755" will give
|
* value that can be parsed by parseFileMode() . One valid form
|
||||||
|
* is an **octal** integer. That is, "root:wheel:755" will give
|
||||||
* you an integer value of four-hundred-ninety-three (493),
|
* you an integer value of four-hundred-ninety-three (493),
|
||||||
* corresponding to the UNIX file permissions rwxr-xr-x,
|
* corresponding to the UNIX file permissions rwxr-xr-x,
|
||||||
* as one would expect from chmod and other command-line utilities.
|
* as one would expect from chmod and other command-line utilities.
|
||||||
@ -90,6 +93,17 @@ private:
|
|||||||
bool m_valid;
|
bool m_valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parses a file-mode and returns it as an integer
|
||||||
|
*
|
||||||
|
* Returns -1 on error.
|
||||||
|
*
|
||||||
|
* Valid forms of @p mode are:
|
||||||
|
* - octal representation, with an optional leading 0 and at most three
|
||||||
|
* octal digits (e.g. 0755 or 644)
|
||||||
|
*/
|
||||||
|
DLLEXPORT int parseFileMode( const QString& mode );
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
|
||||||
#endif // LIBCALAMARES_PERMISSIONS_H
|
#endif // LIBCALAMARES_PERMISSIONS_H
|
||||||
|
@ -63,6 +63,7 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
/** @section Test that all the UMask objects work correctly. */
|
/** @section Test that all the UMask objects work correctly. */
|
||||||
void testUmask();
|
void testUmask();
|
||||||
|
void testPermissions();
|
||||||
|
|
||||||
/** @section Tests the entropy functions. */
|
/** @section Tests the entropy functions. */
|
||||||
void testEntropy();
|
void testEntropy();
|
||||||
@ -571,6 +572,24 @@ LibCalamaresTests::testUmask()
|
|||||||
QCOMPARE( Calamares::setUMask( m ), mode_t( 022 ) );
|
QCOMPARE( Calamares::setUMask( m ), mode_t( 022 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LibCalamaresTests::testPermissions()
|
||||||
|
{
|
||||||
|
for ( int i = 0; i <= 0777; ++i )
|
||||||
|
{
|
||||||
|
const QString repr = QString::number( i, 8 );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( repr ), i );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QChar( '0' ) + repr ), i );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QStringLiteral( " %1\n" ).arg( repr ) ), i );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failures
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "1024" ) ), -1 );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "rwxr-----" ) ), -1 );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "o644" ) ), -1 );
|
||||||
|
QCOMPARE( Calamares::parseFileMode( QStringLiteral( "O_WRONLY" ) ), -1 );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
LibCalamaresTests::testEntropy()
|
LibCalamaresTests::testEntropy()
|
||||||
{
|
{
|
||||||
|
@ -11,19 +11,37 @@
|
|||||||
#include "WaitingWidget.h"
|
#include "WaitingWidget.h"
|
||||||
|
|
||||||
#include "utils/Gui.h"
|
#include "utils/Gui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
|
#include <QEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
|
static void
|
||||||
|
colorSpinner( WaitingSpinnerWidget* spinner )
|
||||||
|
{
|
||||||
|
const auto color = spinner->palette().text().color();
|
||||||
|
spinner->setTextColor( color );
|
||||||
|
spinner->setColor( color );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
styleSpinner( WaitingSpinnerWidget* spinner, int size )
|
||||||
|
{
|
||||||
|
spinner->setFixedSize( size, size );
|
||||||
|
spinner->setInnerRadius( size / 2 );
|
||||||
|
spinner->setLineLength( size / 2 );
|
||||||
|
spinner->setLineWidth( size / 8 );
|
||||||
|
colorSpinner( spinner );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
WaitingWidget::WaitingWidget( const QString& text, QWidget* parent )
|
WaitingWidget::WaitingWidget( const QString& text, QWidget* parent )
|
||||||
: WaitingSpinnerWidget( parent, false, false )
|
: WaitingSpinnerWidget( parent, false, false )
|
||||||
{
|
{
|
||||||
int spnrSize = Calamares::defaultFontHeight() * 4;
|
int spnrSize = Calamares::defaultFontHeight() * 4;
|
||||||
setFixedSize( spnrSize, spnrSize );
|
styleSpinner( this, spnrSize );
|
||||||
setInnerRadius( spnrSize / 2 );
|
|
||||||
setLineLength( spnrSize / 2 );
|
|
||||||
setLineWidth( spnrSize / 8 );
|
|
||||||
setAlignment( Qt::AlignmentFlag::AlignBottom );
|
setAlignment( Qt::AlignmentFlag::AlignBottom );
|
||||||
setText( text );
|
setText( text );
|
||||||
start();
|
start();
|
||||||
@ -31,6 +49,16 @@ WaitingWidget::WaitingWidget( const QString& text, QWidget* parent )
|
|||||||
|
|
||||||
WaitingWidget::~WaitingWidget() {}
|
WaitingWidget::~WaitingWidget() {}
|
||||||
|
|
||||||
|
void
|
||||||
|
WaitingWidget::changeEvent( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::PaletteChange )
|
||||||
|
{
|
||||||
|
colorSpinner( this );
|
||||||
|
}
|
||||||
|
WaitingSpinnerWidget::changeEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
struct CountdownWaitingWidget::Private
|
struct CountdownWaitingWidget::Private
|
||||||
{
|
{
|
||||||
std::chrono::seconds duration;
|
std::chrono::seconds duration;
|
||||||
@ -52,13 +80,8 @@ CountdownWaitingWidget::CountdownWaitingWidget( std::chrono::seconds duration, Q
|
|||||||
{
|
{
|
||||||
// Set up the label first for sizing
|
// Set up the label first for sizing
|
||||||
const int labelHeight = qBound( 16, Calamares::defaultFontHeight() * 3 / 2, 64 );
|
const int labelHeight = qBound( 16, Calamares::defaultFontHeight() * 3 / 2, 64 );
|
||||||
|
styleSpinner( this, labelHeight );
|
||||||
// Set up the spinner
|
|
||||||
setFixedSize( labelHeight, labelHeight );
|
|
||||||
setRevolutionsPerSecond( 1.0 / double( duration.count() ) );
|
setRevolutionsPerSecond( 1.0 / double( duration.count() ) );
|
||||||
setInnerRadius( labelHeight / 2 );
|
|
||||||
setLineLength( labelHeight / 2 );
|
|
||||||
setLineWidth( labelHeight / 8 );
|
|
||||||
setAlignment( Qt::AlignmentFlag::AlignVCenter );
|
setAlignment( Qt::AlignmentFlag::AlignVCenter );
|
||||||
|
|
||||||
// Last because it updates the text
|
// Last because it updates the text
|
||||||
@ -117,3 +140,13 @@ CountdownWaitingWidget::tick()
|
|||||||
timeout();
|
timeout();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CountdownWaitingWidget::changeEvent( QEvent* event )
|
||||||
|
{
|
||||||
|
if ( event->type() == QEvent::PaletteChange )
|
||||||
|
{
|
||||||
|
colorSpinner( this );
|
||||||
|
}
|
||||||
|
WaitingSpinnerWidget::changeEvent( event );
|
||||||
|
}
|
||||||
|
@ -32,6 +32,9 @@ public:
|
|||||||
/// Create a WaitingWidget with initial @p text label.
|
/// Create a WaitingWidget with initial @p text label.
|
||||||
explicit WaitingWidget( const QString& text, QWidget* parent = nullptr );
|
explicit WaitingWidget( const QString& text, QWidget* parent = nullptr );
|
||||||
~WaitingWidget() override;
|
~WaitingWidget() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent( QEvent* event ) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @brief A spinner and a countdown inside it
|
/** @brief A spinner and a countdown inside it
|
||||||
@ -64,6 +67,9 @@ Q_SIGNALS:
|
|||||||
protected Q_SLOTS:
|
protected Q_SLOTS:
|
||||||
void tick();
|
void tick();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void changeEvent( QEvent* event ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Private;
|
struct Private;
|
||||||
std::unique_ptr< Private > d;
|
std::unique_ptr< Private > d;
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
#include "SetKeyboardLayoutJob.h"
|
#include "SetKeyboardLayoutJob.h"
|
||||||
#include "keyboardwidget/keyboardpreview.h"
|
|
||||||
|
|
||||||
#include "GlobalStorage.h"
|
#include "GlobalStorage.h"
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
@ -27,6 +26,7 @@
|
|||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#include <QDBusConnection>
|
#include <QDBusConnection>
|
||||||
@ -36,7 +36,7 @@
|
|||||||
/* Returns stringlist with suitable setxkbmap command-line arguments
|
/* Returns stringlist with suitable setxkbmap command-line arguments
|
||||||
* to set the given @p model.
|
* to set the given @p model.
|
||||||
*/
|
*/
|
||||||
static inline QStringList
|
static QStringList
|
||||||
xkbmap_model_args( const QString& model )
|
xkbmap_model_args( const QString& model )
|
||||||
{
|
{
|
||||||
QStringList r { "-model", model };
|
QStringList r { "-model", model };
|
||||||
@ -46,7 +46,7 @@ xkbmap_model_args( const QString& model )
|
|||||||
/* Returns stringlist with suitable setxkbmap command-line arguments
|
/* Returns stringlist with suitable setxkbmap command-line arguments
|
||||||
* to set the given @p layout and @p variant.
|
* to set the given @p layout and @p variant.
|
||||||
*/
|
*/
|
||||||
static inline QStringList
|
static QStringList
|
||||||
xkbmap_layout_args( const QString& layout, const QString& variant )
|
xkbmap_layout_args( const QString& layout, const QString& variant )
|
||||||
{
|
{
|
||||||
QStringList r { "-layout", layout };
|
QStringList r { "-layout", layout };
|
||||||
@ -57,10 +57,10 @@ xkbmap_layout_args( const QString& layout, const QString& variant )
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QStringList
|
static QStringList
|
||||||
xkbmap_layout_args( const QStringList& layouts,
|
xkbmap_layout_args_with_group_switch( const QStringList& layouts,
|
||||||
const QStringList& variants,
|
const QStringList& variants,
|
||||||
const QString& switchOption = "grp:alt_shift_toggle" )
|
const QString& switchOption )
|
||||||
{
|
{
|
||||||
if ( layouts.size() != variants.size() )
|
if ( layouts.size() != variants.size() )
|
||||||
{
|
{
|
||||||
@ -161,24 +161,16 @@ Config::Config( QObject* parent )
|
|||||||
, m_keyboardVariantsModel( new KeyboardVariantsModel( this ) )
|
, m_keyboardVariantsModel( new KeyboardVariantsModel( this ) )
|
||||||
, m_KeyboardGroupSwitcherModel( new KeyboardGroupsSwitchersModel( this ) )
|
, m_KeyboardGroupSwitcherModel( new KeyboardGroupsSwitchersModel( this ) )
|
||||||
{
|
{
|
||||||
m_setxkbmapTimer.setSingleShot( true );
|
m_applyTimer.setSingleShot( true );
|
||||||
|
connect( &m_applyTimer, &QTimer::timeout, this, &Config::apply );
|
||||||
|
|
||||||
// Connect signals and slots
|
// Connect signals and slots
|
||||||
connect( m_keyboardModelsModel,
|
connect( m_keyboardModelsModel,
|
||||||
&KeyboardModelsModel::currentIndexChanged,
|
&KeyboardModelsModel::currentIndexChanged,
|
||||||
[ & ]( int index )
|
[ & ]( int index )
|
||||||
{
|
{
|
||||||
// Set Xorg keyboard model
|
|
||||||
m_selectedModel = m_keyboardModelsModel->key( index );
|
m_selectedModel = m_keyboardModelsModel->key( index );
|
||||||
if ( m_useLocale1 )
|
somethingChanged();
|
||||||
{
|
|
||||||
locale1Apply();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QProcess::execute( "setxkbmap", xkbmap_model_args( m_selectedModel ) );
|
|
||||||
}
|
|
||||||
emit prettyStatusChanged();
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
connect( m_keyboardLayoutsModel,
|
connect( m_keyboardLayoutsModel,
|
||||||
@ -195,16 +187,14 @@ Config::Config( QObject* parent )
|
|||||||
[ & ]( int index )
|
[ & ]( int index )
|
||||||
{
|
{
|
||||||
m_selectedVariant = m_keyboardVariantsModel->key( index );
|
m_selectedVariant = m_keyboardVariantsModel->key( index );
|
||||||
xkbChanged();
|
somethingChanged();
|
||||||
emit prettyStatusChanged();
|
|
||||||
} );
|
} );
|
||||||
connect( m_KeyboardGroupSwitcherModel,
|
connect( m_KeyboardGroupSwitcherModel,
|
||||||
&KeyboardGroupsSwitchersModel::currentIndexChanged,
|
&KeyboardGroupsSwitchersModel::currentIndexChanged,
|
||||||
[ & ]( int index )
|
[ & ]( int index )
|
||||||
{
|
{
|
||||||
m_selectedGroup = m_KeyboardGroupSwitcherModel->key( index );
|
m_selectedGroup = m_KeyboardGroupSwitcherModel->key( index );
|
||||||
xkbChanged();
|
somethingChanged();
|
||||||
emit prettyStatusChanged();
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
// If the user picks something explicitly -- not a consequence of
|
// If the user picks something explicitly -- not a consequence of
|
||||||
@ -224,30 +214,36 @@ Config::Config( QObject* parent )
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::xkbChanged()
|
Config::somethingChanged()
|
||||||
{
|
{
|
||||||
// Set Xorg keyboard layout + variant
|
if ( m_applyTimer.isActive() )
|
||||||
if ( m_setxkbmapTimer.isActive() )
|
|
||||||
{
|
{
|
||||||
m_setxkbmapTimer.stop();
|
m_applyTimer.stop();
|
||||||
m_setxkbmapTimer.disconnect( this );
|
|
||||||
}
|
}
|
||||||
|
m_applyTimer.start( QApplication::keyboardInputInterval() );
|
||||||
if ( m_useLocale1 )
|
|
||||||
{
|
|
||||||
connect( &m_setxkbmapTimer, &QTimer::timeout, this, &Config::locale1Apply );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
connect( &m_setxkbmapTimer, &QTimer::timeout, this, &Config::xkbApply );
|
|
||||||
}
|
|
||||||
|
|
||||||
m_setxkbmapTimer.start( QApplication::keyboardInputInterval() );
|
|
||||||
emit prettyStatusChanged();
|
emit prettyStatusChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::locale1Apply()
|
Config::apply()
|
||||||
|
{
|
||||||
|
if ( m_configureXkb )
|
||||||
|
{
|
||||||
|
applyXkb();
|
||||||
|
}
|
||||||
|
if ( m_configureLocale1 )
|
||||||
|
{
|
||||||
|
applyLocale1();
|
||||||
|
}
|
||||||
|
if ( m_configureKWin )
|
||||||
|
{
|
||||||
|
applyKWin();
|
||||||
|
}
|
||||||
|
// Writing /etc/ files is not needed "live"
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::applyLocale1()
|
||||||
{
|
{
|
||||||
m_additionalLayoutInfo = getAdditionalLayoutInfo( m_selectedLayout );
|
m_additionalLayoutInfo = getAdditionalLayoutInfo( m_selectedLayout );
|
||||||
|
|
||||||
@ -283,10 +279,11 @@ Config::locale1Apply()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::xkbApply()
|
Config::applyXkb()
|
||||||
{
|
{
|
||||||
m_additionalLayoutInfo = getAdditionalLayoutInfo( m_selectedLayout );
|
m_additionalLayoutInfo = getAdditionalLayoutInfo( m_selectedLayout );
|
||||||
|
|
||||||
|
QStringList basicArguments = xkbmap_model_args( m_selectedModel );
|
||||||
if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() )
|
if ( !m_additionalLayoutInfo.additionalLayout.isEmpty() )
|
||||||
{
|
{
|
||||||
if ( !m_selectedGroup.isEmpty() )
|
if ( !m_selectedGroup.isEmpty() )
|
||||||
@ -303,10 +300,11 @@ Config::xkbApply()
|
|||||||
m_additionalLayoutInfo.groupSwitcher = "grp:alt_shift_toggle";
|
m_additionalLayoutInfo.groupSwitcher = "grp:alt_shift_toggle";
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcess::execute( "setxkbmap",
|
basicArguments.append(
|
||||||
xkbmap_layout_args( { m_additionalLayoutInfo.additionalLayout, m_selectedLayout },
|
xkbmap_layout_args_with_group_switch( { m_additionalLayoutInfo.additionalLayout, m_selectedLayout },
|
||||||
{ m_additionalLayoutInfo.additionalVariant, m_selectedVariant },
|
{ m_additionalLayoutInfo.additionalVariant, m_selectedVariant },
|
||||||
m_additionalLayoutInfo.groupSwitcher ) );
|
m_additionalLayoutInfo.groupSwitcher ) );
|
||||||
|
QProcess::execute( "setxkbmap", basicArguments );
|
||||||
|
|
||||||
cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant << "(added "
|
cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant << "(added "
|
||||||
<< m_additionalLayoutInfo.additionalLayout << "-" << m_additionalLayoutInfo.additionalVariant
|
<< m_additionalLayoutInfo.additionalLayout << "-" << m_additionalLayoutInfo.additionalVariant
|
||||||
@ -314,12 +312,92 @@ Config::xkbApply()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QProcess::execute( "setxkbmap", xkbmap_layout_args( m_selectedLayout, m_selectedVariant ) );
|
basicArguments.append( xkbmap_layout_args( m_selectedLayout, m_selectedVariant ) );
|
||||||
|
QProcess::execute( "setxkbmap", basicArguments );
|
||||||
cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant;
|
cDebug() << "xkbmap selection changed to: " << m_selectedLayout << '-' << m_selectedVariant;
|
||||||
}
|
}
|
||||||
m_setxkbmapTimer.disconnect( this );
|
m_applyTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// In a config-file's list of lines, replace lines <key>=<something> by <key>=<value>
|
||||||
|
static void
|
||||||
|
replaceKey( QStringList& content, const QString& key, const QString& value )
|
||||||
|
{
|
||||||
|
for ( int i = 0; i < content.length(); ++i )
|
||||||
|
{
|
||||||
|
if ( content.at( i ).startsWith( key ) )
|
||||||
|
{
|
||||||
|
content[ i ] = key + value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
rewriteKWin( const QString& path, const QString& model, const QString& layouts, const QString& variants )
|
||||||
|
{
|
||||||
|
if ( !QFile::exists( path ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile config( path );
|
||||||
|
if ( !config.open( QIODevice::ReadOnly ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QStringList content = []( QFile& f )
|
||||||
|
{
|
||||||
|
QTextStream s( &f );
|
||||||
|
return s.readAll().split( '\n' );
|
||||||
|
}( config );
|
||||||
|
config.close();
|
||||||
|
|
||||||
|
if ( !config.open( QIODevice::WriteOnly ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
replaceKey( content, QStringLiteral( "Model=" ), model );
|
||||||
|
replaceKey( content, QStringLiteral( "LayoutList=" ), layouts );
|
||||||
|
replaceKey( content, QStringLiteral( "VariantList=" ), variants );
|
||||||
|
|
||||||
|
config.write( content.join( '\n' ).toUtf8() );
|
||||||
|
config.close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::applyKWin()
|
||||||
|
{
|
||||||
|
const auto paths = QStandardPaths::standardLocations( QStandardPaths::ConfigLocation );
|
||||||
|
|
||||||
|
auto join = [ &additional = m_additionalLayoutInfo.additionalLayout ]( const QString& s1, const QString& s2 )
|
||||||
|
{ return additional.isEmpty() ? s1 : QStringLiteral( "%1,%2" ).arg( s1, s2 ); };
|
||||||
|
|
||||||
|
const QString layouts = join( m_selectedLayout, m_additionalLayoutInfo.additionalLayout );
|
||||||
|
const QString variants = join( m_selectedVariant, m_additionalLayoutInfo.additionalVariant );
|
||||||
|
|
||||||
|
bool updated = false;
|
||||||
|
for ( const auto& path : paths )
|
||||||
|
{
|
||||||
|
const QString candidate = path + QStringLiteral( "/kxkbrc" );
|
||||||
|
if ( rewriteKWin( candidate, m_selectedModel, layouts, variants ) )
|
||||||
|
{
|
||||||
|
updated = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( updated )
|
||||||
|
{
|
||||||
|
auto kwin = QDBusMessage::createSignal(
|
||||||
|
QStringLiteral( "/Layouts" ), QStringLiteral( "org.kde.keyboard" ), QStringLiteral( "reloadConfig" ) );
|
||||||
|
QDBusConnection::sessionBus().send( kwin );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
KeyboardModelsModel*
|
KeyboardModelsModel*
|
||||||
Config::keyboardModels() const
|
Config::keyboardModels() const
|
||||||
{
|
{
|
||||||
@ -455,7 +533,7 @@ Config::detectCurrentKeyboardLayout()
|
|||||||
QString currentVariant;
|
QString currentVariant;
|
||||||
QString currentModel;
|
QString currentModel;
|
||||||
|
|
||||||
if ( m_useLocale1 )
|
if ( m_configureLocale1 )
|
||||||
{
|
{
|
||||||
getCurrentKeyboardLayoutLocale1( currentLayout, currentVariant, currentModel );
|
getCurrentKeyboardLayoutLocale1( currentLayout, currentVariant, currentModel );
|
||||||
}
|
}
|
||||||
@ -501,10 +579,10 @@ Config::detectCurrentKeyboardLayout()
|
|||||||
QString
|
QString
|
||||||
Config::prettyStatus() const
|
Config::prettyStatus() const
|
||||||
{
|
{
|
||||||
QString status;
|
QString status
|
||||||
status
|
= tr( "Keyboard model has been set to %1.", "@label, %1 is keyboard model, as in Apple Magic Keyboard" )
|
||||||
+= tr( "Keyboard model has been set to %1<br/>.", "@label, %1 is keyboard model, as in Apple Magic Keyboard" )
|
.arg( m_keyboardModelsModel->label( m_keyboardModelsModel->currentIndex() ) );
|
||||||
.arg( m_keyboardModelsModel->label( m_keyboardModelsModel->currentIndex() ) );
|
status += QStringLiteral( "<br/>" );
|
||||||
|
|
||||||
QString layout = m_keyboardLayoutsModel->item( m_keyboardLayoutsModel->currentIndex() ).second.description;
|
QString layout = m_keyboardLayoutsModel->item( m_keyboardLayoutsModel->currentIndex() ).second.description;
|
||||||
QString variant = m_keyboardVariantsModel->currentIndex() >= 0
|
QString variant = m_keyboardVariantsModel->currentIndex() >= 0
|
||||||
@ -527,8 +605,8 @@ Config::createJobs()
|
|||||||
m_additionalLayoutInfo,
|
m_additionalLayoutInfo,
|
||||||
m_xOrgConfFileName,
|
m_xOrgConfFileName,
|
||||||
m_convertedKeymapPath,
|
m_convertedKeymapPath,
|
||||||
m_writeEtcDefaultKeyboard,
|
m_configureEtcDefaultKeyboard,
|
||||||
m_useLocale1 );
|
m_configureLocale1 );
|
||||||
list.append( Calamares::job_ptr( j ) );
|
list.append( Calamares::job_ptr( j ) );
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
@ -718,8 +796,13 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_xOrgConfFileName = xorgConfDefault;
|
m_xOrgConfFileName = xorgConfDefault;
|
||||||
}
|
}
|
||||||
m_convertedKeymapPath = getString( configurationMap, "convertedKeymapPath" );
|
m_convertedKeymapPath = getString( configurationMap, "convertedKeymapPath" );
|
||||||
m_writeEtcDefaultKeyboard = getBool( configurationMap, "writeEtcDefaultKeyboard", true );
|
m_configureEtcDefaultKeyboard = getBool( configurationMap, "writeEtcDefaultKeyboard", true );
|
||||||
m_useLocale1 = getBool( configurationMap, "useLocale1", !isX11 );
|
m_configureLocale1 = getBool( configurationMap, "useLocale1", !isX11 );
|
||||||
|
|
||||||
|
bool bogus = false;
|
||||||
|
const auto configureItems = getSubMap( configurationMap, "configure", bogus );
|
||||||
|
m_configureKWin = getBool( configureItems, "kwin", false );
|
||||||
|
|
||||||
m_guessLayout = getBool( configurationMap, "guessLayout", true );
|
m_guessLayout = getBool( configurationMap, "guessLayout", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,14 +86,17 @@ private:
|
|||||||
* keyboard layout. This introduces a slight delay between selecting
|
* keyboard layout. This introduces a slight delay between selecting
|
||||||
* a keyboard, and applying it to the system -- so that if you
|
* a keyboard, and applying it to the system -- so that if you
|
||||||
* scroll through or down-arrow through the list of keyboards,
|
* scroll through or down-arrow through the list of keyboards,
|
||||||
* you don't get buried under xkbset processes.
|
* you don't get buried under updates which might take some time.
|
||||||
*
|
*
|
||||||
* xkbChanged() is called when the selection changes, and triggers
|
* somethingChanged() is called when the selection changes, and triggers
|
||||||
* a delayed call to xkbApply() which does the actual work.
|
* a delayed call to apply() which does the actual work by calling the
|
||||||
|
* relevant apply*() functions.
|
||||||
*/
|
*/
|
||||||
void xkbChanged();
|
void somethingChanged();
|
||||||
void xkbApply();
|
void apply();
|
||||||
void locale1Apply();
|
void applyLocale1();
|
||||||
|
void applyXkb();
|
||||||
|
void applyKWin();
|
||||||
|
|
||||||
void getCurrentKeyboardLayoutXkb( QString& currentLayout, QString& currentVariant, QString& currentModel );
|
void getCurrentKeyboardLayoutXkb( QString& currentLayout, QString& currentVariant, QString& currentModel );
|
||||||
void getCurrentKeyboardLayoutLocale1( QString& currentLayout, QString& currentVariant, QString& currentModel );
|
void getCurrentKeyboardLayoutLocale1( QString& currentLayout, QString& currentVariant, QString& currentModel );
|
||||||
@ -111,13 +114,15 @@ private:
|
|||||||
// Layout (and corresponding info) added if current one doesn't support ASCII (e.g. Russian or Japanese)
|
// Layout (and corresponding info) added if current one doesn't support ASCII (e.g. Russian or Japanese)
|
||||||
AdditionalLayoutInfo m_additionalLayoutInfo;
|
AdditionalLayoutInfo m_additionalLayoutInfo;
|
||||||
|
|
||||||
QTimer m_setxkbmapTimer;
|
QTimer m_applyTimer;
|
||||||
|
|
||||||
// From configuration
|
// From configuration
|
||||||
QString m_xOrgConfFileName;
|
QString m_xOrgConfFileName;
|
||||||
QString m_convertedKeymapPath;
|
QString m_convertedKeymapPath;
|
||||||
bool m_writeEtcDefaultKeyboard = true;
|
bool m_configureXkb = true;
|
||||||
bool m_useLocale1 = false;
|
bool m_configureEtcDefaultKeyboard = true;
|
||||||
|
bool m_configureLocale1 = false;
|
||||||
|
bool m_configureKWin = false;
|
||||||
bool m_guessLayout = false;
|
bool m_guessLayout = false;
|
||||||
|
|
||||||
// The state determines whether we guess settings or preserve them:
|
// The state determines whether we guess settings or preserve them:
|
||||||
|
@ -31,3 +31,15 @@ convertedKeymapPath: "/lib/kbd/keymaps/xkb"
|
|||||||
# Guess the default layout from the user locale. If false, keeps the current
|
# Guess the default layout from the user locale. If false, keeps the current
|
||||||
# OS keyboard layout as the default (useful if the layout is pre-configured).
|
# OS keyboard layout as the default (useful if the layout is pre-configured).
|
||||||
#guessLayout: true
|
#guessLayout: true
|
||||||
|
|
||||||
|
# Things that should be configured.
|
||||||
|
configure:
|
||||||
|
# Configure KWin (KDE Plasma) directly by editing the
|
||||||
|
# configuration file and informing KWin over DBus. This is
|
||||||
|
# useful in a system that uses Wayland but does **not** connect
|
||||||
|
# locale1 with KWin.
|
||||||
|
#
|
||||||
|
# Systems that use KDE Plasma Wayland and locale1 can instead start the
|
||||||
|
# compositor KWin with command-line argument `--locale1`. That
|
||||||
|
# argument makes this configuration option unnecessary.
|
||||||
|
kwin: false
|
||||||
|
@ -11,4 +11,9 @@ properties:
|
|||||||
writeEtcDefaultKeyboard: { type: boolean, default: true }
|
writeEtcDefaultKeyboard: { type: boolean, default: true }
|
||||||
useLocale1: { type: boolean, default: false }
|
useLocale1: { type: boolean, default: false }
|
||||||
guessLayout: { type: boolean, default: true }
|
guessLayout: { type: boolean, default: true }
|
||||||
|
configure:
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
kwin: { type: boolean, default: false }
|
||||||
required: [ xOrgConfFileName, convertedKeymapPath ]
|
required: [ xOrgConfFileName, convertedKeymapPath ]
|
||||||
|
@ -376,9 +376,11 @@ Config::setLCLocaleExplicitly( const QString& locale )
|
|||||||
QString
|
QString
|
||||||
Config::currentLocationStatus() const
|
Config::currentLocationStatus() const
|
||||||
{
|
{
|
||||||
return tr( "Set timezone to %1/%2", "@action" )
|
if ( m_currentLocation )
|
||||||
.arg( m_currentLocation ? m_currentLocation->region() : QString(),
|
{
|
||||||
m_currentLocation ? m_currentLocation->zone() : QString() );
|
return tr( "Set timezone to %1.", "@action" ).arg( currentTimezoneName());
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
|
@ -78,6 +78,18 @@ unmountTargetMounts( const QString& rootMountPoint )
|
|||||||
.arg( m.device, m.mountPoint ) );
|
.arg( m.device, m.mountPoint ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Last we unmount the root
|
||||||
|
if ( Calamares::Partition::unmount( rootMountPoint, { "-lv" } ) )
|
||||||
|
{
|
||||||
|
return Calamares::JobResult::error(
|
||||||
|
QCoreApplication::translate( UmountJob::staticMetaObject.className(),
|
||||||
|
"Could not unmount the root of the target system." ),
|
||||||
|
QCoreApplication::translate( UmountJob::staticMetaObject.className(),
|
||||||
|
"The device mounted at '%1' could not be unmounted." )
|
||||||
|
.arg( rootMountPoint ) );
|
||||||
|
}
|
||||||
|
|
||||||
return Calamares::JobResult::ok();
|
return Calamares::JobResult::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +151,7 @@ UmountJob::exec()
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For ZFS systems, export the pools
|
// For ZFS systems, export the pools
|
||||||
{
|
{
|
||||||
auto r = exportZFSPools();
|
auto r = exportZFSPools();
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
#include "compat/Variant.h"
|
#include "compat/Variant.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Permissions.h"
|
||||||
#include "utils/String.h"
|
#include "utils/String.h"
|
||||||
#include "utils/StringExpander.h"
|
#include "utils/StringExpander.h"
|
||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
@ -946,6 +947,21 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_forbiddenLoginNames = Calamares::getStringList( userSettings, "forbidden_names" );
|
m_forbiddenLoginNames = Calamares::getStringList( userSettings, "forbidden_names" );
|
||||||
m_forbiddenLoginNames << alwaysForbiddenLoginNames();
|
m_forbiddenLoginNames << alwaysForbiddenLoginNames();
|
||||||
tidy( m_forbiddenLoginNames );
|
tidy( m_forbiddenLoginNames );
|
||||||
|
|
||||||
|
const auto permissionKey = QStringLiteral( "home_permissions" );
|
||||||
|
if ( userSettings.contains( permissionKey ) )
|
||||||
|
{
|
||||||
|
const auto value = Calamares::getString( userSettings, permissionKey );
|
||||||
|
m_homeDirPermissions = Calamares::parseFileMode( value );
|
||||||
|
if ( m_homeDirPermissions < 0 )
|
||||||
|
{
|
||||||
|
cWarning() << "Setting for" << permissionKey << '(' << value << userSettings[permissionKey] << ") is invalid.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_homeDirPermissions = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setAutoLoginGroup( either< QString, const QString& >(
|
setAutoLoginGroup( either< QString, const QString& >(
|
||||||
|
@ -259,6 +259,9 @@ public:
|
|||||||
const QStringList& forbiddenLoginNames() const;
|
const QStringList& forbiddenLoginNames() const;
|
||||||
const QStringList& forbiddenHostNames() const;
|
const QStringList& forbiddenHostNames() const;
|
||||||
|
|
||||||
|
int homePermissions() const { return m_homeDirPermissions; }
|
||||||
|
int homeUMask() const { return m_homeDirPermissions >= 0 ? ( ( ~m_homeDirPermissions ) & 0777 ) : -1; }
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/** @brief Sets the user's shell if possible
|
/** @brief Sets the user's shell if possible
|
||||||
*
|
*
|
||||||
@ -368,6 +371,8 @@ private:
|
|||||||
QStringList m_forbiddenLoginNames;
|
QStringList m_forbiddenLoginNames;
|
||||||
|
|
||||||
PasswordCheckList m_passwordChecks;
|
PasswordCheckList m_passwordChecks;
|
||||||
|
|
||||||
|
int m_homeDirPermissions = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -46,7 +46,7 @@ CreateUserJob::prettyStatusMessage() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Calamares::JobResult
|
static Calamares::JobResult
|
||||||
createUser( const QString& loginName, const QString& fullName, const QString& shell )
|
createUser( const QString& loginName, const QString& fullName, const QString& shell, int umask )
|
||||||
{
|
{
|
||||||
QStringList useraddCommand;
|
QStringList useraddCommand;
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
@ -67,6 +67,10 @@ createUser( const QString& loginName, const QString& fullName, const QString& sh
|
|||||||
useraddCommand << "-s" << shell;
|
useraddCommand << "-s" << shell;
|
||||||
}
|
}
|
||||||
useraddCommand << "-c" << fullName;
|
useraddCommand << "-c" << fullName;
|
||||||
|
if ( umask >= 0 )
|
||||||
|
{
|
||||||
|
useraddCommand << "-K" << ( QStringLiteral( "UMASK=" ) + QString::number( umask, 8 ) );
|
||||||
|
}
|
||||||
useraddCommand << loginName;
|
useraddCommand << loginName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -136,7 +140,8 @@ CreateUserJob::exec()
|
|||||||
|
|
||||||
m_status = tr( "Creating user %1…", "@status" ).arg( m_config->loginName() );
|
m_status = tr( "Creating user %1…", "@status" ).arg( m_config->loginName() );
|
||||||
emit progress( 0.5 );
|
emit progress( 0.5 );
|
||||||
auto useraddResult = createUser( m_config->loginName(), m_config->fullName(), m_config->userShell() );
|
auto useraddResult
|
||||||
|
= createUser( m_config->loginName(), m_config->fullName(), m_config->userShell(), m_config->homeUMask() );
|
||||||
if ( !useraddResult )
|
if ( !useraddResult )
|
||||||
{
|
{
|
||||||
return useraddResult;
|
return useraddResult;
|
||||||
|
@ -56,6 +56,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void testUserYAML_data();
|
void testUserYAML_data();
|
||||||
void testUserYAML();
|
void testUserYAML();
|
||||||
|
void testUserUmask_data();
|
||||||
|
void testUserUmask();
|
||||||
};
|
};
|
||||||
|
|
||||||
UserTests::UserTests() {}
|
UserTests::UserTests() {}
|
||||||
@ -511,6 +513,56 @@ UserTests::testUserYAML()
|
|||||||
QCOMPARE( c.userShell(), shell );
|
QCOMPARE( c.userShell(), shell );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTests::testUserUmask_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn< QString >( "filename" );
|
||||||
|
QTest::addColumn< int >( "permission" );
|
||||||
|
QTest::addColumn< int >( "umask" );
|
||||||
|
|
||||||
|
QTest::newRow( "good " ) << "tests/8a-issue-2362.conf" << 0700 << 0077;
|
||||||
|
QTest::newRow( "open " ) << "tests/8b-issue-2362.conf" << 0755 << 0022;
|
||||||
|
QTest::newRow( "weird" ) << "tests/8c-issue-2362.conf" << 0126 << 0651;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTests::testUserUmask()
|
||||||
|
{
|
||||||
|
static constexpr int no_permissions = -1;
|
||||||
|
const QString old_shell = QStringLiteral( "/bin/ls" );
|
||||||
|
const QString new_shell = QStringLiteral( "/usr/bin/new" );
|
||||||
|
const QStringList forbidden { QStringLiteral( "me" ), QStringLiteral( "myself" ), QStringLiteral( "moi" ) };
|
||||||
|
Config c;
|
||||||
|
c.setUserShell( old_shell );
|
||||||
|
QCOMPARE( c.homePermissions(), no_permissions );
|
||||||
|
QCOMPARE( c.homeUMask(), no_permissions );
|
||||||
|
|
||||||
|
QFETCH( QString, filename );
|
||||||
|
QFETCH( int, permission );
|
||||||
|
QFETCH( int, umask );
|
||||||
|
|
||||||
|
QCOMPARE( permission & umask, 0 );
|
||||||
|
QCOMPARE( permission | umask, 0777 );
|
||||||
|
|
||||||
|
QFileInfo fi( QString( "%1/%2" ).arg( BUILD_AS_TEST, filename ) );
|
||||||
|
QVERIFY( fi.exists() );
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
const auto map = Calamares::YAML::load( fi, &ok );
|
||||||
|
QVERIFY( ok );
|
||||||
|
QVERIFY( map.count() > 0 );
|
||||||
|
|
||||||
|
QCOMPARE( c.userShell(), old_shell );
|
||||||
|
c.setConfigurationMap( map );
|
||||||
|
QCOMPARE( c.userShell(), new_shell );
|
||||||
|
|
||||||
|
QCOMPARE( c.homePermissions(), permission );
|
||||||
|
QCOMPARE( c.homeUMask(), umask );
|
||||||
|
|
||||||
|
QCOMPARE( c.forbiddenLoginNames(), forbidden );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN( UserTests )
|
QTEST_GUILESS_MAIN( UserTests )
|
||||||
|
|
||||||
#include "utils/moc-warnings.h"
|
#include "utils/moc-warnings.h"
|
||||||
|
11
src/modules/users/tests/8a-issue-2362.conf
Normal file
11
src/modules/users/tests/8a-issue-2362.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
user:
|
||||||
|
shell: /usr/bin/new
|
||||||
|
forbidden_names:
|
||||||
|
- me
|
||||||
|
- myself
|
||||||
|
- moi
|
||||||
|
home_permissions: "700"
|
11
src/modules/users/tests/8b-issue-2362.conf
Normal file
11
src/modules/users/tests/8b-issue-2362.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
user:
|
||||||
|
shell: /usr/bin/new
|
||||||
|
forbidden_names:
|
||||||
|
- me
|
||||||
|
- myself
|
||||||
|
- moi
|
||||||
|
home_permissions: "755"
|
11
src/modules/users/tests/8c-issue-2362.conf
Normal file
11
src/modules/users/tests/8c-issue-2362.conf
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
---
|
||||||
|
user:
|
||||||
|
shell: /usr/bin/new
|
||||||
|
forbidden_names:
|
||||||
|
- me
|
||||||
|
- myself
|
||||||
|
- moi
|
||||||
|
home_permissions: "126"
|
@ -214,9 +214,15 @@ allowWeakPasswordsDefault: false
|
|||||||
# contains "root" and "nobody", but may be extended to list other special
|
# contains "root" and "nobody", but may be extended to list other special
|
||||||
# names for a given distro (eg. "video", or "mysql" might not be a valid
|
# names for a given distro (eg. "video", or "mysql" might not be a valid
|
||||||
# end-user login name).
|
# end-user login name).
|
||||||
|
# - *home_permissions* Home directory of the user is given **approximately**
|
||||||
|
# this set of permissions. Write the permissions in octal. If not set,
|
||||||
|
# there is no default and no permission-setting is done (uses defaults of
|
||||||
|
# `useradd` in the target). A umask is computed from these permissions
|
||||||
|
# and passed to `useradd`. Take care to quote the numeric value.
|
||||||
user:
|
user:
|
||||||
shell: /bin/bash
|
shell: /bin/bash
|
||||||
forbidden_names: [ root ]
|
forbidden_names: [ root ]
|
||||||
|
home_permissions: "0700"
|
||||||
|
|
||||||
|
|
||||||
# Hostname settings
|
# Hostname settings
|
||||||
|
@ -13,6 +13,7 @@ properties:
|
|||||||
# User shell, should be path to /bin/sh or so
|
# User shell, should be path to /bin/sh or so
|
||||||
shell: { type: string }
|
shell: { type: string }
|
||||||
forbidden_names: { type: array, items: { type: string } }
|
forbidden_names: { type: array, items: { type: string } }
|
||||||
|
home_permissions: { type: string }
|
||||||
# Group settings
|
# Group settings
|
||||||
defaultGroups:
|
defaultGroups:
|
||||||
type: array
|
type: array
|
||||||
|
@ -35,7 +35,7 @@ paintRequirement( QPainter* painter, const QStyleOptionViewItem& option, const Q
|
|||||||
|
|
||||||
Calamares::ImageType statusImage = Calamares::StatusOk;
|
Calamares::ImageType statusImage = Calamares::StatusOk;
|
||||||
|
|
||||||
painter->setPen( Qt::black );
|
painter->setPen( option.palette.text().color() );
|
||||||
if ( index.data( Calamares::RequirementsModel::Satisfied ).toBool() )
|
if ( index.data( Calamares::RequirementsModel::Satisfied ).toBool() )
|
||||||
{
|
{
|
||||||
painter->fillRect( textRect, option.palette.window().color() );
|
painter->fillRect( textRect, option.palette.window().color() );
|
||||||
|
Loading…
Reference in New Issue
Block a user