Compare commits

..

78 Commits

Author SHA1 Message Date
Adriaan de Groot
5d6375dab7 Changes: pre-release housekeeping 2022-01-18 12:50:47 +01:00
Adriaan de Groot
546780d7a8 Merge branch 'issue-1864' into calamares
FIXES #1864
2022-01-18 12:39:46 +01:00
Calamares CI
ac083f787d i18n: [python] Automatic merge of Transifex translations 2022-01-18 12:38:45 +01:00
Calamares CI
bca4b73677 i18n: [calamares] Automatic merge of Transifex translations 2022-01-18 12:38:45 +01:00
Adriaan de Groot
da2612d2d9 [locale] Update language even if there is a current location
- the first time we arrive at locale, there isn't a current location
  and the setCurrentLocation(...) method ends up calling setLanguage(),
  usually. The second time, this call is skipped (not called from
  the overloaded setCurrentLocation() which is called from onActivate),
  so the language didn't update.
- now call setLanguage() unless there has been one set explicitly.
2022-01-18 12:28:57 +01:00
Adriaan de Groot
08cd79f0c2 Merge pull request #1876 from dalto8/pacman-changes
[packages] Make pacman output more verbose
2022-01-18 12:24:41 +01:00
dalto
4811c59e33 [packages] Make pacman output more verbose 2022-01-17 16:24:56 -06:00
Adriaan de Groot
11f3f938d8 Merge pull request #1875 from dalto8/pacman-logs
[packages] Ensure all pacman output is available in debug log
2022-01-17 15:20:55 +01:00
Adriaan de Groot
85a3d1dc84 Changes: document locale fix 2022-01-17 15:15:20 +01:00
Adriaan de Groot
6101dd9079 [locale] Code style 2022-01-17 14:51:42 +01:00
tjpark88
79a91b486a [locale] Update language always
onActivate of locale updates the language only when currentLocation changed
or when onActivate of locale is called for the first time.
However, It is irrelevant solution since the language is set by the welcome.
So language should be updated always.
The language is used by keyboard module to guessing a layout of keyboard.
Once you face the locale, you can't change language in the welcome
if you don't change the timezone.
2022-01-17 14:51:42 +01:00
Adriaan de Groot
2aaaabe152 [partition] Set bigtime on XFS filesystems
FIXES #1874
2022-01-17 14:50:43 +01:00
Adriaan de Groot
a93126a6d0 [libcalamares] More meaningful name for JobResult success 2022-01-17 14:19:28 +01:00
dalto
112d0b2e90 [packages] Ensure all pacman output is available in debug log 2022-01-17 07:07:09 -06:00
Calamares CI
98bbc222cb i18n: [python] Automatic merge of Transifex translations 2022-01-17 13:50:42 +01:00
Calamares CI
fad23c9ac6 i18n: [calamares] Automatic merge of Transifex translations 2022-01-17 13:50:41 +01:00
Adriaan de Groot
e6813949af [libcalamares] Hook up Python's error() to error, rather than warning 2022-01-17 13:47:47 +01:00
Adriaan de Groot
4be932ff9d [umount] Now mark deprecated use as an error 2022-01-17 13:42:36 +01:00
Adriaan de Groot
8eb7eb8b1f Changes: remind about *umount* replacement 2022-01-17 12:51:03 +01:00
Adriaan de Groot
a8f6596d38 Merge branch 'issue-1870' into calamares
- Improve the error messages in general
- Warn specifically if there isn't an *unpack* key

FIXES #1870
2022-01-12 14:39:54 +01:00
Adriaan de Groot
b227419f01 Merge pull request #1871 from dalto8/zfsfix-initcpiocfg
[initcpiocfg] Only add zfs hook if zfs is enabled
2022-01-12 11:31:53 +01:00
Adriaan de Groot
da03e12b7b Merge pull request #1869 from dalto8/initramfs-fix
[initramfs] Fix condition when call to uname fails
2022-01-12 11:31:13 +01:00
Adriaan de Groot
f349a9c864 Changes: document new things 2022-01-12 11:28:34 +01:00
Adriaan de Groot
624bb13736 Merge pull request #1868 from dalto8/fix-initcpio
initcpio module fixes
2022-01-12 11:19:36 +01:00
Adriaan de Groot
94bca61491 Docs: be a little more explicit about emergency mode 2022-01-12 11:16:42 +01:00
Adriaan de Groot
ee2fea74df Merge pull request #1866 from dalto8/umount-emergency
[umount] Add support for umount to be an emergency module
2022-01-12 11:11:20 +01:00
dalto
1f9ae6cae6 [initcpiocfg] Only add zfshook if zfs is enabled 2022-01-07 14:49:26 -06:00
Adriaan de Groot
e14fa5de75 [unpackfs] Improve error messages
- the module is 'unpackfs', not 'unsquash'
- add a warning + specific error if there is no unpack key in the config
- the 'doing nothing' part isn't true: the module errors out instead
  of doing nothing.

SEE #1870
2022-01-06 23:51:18 +01:00
dalto
626ab98949 [initramfs] Fix condition when call to uname fails 2022-01-02 08:41:47 -06:00
dalto
3be6946d93 [initcpio] Minor documentation updates 2022-01-01 12:14:42 -06:00
dalto
475c0d21a1 [initcpio] Spell mkinitcpio properly 2022-01-01 10:48:48 -06:00
dalto
c2ae5fad96 [initcpio] Make implementation match config description and remove broken uname option 2022-01-01 10:05:00 -06:00
dalto
4fe5f1c06f [umount] Add support for umount to be an emergency module 2021-12-31 08:06:13 -06:00
Adriaan de Groot
4e61f24960 [partition] Tidy up iso9660 detection 2021-12-25 18:27:13 +01:00
Adriaan de Groot
1c853941dc Merge pull request #1863 from demmm/calamares
[luksopenswaphookcfg] set plugin name according to module name
2021-12-24 17:16:06 +01:00
demmm
7cfa654a68 [luksopenswaphookcfg] set plugin name according to module name
either this, or have all distros adjust settings.conf from luksopenswaphookcfg to luksopenswaphook
2021-12-22 22:17:13 +01:00
Adriaan de Groot
7864ab5cfa Docs: link to GPLv3+ 2021-12-21 01:02:13 +01:00
Adriaan de Groot
905f1241e3 Merge pull request #1861 from dalto8/readme-emergency
Update modules readme for Python emergency modules support
2021-12-19 23:53:35 +01:00
dalto
f0aba5db96 Update modules readme for Python emergency modules support 2021-12-19 15:29:42 -06:00
Adriaan de Groot
480fe56ae3 README, link to actual GPL 3.0 license
FIXES #1859
2021-12-19 14:03:21 +01:00
demmm
728315d3cc README, link to actual GPL 3.0 license
fixing https://github.com/calamares/calamares/issues/1859
2021-12-19 12:54:39 +01:00
Adriaan de Groot
da72e815dc [luksopenswaphookcfg] Fix build, missing include 2021-12-18 00:43:30 +01:00
Adriaan de Groot
0145f6fe7d CMake: language stats 2021-12-18 00:38:58 +01:00
Calamares CI
cfeba736d5 i18n: [python] Automatic merge of Transifex translations 2021-12-18 00:38:13 +01:00
Calamares CI
be18e51bc9 i18n: [calamares] Automatic merge of Transifex translations 2021-12-18 00:38:06 +01:00
Adriaan de Groot
7fc2859f23 [luksopenswaphookcfg] Port to C++
Merge pull request #1845 from calamares/issue-1659

FIXES #1659
FIXES #1644
2021-12-17 20:31:05 +01:00
Adriaan de Groot
587a18a6fa [partition] Use runCommand() for future-proofing 2021-12-14 12:50:27 +01:00
Adriaan de Groot
043619cd4b Merge branch 'improve-partition-reporting' into calamares
This strips out the === from KPMCore reports so that they are
more readable when presented in the error dialog. Introduces
some code-conveniences, too, but that is all under-the-hood.
2021-12-13 20:03:38 +01:00
Adriaan de Groot
f04394d014 [partition] Improve rendering of KPMCore errors 2021-12-13 20:02:52 +01:00
Adriaan de Groot
07354a26a9 [partition] Simplify debug calls to executables
- Use the Calamares support-functions for running lsblk and mount
  (these might need to have privilege support if Cala is not
  running as root, so this is future-proofing)
2021-12-13 20:02:52 +01:00
Adriaan de Groot
fdf0f208f0 [partition] Use lvalue-overload of execute() convenience
- These jobs may take a long time, and report progress; we need
  the operation around to be able to connect the signals and slots
2021-12-13 20:02:52 +01:00
Adriaan de Groot
6680584724 [partition] Use convenience function execute()
This job needs the lvalue-overload of execute() because it needs to
call a method on the operation after execute() finishes successfully.
2021-12-13 20:02:52 +01:00
Adriaan de Groot
c5573a1997 [partition] Add non-const lvalue overload for execute() 2021-12-13 20:02:52 +01:00
Adriaan de Groot
b8ce21d572 [partition] Use convenience function for running operations 2021-12-13 20:02:52 +01:00
Adriaan de Groot
1356012fb4 [partition] With rvalue, code becomes even more compact 2021-12-13 20:02:52 +01:00
Adriaan de Groot
8bb2c5fc6b [partition] Use convenience-method for running operation 2021-12-13 20:02:52 +01:00
Adriaan de Groot
dc7a1e43b7 [partition] Add helper for running a KPMCore operation
Most *partition* module jobs run an operation and turn that into
a JobResult -- ok if it succeeds, and with the report text otherwise.
Factor it out into a separate method that can be used as shorthand.
2021-12-13 20:02:52 +01:00
Adriaan de Groot
53c90516b2 Merge branch 'issue-1851' into calamares
FIXES #1851
2021-12-13 16:58:59 +01:00
Adriaan de Groot
d3ed5663d0 [preservefiles] Add a schema-file 2021-12-13 16:56:07 +01:00
Adriaan de Groot
778c2855f4 [preservefiles] Introduce the notion of optionally-preserved files 2021-12-13 16:34:38 +01:00
Adriaan de Groot
445ed870cc [preservefiles] Simplify code to help gcc warnings 2021-12-13 15:53:42 +01:00
Adriaan de Groot
3be52f8b37 [preservefiles] Expand tests with reading some existing config-items 2021-12-13 15:53:42 +01:00
Adriaan de Groot
a1b7ba0dc5 [preservefiles] Accessor for item-type (needed for tests) 2021-12-13 15:44:07 +01:00
Adriaan de Groot
8b5e49d980 [preservefiles] Add (stub) tests 2021-12-13 15:07:24 +01:00
Adriaan de Groot
90f6ea1fc8 [preservefiles] polish the documentation 2021-12-13 15:07:24 +01:00
Adriaan de Groot
238672ef78 [preservefiles] Split file-items into separate header
Put the Item class in a separate header; give it functionality
to create itself from Variants (e.g. from the configuration data)
and to run itself (do whatever the item is supposed to do).
This makes the polymorphic approach unnecessary: we just have
items that are sufficiently smart.

This moves do-a-thing to the Item, while the Job now has one
job: be a loop around creating Items and running items.
2021-12-13 15:05:05 +01:00
Adriaan de Groot
b1ecbb4151 [preservefiles] Start cleanup of structure, polymorphism 2021-12-13 15:05:05 +01:00
Adriaan de Groot
795b2c88e8 Merge pull request #1852 from killajoe/patch-1
[preservefiles] Fix typo in preservefiles.conf
2021-12-13 00:19:34 +01:00
Johannes Kamprad
becb1d5710 Update preservefiles.conf 2021-12-12 01:22:22 +01:00
arcolinuxz
5b225cf960 [preservefiles] Put the logs in /var/log 2021-12-11 23:58:23 +01:00
Adriaan de Groot
6261f8a5cb Changes: post-release housekeeping 2021-12-11 15:33:22 +01:00
Adriaan de Groot
132ebd2c2d [networkcfg] NetworkManager files are UTF-8 encoded
The filenames don't matter, but the contents of the file are also
UTF-8, and depending on the default encoding of the Python
interpreter, this can fail on non-ASCII characters in the
file. Set the encoding explicitly while reading and writing
the NetworkManager configuration files.

FIXES #1848
2021-12-11 15:12:51 +01:00
Adriaan de Groot
3870851074 [luksopenswaphookcfg] Remove Python implementation 2021-12-08 14:35:52 +01:00
Adriaan de Groot
046a228d62 [luksopenswaphookcfg] Expand tests with lines more-closely tailored to the actual file-format 2021-12-08 14:25:03 +01:00
Adriaan de Groot
2c20a00cc3 [luksopenswaphookcfg] Read GS for finding LUKS config 2021-12-08 14:12:25 +01:00
Adriaan de Groot
45d6eb36fb [luksopenswaphookcfg] Extend info with btrfs subvol
This is a C++-ification of e8936392 from dalto8 . Add a line
for options to the empty-file-fallback.
2021-12-08 14:12:25 +01:00
Adriaan de Groot
7ea21663ca [luksopenswaphookcfg] Partial implementation in C++
- Futz a bit with the string replacements -- do not assume #
  will introduce a comment half-way through a line.
2021-12-08 14:12:20 +01:00
Adriaan de Groot
5ca029df25 [luksopenswaphookcfg] Start a C++ port
- this module needs work to handle BTRFS special-cases *anyway*
- limited in scope, few options: port it while doing the
  special-cases

So far, this is just a C++ stub.

SEE #1659 #1644
2021-12-08 14:12:20 +01:00
71 changed files with 10913 additions and 609 deletions

View File

@@ -7,6 +7,44 @@ contributors are listed. Note that Calamares does not have a historical
changelog -- this log starts with version 3.2.0. The release notes on the
website will have to do for older versions.
# 3.2.50 (2022-01-18) #
This release contains contributions from (alphabetically by first name):
- Anke Boersma
- Erik Dubois
- Evan James
- Johannes Kamprad
- Taejun Park (new contributor, welcome!)
**Replacement notice:** The *umount* module will be replaced by a C++
implementation in the next release. The "preserve log file" feature
will be removed in that release. Use the *preservefiles* module instead.
## Core ##
- No core changes yet
## Modules ##
- *initcpiocfg* mentioned a special kernel-name "all", which did not work,
and a special kernel-name "$uname" which cannot work. Fixed the former
and removed the "$uname" special key. (Thanks Evan)
- *luksswaphookcfg* has been converted to a C++ module.
- *networkcfg* could fail to update the NetworkManager configuration
if the SSID or username contained non-ASCII characters **and** the
default Python text-file encoding was set to ASCII. The files are
now read and written in UTF-8, explicitly. #1848
- *partition* always sets *bigtime* option on XFS filesystems, if possible.
Requires sufficiently-recent xfsprogs. #1874
- *preservefiles* was missing some necessary features, needed for it
to replace the deprecated log-file-saving functionality in the *umount*
module. (Thanks Erik and Joe for testing) #1851
- *umount* is now marked as an emergency module in the example configuration,
since it should **probably** be run as a cleanup. (Thanks Evan)
- *welcome* and *locale* could be confusing, together, and configure
the target system with a language that does not match the installer
language, even though the user did not make any explicit choice.
(Thanks Taejun) #1864
# 3.2.49.1 (2021-12-11) #
This is a hot-fix release, to fix a regression in the calculation of

View File

@@ -41,7 +41,7 @@
# TODO:3.3: Require CMake 3.12
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
project( CALAMARES
VERSION 3.2.49.1
VERSION 3.2.50
LANGUAGES C CXX
)
@@ -135,15 +135,15 @@ set( CALAMARES_DESCRIPTION_SUMMARY
# NOTE: update these lines by running `txstats.py`, or for full automation
# `txstats.py -e`. See also
#
# Total 81 languages
set( _tx_complete az az_AZ ca de fa fi_FI he hr ja ko lt pt_PT si
sq tr_TR uk zh_TW )
set( _tx_good as be ca@valencia cs_CZ da fr fur hi it_IT ml nl
pt_BR ru sk sv tg vi zh_CN )
# Total 74 languages
set( _tx_complete az az_AZ ca de fa fi_FI he hi hr ja ko lt pt_BR
pt_PT si sq sv tr_TR uk zh_TW )
set( _tx_good as be ca@valencia cs_CZ da fr fur it_IT ml nl ru sk
tg vi zh_CN )
set( _tx_ok ar ast bg bn el en_GB es es_MX et eu gl hu id is mr nb
pl ro sl sr sr@latin th )
set( _tx_incomplete en_HK en_IN eo es_PE es_PR fr_CH gu hi_IN id_ID
ie kk kn ko_KR lo lv mk ne ne_NP te te_IN ur zh zh_HK )
set( _tx_incomplete eo es_PR gu ie kk kn lo lv mk ne ne_NP ta_IN te
ur zh zh_HK )
### Required versions
#

View File

@@ -8,7 +8,7 @@
[![Current issue](https://img.shields.io/badge/issue-in_progress-FE9B48)](https://github.com/calamares/calamares/labels/hacking%3A%20in-progress)
[![GitHub release](https://img.shields.io/github/release/calamares/calamares.svg)](https://github.com/calamares/calamares/releases)
[![GitHub Build Status](https://img.shields.io/github/workflow/status/calamares/calamares/ci?label=GH%20build)](https://github.com/calamares/calamares/actions?query=workflow%3Aci)
[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSE)
[![GitHub license](https://img.shields.io/github/license/calamares/calamares.svg)](https://github.com/calamares/calamares/blob/calamares/LICENSES/GPL-3.0-or-later.txt)
| [Report a Bug](https://github.com/calamares/calamares/issues/new) | [Translate](https://www.transifex.com/projects/p/calamares/) | [Contribute](CONTRIBUTING.md) | [Matrix: #calamares:kde.org](https://webchat.kde.org/#/room/%23calamares:kde.org) | [IRC: Libera.Chat #calamares](https://kiwiirc.com/client/irc.libera.chat/#calamares) | [Wiki](https://github.com/calamares/calamares/wiki) |

View File

@@ -693,27 +693,27 @@ Instalační program bude ukončen a všechny změny ztraceny.</translation>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>Úspěšně odpojeno %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>Úspěšně vypnut swap %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>Úspěšně vyčištěn swap %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation>Úspěšně zavřeno mapper zařízení %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation>Úspěšně vypnuta skupina svazků %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -1989,7 +1989,7 @@ The installer will quit and all changes will be lost.</translation>
<message>
<location filename="../src/modules/machineid/MachineIdJob.cpp" line="53"/>
<source>Configuration Error</source>
<translation type="unfinished"/>
<translation>Configuration Error </translation>
</message>
<message>
<location filename="../src/modules/machineid/MachineIdJob.cpp" line="54"/>

View File

@@ -689,27 +689,27 @@ The installer will quit and all changes will be lost.</source>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>%1 </translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>%1 िि </translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>%1 ि </translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation>िि %1 </translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation> %1 िि </translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -6,7 +6,7 @@
<message>
<location filename="../src/modules/partition/jobs/AutoMountManagementJob.cpp" line="22"/>
<source>Manage auto-mount settings</source>
<translation type="unfinished"/>
<translation>Kelola pengaturan mount otomatis</translation>
</message>
</context>
<context>
@@ -114,12 +114,12 @@
<message>
<location filename="../src/calamares/DebugWindow.ui" line="141"/>
<source>Uploads the session log to the configured pastebin.</source>
<translation type="unfinished"/>
<translation>Unggah catatan sesi ke pastebin yang telah dikonfigurasi.</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="144"/>
<source>Send Session Log</source>
<translation type="unfinished"/>
<translation>Kirim Catatan Sesi</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="118"/>
@@ -165,7 +165,7 @@
<message>
<location filename="../src/libcalamares/JobExample.cpp" line="30"/>
<source>Programmed job failure was explicitly requested.</source>
<translation type="unfinished"/>
<translation>Kegagalan pekerjaan diprogram diminta secara eksplisit. </translation>
</message>
</context>
<context>
@@ -189,7 +189,7 @@
<message>
<location filename="../src/libcalamares/ProcessJob.cpp" line="43"/>
<source>Run command '%1' in target system.</source>
<translation>Jalankan perintah '%1' di dalam sistem target.</translation>
<translation>Jalankan perintah '%1' pada sistem target.</translation>
</message>
<message>
<location filename="../src/libcalamares/ProcessJob.cpp" line="43"/>
@@ -245,7 +245,7 @@
<message>
<location filename="../src/libcalamaresui/viewpages/QmlViewStep.cpp" line="88"/>
<source>QML Step &lt;i&gt;%1&lt;/i&gt;.</source>
<translation type="unfinished"/>
<translation>QML Langkah &lt;i&gt;%1&lt;/i&gt;.</translation>
</message>
<message>
<location filename="../src/libcalamaresui/viewpages/QmlViewStep.cpp" line="268"/>
@@ -277,7 +277,7 @@
<message>
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="121"/>
<source>System-requirements checking is complete.</source>
<translation type="unfinished"/>
<translation>Pengecekan kebutuhan sistem telah selesai.</translation>
</message>
</context>
<context>
@@ -295,7 +295,7 @@
<message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="163"/>
<source>Would you like to paste the install log to the web?</source>
<translation>Maukah anda untuk menempelkan log instalasi ke situs?</translation>
<translation>Maukah anda menempelkan log instalasi ke situs?</translation>
</message>
<message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="179"/>
@@ -429,7 +429,7 @@ Link copied to clipboard</source>
<message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="425"/>
<source>&amp;Done</source>
<translation>&amp;Kelar</translation>
<translation>&amp;Selesai</translation>
</message>
<message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="444"/>
@@ -1054,12 +1054,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/partition/gui/CreatePartitionDialog.ui" line="231"/>
<source>Label for the filesystem</source>
<translation type="unfinished"/>
<translation>Label untuk filesystem</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/CreatePartitionDialog.ui" line="241"/>
<source>FS Label:</source>
<translation type="unfinished"/>
<translation>Label FS:</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/CreatePartitionDialog.cpp" line="65"/>
@@ -1418,12 +1418,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/partition/gui/EditExistingPartitionDialog.ui" line="186"/>
<source>Label for the filesystem</source>
<translation type="unfinished"/>
<translation>Label untuk filesystem</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/EditExistingPartitionDialog.ui" line="196"/>
<source>FS Label:</source>
<translation type="unfinished"/>
<translation>Label FS:</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/EditExistingPartitionDialog.cpp" line="291"/>
@@ -1582,7 +1582,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/partition/jobs/FormatPartitionJob.cpp" line="36"/>
<source>Format partition %1 (file system: %2, size: %3 MiB) on %4.</source>
<translation type="unfinished"/>
<translation>Format partisi %1 (file system: %2, ukuran %3 MiB) pada %4.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/FormatPartitionJob.cpp" line="47"/>
@@ -1645,12 +1645,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/welcome/checker/GeneralRequirements.cpp" line="193"/>
<source>is running the installer as an administrator (root)</source>
<translation type="unfinished"/>
<translation>menjalankan installer sebagai administrator (root)</translation>
</message>
<message>
<location filename="../src/modules/welcome/checker/GeneralRequirements.cpp" line="196"/>
<source>The setup program is not running with administrator rights.</source>
<translation type="unfinished"/>
<translation>Installer tidak dijalankan dengan kewenangan administrator.</translation>
</message>
<message>
<location filename="../src/modules/welcome/checker/GeneralRequirements.cpp" line="197"/>
@@ -1699,7 +1699,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/oemid/IDJob.cpp" line="53"/>
<source>Could not open file &lt;code&gt;%1&lt;/code&gt;.</source>
<translation type="unfinished"/>
<translation>Tidak dapat membuka berkas &lt;code&gt;%1&lt;/code&gt;.</translation>
</message>
<message>
<location filename="../src/modules/oemid/IDJob.cpp" line="60"/>
@@ -1712,7 +1712,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/initcpio/InitcpioJob.cpp" line="31"/>
<source>Creating initramfs with mkinitcpio.</source>
<translation type="unfinished"/>
<translation>Membuat initramfs menggunakan mkinitcpio.</translation>
</message>
</context>
<context>
@@ -1720,7 +1720,7 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/initramfs/InitramfsJob.cpp" line="28"/>
<source>Creating initramfs.</source>
<translation type="unfinished"/>
<translation>Membuat initramfs.</translation>
</message>
</context>
<context>
@@ -2031,12 +2031,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="52"/>
<source>Browser software</source>
<translation>Peramban perangkat lunak</translation>
<translation>Perangkat lunak peramban</translation>
</message>
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="53"/>
<source>Browser package</source>
<translation>Peramban paket</translation>
<translation>Paket peramban</translation>
</message>
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="54"/>
@@ -2046,12 +2046,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="55"/>
<source>Kernel</source>
<translation>Inti</translation>
<translation>Kernel</translation>
</message>
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="56"/>
<source>Services</source>
<translation>Jasa</translation>
<translation>Servis</translation>
</message>
<message>
<location filename="../src/modules/netinstall/NetInstallViewStep.cpp" line="57"/>
@@ -2587,12 +2587,12 @@ Instalasi dapat dilanjutkan, namun beberapa fitur akan dinonfungsikan.</translat
<location filename="../src/modules/users/page_usersetup.ui" line="380"/>
<location filename="../src/modules/users/page_usersetup.ui" line="550"/>
<source>Repeat Password</source>
<translation type="unfinished"/>
<translation>Ulangi Kata Sandi</translation>
</message>
<message>
<location filename="../src/modules/users/page_usersetup.ui" line="455"/>
<source>When this box is checked, password-strength checking is done and you will not be able to use a weak password.</source>
<translation type="unfinished"/>
<translation>Ketikan kotak ini dicentang, pengecekan kekuatan kata sandi akan dilakukan dan anda tidak akan dapat menggunakan kata sandi yang lemah.</translation>
</message>
<message>
<location filename="../src/modules/users/page_usersetup.ui" line="458"/>
@@ -4252,7 +4252,7 @@ Keluaran:
<message>
<location filename="../src/modules/usersq/usersq.qml" line="136"/>
<source>root is not allowed as username.</source>
<translation type="unfinished"/>
<translation>root tidak boleh digunakan sebagai nama pengguna.</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="145"/>
@@ -4287,7 +4287,7 @@ Keluaran:
<message>
<location filename="../src/modules/usersq/usersq.qml" line="234"/>
<source>Repeat Password</source>
<translation type="unfinished"/>
<translation>Ulangi Kata Sandi</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="261"/>
@@ -4297,27 +4297,27 @@ Keluaran:
<message>
<location filename="../src/modules/usersq/usersq.qml" line="406"/>
<source>Validate passwords quality</source>
<translation type="unfinished"/>
<translation>Validasi kualitas kata sandi</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="416"/>
<source>When this box is checked, password-strength checking is done and you will not be able to use a weak password.</source>
<translation type="unfinished"/>
<translation>Ketikan kotak ini dicentang, pengecekan kekuatan kata sandi akan dilakukan dan anda tidak akan dapat menggunakan kata sandi yang lemah.</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="398"/>
<source>Log in automatically without asking for the password</source>
<translation type="unfinished"/>
<translation>Masuk ke dalam sesi secara otomatis tanpa menanyakan kata sandi</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="190"/>
<source>Only letters, numbers, underscore and hyphen are allowed, minimal of two characters.</source>
<translation type="unfinished"/>
<translation>Hanya huruf, angka, garis bawah, dan tanda hubung yang diperbolehkan, minimal dua karakter.</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="293"/>
<source>Reuse user password as root password</source>
<translation type="unfinished"/>
<translation>Gunakan kata sandi pengguna sebagai kata sandi root</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="301"/>
@@ -4332,12 +4332,12 @@ Keluaran:
<message>
<location filename="../src/modules/usersq/usersq.qml" line="324"/>
<source>Root Password</source>
<translation type="unfinished"/>
<translation>Kata Sandi Root</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="342"/>
<source>Repeat Root Password</source>
<translation type="unfinished"/>
<translation>Ulangi Kata Sandi</translation>
</message>
<message>
<location filename="../src/modules/usersq/usersq.qml" line="368"/>

4366
lang/calamares_ja-Hira.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -2014,7 +2014,7 @@ O instalador será encerrado e todas as alterações serão perdidas.</translati
<source>Please select your preferred location on the map so the installer can suggest the locale
and timezone settings for you. You can fine-tune the suggested settings below. Search the map by dragging
to move and using the +/- buttons to zoom in/out or use mouse scrolling for zooming.</source>
<translation>Por favor selecione o seu local preferido no mapa para que o instalador possa sugerir a localização
<translation>Selecione o seu local preferido no mapa para que o instalador possa sugerir a localização
e fuso horário para si. Pode ajustar as definições sugeridas abaixo. Procure no mapa arrastando
para mover e utilizando os botões +/- para aumentar/diminuir ou utilize a roda do rato para dar zoom.</translation>
</message>
@@ -4003,7 +4003,7 @@ Saída de Dados:
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="238"/>
<source>&lt;h1&gt;%1&lt;/h1&gt;&lt;br/&gt;&lt;strong&gt;%2&lt;br/&gt;for %3&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Copyright 2014-2017 Teo Mrnjavac &amp;lt;teo@kde.org&amp;gt;&lt;br/&gt;Copyright 2017-2020 Adriaan de Groot &amp;lt;groot@kde.org&amp;gt;&lt;br/&gt;Thanks to &lt;a href="https://calamares.io/team/"&gt;the Calamares team&lt;/a&gt; and the &lt;a href="https://www.transifex.com/calamares/calamares/"&gt;Calamares translators team&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;&lt;a href="https://calamares.io/"&gt;Calamares&lt;/a&gt; development is sponsored by &lt;br/&gt;&lt;a href="http://www.blue-systems.com/"&gt;Blue Systems&lt;/a&gt; - Liberating Software.</source>
<translation>&lt;h1&gt;%1&lt;/h1&gt;&lt;br/&gt;&lt;strong&gt;%2&lt;br/&gt;para %3&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Copyright 2014-2017 Teo Mrnjavac &amp;lt;teo@kde.org&amp;gt;&lt;br/&gt;Copyright 2017-2020 Adriaan de Groot &amp;lt;groot@kde.org&amp;gt;&lt;br/&gt;Obrigado à &lt;a href="https://calamares.io/team/"&gt;equipa Calamares&lt;/a&gt; e à &lt;a href="https://www.transifex.com/calamares/calamares/"&gt;equipa de tradutores do Calamares&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;O desenvolvimento do &lt;a href="https://calamares.io/"&gt;Calamares&lt;/a&gt; é patrocinado pela &lt;br/&gt;&lt;a href="http://www.blue-systems.com/"&gt;Blue Systems&lt;/a&gt; - Liberating Software.</translation>
<translation>&lt;h1&gt;%1&lt;/h1&gt;&lt;br/&gt;&lt;strong&gt;%2&lt;br/&gt;para o %3&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Copyright 2014-2017 Teo Mrnjavac &amp;lt;teo@kde.org&amp;gt;&lt;br/&gt;Copyright 2017-2020 Adriaan de Groot &amp;lt;groot@kde.org&amp;gt;&lt;br/&gt;Obrigado à &lt;a href="https://calamares.io/team/"&gt;equipa Calamares&lt;/a&gt; e à &lt;a href="https://www.transifex.com/calamares/calamares/"&gt;equipa de tradutores do Calamares&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;O desenvolvimento do &lt;a href="https://calamares.io/"&gt;Calamares&lt;/a&gt; é patrocinado pela &lt;br/&gt;&lt;a href="http://www.blue-systems.com/"&gt;Blue Systems&lt;/a&gt; - Liberating Software.</translation>
</message>
</context>
<context>

View File

@@ -104,17 +104,17 @@
<message>
<location filename="../src/calamares/DebugWindow.ui" line="102"/>
<source>Crashes Calamares, so that Dr. Konqui can look at it.</source>
<translation type="unfinished"/>
<translation> crash lui Calamares, pentru ca doctorul Konqui se uite la el.</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="115"/>
<source>Reloads the stylesheet from the branding directory.</source>
<translation type="unfinished"/>
<translation>Reîncarcă foaia de stil din directorul branding.</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="141"/>
<source>Uploads the session log to the configured pastebin.</source>
<translation type="unfinished"/>
<translation>Încarcă jurnalul sesiunii pe pastebin-ul configurat.</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="144"/>
@@ -134,7 +134,7 @@
<message>
<location filename="../src/calamares/DebugWindow.ui" line="131"/>
<source>Widget Tree</source>
<translation>Lista widget</translation>
<translation>Arborele de widget</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.cpp" line="221"/>
@@ -1991,7 +1991,7 @@ Programul de instalare va ieși, iar toate modificările vor fi pierdute.</trans
<message>
<location filename="../src/modules/machineid/MachineIdJob.cpp" line="53"/>
<source>Configuration Error</source>
<translation type="unfinished"/>
<translation>Eroare de configurare</translation>
</message>
<message>
<location filename="../src/modules/machineid/MachineIdJob.cpp" line="54"/>

4377
lang/calamares_ta_IN.ts Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
<message>
<location filename="../src/modules/partition/jobs/AutoMountManagementJob.cpp" line="22"/>
<source>Manage auto-mount settings</source>
<translation type="unfinished"/>
<translation>Идора кардани танзимоти васлкунии худкор</translation>
</message>
</context>
<context>

View File

@@ -6,7 +6,7 @@
<message>
<location filename="../src/modules/partition/jobs/AutoMountManagementJob.cpp" line="22"/>
<source>Manage auto-mount settings</source>
<translation type="unfinished"/>
<translation>Quản cài đt tự đng gắn kết(auto-mount)</translation>
</message>
</context>
<context>
@@ -104,22 +104,22 @@
<message>
<location filename="../src/calamares/DebugWindow.ui" line="102"/>
<source>Crashes Calamares, so that Dr. Konqui can look at it.</source>
<translation type="unfinished"/>
<translation>Gây crash Calamares, đ Dr. Konqui thể xem .</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="115"/>
<source>Reloads the stylesheet from the branding directory.</source>
<translation type="unfinished"/>
<translation>Tải lại stylesheet từ thư mục branding</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="141"/>
<source>Uploads the session log to the configured pastebin.</source>
<translation type="unfinished"/>
<translation>Đăng tải log của phiên này lên pastebin đã đưc cấu hình</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="144"/>
<source>Send Session Log</source>
<translation type="unfinished"/>
<translation>Gửi log của phiên này</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="118"/>
@@ -129,7 +129,7 @@
<message>
<location filename="../src/calamares/DebugWindow.ui" line="128"/>
<source>Displays the tree of widget names in the log (for stylesheet debugging).</source>
<translation type="unfinished"/>
<translation>Hiễn thị cây của tên widget trong log(đ gỡ lỗi stylesheet)</translation>
</message>
<message>
<location filename="../src/calamares/DebugWindow.ui" line="131"/>

View File

@@ -688,27 +688,27 @@ The installer will quit and all changes will be lost.</source>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation> %1</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation> %1</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation> %1</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation> %1</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation> %1</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -6,7 +6,7 @@
# Translators:
# pavelrz, 2017
# LiberteCzech <martin.kriz.czech@gmail.com>, 2020
# Pavel Borecki <pavel.borecki@gmail.com>, 2021
# Pavel Borecki <pavel.borecki@gmail.com>, 2022
#
#, fuzzy
msgid ""
@@ -15,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
"PO-Revision-Date: 2017-08-09 10:34+0000\n"
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>, 2021\n"
"Last-Translator: Pavel Borecki <pavel.borecki@gmail.com>, 2022\n"
"Language-Team: Czech (Czech Republic) (https://www.transifex.com/calamares/teams/20061/cs_CZ/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -331,7 +331,7 @@ msgstr "Nedaří se zapnout systemd službu <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Nedaří se zapnout systemd časovač <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -413,6 +413,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Nepodařilo se nalézt nástroj unsquashfs ověřte, že je nainstalovaný "
"balíček squashfs-tools."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -5,6 +5,7 @@
#
# Translators:
# Jason Collins <JasonPCollins@protonmail.com>, 2018
# Karthik Balan, 2021
#
#, fuzzy
msgid ""
@@ -13,7 +14,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
"PO-Revision-Date: 2017-08-09 10:34+0000\n"
"Last-Translator: Jason Collins <JasonPCollins@protonmail.com>, 2018\n"
"Last-Translator: Karthik Balan, 2021\n"
"Language-Team: English (United Kingdom) (https://www.transifex.com/calamares/teams/20061/en_GB/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -35,7 +36,7 @@ msgstr ""
#: src/modules/luksopenswaphookcfg/main.py:86
#: src/modules/luksopenswaphookcfg/main.py:90
msgid "Configuration Error"
msgstr ""
msgstr "Configuration Error "
#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356
#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145
@@ -61,7 +62,7 @@ msgstr ""
#: src/modules/bootloader/main.py:508
msgid "Bootloader installation error"
msgstr ""
msgstr "Bootloader installation error"
#: src/modules/bootloader/main.py:509
msgid ""
@@ -91,7 +92,7 @@ msgstr ""
#: src/modules/displaymanager/main.py:526
msgid "Cannot write KDM configuration file"
msgstr ""
msgstr "Cannot write KDM configuration file"
#: src/modules/displaymanager/main.py:527
msgid "KDM config file {!s} does not exist"
@@ -145,7 +146,7 @@ msgstr ""
#: src/modules/services-openrc/main.py:29
msgid "Configure OpenRC services"
msgstr ""
msgstr "Configure OpenRC services"
#: src/modules/services-openrc/main.py:57
msgid "Cannot add service {name!s} to run-level {level!s}."
@@ -173,7 +174,7 @@ msgstr ""
#: src/modules/services-openrc/main.py:101
msgid "Target runlevel does not exist"
msgstr ""
msgstr "Target runlevel does not exist"
#: src/modules/services-openrc/main.py:102
msgid ""
@@ -193,7 +194,7 @@ msgstr ""
#: src/modules/networkcfg/main.py:29
msgid "Saving network configuration."
msgstr ""
msgstr "Saving network configuration "
#: src/modules/packages/main.py:50 src/modules/packages/main.py:59
#: src/modules/packages/main.py:69
@@ -222,7 +223,7 @@ msgstr[1] "Removing %(num)d packages."
#: src/modules/packages/main.py:638 src/modules/packages/main.py:650
#: src/modules/packages/main.py:678
msgid "Package Manager error"
msgstr ""
msgstr "Package Manager error"
#: src/modules/packages/main.py:639
msgid ""

View File

@@ -319,7 +319,7 @@ msgstr "systemd लक्ष्य <code>{name!s}</code>सक्रिय क
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "systemd टाइमर <code>{name!s}</code>सक्रिय करना विफल।"
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -399,6 +399,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"unsqaushfs खोजने में विफल, सुनिश्चित करें कि squashfs-tools पैकेज इंस्टॉल "
"है।"
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

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

View File

@@ -4,7 +4,7 @@
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
# Translators:
# Marcin Mikołajczak <me@mkljczk.pl>, 2017
# marcin mikołajczak <me@mkljczk.pl>, 2017
# KagiSame, 2018
# Piotr Strębski <strebski@gmail.com>, 2020
# Jacob B. <brickminerplyt@gmail.com>, 2021

View File

@@ -6,6 +6,7 @@
# Translators:
# Jobava Jobava <jobaval10n@gmail.com>, 2018
# Sebastian Brici <bricisebastian@gmail.com>, 2018
# Chele Ion <krovyoll@gmail.com>, 2021
#
#, fuzzy
msgid ""
@@ -14,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
"PO-Revision-Date: 2017-08-09 10:34+0000\n"
"Last-Translator: Sebastian Brici <bricisebastian@gmail.com>, 2018\n"
"Last-Translator: Chele Ion <krovyoll@gmail.com>, 2021\n"
"Language-Team: Romanian (https://www.transifex.com/calamares/teams/20061/ro/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -24,7 +25,7 @@ msgstr ""
#: src/modules/initramfscfg/main.py:32
msgid "Configuring initramfs."
msgstr ""
msgstr "Configurare initramfs"
#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89
#: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361
@@ -36,21 +37,21 @@ msgstr ""
#: src/modules/luksopenswaphookcfg/main.py:86
#: src/modules/luksopenswaphookcfg/main.py:90
msgid "Configuration Error"
msgstr ""
msgstr "Eroare de configurare"
#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356
#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145
#: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73
#: src/modules/luksopenswaphookcfg/main.py:87
msgid "No partitions are defined for <pre>{!s}</pre> to use."
msgstr ""
msgstr "Nu sunt partiţii definite ca 1{!s}1 ."
#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362
#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232
#: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77
#: src/modules/luksopenswaphookcfg/main.py:91
msgid "No root mount point is given for <pre>{!s}</pre> to use."
msgstr ""
msgstr "Nu este definită o partiţie rădăcină pentru 1{!s}1 ."
#: src/modules/grubcfg/main.py:28
msgid "Configure GRUB."

View File

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

View File

@@ -5,7 +5,7 @@
#
# Translators:
# T. Tran <transifex@emiu.net>, 2020
# Th1nhhdk, 2021
# th1nhhdk <th1nhhdk@tutanota.com>, 2021
#
#, fuzzy
msgid ""
@@ -14,7 +14,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
"PO-Revision-Date: 2017-08-09 10:34+0000\n"
"Last-Translator: Th1nhhdk, 2021\n"
"Last-Translator: th1nhhdk <th1nhhdk@tutanota.com>, 2021\n"
"Language-Team: Vietnamese (https://www.transifex.com/calamares/teams/20061/vi/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"

View File

@@ -9,6 +9,7 @@
# Feng Chao <chaofeng111@qq.com>, 2020
# Bobby Rong <admin@bobby285271.top>, 2020
# 玉堂白鹤 <yjwork@qq.com>, 2021
# Giovanni Schiano-Moriello, 2022
#
#, fuzzy
msgid ""
@@ -17,7 +18,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
"PO-Revision-Date: 2017-08-09 10:34+0000\n"
"Last-Translator: 玉堂白鹤 <yjwork@qq.com>, 2021\n"
"Last-Translator: Giovanni Schiano-Moriello, 2022\n"
"Language-Team: Chinese (China) (https://www.transifex.com/calamares/teams/20061/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -305,7 +306,7 @@ msgstr "无法启用 systemd 目标 <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "无法启用 systemd 计时器 <code>{name!s}</code>。"
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -384,7 +385,7 @@ msgstr "源文件系统 \"{}\" 不存在"
msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
msgstr "寻找 unsquashfs 失败,请确定您已安装 squashfs-tools 软体包。"
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -47,7 +47,7 @@ public:
/** @brief Is this JobResult a success?
*
* Equivalent to errorCode() == 0, might be named isValid().
* Equivalent to errorCode() == 0, see succeeded().
*/
virtual operator bool() const;
@@ -58,6 +58,11 @@ public:
virtual void setDetails( const QString& details );
int errorCode() const { return m_number; }
/** @brief Is this JobResult a success?
*
* Equivalent to errorCode() == 0.
*/
bool succeeded() const { return this->operator bool(); }
/// @brief an "ok status" result
static JobResult ok();

View File

@@ -100,7 +100,7 @@ BOOST_PYTHON_MODULE( libcalamares )
bp::args( "s" ),
"Writes the given string to the Calamares warning stream." );
bp::def(
"error", &CalamaresPython::warning, bp::args( "s" ), "Writes the given string to the Calamares error stream." );
"error", &CalamaresPython::error, bp::args( "s" ), "Writes the given string to the Calamares error stream." );
// .. YAML functions

View File

@@ -67,7 +67,7 @@ Note that process modules are not recommended.
Module descriptors **may** have the following keys:
- *emergency* (a boolean value, set to true to mark the module
as an emergency module)
as an emergency module; see the section *Emergency Modules*, below)
- *noconfig* (a boolean value, set to true to state that the module
has no configuration file; defaults to false)
- *requiredModules* (a list of modules which are required for this module
@@ -86,24 +86,30 @@ it needs those keys.
### Emergency Modules
Only C++ modules and job modules may be emergency modules. If, during an
*exec* step in the sequence, a module fails, installation as a whole fails
and the install is aborted. If there are emergency modules in the **same**
exec block, those will be executed before the installation is aborted.
Non-emergency modules are not executed.
If, during an *exec* step in the sequence, a module fails, installation as
a whole fails and the install is aborted. If there are emergency modules
in the **same** exec block, those will be executed before the installation
is aborted. Non-emergency modules are not executed.
If an emergency-module fails while processing emergency-modules for
another failed module, that failure is ignored and emergency-module
processing continues.
Use the EMERGENCY keyword in the CMake description of a C++ module
to generate a suitable `module.desc`.
to generate a suitable `module.desc`. For Python modules, manually add
`emergency: true` to `module.desc`.
A module that is marked as an emergency module in its module.desc
must **also** set the *emergency* key to *true* in its configuration file
(see below). If it does not, the module is not considered to be an emergency
module after all (this is so that you can have modules that have several
instances, only some of which are actually needed for emergencies).
module after all. This is so that you can have modules that have several
instances, only some of which are actually needed for emergencies.
In summary:
- in `module.desc`, write `emergency: true` to make it **possible** to
run the module in emergency mode,
- in `<modulename>.conf`, write `emergency: true` to make that specific
module run in emergency mode.
### Module-specific configuration
@@ -112,6 +118,10 @@ named `<modulename>.conf`. If such a file is present in the
module's directory, it can be shipped as a *default* configuration file.
This only happens if the CMake-time option `INSTALL_CONFIG` is on.
The name of the configuration file for a given module can be
influenced by the `settings.conf` of the overall Calamares configuration.
By default, though, the module's own name is used.
Modules that have *noconfig* set to true will not attempt to
read a configuration file, and will not warn that one is missing;
conversely if *noconfig* is set to false (or is missing, since

View File

@@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
* SPDX-FileCopyrightText: 2022 Evan James <dalto@fastmail.com>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
@@ -31,15 +32,22 @@ InitcpioJob::prettyName() const
return tr( "Creating initramfs with mkinitcpio." );
}
/** @brief Sets secure permissions on each initramfs
*
* Iterates over each initramfs contained directly in the directory @p d.
* For each initramfs found, the permissions are set to owner read/write only.
*
*/
void
fixPermissions( const QDir& d )
{
for ( const auto& fi : d.entryInfoList( { "initramfs*" }, QDir::Files ) )
const auto initramList = d.entryInfoList( { "initramfs*" }, QDir::Files );
for ( const auto& fi : initramList )
{
QFile f( fi.absoluteFilePath() );
if ( f.exists() )
{
cDebug() << "initcpio fixing permissions for" << f.fileName();
cDebug() << "initcpio setting permissions for" << f.fileName();
f.setPermissions( QFileDevice::ReadOwner | QFileDevice::WriteOwner );
}
}
@@ -63,9 +71,19 @@ InitcpioJob::exec()
}
}
// If the kernel option isn't set to a specific kernel, run mkinitcpio on all kernels
QStringList command = { "mkinitcpio" };
if ( m_kernel.isEmpty() || m_kernel == "all" )
{
command.append( "-P" );
}
else
{
command.append( { "-p", m_kernel } );
}
cDebug() << "Updating initramfs with kernel" << m_kernel;
auto r = CalamaresUtils::System::instance()->targetEnvCommand(
{ "mkinitcpio", "-p", m_kernel }, QString(), QString() /* no timeout , 0 */ );
auto r = CalamaresUtils::System::instance()->targetEnvCommand( command, QString(), QString() /* no timeout , 0 */ );
return r.explainProcess( "mkinitcpio", std::chrono::seconds( 10 ) /* fake timeout */ );
}
@@ -73,28 +91,6 @@ void
InitcpioJob::setConfigurationMap( const QVariantMap& configurationMap )
{
m_kernel = CalamaresUtils::getString( configurationMap, "kernel" );
if ( m_kernel.isEmpty() )
{
m_kernel = QStringLiteral( "all" );
}
else if ( m_kernel == "$uname" )
{
auto r = CalamaresUtils::System::runCommand( CalamaresUtils::System::RunLocation::RunInHost,
{ "/bin/uname", "-r" },
QString(),
QString(),
std::chrono::seconds( 3 ) );
if ( r.getExitCode() == 0 )
{
m_kernel = r.getOutput();
cDebug() << "*initcpio* using running kernel" << m_kernel;
}
else
{
cWarning() << "*initcpio* could not determine running kernel, using 'all'." << Logger::Continuation
<< r.getExitCode() << r.getOutput();
}
}
m_unsafe = CalamaresUtils::getBool( configurationMap, "be_unsafe", false );
}

View File

@@ -5,21 +5,22 @@
---
# This key defines the kernel to be loaded.
# It can have the following values:
# - empty or unset, interpreted as "all"
# - the literal string "$uname" (without quotes, with dollar),
# which will use the output of `uname -r` to determine the
# running kernel, and use that.
# - any other string.
# - the name of a single mkinitcpio preset
# - empty or unset
# - the literal string "all"
#
# Whatever is set, that string is passed as *preset* argument to the
# `-p` option of *mkinitcpio*. Take care that both "$uname" operates
# in the host system, and might not be correct if the target system is
# updated (to a newer kernel) as part of the installation.
# If kernel is set to "all" or empty/unset then mkinitpio is called for all
# kernels. Otherwise it is called with a single preset with the value
# contained in kernel.
#
# Note that "all" is probably not a good preset to use either.
kernel: linux312
kernel: linux
# Set this to true to turn off mitigations for lax file
# permissions on initramfs (which, in turn, can compromise
# your LUKS encryption keys, CVS-2019-13179).
#
# If your initramfs are stored in the EFI partition or another non-POSIX
# filesystem, this has no effect as the file permissions cannot be changed.
# In this case, ensure the partition is mounted securely.
#
be_unsafe: false

View File

@@ -173,7 +173,8 @@ def find_initcpio_features(partitions, root_mount_point):
if partition["fs"] == "btrfs":
uses_btrfs = True
if partition["fs"] == "zfs":
# In addition to checking the filesystem, check to ensure that zfs is enabled
if partition["fs"] == "zfs" and libcalamares.globalstorage.contains("zfsPoolInfo"):
uses_zfs = True
if "lvm2" in partition["fs"]:

View File

@@ -81,6 +81,7 @@ InitramfsJob::setConfigurationMap( const QVariantMap& configurationMap )
}
else
{
m_kernel = QStringLiteral( "all" );
cWarning() << "*initramfs* could not determine running kernel, using 'all'." << Logger::Continuation
<< r.getExitCode() << r.getOutput();
}

View File

@@ -221,6 +221,11 @@ Config::setCurrentLocation()
{
setCurrentLocation( m_startingTimezone.first, m_startingTimezone.second );
}
if ( !m_selectedLocaleConfiguration.explicit_lang )
{
auto newLocale = automaticLocaleConfiguration();
setLanguage( newLocale.language() );
}
}
void
@@ -252,15 +257,21 @@ Config::setCurrentLocation( const QString& regionName, const QString& zoneName )
void
Config::setCurrentLocation( const CalamaresUtils::Locale::TimeZoneData* location )
{
if ( location != m_currentLocation )
const bool updateLocation = ( location != m_currentLocation );
if ( updateLocation )
{
m_currentLocation = location;
// Overwrite those settings that have not been made explicit.
auto newLocale = automaticLocaleConfiguration();
if ( !m_selectedLocaleConfiguration.explicit_lang )
{
setLanguage( newLocale.language() );
}
}
// lang should be always be updated
auto newLocale = automaticLocaleConfiguration();
if ( !m_selectedLocaleConfiguration.explicit_lang )
{
setLanguage( newLocale.language() );
}
if ( updateLocation )
{
if ( !m_selectedLocaleConfiguration.explicit_lc )
{
m_selectedLocaleConfiguration.lc_numeric = newLocale.lc_numeric;

View File

@@ -0,0 +1,22 @@
# === This file is part of Calamares - <https://calamares.io> ===
#
# SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
#
# Because LUKS Open Swap Hook (Job) is such a mouthful, we'll
# use LOSH all over the place as a shorthand.
calamares_add_plugin( luksopenswaphookcfg
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
LOSHJob.cpp
SHARED_LIB
)
calamares_add_test(
luksopenswaphooktest
SOURCES
LOSHJob.cpp
Tests.cpp
)

View File

@@ -0,0 +1,66 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef LUKSOPENSWAPHOOKCFG_LOSHINFO_H
#define LUKSOPENSWAPHOOKCFG_LOSHINFO_H
#include <QString>
/** @brief Information needed to create a suitable config file
*
* The LUKS swap configuration has a handful of keys that need to
* be written to the config file. This struct holds those keys
* and can find the key values from Global Storage (where the
* *partition* module sets them).
*/
struct LOSHInfo
{
// Member names copied from Python code
QString swap_outer_uuid;
QString swap_mapper_name;
QString mountable_keyfile_device;
QString swap_device_path;
QString keyfile_device_mount_options;
bool isValid() const { return !swap_device_path.isEmpty(); }
/** @brief Helper method for doing key-value replacements
*
* Given a named @p key (e.g. "duck", or "swap_device"), returns the
* value set for that key. Invalid keys (e.g. "duck") return an empty string.
*/
QString replacementFor( const QString& key ) const
{
if ( key == QStringLiteral( "swap_device" ) )
{
return swap_device_path;
}
if ( key == QStringLiteral( "crypt_swap_name" ) )
{
return swap_mapper_name;
}
if ( key == QStringLiteral( "keyfile_device" ) )
{
return mountable_keyfile_device;
}
if ( key == QStringLiteral( "keyfile_filename" ) )
{
return QStringLiteral( "crypto_keyfile.bin" );
}
if ( key == QStringLiteral( "keyfile_device_mount_options" ) )
{
return keyfile_device_mount_options;
}
return QString();
}
/** @brief Creates a struct from information already set in GS
*
*/
static LOSHInfo fromGlobalStorage();
};
#endif

View File

@@ -0,0 +1,181 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "LOSHJob.h"
#include "LOSHInfo.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/Permissions.h"
#include "utils/PluginFactory.h"
#include "utils/String.h"
#include "utils/Variant.h"
#include <QList>
#include <QObject>
#include <QRegularExpression>
#include <QVariantMap>
LOSHJob::LOSHJob( QObject* parent )
: Calamares::CppJob( parent )
{
}
LOSHJob::~LOSHJob() {}
QString
LOSHJob::prettyName() const
{
return tr( "Configuring encrypted swap." );
}
STATICTEST QString
get_assignment_part( const QString& line )
{
static QRegularExpression re( "^[# \\t]*([A-Za-z_]+)[ \\t]*=" );
auto m = re.match( line );
if ( m.hasMatch() )
{
return m.captured( 1 );
}
return QString();
}
/** Writes the config file at @p path
*
* NOTE: @p path is relative to the target system, not an absolute path.
*/
STATICTEST void
write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info )
{
if ( info.isValid() )
{
for ( auto& line : contents )
{
const QString key = get_assignment_part( line );
QString replacement = info.replacementFor( key );
if ( !replacement.isEmpty() )
{
line.clear();
line.append( QStringLiteral( "%1=%2" ).arg( key, replacement ) );
}
}
cDebug() << "Writing" << contents.length() << "line configuration to" << path;
// \n between each two lines, and a \n at the end
CalamaresUtils::System::instance()->createTargetFile(
path, contents.join( '\n' ).append( '\n' ).toUtf8(), CalamaresUtils::System::WriteMode::Overwrite );
}
else
{
cDebug() << "Will not write an invalid configuration to" << path;
}
}
Calamares::JobResult
LOSHJob::exec()
{
const auto* sys = CalamaresUtils::System::instance();
if ( !sys )
{
return Calamares::JobResult::internalError(
"LuksOpenSwapHook", tr( "No target system available." ), Calamares::JobResult::InvalidConfiguration );
}
Calamares::GlobalStorage* gs
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( !gs || gs->value( "rootMountPoint" ).toString().isEmpty() )
{
return Calamares::JobResult::internalError(
"LuksOpenSwapHook", tr( "No rootMountPoint is set." ), Calamares::JobResult::InvalidConfiguration );
}
if ( m_configFilePath.isEmpty() )
{
return Calamares::JobResult::internalError(
"LuksOpenSwapHook", tr( "No configFilePath is set." ), Calamares::JobResult::InvalidConfiguration );
}
QStringList contents = sys->readTargetFile( m_configFilePath );
if ( contents.isEmpty() )
{
contents << QStringLiteral( "# swap_device=" ) << QStringLiteral( "# crypt_swap_name=" )
<< QStringLiteral( "# keyfile_device=" ) << QStringLiteral( "# keyfile_filename=" )
<< QStringLiteral( "# keyfile_device_mount_options" );
}
write_openswap_conf( m_configFilePath, contents, LOSHInfo::fromGlobalStorage() );
return Calamares::JobResult::ok();
}
void
LOSHJob::setConfigurationMap( const QVariantMap& configurationMap )
{
m_configFilePath = CalamaresUtils::getString(
configurationMap, QStringLiteral( "configFilePath" ), QStringLiteral( "/etc/openswap.conf" ) );
}
STATICTEST void
globalStoragePartitionInfo( Calamares::GlobalStorage* gs, LOSHInfo& info )
{
if ( !gs )
{
return;
}
QVariantList l = gs->value( "partitions" ).toList();
if ( l.isEmpty() )
{
return;
}
for ( const auto& pv : l )
{
const QVariantMap partition = pv.toMap();
if ( !partition.isEmpty() )
{
QString mountPoint = partition.value( "mountPoint" ).toString();
QString fileSystem = partition.value( "fs" ).toString();
QString luksMapperName = partition.value( "luksMapperName" ).toString();
// if partition["fs"] == "linuxswap" and "luksMapperName" in partition:
if ( fileSystem == QStringLiteral( "linuxswap" ) && !luksMapperName.isEmpty() )
{
info.swap_outer_uuid = partition.value( "luksUuid" ).toString();
info.swap_mapper_name = luksMapperName;
}
else if ( mountPoint == QStringLiteral( "/" ) && !luksMapperName.isEmpty() )
{
info.mountable_keyfile_device = QStringLiteral( "/dev/mapper/" ) + luksMapperName;
}
}
}
if ( !info.mountable_keyfile_device.isEmpty() && !info.swap_outer_uuid.isEmpty() )
{
info.swap_device_path = QStringLiteral( "/dev/disk/by-uuid/" ) + info.swap_outer_uuid;
}
QString btrfsRootSubvolume = gs->value( "btrfsRootSubvolume" ).toString();
if ( !btrfsRootSubvolume.isEmpty() )
{
CalamaresUtils::removeLeading( btrfsRootSubvolume, '/' );
info.keyfile_device_mount_options
= QStringLiteral( "keyfile_device_mount_options=--options=subvol=" ) + btrfsRootSubvolume;
}
}
LOSHInfo
LOSHInfo::fromGlobalStorage()
{
LOSHInfo i {};
globalStoragePartitionInfo(
Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr, i );
return i;
}
CALAMARES_PLUGIN_FACTORY_DEFINITION( LOSHJobFactory, registerPlugin< LOSHJob >(); )

View File

@@ -0,0 +1,37 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef LUKSOPENSWAPHOOKCFG_LOSHJOB_H
#define LUKSOPENSWAPHOOKCFG_LOSHJOB_H
#include "CppJob.h"
#include "DllMacro.h"
#include "utils/PluginFactory.h"
#include <QString>
#include <QVariantMap>
class PLUGINDLLEXPORT LOSHJob : public Calamares::CppJob
{
Q_OBJECT
public:
explicit LOSHJob( QObject* parent = nullptr );
~LOSHJob() override;
QString prettyName() const override;
Calamares::JobResult exec() override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
QString m_configFilePath;
};
CALAMARES_PLUGIN_FACTORY_DECLARATION( LOSHJobFactory )
#endif

View File

@@ -0,0 +1,253 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "LOSHInfo.h"
#include "LOSHJob.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <QtTest/QtTest>
// LOSH = LUKS Open Swap Hook (Job)
// Implementation details
extern QString get_assignment_part( const QString& line );
extern void write_openswap_conf( const QString& path, QStringList& contents, const LOSHInfo& info );
class LOSHTests : public QObject
{
Q_OBJECT
public:
LOSHTests();
~LOSHTests() override {}
private Q_SLOTS:
void initTestCase();
void testAssignmentExtraction_data();
void testAssignmentExtraction();
void testLOSHInfo();
void testConfigWriting();
void testJob();
};
LOSHTests::LOSHTests() {}
void
LOSHTests::initTestCase()
{
Logger::setupLogLevel( Logger::LOGDEBUG );
cDebug() << "LOSH test started.";
}
void
LOSHTests::testAssignmentExtraction_data()
{
QTest::addColumn< QString >( "line" );
QTest::addColumn< QString >( "match" );
QTest::newRow( "empty" ) << QString() << QString();
QTest::newRow( "comment-only1" ) << QStringLiteral( "# " ) << QString();
QTest::newRow( "comment-only2" ) << QStringLiteral( "###" ) << QString();
QTest::newRow( "comment-only3" ) << QStringLiteral( "# # #" ) << QString();
QTest::newRow( "comment-text" ) << QStringLiteral( "# NOTE:" ) << QString();
QTest::newRow( "comment-story" ) << QStringLiteral( "# This is a shell comment" ) << QString();
// We look for assignments, but only for single-words
QTest::newRow( "comment-space-eq" ) << QStringLiteral( "# Check that a = b" ) << QString();
QTest::newRow( "assignment1" ) << QStringLiteral( "a=1" ) << QStringLiteral( "a" );
QTest::newRow( "assignment2" ) << QStringLiteral( "a = 1" ) << QStringLiteral( "a" );
QTest::newRow( "assignment3" ) << QStringLiteral( "# a=1" ) << QStringLiteral( "a" );
QTest::newRow( "assignment4" ) << QStringLiteral( "cows = 12" ) << QStringLiteral( "cows" );
QTest::newRow( "assignment5" ) << QStringLiteral( "# # cows=1" ) << QStringLiteral( "cows" );
QTest::newRow( "assignment6" ) << QStringLiteral( "# moose='cool' # not cows" ) << QStringLiteral( "moose" );
QTest::newRow( "assignment7" ) << QStringLiteral( " moose=cows=42" ) << QStringLiteral( "moose" );
QTest::newRow( "assignment8" ) << QStringLiteral( "#swap_device=/dev/something" )
<< QStringLiteral( "swap_device" );
QTest::newRow( "assignment9" ) << QStringLiteral( "# swap_device=/dev/something" )
<< QStringLiteral( "swap_device" );
QTest::newRow( "assignment10" ) << QStringLiteral( "swap_device=/dev/something" )
<< QStringLiteral( "swap_device" );
}
void
LOSHTests::testAssignmentExtraction()
{
QFETCH( QString, line );
QFETCH( QString, match );
QCOMPARE( get_assignment_part( line ), match );
}
static CalamaresUtils::System*
file_setup( const QTemporaryDir& tempRoot )
{
CalamaresUtils::System* ss = CalamaresUtils::System::instance();
if ( !ss )
{
ss = new CalamaresUtils::System( true );
}
Calamares::GlobalStorage* gs
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
if ( !gs )
{
cDebug() << "Creating new JobQueue";
(void)new Calamares::JobQueue();
gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
}
if ( gs )
{
// Working with a rootMountPoint set
gs->insert( "rootMountPoint", tempRoot.path() );
}
return ss;
}
static void
make_valid_loshinfo( LOSHInfo& i )
{
i.swap_outer_uuid = QStringLiteral( "UUID-0000" );
i.swap_mapper_name = QStringLiteral( "/dev/mapper/0000" );
i.swap_device_path = QStringLiteral( "/dev/sda0" );
i.mountable_keyfile_device = QStringLiteral( "/dev/ada0p0s0" );
}
void
LOSHTests::testLOSHInfo()
{
LOSHInfo i {};
QVERIFY( !i.isValid() );
make_valid_loshinfo( i );
QVERIFY( i.isValid() );
QCOMPARE( i.replacementFor( QStringLiteral( "swap_device" ) ), QStringLiteral( "/dev/sda0" ) );
QCOMPARE( i.replacementFor( QStringLiteral( "duck" ) ), QString() );
}
void
LOSHTests::testConfigWriting()
{
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
QVERIFY( tempRoot.isValid() );
auto* ss = file_setup( tempRoot );
QVERIFY( ss );
QVERIFY( Calamares::JobQueue::instance()->globalStorage() );
QVERIFY( QFile::exists( tempRoot.path() ) );
QVERIFY( QFileInfo( tempRoot.path() ).isDir() );
const QString targetFilePath = QStringLiteral( "losh.conf" );
const QString filePath = tempRoot.filePath( targetFilePath );
QStringList contents { QStringLiteral( "# Calamares demo" ),
QStringLiteral( "# swap_device=a thing" ),
QStringLiteral( "# duck duck swap_device=another" ) };
// When the information is invalid, file contents are unchanged,
// and no file is written either.
LOSHInfo i {};
QVERIFY( !i.isValid() );
QVERIFY( !QFile::exists( filePath ) );
write_openswap_conf( targetFilePath, contents, i ); // Invalid i
QVERIFY( !QFile::exists( filePath ) );
QCOMPARE( contents.length(), 3 );
QCOMPARE( contents.at( 1 ).left( 4 ), QStringLiteral( "# s" ) );
// Can we write there at all?
QFile derp( filePath );
QVERIFY( derp.open( QIODevice::WriteOnly ) );
QVERIFY( derp.write( "xx", 2 ) );
derp.close();
QVERIFY( QFile::exists( filePath ) );
QVERIFY( QFile::remove( filePath ) );
// Once the information is valid, though, the file is written
make_valid_loshinfo( i );
QVERIFY( i.isValid() );
QVERIFY( !QFile::exists( filePath ) );
write_openswap_conf( targetFilePath, contents, i ); // Now it is valid
QVERIFY( QFile::exists( filePath ) );
QCOMPARE( contents.length(), 3 );
QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/sda0" ) ); // expected key value
QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/sda0" ) ); // expected line
// readLine() returns with newlines-added
QFile f( filePath );
QVERIFY( f.open( QIODevice::ReadOnly ) );
QCOMPARE( f.readLine(), QStringLiteral( "# Calamares demo\n" ) );
QCOMPARE( f.readLine(), QStringLiteral( "swap_device=/dev/sda0\n" ) );
QCOMPARE( f.readLine(), QStringLiteral( "# duck duck swap_device=another\n" ) );
QCOMPARE( f.readLine(), QString() );
QVERIFY( f.atEnd() );
// Note how the contents is updated on every write_openswap_conf()
i.swap_device_path = QStringLiteral( "/dev/zram/0.zram" );
write_openswap_conf( targetFilePath, contents, i ); // Still valid
QCOMPARE( contents.length(), 3 );
QCOMPARE( i.swap_device_path, QStringLiteral( "/dev/zram/0.zram" ) ); // expected key value
QCOMPARE( contents.at( 1 ), QStringLiteral( "swap_device=/dev/zram/0.zram" ) ); // expected line
}
void
LOSHTests::testJob()
{
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
QVERIFY( tempRoot.isValid() );
auto* ss = file_setup( tempRoot );
QVERIFY( ss );
Calamares::GlobalStorage* gs
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
QVERIFY( gs );
{
QDir d( tempRoot.path() );
d.mkdir( "etc" );
}
QVERIFY( !LOSHInfo::fromGlobalStorage().isValid() );
QVariantList outerPartition;
QVariantMap innerPartition;
innerPartition.insert( "mountPoint", "/" );
innerPartition.insert( "fs", "ext4" );
innerPartition.insert( "luksMapperName", "root" );
innerPartition.insert( "luksUUID", "0000" );
outerPartition.append( innerPartition );
innerPartition.remove( "mountPoint" );
innerPartition.insert( "fs", "linuxswap" );
innerPartition.insert( "luksMapperName", "swap" );
innerPartition.insert( "luksUuid", "0001" );
outerPartition.append( innerPartition );
gs->insert( "partitions", outerPartition );
QVERIFY( LOSHInfo::fromGlobalStorage().isValid() );
LOSHJob j;
j.setConfigurationMap( QVariantMap() );
auto jobresult = j.exec();
QVERIFY( jobresult );
{
QFile f( tempRoot.filePath( "etc/openswap.conf" ) );
QVERIFY( f.exists() );
QVERIFY( f.open( QIODevice::ReadOnly ) );
cDebug() << f.readAll();
}
}
QTEST_GUILESS_MAIN( LOSHTests )
#include "utils/moc-warnings.h"
#include "Tests.moc"

View File

@@ -1,100 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# === This file is part of Calamares - <https://calamares.io> ===
#
# SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
# SPDX-FileCopyrightText: 2017 Alf Gaida <agaida@siduction.org>
# SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
#
# Calamares is Free Software: see the License-Identifier above.
#
import libcalamares
import os.path
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
def pretty_name():
return _("Configuring encrypted swap.")
def write_openswap_conf(partitions, root_mount_point, openswap_conf_path):
swap_outer_uuid = ""
swap_mapper_name = ""
mountable_keyfile_device = ""
for partition in partitions:
if partition["fs"] == "linuxswap" and "luksMapperName" in partition:
swap_outer_uuid = partition["luksUuid"]
swap_mapper_name = partition["luksMapperName"]
elif partition["mountPoint"] == "/" and "luksMapperName" in partition:
mountable_keyfile_device = (
"/dev/mapper/{!s}".format(partition["luksMapperName"])
)
if not mountable_keyfile_device or not swap_outer_uuid:
return None
swap_device_path = "/dev/disk/by-uuid/{!s}".format(swap_outer_uuid)
lines = []
with open(os.path.join(root_mount_point,
openswap_conf_path), 'r') as openswap_file:
lines = [x.strip() for x in openswap_file.readlines()]
for i in range(len(lines)):
if lines[i].startswith("swap_device"):
lines[i] = "swap_device={!s}".format(swap_device_path)
elif lines[i].startswith("crypt_swap_name"):
lines[i] = "crypt_swap_name={!s}".format(swap_mapper_name)
elif lines[i].startswith("keyfile_device"):
lines[i] = "keyfile_device={!s}".format(mountable_keyfile_device)
elif lines[i].startswith("keyfile_filename"):
lines[i] = "keyfile_filename=crypto_keyfile.bin"
elif lines[i].startswith("#keyfile_device_mount_options"):
if libcalamares.globalstorage.contains("btrfsRootSubvolume"):
btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume")
lines[i] = "keyfile_device_mount_options=--options=subvol=" + btrfs_root_subvolume.lstrip("/")
with open(os.path.join(root_mount_point,
openswap_conf_path), 'w') as openswap_file:
openswap_file.write("\n".join(lines) + "\n")
return None
def run():
"""
This module sets up the openswap hook for a resumable encrypted swap.
:return:
"""
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
openswap_conf_path = libcalamares.job.configuration["configFilePath"]
partitions = libcalamares.globalstorage.value("partitions")
if not partitions:
libcalamares.utils.warning("partitions is empty, {!s}".format(partitions))
return (_("Configuration Error"),
_("No partitions are defined for <pre>{!s}</pre> to use.").format("luksopenswaphookcfg"))
if not root_mount_point:
libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point))
return (_("Configuration Error"),
_("No root mount point is given for <pre>{!s}</pre> to use.").format("luksopenswaphookcfg"))
openswap_conf_path = openswap_conf_path.lstrip('/')
return write_openswap_conf(partitions, root_mount_point, openswap_conf_path)

View File

@@ -1,7 +0,0 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
---
type: "job"
name: "luksopenswaphookcfg"
interface: "python"
script: "main.py"

View File

@@ -73,12 +73,12 @@ def replace_username(nm_config_filename, live_user, target_user):
if not os.path.exists(nm_config_filename):
return
with open(nm_config_filename, "r") as network_conf:
with open(nm_config_filename, "r", encoding="UTF-8") as network_conf:
text = network_conf.readlines()
live_permissions = 'permissions=user:{}:;'.format(live_user)
target_permissions = 'permissions=user:{}:;\n'.format(target_user)
with open(nm_config_filename, "w") as network_conf:
with open(nm_config_filename, "w", encoding="UTF-8") as network_conf:
for line in text:
if live_permissions in line:
line = target_permissions

View File

@@ -382,7 +382,7 @@ class PMPacman(PackageManager):
def line_cb(line):
if line.startswith(":: "):
self.in_package_changes = "package changes" in line
self.in_package_changes = "package" in line or "hooks" in line
else:
if self.in_package_changes and line.endswith("...\n"):
# Update the message, untranslated; do not change the
@@ -392,7 +392,7 @@ class PMPacman(PackageManager):
global custom_status_message
custom_status_message = "pacman: " + line.strip()
libcalamares.job.setprogress(self.progress_fraction)
libcalamares.utils.debug(line)
libcalamares.utils.debug(line)
self.in_package_changes = False
self.line_cb = line_cb
@@ -444,8 +444,12 @@ class PMPacman(PackageManager):
else:
command.append("-S")
# Don't ask for user intervention, take the default action
command.append("--noconfirm")
# Don't report download progress for each file
command.append("--noprogressbar")
if self.pacman_needed_only is True:
command.append("--needed")

View File

@@ -11,6 +11,7 @@
#include "DeviceList.h"
#include "partition/PartitionIterator.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <kpmcore/backend/corebackend.h>
@@ -40,16 +41,30 @@ hasRootPartition( Device* device )
return false;
}
/** @brief Check if @p path holds an iso9660 filesystem
*
* The @p path should point to a device; blkid is used to check the FS type.
*/
static bool
blkIdCheckIso9660( const QString& path )
{
QProcess blkid;
blkid.start( "blkid", { path } );
blkid.waitForFinished();
QString output = QString::fromLocal8Bit( blkid.readAllStandardOutput() );
return output.contains( "iso9660" );
// If blkid fails, there's no output, but we don't care
auto r = CalamaresUtils::System::runCommand( { "blkid", path }, std::chrono::seconds( 30 ) );
return r.getOutput().contains( "iso9660" );
}
/// @brief Convenience to check if @p partition holds an iso9660 filesystem
static bool
blkIdCheckIso9660P( const Partition* partition )
{
return blkIdCheckIso9660( partition->partitionPath() );
}
/** @brief Check if the @p device is an iso9660 device
*
* An iso9660 device is **probably** a CD-ROM. If the device holds an
* iso9660 FS, or any of its partitions do, then we call it an iso9660 device.
*/
static bool
isIso9660( const Device* device )
{
@@ -65,13 +80,8 @@ isIso9660( const Device* device )
if ( device->partitionTable() && !device->partitionTable()->children().isEmpty() )
{
for ( const Partition* partition : device->partitionTable()->children() )
{
if ( blkIdCheckIso9660( partition->partitionPath() ) )
{
return true;
}
}
const auto& p = device->partitionTable()->children();
return std::any_of( p.cbegin(), p.cend(), blkIdCheckIso9660P );
}
return false;
}

View File

@@ -15,8 +15,8 @@
#include "partition/PartitionIterator.h"
#include "utils/Logger.h"
#include "utils/String.h"
// KPMcore
#include <kpmcore/backend/corebackendmanager.h>
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
@@ -127,4 +127,23 @@ clonePartition( Device* device, Partition* partition )
partition->activeFlags() );
}
Calamares::JobResult
execute( Operation& operation, const QString& failureMessage )
{
operation.setStatus( Operation::StatusRunning );
Report report( nullptr );
if ( operation.execute( report ) )
{
return Calamares::JobResult::ok();
}
// Remove the === lines from the report by trimming them to empty
QStringList l = report.toText().split( '\n' );
std::for_each( l.begin(), l.end(), []( QString& s ) { CalamaresUtils::removeLeading( s, '=' ); } );
return Calamares::JobResult::error( failureMessage, l.join( '\n' ) );
}
} // namespace KPMHelpers

View File

@@ -11,11 +11,13 @@
#ifndef KPMHELPERS_H
#define KPMHELPERS_H
// KPMcore
#include "Job.h"
#include <kpmcore/core/partitiontable.h>
#include <kpmcore/fs/filesystem.h>
#include <kpmcore/ops/operation.h>
#include <kpmcore/util/report.h>
// Qt
#include <QList>
#include <functional>
@@ -72,6 +74,24 @@ Partition* createNewEncryptedPartition( PartitionNode* parent,
Partition* clonePartition( Device* device, Partition* partition );
/** @brief Return a result for an @p operation
*
* Executes the operation, and if successful, returns a success result.
* Otherwise returns an error using @p failureMessage as the primary part
* of the error, and details obtained from the operation.
*/
Calamares::JobResult execute( Operation& operation, const QString& failureMessage );
/** @brief Return a result for an @p operation
*
* It's acceptable to use an rvalue: the operation-running is the effect
* you're interested in, rather than keeping the temporary around.
*/
static inline Calamares::JobResult
execute( Operation&& operation, const QString& failureMessage )
{
return execute( operation, failureMessage );
}
} // namespace KPMHelpers
#endif /* KPMHELPERS_H */

View File

@@ -11,7 +11,9 @@
#include "CreatePartitionJob.h"
#include "core/KPMHelpers.h"
#include "core/PartitionInfo.h"
#include "partition/FileSystem.h"
#include "partition/PartitionQuery.h"
#include "utils/CalamaresUtilsSystem.h"
@@ -273,17 +275,9 @@ CreatePartitionJob::exec()
return createZfs( m_partition, m_device );
}
Report report( nullptr );
NewOperation op( *m_device, m_partition );
op.setStatus( Operation::StatusRunning );
QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute(
NewOperation( *m_device, m_partition ),
tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ) );
}
void

View File

@@ -12,9 +12,11 @@
#include "CreatePartitionTableJob.h"
#include "partition/PartitionIterator.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
// KPMcore
#include "core/KPMHelpers.h"
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
@@ -63,8 +65,6 @@ CreatePartitionTableJob::prettyStatusMessage() const
Calamares::JobResult
CreatePartitionTableJob::exec()
{
Report report( nullptr );
QString message = tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() );
PartitionTable* table = m_device->partitionTable();
@@ -76,30 +76,16 @@ CreatePartitionTableJob::exec()
cDebug() << Logger::SubEntry << ( ( *it ) ? ( *it )->deviceNode() : QString( "<null device>" ) );
}
QProcess lsblk;
lsblk.setProgram( "lsblk" );
lsblk.setProcessChannelMode( QProcess::MergedChannels );
lsblk.start();
lsblk.waitForFinished();
cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblk.readAllStandardOutput();
auto lsblkResult = CalamaresUtils::System::runCommand( { "lsblk" }, std::chrono::seconds( 30 ) );
cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblkResult.getOutput();
QProcess mount;
mount.setProgram( "mount" ); // Debug output only, not mounting something
mount.setProcessChannelMode( QProcess::MergedChannels );
mount.start();
mount.waitForFinished();
cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mount.readAllStandardOutput();
auto mountResult = CalamaresUtils::System::runCommand( { "mount" }, std::chrono::seconds( 30 ) );
cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mountResult.getOutput();
}
CreatePartitionTableOperation op( *m_device, table );
op.setStatus( Operation::StatusRunning );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute(
CreatePartitionTableOperation( *m_device, table ),
tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() ) );
}
void

View File

@@ -9,7 +9,8 @@
#include "CreateVolumeGroupJob.h"
// KPMcore
#include "core/KPMHelpers.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/ops/createvolumegroupoperation.h>
@@ -46,19 +47,8 @@ CreateVolumeGroupJob::prettyStatusMessage() const
Calamares::JobResult
CreateVolumeGroupJob::exec()
{
Report report( nullptr );
CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize );
op.setStatus( Operation::StatusRunning );
QString message = tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute( CreateVolumeGroupOperation( m_vgName, m_pvList, m_peSize ),
tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName ) );
}
void

View File

@@ -9,6 +9,8 @@
#include "DeactivateVolumeGroupJob.h"
#include "core/KPMHelpers.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/ops/deactivatevolumegroupoperation.h>
#include <kpmcore/util/report.h>
@@ -39,18 +41,12 @@ DeactivateVolumeGroupJob::prettyStatusMessage() const
Calamares::JobResult
DeactivateVolumeGroupJob::exec()
{
Report report( nullptr );
DeactivateVolumeGroupOperation op( *m_device );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() );
if ( op.execute( report ) )
auto r = KPMHelpers::execute(
op, tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() ) );
if ( r )
{
op.preview();
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return r;
}

View File

@@ -10,9 +10,11 @@
*/
#include "DeletePartitionJob.h"
#include "core/KPMHelpers.h"
#include "utils/CalamaresUtilsSystem.h"
// KPMcore
#include <kpmcore/core/device.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/core/partitiontable.h>
@@ -45,7 +47,7 @@ removePartition( Partition* partition )
auto r = CalamaresUtils::System::instance()->runCommand(
{ "sfdisk", "--delete", "--force", partition->devicePath(), QString::number( partition->number() ) },
std::chrono::seconds( 5 ) );
if ( r.getExitCode() !=0 || r.getOutput().contains("failed") )
if ( r.getExitCode() != 0 || r.getOutput().contains( "failed" ) )
{
return Calamares::JobResult::error(
QCoreApplication::translate( DeletePartitionJob::staticMetaObject.className(), "Deletion Failed" ),
@@ -96,17 +98,8 @@ DeletePartitionJob::exec()
return removePartition( m_partition );
}
Report report( nullptr );
DeleteOperation op( *m_device, m_partition );
op.setStatus( Operation::StatusRunning );
QString message = tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute( DeleteOperation( *m_device, m_partition ),
tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() ) );
}
void

View File

@@ -11,7 +11,10 @@
#include "FormatPartitionJob.h"
#include "core/KPMHelpers.h"
#include "partition/FileSystem.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <kpmcore/core/device.h>
@@ -65,17 +68,18 @@ FormatPartitionJob::prettyStatusMessage() const
Calamares::JobResult
FormatPartitionJob::exec()
{
Report report( nullptr ); // Root of the report tree, no parent
CreateFileSystemOperation op( *m_device, *m_partition, m_partition->fileSystem().type() );
op.setStatus( Operation::StatusRunning );
QString message = tr( "The installer failed to format partition %1 on disk '%2'." )
.arg( m_partition->partitionPath(), m_device->name() );
if ( op.execute( report ) )
const auto fsType = m_partition->fileSystem().type();
auto r = KPMHelpers::execute( CreateFileSystemOperation( *m_device, *m_partition, fsType ),
tr( "The installer failed to format partition %1 on disk '%2'." )
.arg( m_partition->partitionPath(), m_device->name() ) );
if ( fsType == FileSystem::Xfs && r.succeeded() )
{
return Calamares::JobResult::ok();
// We are going to try to set modern timestamps for the filesystem,
// (ignoring whether this succeeds). Requires a sufficiently-new
// xfs_admin and xfs_repair and might be made obsolete by newer
// kpmcore releases.
CalamaresUtils::System::runCommand( { "xfs_admin", "-O", "bigtime=1", m_partition->partitionPath() },
std::chrono::seconds( 60 ) );
}
return Calamares::JobResult::error( message, report.toText() );
return r;
}

View File

@@ -9,6 +9,8 @@
#include "RemoveVolumeGroupJob.h"
#include "core/KPMHelpers.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/ops/removevolumegroupoperation.h>
#include <kpmcore/util/report.h>
@@ -39,17 +41,7 @@ RemoveVolumeGroupJob::prettyStatusMessage() const
Calamares::JobResult
RemoveVolumeGroupJob::exec()
{
Report report( nullptr );
RemoveVolumeGroupOperation op( *m_device );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute(
RemoveVolumeGroupOperation( *m_device ),
tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() ) );
}

View File

@@ -11,9 +11,10 @@
#include "ResizePartitionJob.h"
#include "core/KPMHelpers.h"
#include "utils/Units.h"
// KPMcore
#include <kpmcore/core/device.h>
#include <kpmcore/ops/resizeoperation.h>
#include <kpmcore/util/report.h>
@@ -66,23 +67,16 @@ ResizePartitionJob::prettyStatusMessage() const
Calamares::JobResult
ResizePartitionJob::exec()
{
Report report( nullptr );
// Restore partition sectors that were modified for preview
m_partition->setFirstSector( m_oldFirstSector );
m_partition->setLastSector( m_oldLastSector );
ResizeOperation op( *m_device, *m_partition, m_newFirstSector, m_newLastSector );
op.setStatus( Operation::StatusRunning );
connect( &op, &Operation::progress, this, &ResizePartitionJob::iprogress );
QString errorMessage = tr( "The installer failed to resize partition %1 on disk '%2'." )
.arg( m_partition->partitionPath() )
.arg( m_device->name() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( errorMessage, report.toText() );
return KPMHelpers::execute( op,
tr( "The installer failed to resize partition %1 on disk '%2'." )
.arg( m_partition->partitionPath() )
.arg( m_device->name() ) );
}
void

View File

@@ -9,7 +9,8 @@
#include "ResizeVolumeGroupJob.h"
// KPMcore
#include "core/KPMHelpers.h"
#include <kpmcore/core/lvmdevice.h>
#include <kpmcore/core/partition.h>
#include <kpmcore/ops/resizevolumegroupoperation.h>
@@ -51,19 +52,9 @@ ResizeVolumeGroupJob::prettyStatusMessage() const
Calamares::JobResult
ResizeVolumeGroupJob::exec()
{
Report report( nullptr );
ResizeVolumeGroupOperation op( *m_device, m_partitionList );
op.setStatus( Operation::OperationStatus::StatusRunning );
QString message = tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( message, report.toText() );
return KPMHelpers::execute(
ResizeVolumeGroupOperation( *m_device, m_partitionList ),
tr( "The installer failed to resize a volume group named '%1'." ).arg( m_device->name() ) );
}
QString

View File

@@ -13,6 +13,8 @@
#include "SetPartitionFlagsJob.h"
#include "core/KPMHelpers.h"
#include "partition/FileSystem.h"
#include "utils/Logger.h"
#include "utils/Units.h"
@@ -148,17 +150,8 @@ SetPartFlagsJob::exec()
cDebug() << "Setting flags on" << m_device->deviceNode() << "partition" << partition()->deviceNode()
<< Logger::DebugList( flagsList );
Report report( nullptr );
SetPartFlagsOperation op( *m_device, *partition(), m_flags );
op.setStatus( Operation::StatusRunning );
connect( &op, &Operation::progress, this, &SetPartFlagsJob::iprogress );
QString errorMessage
= tr( "The installer failed to set flags on partition %1." ).arg( m_partition->partitionPath() );
if ( op.execute( report ) )
{
return Calamares::JobResult::ok();
}
return Calamares::JobResult::error( errorMessage, report.toText() );
return KPMHelpers::execute(
op, tr( "The installer failed to set flags on partition %1." ).arg( m_partition->partitionPath() ) );
}

View File

@@ -3,14 +3,20 @@
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
#
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
calamares_add_plugin( preservefiles
TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
Item.cpp
PreserveFiles.cpp
# REQUIRES mount # To set the rootMountPoint
SHARED_LIB
EMERGENCY
)
calamares_add_test(
preservefilestest
SOURCES
Item.cpp
Tests.cpp
)

View File

@@ -0,0 +1,159 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2018, 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#include "Item.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/Units.h"
#include "utils/Variant.h"
#include <QFile>
using namespace CalamaresUtils::Units;
static bool
copy_file( const QString& source, const QString& dest )
{
QFile sourcef( source );
if ( !sourcef.open( QFile::ReadOnly ) )
{
cWarning() << "Could not read" << source;
return false;
}
QFile destf( dest );
if ( !destf.open( QFile::WriteOnly ) )
{
sourcef.close();
cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source;
return false;
}
QByteArray b;
do
{
b = sourcef.read( 1_MiB );
destf.write( b );
} while ( b.count() > 0 );
sourcef.close();
destf.close();
return true;
}
Item
Item::fromVariant( const QVariant& v, const CalamaresUtils::Permissions& defaultPermissions )
{
if ( v.type() == QVariant::String )
{
QString filename = v.toString();
if ( !filename.isEmpty() )
{
return { filename, filename, defaultPermissions, ItemType::Path, false };
}
else
{
cWarning() << "Empty filename for preservefiles, item" << v;
return {};
}
}
else if ( v.type() == QVariant::Map )
{
const auto map = v.toMap();
CalamaresUtils::Permissions perm( defaultPermissions );
ItemType t = ItemType::None;
bool optional = CalamaresUtils::getBool( map, "optional", false );
{
QString perm_string = map[ "perm" ].toString();
if ( !perm_string.isEmpty() )
{
perm = CalamaresUtils::Permissions( perm_string );
}
}
{
QString from = map[ "from" ].toString();
t = ( from == "log" ) ? ItemType::Log : ( from == "config" ) ? ItemType::Config : ItemType::None;
if ( t == ItemType::None && !map[ "src" ].toString().isEmpty() )
{
t = ItemType::Path;
}
}
QString dest = map[ "dest" ].toString();
if ( dest.isEmpty() )
{
cWarning() << "Empty dest for preservefiles, item" << v;
return {};
}
switch ( t )
{
case ItemType::Config:
return { QString(), dest, perm, t, optional };
case ItemType::Log:
return { QString(), dest, perm, t, optional };
case ItemType::Path:
return { map[ "src" ].toString(), dest, perm, t, optional };
case ItemType::None:
cWarning() << "Invalid type for preservefiles, item" << v;
return {};
}
}
cWarning() << "Invalid type for preservefiles, item" << v;
return {};
}
bool
Item::exec( const std::function< QString( QString ) >& replacements ) const
{
QString expanded_dest = replacements( dest );
QString full_dest = CalamaresUtils::System::instance()->targetPath( expanded_dest );
bool success = false;
switch ( m_type )
{
case ItemType::None:
cWarning() << "Invalid item for preservefiles skipped.";
return false;
case ItemType::Config:
if ( !( success = Calamares::JobQueue::instance()->globalStorage()->saveJson( full_dest ) ) )
{
cWarning() << "Could not write a JSON dump of global storage to" << full_dest;
}
break;
case ItemType::Log:
if ( !( success = copy_file( Logger::logFile(), full_dest ) ) )
{
cWarning() << "Could not preserve log file to" << full_dest;
}
break;
case ItemType::Path:
if ( !( success = copy_file( source, full_dest ) ) )
{
cWarning() << "Could not preserve" << source << "to" << full_dest;
}
break;
}
if ( !success )
{
CalamaresUtils::System::instance()->removeTargetFile( expanded_dest );
return false;
}
else
{
return perm.apply( full_dest );
}
}

View File

@@ -0,0 +1,76 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2018, 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
*/
#ifndef PRESERVEFILES_ITEM_H
#define PRESERVEFILES_ITEM_H
#include "utils/Permissions.h"
#include <QString>
#include <QVariant>
#include <memory>
enum class ItemType
{
None,
Path,
Log,
Config
};
/** @brief Represents one item to copy
*
* All item types need a destination (to place the data), this is
* intepreted within the target system. All items need a permission,
* which is applied to the data once written.
*
* The source may be a path, but not all types need a source.
*/
class Item
{
QString source;
QString dest;
CalamaresUtils::Permissions perm;
ItemType m_type = ItemType::None;
bool m_optional = false;
public:
Item( const QString& src, const QString& d, CalamaresUtils::Permissions p, ItemType t, bool optional )
: source( src )
, dest( d )
, perm( std::move( p ) )
, m_type( t )
, m_optional( optional )
{
}
Item()
: m_type( ItemType::None )
{
}
operator bool() const { return m_type != ItemType::None; }
ItemType type() const { return m_type; }
bool isOptional() const { return m_optional; }
bool exec( const std::function< QString( QString ) >& replacements ) const;
/** @brief Create an Item -- or one of its subclasses -- from @p v
*
* Depending on the structure and contents of @p v, a pointer
* to an Item is returned. If @p v cannot be interpreted meaningfully,
* then a nullptr is returned.
*
* When the entry contains a *perm* key, use that permission, otherwise
* apply @p defaultPermissions to the item.
*/
static Item fromVariant( const QVariant& v, const CalamaresUtils::Permissions& defaultPermissions );
};
#endif

View File

@@ -7,46 +7,20 @@
#include "PreserveFiles.h"
#include "Item.h"
#include "CalamaresVersion.h"
#include "GlobalStorage.h"
#include "JobQueue.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/CommandList.h"
#include "utils/Logger.h"
#include "utils/Permissions.h"
#include "utils/Units.h"
#include <QFile>
using namespace CalamaresUtils::Units;
QString
targetPrefix()
{
if ( CalamaresUtils::System::instance()->doChroot() )
{
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
if ( gs && gs->contains( "rootMountPoint" ) )
{
QString r = gs->value( "rootMountPoint" ).toString();
if ( !r.isEmpty() )
{
return r;
}
else
{
cDebug() << "RootMountPoint is empty";
}
}
else
{
cDebug() << "No rootMountPoint defined, preserving files to '/'";
}
}
return QLatin1String( "/" );
}
QString
atReplacements( QString s )
{
@@ -79,95 +53,34 @@ PreserveFiles::prettyName() const
return tr( "Saving files for later ..." );
}
static bool
copy_file( const QString& source, const QString& dest )
{
QFile sourcef( source );
if ( !sourcef.open( QFile::ReadOnly ) )
{
cWarning() << "Could not read" << source;
return false;
}
QFile destf( dest );
if ( !destf.open( QFile::WriteOnly ) )
{
sourcef.close();
cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source;
return false;
}
QByteArray b;
do
{
b = sourcef.read( 1_MiB );
destf.write( b );
} while ( b.count() > 0 );
sourcef.close();
destf.close();
return true;
}
Calamares::JobResult
PreserveFiles::exec()
{
if ( m_items.isEmpty() )
if ( m_items.empty() )
{
return Calamares::JobResult::error( tr( "No files configured to save for later." ) );
}
QString prefix = targetPrefix();
if ( !prefix.endsWith( '/' ) )
{
prefix.append( '/' );
}
int count = 0;
for ( const auto& it : m_items )
for ( const auto& it : qAsConst( m_items ) )
{
QString source = it.source;
QString bare_dest = atReplacements( it.dest );
QString dest = prefix + bare_dest;
if ( it.type == ItemType::Log )
if ( !it )
{
source = Logger::logFile();
// Invalid entries are nullptr, ignore them but count as a success
// because they shouldn't block the installation. There are
// warnings in the log showing what the configuration problem is.
++count;
continue;
}
if ( it.type == ItemType::Config )
// Try to preserve the file. If it's marked as optional, count it
// as a success regardless.
if ( it.exec( atReplacements ) || it.isOptional() )
{
if ( !Calamares::JobQueue::instance()->globalStorage()->saveJson( dest ) )
{
cWarning() << "Could not write a JSON dump of global storage to" << dest;
}
else
{
++count;
}
}
else if ( source.isEmpty() )
{
cWarning() << "Skipping unnamed source file for" << dest;
}
else
{
if ( copy_file( source, dest ) )
{
if ( it.perm.isValid() )
{
if ( !it.perm.apply( CalamaresUtils::System::instance()->targetPath( bare_dest ) ) )
{
cWarning() << "Could not set attributes of" << bare_dest;
}
}
++count;
}
++count;
}
}
return count == m_items.count()
return count == m_items.size()
? Calamares::JobResult::ok()
: Calamares::JobResult::error( tr( "Not all of the configured files could be preserved." ) );
}
@@ -193,53 +106,11 @@ PreserveFiles::setConfigurationMap( const QVariantMap& configurationMap )
{
defaultPermissions = QStringLiteral( "root:root:0400" );
}
CalamaresUtils::Permissions perm( defaultPermissions );
QVariantList l = files.toList();
unsigned int c = 0;
for ( const auto& li : l )
for ( const auto& li : files.toList() )
{
if ( li.type() == QVariant::String )
{
QString filename = li.toString();
if ( !filename.isEmpty() )
m_items.append(
Item { filename, filename, CalamaresUtils::Permissions( defaultPermissions ), ItemType::Path } );
else
{
cDebug() << "Empty filename for preservefiles, item" << c;
}
}
else if ( li.type() == QVariant::Map )
{
const auto map = li.toMap();
QString dest = map[ "dest" ].toString();
QString from = map[ "from" ].toString();
ItemType t = ( from == "log" ) ? ItemType::Log : ( from == "config" ) ? ItemType::Config : ItemType::None;
QString perm = map[ "perm" ].toString();
if ( perm.isEmpty() )
{
perm = defaultPermissions;
}
if ( dest.isEmpty() )
{
cDebug() << "Empty dest for preservefiles, item" << c;
}
else if ( t == ItemType::None )
{
cDebug() << "Invalid type for preservefiles, item" << c;
}
else
{
m_items.append( Item { QString(), dest, CalamaresUtils::Permissions( perm ), t } );
}
}
else
{
cDebug() << "Invalid type for preservefiles, item" << c;
}
++c;
m_items.push_back( Item::fromVariant( li, perm ) );
}
}

View File

@@ -10,33 +10,14 @@
#include "CppJob.h"
#include "DllMacro.h"
#include "utils/Permissions.h"
#include "utils/PluginFactory.h"
#include <QList>
#include <QObject>
#include <QVariantMap>
class Item;
class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob
{
Q_OBJECT
enum class ItemType
{
None,
Path,
Log,
Config
};
struct Item
{
QString source;
QString dest;
CalamaresUtils::Permissions perm;
ItemType type;
};
using ItemList = QList< Item >;
public:

View File

@@ -0,0 +1,93 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#include "Item.h"
#include "Settings.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include "utils/NamedEnum.h"
#include "utils/Yaml.h"
#include <QtTest/QtTest>
class PreserveFilesTests : public QObject
{
Q_OBJECT
public:
PreserveFilesTests();
~PreserveFilesTests() override {}
private Q_SLOTS:
void initTestCase();
void testItems_data();
void testItems();
};
PreserveFilesTests::PreserveFilesTests() {}
void
PreserveFilesTests::initTestCase()
{
Logger::setupLogLevel( Logger::LOGDEBUG );
cDebug() << "PreserveFiles test started.";
// Ensure we have a system object, expect it to be a "bogus" one
CalamaresUtils::System* system = CalamaresUtils::System::instance();
QVERIFY( system );
cDebug() << Logger::SubEntry << "System @" << Logger::Pointer( system );
const auto* settings = Calamares::Settings::instance();
if ( !settings )
{
(void)new Calamares::Settings( true );
}
}
void
PreserveFilesTests::testItems_data()
{
QTest::addColumn< QString >( "filename" );
QTest::addColumn< bool >( "ok" );
QTest::addColumn< int >( "type_i" );
QTest::newRow( "log " ) << QString( "1a-log.conf" ) << true << smash( ItemType::Log );
QTest::newRow( "config " ) << QString( "1b-config.conf" ) << true << smash( ItemType::Config );
QTest::newRow( "src " ) << QString( "1c-src.conf" ) << true << smash( ItemType::Path );
QTest::newRow( "filename" ) << QString( "1d-filename.conf" ) << true << smash( ItemType::Path );
QTest::newRow( "empty " ) << QString( "1e-empty.conf" ) << false << smash( ItemType::None );
QTest::newRow( "bad " ) << QString( "1f-bad.conf" ) << false << smash( ItemType::None );
}
void
PreserveFilesTests::testItems()
{
QFETCH( QString, filename );
QFETCH( bool, ok );
QFETCH( int, type_i );
QFile fi( QString( "%1/tests/%2" ).arg( BUILD_AS_TEST, filename ) );
QVERIFY( fi.exists() );
bool config_file_ok = false;
const auto map = CalamaresUtils::loadYaml( fi, &config_file_ok );
QVERIFY( config_file_ok );
CalamaresUtils::Permissions perm( QStringLiteral( "adridg:adridg:0750" ) );
auto i = Item::fromVariant( map[ "item" ], perm );
QCOMPARE( bool( i ), ok );
QCOMPARE( smash( i.type() ), type_i );
}
QTEST_GUILESS_MAIN( PreserveFilesTests )
#include "utils/moc-warnings.h"
#include "Tests.moc"

View File

@@ -7,42 +7,58 @@
# the list should have one of these forms:
#
# - an absolute path (probably within the host system). This will be preserved
# as the same path within the target system (chroot). If, globally, dontChroot
# is true, then these items are ignored (since the destination is the same
# as the source).
# as the same path within the target system (chroot). If, globally,
# *dontChroot* is true, then these items will be ignored (since the
# destination is the same as the source).
# - a map with a *dest* key. The *dest* value is a path interpreted in the
# target system (if dontChroot is true, in the host system). Relative paths
# are not recommended. There are three possible other keys in the map:
# target system (if the global *dontChroot* is true, then the host is the
# target as well). Relative paths are not recommended. There are two
# ways to select the source data for the file:
# - *from*, which must have one of the values, below; it is used to
# preserve files whose pathname is known to Calamares internally.
# - *src*, to refer to a path interpreted in the host system. Relative
# paths are not recommended, and are interpreted relative to where
# Calamares is being run.
# Exactly one of the two source keys (either *from* or *src*) must be set.
#
# Special values for the key *from* are:
# - *log*, for the complete log file (up to the moment the preservefiles
# module is run),
# - *config*, for a JSON dump of the contents of global storage.
# Note that this may contain sensitive information, and should be
# given restrictive permissions.
#
# A map with a *dest* key can have these additional fields:
# - *perm*, is a colon-separated tuple of <user>:<group>:<mode>
# where <mode> is in octal (e.g. 4777 for wide-open, 0400 for read-only
# by owner). If set, the file's ownership and permissions are set to
# those values within the target system; if not set, no permissions
# are changed.
# Only one of the two source keys (either *from* or *src*) may be set.
# - *optional*, is a boolean; if this is set to `true` then failure to
# preserve the file will **not** be counted as a failure of the
# module, and installation will proceed. Set this for files that might
# not exist in the host system (e.g. nvidia configuration files that
# are created in some boot scenarios and not in others).
#
# The target filename is modified as follows:
# - `@@ROOT@@` is replaced by the path to the target root (may be /)
# The target path (*dest*) is modified as follows:
# - `@@ROOT@@` is replaced by the path to the target root (may be /).
# There is never any reason to use this, since the *dest* is already
# interpreted in the target system.
# - `@@USER@@` is replaced by the username entered by on the user
# page (may be empty, for instance if no user page is enabled)
#
# Special values for the key *from* are:
# - *log*, for the complete log file (up to the moment the preservefiles
# module is run),
# - *config*, for a JSON dump of the contents of global storage
---
#
#
files:
- /etc/oem-information
- from: log
dest: /root/install.log
perm: root:wheel:644
dest: /var/log/Calamares.log
perm: root:wheel:600
- from: config
dest: /root/install.json
perm: root:wheel:400
dest: /var/log/Calamares-install.json
perm: root:wheel:600
# - src: /var/log/nvidia.conf
# dest: /var/log/Calamares-nvidia.conf
# optional: true
# The *perm* key contains a default value to apply to all files listed
# above that do not have a *perm* key of their own. If not set,

View File

@@ -0,0 +1,37 @@
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
# SPDX-License-Identifier: GPL-3.0-or-later
---
$schema: https://json-schema.org/schema#
$id: https://calamares.io/schemas/preservefiles
additionalProperties: false
type: object
properties:
# TODO: it's a particularly-formatted string
perm: { type: string }
files:
type: array
items:
# There are three entries here because: string, or an entry with
# a src (but no from) or an entry with from (but no src).
anyOf:
- type: string
- type: object
properties:
dest: { type: string }
src: { type: string }
# TODO: it's a particularly-formatted string
perm: { type: string }
optional: { type: boolean }
required: [ dest ]
additionalProperties: false
- type: object
properties:
dest: { type: string }
from: { type: string, enum: [config, log] }
# TODO: it's a particularly-formatted string
perm: { type: string }
optional: { type: boolean }
required: [ dest ]
additionalProperties: false
required: [ files ]

View File

@@ -0,0 +1,7 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
item:
from: log
dest: /var/log/Calamares.log
perm: root:wheel:601

View File

@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
item:
from: config
dest: /var/log/Calamares-install.json
perm: root:wheel:600

View File

@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
item:
src: /root/.cache/calamares/session.log
dest: /var/log/Calamares.log
perm: root:wheel:600

View File

@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
item:
src: /root/.cache/calamares/session.log
dest: /var/log/Calamares.log
perm: root:wheel:600

View File

@@ -0,0 +1,3 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
item: []

View File

@@ -0,0 +1,4 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
item:
bop: 1

View File

@@ -77,10 +77,13 @@ def run():
"""
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
if(libcalamares.job.configuration and
"srcLog" in libcalamares.job.configuration or
"destLog" in libcalamares.job.configuration):
libcalamares.utils.error("Log-file preserving is **deprecated** in the *umount* module and removed in the next release")
if(libcalamares.job.configuration and
"srcLog" in libcalamares.job.configuration and
"destLog" in libcalamares.job.configuration):
libcalamares.utils.warning("Log-file preserving is **deprecated** in the *umount* module")
log_source = libcalamares.job.configuration["srcLog"]
log_destination = libcalamares.job.configuration["destLog"]
# Relocate log_destination into target system

View File

@@ -5,3 +5,4 @@ type: "job"
name: "umount"
interface: "python"
script: "main.py"
emergency: true

View File

@@ -28,3 +28,7 @@
#srcLog: "/home/live/installation.log"
#destLog: "/var/log/installation.log"
srcLog: "/bogus/just/do/not/use/this/anymore.txt"
# Setting emergency to true will make it so this module is still run
# when a prior module fails
# emergency: true

View File

@@ -428,14 +428,16 @@ def run():
if not root_mount_point:
libcalamares.utils.warning("No mount point for root partition")
return (_("No mount point for root partition"),
_("globalstorage does not contain a \"rootMountPoint\" key, "
"doing nothing"))
_("globalstorage does not contain a \"rootMountPoint\" key."))
if not os.path.exists(root_mount_point):
libcalamares.utils.warning("Bad root mount point \"{}\"".format(root_mount_point))
return (_("Bad mount point for root partition"),
_("rootMountPoint is \"{}\", which does not "
"exist, doing nothing").format(root_mount_point))
_("rootMountPoint is \"{}\", which does not exist.".format(root_mount_point)))
if libcalamares.job.configuration.get("unpack", None) is None:
libcalamares.utils.warning("No *unpack* key in job configuration.")
return (_("Bad unpackfs configuration"),
_("There is no configuration information."))
supported_filesystems = get_supported_filesystems()
@@ -450,17 +452,17 @@ def run():
if sourcefs not in supported_filesystems:
libcalamares.utils.warning("The filesystem for \"{}\" ({}) is not supported by your current kernel".format(source, sourcefs))
libcalamares.utils.warning(" ... modprobe {} may solve the problem".format(sourcefs))
return (_("Bad unsquash configuration"),
return (_("Bad unpackfs configuration"),
_("The filesystem for \"{}\" ({}) is not supported by your current kernel").format(source, sourcefs))
if not os.path.exists(source):
libcalamares.utils.warning("The source filesystem \"{}\" does not exist".format(source))
return (_("Bad unsquash configuration"),
return (_("Bad unpackfs configuration"),
_("The source filesystem \"{}\" does not exist").format(source))
if sourcefs == "squashfs":
if shutil.which("unsquashfs") is None:
libcalamares.utils.warning("Failed to find unsquashfs")
return (_("Bad unsquash configuration"),
return (_("Bad unpackfs configuration"),
_("Failed to find unsquashfs, make sure you have the squashfs-tools package installed.") +
" " + _("Failed to unpack image \"{}\"").format(source))
@@ -475,7 +477,7 @@ def run():
if not os.path.isdir(destination) and sourcefs != "file":
libcalamares.utils.warning(("The destination \"{}\" in the target system is not a directory").format(destination))
if is_first:
return (_("Bad unsquash configuration"),
return (_("Bad unpackfs configuration"),
_("The destination \"{}\" in the target system is not a directory").format(destination))
else:
libcalamares.utils.debug(".. assuming that the previous targets will create that directory.")