Compare commits

...

246 Commits

Author SHA1 Message Date
Adriaan de Groot
3aa4b7368c [partition] Log partition-model lookup failures 2021-12-15 13:57:20 +01:00
Adriaan de Groot
288674a924 [partition] Stub validator for LV name
- An empty LV name isn't allowed, but the create-partition-dialog
  doesn't check for that.
2021-12-15 13:01:58 +01:00
Adriaan de Groot
30b5be0fd4 [partition] Use name PartitionVector consistently
- move definition to a central place,
- drop per-class definitions and corresponding checks,
- use it and add constness as appropriate.
2021-12-15 12:19:59 +01:00
Adriaan de Groot
10334ab14f [partition] More constness, fixes build 2021-12-15 00:30:23 +01:00
Adriaan de Groot
46d69b04d4 [partition] Make the naming of type PartitionVector consistent
- static assert that various names are consistent (in gui, because we can have
  a dependency gui->core)
2021-12-15 00:20:23 +01:00
Adriaan de Groot
f1185d38d8 [partition] Drop unneeded parameters and stored references
- the dialog can return, by value, the selected PVs and
  doesn't need to hold a reference to external storage.

Doesn't compile because the actions in core want a reference.
2021-12-14 17:52:13 +01:00
Adriaan de Groot
2c16d812cd [partition] Factor out determining which PVs exist 2021-12-14 17:27:15 +01:00
Adriaan de Groot
7a071207a2 [partition] Hit VG code with a hammer until it compiles again 2021-12-14 16:53:33 +01:00
Adriaan de Groot
3edfa5ebb5 [partition] Sanitize the base dialog for VGs
- force broken compilation by changing order of parameters to
  constructor; this is to help identify all the consumers.
- improve naming of UI-access-methods.
2021-12-14 16:28:25 +01:00
Adriaan de Groot
898f4498e8 [partition] document UI-accessors as such 2021-12-14 16:02:26 +01:00
Adriaan de Groot
e2d5f01aa1 [partition] Group partition- and VG-methods 2021-12-14 15:53:50 +01:00
Adriaan de Groot
8d7c08612f [partition] Conventional const-ness 2021-12-14 15:52:41 +01:00
Adriaan de Groot
febc5f5b41 [partition] Conventional const-ness 2021-12-14 15:50:04 +01:00
Adriaan de Groot
35a4273127 [partition] Avoid storing references; provide getter for dialog. 2021-12-14 15:43:58 +01:00
Adriaan de Groot
4402ebd8e8 [partition] Clarify name peSize 2021-12-14 15:24:58 +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
db86c24638 Changes: pre-hotfix-release housekeeping 2021-12-11 13:23:23 +01:00
Adriaan de Groot
03da766b39 [partition] Keep 64-bit integers for swap sizes
FIXES #1849
2021-12-11 13:19:08 +01:00
Adriaan de Groot
adaed52818 Changes: post-release housekeeping 2021-12-10 17:01:42 +01:00
Adriaan de Groot
7ac42b5f40 [umount] Tests don't like an empty config
- modules with no configuration should be marked 'noconfig',
  but umount is special: it has no **useful** configuration
  (maybe no **non-deprecated** configuration), but isn't
  marked 'noconfig' **yet**.
2021-12-10 16:44:01 +01:00
Calamares CI
3cdb019de7 i18n: [calamares] Automatic merge of Transifex translations 2021-12-10 15:55:58 +01:00
Adriaan de Groot
b4afedc79e Changes: pre-release housekeeping 2021-12-10 15:46:11 +01:00
Adriaan de Groot
c834a5066d [umount] Make it much more clear that the logfiles-thing is going away. 2021-12-05 02:26:23 +01:00
Adriaan de Groot
1d96c5af46 [partition] Table type 'none' is a late addition. 2021-12-05 01:32:51 +01:00
Adriaan de Groot
bc2713ccbb [libcalamares] Add string functions for lstrip() and rstrip()-like 2021-12-08 14:08:37 +01:00
Adriaan de Groot
bb948c47dc [fstab] Cut the example btrfs flags to 'defaults'
Testing shows that the flags can influence -- maybe cause -- data
corruption when noatime is set.

FIXES #1846
2021-12-08 13:06:53 +01:00
Adriaan de Groot
fa29ae2c5e Merge branch 'reduce-warnings' into calamares 2021-12-08 01:02:32 +01:00
Adriaan de Groot
043bdc36d6 Changes: document contributors 2021-12-08 01:02:27 +01:00
Adriaan de Groot
f0eb7ffbda [partition Untangle, Warnings--
The translations apply to labels and a tooltip, which depends on
the partition-table type. Move the strings together and make
the whole range of the switch explicitly.
2021-12-08 00:59:20 +01:00
Adriaan de Groot
e8ca298712 [partition] Reduce warnings 2021-12-08 00:15:01 +01:00
Adriaan de Groot
13700b18c8 [partition] Warnings--
- remove superfluous `break`
- massage types around partition sizes
2021-12-08 00:06:17 +01:00
Adriaan de Groot
1197d8c750 [interactiveterminal] Warnings-- with KF5 5.86-or-later 2021-12-07 18:19:32 +01:00
Adriaan de Groot
09f47b5762 [partition] Build tests with consistent flags (in particular, KPMCore4-API flags) 2021-12-07 15:51:45 +01:00
Adriaan de Groot
4611545f93 [libcalamares] Warnings-- on switch()
- some switch statements handle a bunch of items explicitly,
  then default the rest. Clang complains about that. Turn off
  the warning for these specific switches, since there's dozens
  of values that simply do not need to be handled.
2021-12-07 15:42:14 +01:00
Adriaan de Groot
6e715205d7 [partition] Warnings-- by calling formatting consistently 2021-12-07 15:36:11 +01:00
Adriaan de Groot
09a03fbbc0 [partition] Warnings--: we don't care about one-byte-in-10^12 2021-12-07 15:31:49 +01:00
Adriaan de Groot
bb3f4442f5 [partition] Warnings-reduction
- use consistent size-formatting
- needs an out-of-line virtual function
2021-12-07 15:30:21 +01:00
Adriaan de Groot
5b05110351 [partition] Add convenience function formatByteSize
We want to use the KPMCore function consistently, but Calamares
uses a qint64 most of the time. Centralize the cast to double
in one place in the code.
2021-12-07 15:29:02 +01:00
Adriaan de Groot
eda85c176a [tracking] Avoid unused-deprecated-methods warnings
- these are internal classes, with no real Qt machinery; remove
  the Q_OBJECT macros.
- replace the tr() calls with calls with an explicit context,
  so that translations do not change.
2021-12-07 15:07:07 +01:00
Adriaan de Groot
32da51b44c [libcalamares] Avoid warnings in Boost::Python macros 2021-12-07 14:48:19 +01:00
Adriaan de Groot
0b6239a996 [libcalamaresui] Warnings-- : we know TCP ports are 16 bit 2021-12-07 14:28:55 +01:00
Adriaan de Groot
79ae3cd00f Merge branch 'shuffle-error-dialog' into calamares 2021-12-07 14:27:13 +01:00
Adriaan de Groot
c2e63f4a6b [libcalamaresui] Don't bother tagging nonexistent 3rdparty sources 2021-12-07 14:20:31 +01:00
Adriaan de Groot
8b804c4ae0 [libcalamaresui] Improve icon+heading layout
- Icon was too wide, heading and message placed off to the side
2021-12-07 14:15:43 +01:00
Adriaan de Groot
3030a710cc [libcalamaresui] Simplify 2021-12-07 12:58:22 +01:00
Adriaan de Groot
b07c9bb4af [libcalamaresui] Use meaningful type for Upload info
- use a struct with named fields instead of a tuple
- offer an operator bool() for the logic of does-it-make-sense-to-upload
2021-12-07 12:53:43 +01:00
Adriaan de Groot
3234de5753 [libcalamaresui] Make web-paste decision more readable 2021-12-07 12:48:17 +01:00
Adriaan de Groot
2f9edb3e08 [libcalamaresui] Code style 2021-12-07 12:44:19 +01:00
Adriaan de Groot
ca7f288488 [libcalamaresui] APIDOX for ErrorDialog 2021-12-07 12:40:05 +01:00
Adriaan de Groot
49890acd04 [libcalamaresui] Fix build after move 2021-12-07 12:39:50 +01:00
Adriaan de Groot
dc11dd2203 [libcalamaresui] Move ErrorDialog to the widgets/ part 2021-12-07 12:24:41 +01:00
Adriaan de Groot
6e59177f54 Merge pull request #1843 from LordTermor/calamares
Rework of error dialog
2021-12-07 12:06:01 +01:00
Calamares CI
d2ac201b98 i18n: [desktop] Automatic merge of Transifex translations 2021-12-07 12:00:03 +01:00
Calamares CI
c8ea3bccf7 i18n: [desktop] Automatic merge of Transifex translations 2021-12-07 12:00:03 +01:00
Calamares CI
8e4c9b8bd6 i18n: [calamares] Automatic merge of Transifex translations 2021-12-07 12:00:03 +01:00
Adriaan de Groot
13196ed2e2 CI: sort .desktop entries for i18n
The ordering of entries jumps around sometimes when reading from
Transifex (this might be Python unordered dictionaries, or based
on translation statistics -- I can't tell). Force an order by
sorting on language code and key-name so they all end up grouped
by language code, sorted Name Icon GenericName Comment.

Although this shuffles some more entries now, longer-term it
will reduce churn in the .desktop file.
2021-12-07 11:59:36 +01:00
Adriaan de Groot
eb2cf60466 CI: support FreeBSD when pulling translations 2021-12-07 10:57:06 +01:00
Adriaan de Groot
149f3ff3fe [partition] Reduce warnings about shadowed variables 2021-12-06 14:52:33 +01:00
Adriaan de Groot
d89553a777 [partition] Avoid problems with MessageAndPath in containers (drop const) 2021-12-06 14:46:26 +01:00
Adriaan de Groot
890c17cd71 [libcalamares] Expand error-logging when creating files 2021-12-06 14:46:26 +01:00
Adriaan de Groot
6ef7acc108 [libcalamares] Add minor tests for new readTargetFile 2021-12-06 14:46:26 +01:00
Adriaan de Groot
baf8297cc4 [libcalamares] Reading a file from target system 2021-12-06 14:46:26 +01:00
Adriaan de Groot
47f2dd3c18 Merge pull request #1844 from dalto8/openswap
Add support for unlocking encrypted swap with root on a btrfs subvol
2021-12-06 10:42:44 +01:00
dalto
6e08da6c8d [bootloader] Fix error with systemd-boot when path exists in the ESP 2021-12-06 10:31:58 +01:00
Adriaan de Groot
b8c02587ae Changes: post-release housekeeping 2021-12-06 10:29:16 +01:00
Artem Grinev
aa332477fd [libcalamaresui] Run clang-format on TranslationFix.cpp 2021-12-06 03:11:16 +04:00
Artem Grinev
d9f7726f7d [libcalamaresui] Add SPDX-header for Error Dialog files 2021-12-06 02:41:17 +04:00
Artem Grinev
2f2a418cc4 [libcalamaresui] Run clang-format 2021-12-06 02:37:11 +04:00
Artem Grinev
2dd77ee828 [libcalamaresui] Initialize Error Dialog field 2021-12-06 02:31:05 +04:00
Artem Grinev
bfa7b9a792 [libcalamaresui] Use translation fix for Error Dialog 2021-12-06 02:27:18 +04:00
Artem Grinev
32c5e18db0 [libcalamaresui] Add QDialogButtonBox translation fix 2021-12-06 02:26:13 +04:00
Adriaan de Groot
003e7949e3 Merge pull request #1841 from dalto8/btrfs-nesting
[mount] Ensure path is available when creating nested btrfs subvolumes
2021-12-05 20:54:23 +01:00
dalto
e8936392e3 [luksopenswaphookcfg] Add support unlocking swap with root on a btrfs subvol 2021-12-05 13:17:23 -06:00
Artem Grinev
6bf0da7230 [libcalamaresui] Initial rework of error dialog 2021-12-05 04:50:13 +04:00
dalto
6e8779cbce [mount] Ensure path is available when creating nested btrfs subvolumes 2021-12-04 08:53:15 -06:00
Adriaan de Groot
ceb9ec4115 [fstab] Avoid KeyError when no subvol is set (from dalto8) 2021-12-04 02:15:33 +01:00
Adriaan de Groot
c22bbea528 [packages] Fix tests; YAML interpretation of 'yes' is not a bool 2021-12-04 02:04:24 +01:00
Adriaan de Groot
5277892e4f Changes: pre-release housekeeping 2021-12-03 23:47:16 +01:00
Calamares CI
5b767e147d i18n: [python] Automatic merge of Transifex translations 2021-12-03 23:30:28 +01:00
Calamares CI
0178fe6782 i18n: [desktop] Automatic merge of Transifex translations 2021-12-03 23:30:27 +01:00
Calamares CI
209c48d67f i18n: [calamares] Automatic merge of Transifex translations 2021-12-03 23:30:27 +01:00
Adriaan de Groot
310d67cf27 Merge branch 'btrfs-no-subvolume' into calamares
FIXES #1837
2021-12-02 22:09:25 +01:00
Adriaan de Groot
f26c81700d [fstab] Suppress empty subvol= options in fstab 2021-12-02 22:08:17 +01:00
Adriaan de Groot
96ccf256b2 [mount] Add documentation to the config file 2021-12-02 22:02:14 +01:00
Adriaan de Groot
951ddfb72a [mount] Experimental: accept 'no' for subvolumes
If there is no subvolume set, skip creation of that subvolume.
This allows root to be on a bare FS, without a tag or subvolume
name. To achieve this, use
    subvolume: no
(no quotes there) in the YAML.
2021-12-01 23:06:02 +01:00
Adriaan de Groot
3845e05834 [locale] Correct timezone 5.0 / 5.5
Timezones 5.0 and 5.5 have considerable overlap; clear up most
of it. Since a pixel is about 55x55km on the ground, and the
translation of latitude and longitude is sketchy at best,
accuracy on this timezone map is not very good.

FIXES #1832
2021-11-29 22:04:31 +01:00
Adriaan de Groot
7cea1cb56e Changes: document fstab 2021-11-29 17:06:10 +01:00
Adriaan de Groot
cdc3a9aad2 Merge pull request #1834 from dalto8/btrfs-swap
[fstab] Use different options for the btrfs swap subvolume
2021-11-29 15:16:17 +01:00
Adriaan de Groot
86ec0a6bd2 Merge branch 'fixup-packages' into calamares
- Add a changelog entry for what has been done.
2021-11-29 15:13:31 +01:00
Adriaan de Groot
dfd13b4948 [packages] Remove bad config-lines
- rootMountPoint is a global thing, not a job-configuration item
2021-11-29 15:02:05 +01:00
Adriaan de Groot
28bd737062 [packages] Validate test-configs, too
- The config-files has a typo, so didn't validate, so
  the loaded data was wrong, leading to test-failures.
  See 61e0d538e9 .
2021-11-29 14:59:43 +01:00
Adriaan de Groot
ec1b73be2b CMake: don't cmake in the source-directory (during development) 2021-11-29 14:56:15 +01:00
Adriaan de Groot
864dcdb2c2 FreeBSD: Calamares is in the official ports-tree already 2021-11-29 14:45:30 +01:00
Adriaan de Groot
61e0d538e9 [packages] Be more explicit in test failures, fix test data 2021-11-29 14:44:12 +01:00
Adriaan de Groot
474aaf7603 [packages] Fix loading of the subkeys for pacman 2021-11-29 14:23:15 +01:00
Adriaan de Groot
65488ca174 [libcalamares] More verbose when loading YAML for Python 2021-11-29 14:19:06 +01:00
Adriaan de Groot
1260d3fcb9 [packages] Expand tests for PM-specifics more 2021-11-29 13:21:50 +01:00
Adriaan de Groot
3e0c9ba056 [packages] Expand tests with PM-specific bits 2021-11-29 13:04:44 +01:00
Adriaan de Groot
fcbe8d3a3e [libcalamares] API for YAML-loading from Python 2021-11-29 12:59:30 +01:00
Adriaan de Groot
7f643010b2 [libcalamares] Expose error() and warn() to Python 2021-11-29 12:26:07 +01:00
Adriaan de Groot
e9970474f5 [libcalamares] Allow Python to log an Error as well 2021-11-29 12:22:02 +01:00
Adriaan de Groot
8a1e5d35fa [packages] Move pacman-options into their own key with subkeys 2021-11-29 11:59:09 +01:00
Adriaan de Groot
90459e434f Merge pull request #1833 from dalto8/pacman
[packages] Additional pacman options
2021-11-29 11:39:01 +01:00
dalto
bd07db544f [packages] Update doumentation for run_pacman() to be more complete 2021-11-28 15:56:16 -06:00
dalto
6b838bbf3d [fstab] Add comment explaining logic 2021-11-26 13:00:30 -06:00
dalto
df3e049e1c [fstab] Use different options for the btrfs swap subvolume 2021-11-26 12:36:15 -06:00
dalto
bb24ee1b3b [packages] Fix location of call to reset_progress() 2021-11-26 10:56:32 -06:00
dalto
c80b4ff4c2 [packages] Make callback logic more sensible 2021-11-26 08:30:18 -06:00
Adriaan de Groot
596e471276 Merge pull request #1829 from dalto8/zfs-readme
Update zfs module documentation
2021-11-26 15:15:29 +01:00
dalto
e1e29780f2 [packages] Change callbacks 2021-11-25 15:55:22 -06:00
dalto
fa10bb8dd3 [packages] Add support for more pacman options 2021-11-25 11:52:41 -06:00
Adriaan de Groot
01d55254f2 i18n: update languages (Farsi at 100%) 2021-11-19 23:17:05 +01:00
Calamares CI
180b12fbaf i18n: [python] Automatic merge of Transifex translations 2021-11-19 23:13:59 +01:00
Calamares CI
dc8901113e i18n: [desktop] Automatic merge of Transifex translations 2021-11-19 23:13:58 +01:00
Calamares CI
f947c072e1 i18n: [calamares] Automatic merge of Transifex translations 2021-11-19 23:13:58 +01:00
dalto
ee032b43fe [zfs] Fix spelling error in readme 2021-11-19 14:24:36 -06:00
dalto
f37a775977 [zfs] Update module documentation 2021-11-19 10:46:23 -06:00
Adriaan de Groot
855391b31d Changes: post-release housekeeping 2021-11-19 14:55:29 +01:00
Adriaan de Groot
8ca6a7caef [displaymanager] Fix tests (don't overwrite developer host configuration) 2021-11-16 17:30:28 +01:00
Adriaan de Groot
b0d951d7e5 [grubcfg] Avoid UnboundLocal, always set zfs_root_path to something 2021-11-16 17:22:43 +01:00
Adriaan de Groot
8233be93cf CI: fix permissions on scripts 2021-11-16 17:15:37 +01:00
Adriaan de Groot
8652fc5f6d [zfs] Fix schema
- typo (canmount vs canMount)
- the canMount property is nominally a string, but YAML is 'special'
  and interprets 'on' and 'off' and 'yes' and 'no' and other strings
  as booleans unless quoted.
2021-11-16 17:14:12 +01:00
Adriaan de Groot
6792eb5191 Changes: pre-release housekeeping 2021-11-16 15:45:44 +01:00
Adriaan de Groot
b00177bd65 [zfs] SPDX tag the documentation 2021-11-19 12:55:23 +01:00
Adriaan de Groot
bcd8ebd614 [displaymanager] SPDX tags for tests 2021-11-19 12:53:42 +01:00
Adriaan de Groot
46c59be541 Changes: document new things 2021-11-19 11:34:35 +01:00
Adriaan de Groot
2f2271aad6 [mount][bootloader] Communicate btrfs root subvolume
Ensure root subvolume is set correctly for systemd-boot.

FIXES #1821
2021-11-19 11:20:09 +01:00
Adriaan de Groot
feba83acdd Merge pull request #1828 from dalto8/remove-setstate
Remove setState call to resolve compat issue with older kpmcore
2021-11-18 23:40:40 +01:00
dalto
f5b882a075 [partition] Remove setState call to resolve compat issue with older kpmcore 2021-11-18 13:36:23 -06:00
dalto
b0f6530a58 [mount][bootloader] Ensure root subvolume is set correctly for systemd-boot 2021-11-18 10:04:49 -06:00
Adriaan de Groot
ece1e338e0 Merge pull request #1822 from dalto8/zfs-wip
[zfs] Support for installing to root-on-ZFS
2021-11-17 12:20:34 +01:00
dalto8
e814920bca [zfs] Fix typo in README 2021-11-17 00:17:59 +00:00
dalto
c70e31a919 [zfs] Add README.md with some implementation notes 2021-11-16 18:16:32 -06:00
dalto
7e17106f34 [bootloader] Cleanup zfs support from testing 2021-11-16 17:48:49 -06:00
dalto
9603cbef14 [grubcfg] Add zfs entry to kernel_params 2021-11-16 17:48:02 -06:00
dalto
87cca4053f [zfs][mount] Refactor zfs dataset mounting logic 2021-11-16 13:59:24 -06:00
dalto
b65321d80b [bootloader] Add zfs support for grub-install 2021-11-16 13:48:34 -06:00
dalto
18307d9f57 Add zfs module to settings.conf 2021-11-16 09:34:50 -06:00
dalto
3ee388526d [zfs] Cleanup code based on review feedback 2021-11-16 09:06:42 -06:00
Adriaan de Groot
13cb84aa75 Merge branch 'issue-1593' into calamares
FIXES #1593
2021-11-16 15:37:41 +01:00
Adriaan de Groot
efe84bc6c0 [partition] Don't log private names
- log device node (/dev/sdb) instead of its name
- don't log job's prettyName() because that's translated, and also
  contains user-visible private names (introducing a non-translated,
  nicely redacted version of prettyName() seems like too much effort
  for something that can be reconstructed from bits earlier in the log)
2021-11-16 15:31:35 +01:00
Adriaan de Groot
5a4e2b73ab [libcalamares][partition] Give RedactedName a convert-to-QString
- use hex-trailer
- while here, convert DebugRow to use a copy rather than a reference,
  to avoid dangling references when applied to temporaries
- convert *partition* module to use the RedactedNames
2021-11-16 15:22:04 +01:00
Adriaan de Groot
152b3c333b [libcalamares] Introduce redaction-of-names class for logging
- redacted names are stable inside of one run of Calamares
- random, private displays of a given string for a context

SEE #1593
2021-11-16 14:47:13 +01:00
Adriaan de Groot
7b3c4db8f0 [libcalamares] Redacted -> RedactedCommand
- For logging (shell) commands where a password might become visible, use
  RedactedCommand. Rename it to allow for other kinds of redaction, too.
2021-11-16 14:21:46 +01:00
Adriaan de Groot
7cc84b89be [partition] Clarify the meaning of the various UUIDs in debug-output 2021-11-16 14:15:00 +01:00
Adriaan de Groot
4db4e983e3 [partition] Don't format tables of attributes in source 2021-11-16 14:04:00 +01:00
Adriaan de Groot
3aac4dea67 [partition] Remove logging-of-a-pointer during device detection 2021-11-16 13:52:10 +01:00
dalto
0a7262148e [umount] Convert zfs export call to use host_env_process_output 2021-11-15 19:03:20 -06:00
dalto
ec8bab4013 Merge branch 'zfs-wip' of github.com:dalto8/calamares into zfs-wip 2021-11-15 18:42:49 -06:00
dalto
4778d9b2dd [mount] zfs changes from review feedback 2021-11-15 18:41:35 -06:00
dalto
3a90382699 [partition] zfs changes from review feedback 2021-11-15 18:41:35 -06:00
dalto
3ebe695a23 [fstab] Exclude zfs partitions from fstab 2021-11-15 18:41:35 -06:00
dalto
ebae698a6e [mount] Move zfs code into a seperate function to improve readability 2021-11-15 18:41:35 -06:00
dalto
18ad188ef6 [zfs] Ensure overlapping datasets don't get created and code cleanup 2021-11-15 18:41:35 -06:00
dalto
6e440bf9bb [umount] Export zpools after unmounting 2021-11-15 18:41:35 -06:00
dalto
490ac8d086 [partition] Ensure format is selected for existing zfs partitions 2021-11-15 18:41:35 -06:00
dalto
c48c91a5bd [partition] Add support for zfs encryption when erase disk is selected 2021-11-15 18:41:35 -06:00
dalto
ee99ee48f6 Add support for multiple zpools 2021-11-15 18:41:35 -06:00
dalto
a5b21b2500 [zfs] Fix typo and add missing continue 2021-11-15 18:41:34 -06:00
dalto
75c947c5a3 [mount] Fix zfs code and add support for encryption 2021-11-15 18:41:34 -06:00
dalto
1ccabf1b13 [zfs] Export zpool so it can later be mounted at the correct location 2021-11-15 18:41:34 -06:00
dalto
6da9bad272 [partition][zfs] Add support for zfs encryption 2021-11-15 18:41:34 -06:00
dalto
074941e2bd [bootloader] Add initial support for zfs 2021-11-15 18:41:34 -06:00
dalto
5d71723aec [mount] Improve error handling for zfs 2021-11-15 18:41:34 -06:00
dalto
de0bbbe90a [mount] Add support for zfs datasets 2021-11-15 18:41:34 -06:00
dalto
7f05096611 [zfs] Add delay before creating the zpool 2021-11-15 18:41:34 -06:00
dalto
7635b76352 [zfs] Add datasets to global storage for other modules 2021-11-15 18:41:34 -06:00
dalto
b9559a9d82 [zfs] Update to Calamares coding standards 2021-11-15 18:41:34 -06:00
dalto
76892136cf [initcpiocfg] Add support for zfs 2021-11-15 18:41:34 -06:00
dalto
11bf84bac7 [zfs] Initial commit for zfs module 2021-11-15 18:41:34 -06:00
dalto
24a376493b [partition] Add support for manually creating a partition for zfs 2021-11-15 18:41:34 -06:00
dalto
ca3f0e2892 [partition] Add zfs to the filesystem list if the zfs modules is enabled 2021-11-15 18:41:34 -06:00
dalto
e861d8b319 [mount] zfs changes from review feedback 2021-11-15 18:00:04 -06:00
dalto
abb6f73725 [partition] zfs changes from review feedback 2021-11-15 17:59:33 -06:00
Adriaan de Groot
3dd02edc78 [libcalamares] Document how to interpret percents
- use 0..1 in floats for percentages (I suppose you could
  call that a perunage, but that would be weird).
2021-11-15 23:16:58 +01:00
Adriaan de Groot
d5bef9efb5 Python: document which exception is thrown on process failure 2021-11-15 21:48:17 +01:00
Adriaan de Groot
5f7b221e11 [displaymanager] Fix greetd commands
- since default_desktop_environment isn't a string, need
  to pick the string -- the command -- out of the object first.
2021-11-15 13:38:46 +01:00
Adriaan de Groot
16a029abd2 [displaymanager] Adjust tests to match real runtime
- the default_desktop_environment isn't a string, but an
  object; it is unusual for it to be used in set_autologin
2021-11-15 13:37:23 +01:00
Adriaan de Groot
f3e85efd41 [displaymanager] Add tests that run parts of the DM code
- load and set autologin for greetd (this was used to shake out
  code bugs in load/save)
- load and set autologin for sddm
2021-11-15 13:00:40 +01:00
Adriaan de Groot
2c186132cd [displaymanager] Add support for greetd
- Includes post-PR code-fixes

CLOSES #1814
2021-11-15 12:30:19 +01:00
Adriaan de Groot
ce6aec158a [displaymanager] Fix config loading-and-saving
- toml.dump() takes a file-like object
 - toml.loads() takes a whole string to parse, (e.g. the TOML data),
   not a pathname, so change to toml.load() which takes a file-like
   object.
2021-11-15 12:23:17 +01:00
Adriaan de Groot
54fd81a87e [displaymanager] Handle case where config file doesn't exist or has no key
- If the config file doesn't exist, the dictionary is empty
 - If it **does** exist, it might not have key 'default_session' in it

Either case should avoid a KeyError by using get() (or setdefault,
in this context). Subsequent use of os.path.exists() is strange,
since the value is a **group** (e.g. a dictionary) in the config
file. Just check if it exists, and then fill something in.
2021-11-15 12:21:27 +01:00
Adriaan de Groot
11424195ef [displaymanager] Missing method call
- Add `()` to call the config_path() method, because we need a path
  to pass to os.path.exists().
2021-11-15 12:20:54 +01:00
Adriaan de Groot
fad2f6ea88 [displaymanager] Add simple test 2021-11-15 11:52:24 +01:00
Adriaan de Groot
58cf9ffeeb [displaymanager] Import toml only for the DMs that actually need it 2021-11-15 11:43:47 +01:00
Adriaan de Groot
85f36c77b1 [displaymanager] Import configparser only for the DMs that actually need it 2021-11-15 11:42:25 +01:00
Adriaan de Groot
138db1c817 Merge branch 'feat/greetd-support' of git://github.com/boredland/calamares into boredland-feat/greetd-support 2021-11-15 11:40:18 +01:00
Adriaan de Groot
126838fe1d Changes: post-release housekeeping 2021-11-15 11:27:20 +01:00
Adriaan de Groot
f0958535df CI: Update release instructions 2021-11-15 11:14:31 +01:00
Adriaan de Groot
d7865a5bcd Merge pull request #1824 from dalto8/spacecache
[fstab] Remove space_cache from btrfs mount options
2021-11-15 11:09:05 +01:00
Adriaan de Groot
dd2e14853c i18n: Update language lists 2021-11-15 11:03:41 +01:00
Calamares CI
b0436bf050 i18n: [calamares] Automatic merge of Transifex translations 2021-11-15 10:58:51 +01:00
dalto
b6692341e7 [fstab] Exclude zfs partitions from fstab 2021-11-14 09:07:58 -06:00
dalto
af4b87a4cc [mount] Move zfs code into a seperate function to improve readability 2021-11-13 14:09:16 -06:00
dalto
c3524c07ad [zfs] Ensure overlapping datasets don't get created and code cleanup 2021-11-13 13:43:26 -06:00
dalto
cca38695ed [umount] Export zpools after unmounting 2021-11-13 11:13:39 -06:00
dalto
cf20d6495b [partition] Ensure format is selected for existing zfs partitions 2021-11-13 10:43:07 -06:00
dalto
8bdfcac0fb [partition] Add support for zfs encryption when erase disk is selected 2021-11-13 09:31:23 -06:00
dalto
4bed079ebf Add support for multiple zpools 2021-11-12 16:06:06 -06:00
dalto
daa5731acf [fstab] Improve comment about space_cache 2021-11-12 09:29:04 -06:00
dalto
9ef520f862 Add comment describing the situation with space_cache on btrfs 2021-11-12 08:58:43 -06:00
dalto
0bef2a91a1 [fstab] Remove space_cache from btrfs mount options 2021-11-10 17:16:09 -06:00
Adriaan de Groot
4fb8993a38 [finishedq] Add sample QML for mobile usage
This has a countdown-timer that automatically restarts;
the rest of the settings follow the finishedq.conf values.

FIXES #1601
2021-11-09 23:08:40 +01:00
dalto
91762e3df4 [zfs] Fix typo and add missing continue 2021-11-09 14:54:46 -06:00
dalto
90452147a3 [mount] Fix zfs code and add support for encryption 2021-11-09 14:53:44 -06:00
dalto
06b6263c24 [zfs] Export zpool so it can later be mounted at the correct location 2021-11-09 07:42:39 -06:00
dalto
2f145fcf44 [partition][zfs] Add support for zfs encryption 2021-11-08 17:26:08 -06:00
dalto
0720d56803 [bootloader] Add initial support for zfs 2021-11-07 09:32:52 -06:00
dalto
85a2160098 [mount] Improve error handling for zfs 2021-11-07 08:01:32 -06:00
dalto
858e271c8a [mount] Add support for zfs datasets 2021-11-06 14:33:43 -05:00
dalto
e3af4f3e26 [zfs] Add delay before creating the zpool 2021-11-06 14:12:40 -05:00
dalto
51a5c4de0f [zfs] Add datasets to global storage for other modules 2021-11-06 13:27:03 -05:00
dalto
7108d4a509 [zfs] Update to Calamares coding standards 2021-11-06 10:30:49 -05:00
dalto
69ef13ef0c [initcpiocfg] Add support for zfs 2021-11-06 09:48:38 -05:00
dalto
e24d14c512 [zfs] Initial commit for zfs module 2021-11-06 09:44:27 -05:00
dalto
7faf4f30df [partition] Add support for manually creating a partition for zfs 2021-11-06 09:42:07 -05:00
dalto
ac44aab74a [partition] Add zfs to the filesystem list if the zfs modules is enabled 2021-11-06 09:16:09 -05:00
dalto
d0100afe02 Merge branch 'calamares' of github.com:dalto8/calamares into calamares 2021-10-30 14:09:17 -05:00
Jonas Strassel
5701937883 fix(greetd): deal with no existing config 2021-10-29 00:02:16 +02:00
Jonas Strassel
fbdb9e6779 feat(greetd): add more greeter fallbacks 2021-10-28 08:14:04 +02:00
Jonas Strassel
e5f5ef0d17 feat(greetd): add greetd to displaymanagers 2021-10-28 08:12:45 +02:00
155 changed files with 4385 additions and 2001 deletions

View File

@@ -7,6 +7,118 @@ 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 (unreleased) #
This release contains contributions from (alphabetically by first name):
- Erik Dubois
## Core ##
- No core changes yet
## Modules ##
- *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
- *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
# 3.2.49.1 (2021-12-11) #
This is a hot-fix release, to fix a regression in the calculation of
swap-size. Reported by EndeavourOS (Joe Kamprad) and Xero Linux.
# 3.2.49 (2021-12-10) #
This release contains contributions from (alphabetically by first name):
- Artem Grinev
- Evan James
Distributions are **specifically** reminded to update the *umount* module
configuration (and to use *preservefiles* if needed).
## Core ##
- Errors (e.g. when an installation fails for whatever reason) are displayed
in a dialog with a scrollable details panel, rather than growing up
to the size of the screen. (Thanks Artem)
## Modules ##
- *bootloader* better supports multiple installations of the same OS.
- *mount* supports btrfs subvolumes on subdirectories of / now.
- *partition* now supports "deep" btrfs subvolume names, e.g. a
separate subvolume for `/usr/local`. (Thanks Evan)
- The *umount* module now warns if the "preserve log file" feature is used.
This has been deprecated for a long time: use the *preservefiles* module
instead. A future release will turn this into an error.
# 3.2.48 (2021-12-03) #
This release contains contributions from (alphabetically by first name):
- Evan James
## Core ##
- Python modules now have `warn()` and `error()` methods they can call,
alongside the existing `debug()` and `warning()` (all live in the
*libcalamares.utils* module).
- Python modules can load YAML files via `libcalamares.utils.load_yaml()`.
This may be the most useful for test-scripts.
## Modules ##
- *fstab* now has a separate, special, flags-setting for swap subvolumes
on btrfs. A swap subvolume is created if a swap **file** (not a separate
partition) is selected in the auto-partitioning page. (Thanks Evan)
- When using btrfs, the *mount* module creates subvolumes. It was not
possible to **avoid** having a subvolume name created for the root.
This is now possible. #1837
- The *packages* module now has some special settings for the `pacman`
package manager (generally used on Arch-derivatives). This allows
tweaking of the installation process, if downloads are slow or
packages may fail to install. See the `packages.conf` file for
details. (Thanks Evan)
# 3.2.47 (2021-11-19) #
This release contains contributions from (alphabetically by first name):
- Evan James
- Jonas Strassel
## Core ##
- The translation for Sinhala (`si`) has reached 100%. Thank you to
හෙළබස and Sandaruwan, translators for Sinhala, for special effort
in completing that translation.
- Logging now supports Redacted names. This reduces the scope for
leaking names or other private information through the logs
(if they are posted to a pastebin). A name is redacted consistently
within one run of Calamares, but differently each time.
## Modules ##
- *bootloader* with systemd-boot now handles root subvolumes better
(Thanks Evan)
- *displaymanager* supports the *greetd* display manager, which is a
kind of meta-DM itself, supporting multiple greeters. (Thanks Jonas)
- *finishedq* now has an extra example QML file that builds the UI in
a different fashion, demonstrating how a mobile-OS customization of
Calamares would present the "all done" message.
- *fstab* has an example configuration file that mentioned `space_cache`
as an option. Since 2014 there was only one possible value, so this
option matched the default-and-only value. Newer kernels with newer
btrfs versions have a `v2` option value as well. Remove the example
option, since the kernel automatically picks the right value, while
setting it to the wrong one may prevent the system from booting.
(Thanks Evan)
- The *partition* module no longer logs recognizable disk names or
UUIDs. These are redacted in the logs. #1593
- The *partition* module, together with the new *zfs* module and changes
in *mount* and *bootloader* can install to ZFS **if** the distribution
kernel supports it. ZFS tools are required, as well as the relevant
kernel modules. See the `README.md` in the *zfs* module. (Thanks Evan)
# 3.2.46 (2021-11-09) #
This release contains contributions from (alphabetically by first name):

View File

@@ -41,11 +41,14 @@
# TODO:3.3: Require CMake 3.12
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
project( CALAMARES
VERSION 3.2.46
VERSION 3.2.50
LANGUAGES C CXX
)
set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development
set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development
if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
message( FATAL_ERROR "Do not build development versions in the source-directory." )
endif()
### OPTIONS
#
@@ -133,12 +136,12 @@ set( CALAMARES_DESCRIPTION_SUMMARY
# `txstats.py -e`. See also
#
# Total 81 languages
set( _tx_complete az az_AZ ca cs_CZ fi_FI he hi hr ja ko lt pt_BR
pt_PT sq sv tr_TR uk zh_CN zh_TW )
set( _tx_good as be ca@valencia da de fr fur it_IT ml nl ru sk tg
vi )
set( _tx_ok ar ast bg bn el en_GB es es_MX et eu fa gl hu id is mr
nb pl ro si sl sr sr@latin th )
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 )
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 )

View File

@@ -21,10 +21,18 @@ Name[as]=চিছটেম ইনস্তল কৰক
Icon[as]=কেলামাৰেচ
GenericName[as]=চিছটেম ইনস্তলাৰ
Comment[as]=কেলামাৰেচ — চিছটেম​ ইনস্তলাৰ
Name[ast]=Instalar el sistema
Icon[ast]=calamares
GenericName[ast]=Instalador del sistema
Comment[ast]=Calamares — Instalador del sistema
Name[az]=Sistemi Quraşdırmaq
Icon[az]=calamares
GenericName[az]=Sistem Quraşdırıcısı
Comment[az]=Calamares Sistem Quraşdırıcısı
Name[az_AZ]=Sistemi quraşdırmaq
Icon[az_AZ]=calamares
GenericName[az_AZ]=Sistem quraşdırcısı
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
Name[be]=Усталяваць сістэму
Icon[be]=calamares
GenericName[be]=Усталёўшчык сістэмы
@@ -41,6 +49,10 @@ Name[ca]=Instal·la el sistema
Icon[ca]=calamares
GenericName[ca]=Instal·lador de sistema
Comment[ca]=Calamares — Instal·lador de sistema
Name[cs_CZ]=Nainstalovat systém
Icon[cs_CZ]=calamares
GenericName[cs_CZ]=Instalátor systému
Comment[cs_CZ]=Calamares instalátor operačních systémů
Name[da]=Installér system
Icon[da]=calamares
GenericName[da]=Systeminstallationsprogram
@@ -57,10 +69,19 @@ Name[en_GB]=Install System
Icon[en_GB]=calamares
GenericName[en_GB]=System Installer
Comment[en_GB]=Calamares — System Installer
Name[eo]=Instali Sistemo
Icon[eo]=calamares
GenericName[eo]=Sistema Instalilo
Comment[eo]=Calamares — Sistema Instalilo
Name[es]=Instalar Sistema
Icon[es]=calamares
GenericName[es]=Instalador del Sistema
Comment[es]=Calamares — Instalador del Sistema
Name[es_MX]=Instalar el Sistema
Icon[es_MX]=calamares
GenericName[es_MX]=Instalador del sistema
Comment[es_MX]=Calamares - Instalador del sistema
Name[es_PR]=Instalar el sistema
Name[et]=Paigalda süsteem
Icon[et]=calamares
GenericName[et]=Süsteemipaigaldaja
@@ -71,9 +92,12 @@ GenericName[eu]=Sistema instalatzailea
Comment[eu]=Calamares - sistema instalatzailea
Name[fa]=نصب سامانه
Icon[fa]=کالامارس
GenericName[fa]=نصب‌کنندهٔ سامانه
Comment[fa]=کالامارس — نصب‌کنندهٔ سامانه
Name[es_PR]=Instalar el sistema
GenericName[fa]=نصب‌کننده سامانه
Comment[fa]=کالامارس — نصب‌کننده سامانه
Name[fi_FI]=Asenna järjestelmä
Icon[fi_FI]=calamares
GenericName[fi_FI]=Järjestelmän asennusohjelma
Comment[fi_FI]=Calamares — Järjestelmän asentaja
Name[fr]=Installer le système
Icon[fr]=calamares
GenericName[fr]=Installateur système
@@ -98,10 +122,6 @@ Name[hr]=Instaliraj sustav
Icon[hr]=calamares
GenericName[hr]=Instalacija sustava
Comment[hr]=Calamares — Instalacija sustava
Name[ie]=Installar li sistema
Icon[ie]=calamares
GenericName[ie]=Installator del sistema
Comment[ie]=Calamares — Installator del sistema
Name[hu]=Rendszer telepítése
Icon[hu]=calamares
GenericName[hu]=Rendszertelepítő
@@ -110,14 +130,18 @@ Name[id]=Instal Sistem
Icon[id]=calamares
GenericName[id]=Pemasang
Comment[id]=Calamares — Pemasang Sistem
Name[ie]=Installar li sistema
Icon[ie]=calamares
GenericName[ie]=Installator del sistema
Comment[ie]=Calamares — Installator del sistema
Name[is]=Setja upp kerfið
Icon[is]=calamares
GenericName[is]=Kerfis uppsetning
Comment[is]=Calamares — Kerfis uppsetning
Name[cs_CZ]=Nainstalovat systém
Icon[cs_CZ]=calamares
GenericName[cs_CZ]=Instalátor systému
Comment[cs_CZ]=Calamares instalátor operačních systémů
Name[it_IT]=Installa il sistema
Icon[it_IT]=calamares
GenericName[it_IT]=Programma d'installazione del sistema
Comment[it_IT]=Calamares — Programma d'installazione del sistema
Name[ja]=システムをインストール
Icon[ja]=calamares
GenericName[ja]=システムインストーラー
@@ -130,10 +154,6 @@ Name[lt]=Įdiegti Sistemą
Icon[lt]=calamares
GenericName[lt]=Sistemos diegimas į kompiuterį
Comment[lt]=Calamares — Sistemos diegimo programa
Name[it_IT]=Installa il sistema
Icon[it_IT]=calamares
GenericName[it_IT]=Programma d'installazione del sistema
Comment[it_IT]=Calamares — Programma d'installazione del sistema
Name[mk]=Инсталирај го системот
Icon[mk]=calamares
GenericName[mk]=Системен Инсталер
@@ -146,14 +166,14 @@ Name[nb]=Installer System
Icon[nb]=calamares
GenericName[nb]=Systeminstallatør
Comment[nb]=Calamares-systeminstallatør
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
Icon[ne_NP]=Calamares
GenericName[ne_NP]=सिस्टम इन्स्टलर
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
Name[nl]=Installeer systeem
Icon[nl]=calamares
GenericName[nl]=Installatieprogramma
Comment[nl]=Calamares — Installatieprogramma
Name[az_AZ]=Sistemi quraşdırmaq
Icon[az_AZ]=calamares
GenericName[az_AZ]=Sistem quraşdırcısı
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
Name[pl]=Zainstaluj system
Icon[pl]=calamares
GenericName[pl]=Instalator systemu
@@ -162,6 +182,10 @@ Name[pt_BR]=Sistema de Instalação
Icon[pt_BR]=calamares
GenericName[pt_BR]=Instalador de Sistema
Comment[pt_BR]=Calamares — Instalador de Sistema
Name[pt_PT]=Instalar Sistema
Icon[pt_PT]=calamares
GenericName[pt_PT]=Instalador de Sistema
Comment[pt_PT]=Instalador de Sistema - Calamares
Name[ro]=Instalează sistemul
Icon[ro]=calamares
GenericName[ro]=Instalator de sistem
@@ -183,15 +207,11 @@ Name[sq]=Instalo Sistemin
Icon[sq]=calamares
GenericName[sq]=Instalues Sistemi
Comment[sq]=Calamares — Instalues Sistemi
Name[fi_FI]=Asenna järjestelmä
Icon[fi_FI]=calamares
GenericName[fi_FI]=Järjestelmän asennusohjelma
Comment[fi_FI]=Calamares — Järjestelmän asentaja
Name[sr@latin]=Instaliraj sistem
Name[sr]=Инсталирај систем
Icon[sr]=calamares
GenericName[sr]=Инсталатер система
Comment[sr]=Каламарес — инсталатер система
Name[sr@latin]=Instaliraj sistem
Name[sv]=Installera system
Icon[sv]=calamares
GenericName[sv]=Systeminstallerare
@@ -201,6 +221,10 @@ Icon[tg]=calamares
GenericName[tg]=Насбкунандаи низомӣ
Comment[tg]=Calamares — Насбкунандаи низомӣ
Name[th]=ติดตั้งระบบ
Name[tr_TR]=Sistemi Yükle
Icon[tr_TR]=calamares
GenericName[tr_TR]=Sistem Yükleyici
Comment[tr_TR]=Calamares — Sistem Yükleyici
Name[uk]=Встановити Систему
Icon[uk]=calamares
GenericName[uk]=Встановлювач системи
@@ -217,27 +241,3 @@ Name[zh_TW]=安裝系統
Icon[zh_TW]=calamares
GenericName[zh_TW]=系統安裝程式
Comment[zh_TW]=Calamares ── 系統安裝程式
Name[ast]=Instalar el sistema
Icon[ast]=calamares
GenericName[ast]=Instalador del sistema
Comment[ast]=Calamares — Instalador del sistema
Name[eo]=Instali Sistemo
Icon[eo]=calamares
GenericName[eo]=Sistema Instalilo
Comment[eo]=Calamares — Sistema Instalilo
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
Icon[ne_NP]=Calamares
GenericName[ne_NP]=सिस्टम इन्स्टलर
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
Name[es_MX]=Instalar el Sistema
Icon[es_MX]=calamares
GenericName[es_MX]=Instalador del sistema
Comment[es_MX]=Calamares - Instalador del sistema
Name[pt_PT]=Instalar Sistema
Icon[pt_PT]=calamares
GenericName[pt_PT]=Instalador de Sistema
Comment[pt_PT]=Calamares - Instalador de Sistema
Name[tr_TR]=Sistemi Yükle
Icon[tr_TR]=calamares
GenericName[tr_TR]=Sistem Yükleyici
Comment[tr_TR]=Calamares — Sistem Yükleyici

View File

@@ -29,7 +29,8 @@
* Double-check the *CALAMARES_VERSION* value at the top of `CMakeLists.txt`.
* Set *CALAMARES_RELEASE_MODE* to `ON` in `CMakeLists.txt`.
* Edit `CHANGES` and set the date of the release.
* Edit `CHANGES-*` and set the date of the release. Pick the right
file for the release-stream.
* Commit both. This is usually done with commit-message
*Changes: pre-release housekeeping*.
@@ -81,24 +82,12 @@ Follow the instructions printed by the release script.
* Bump the version number in `CMakeLists.txt` in *CALAMARES_VERSION*.
* Set *CALAMARES_RELEASE_MODE* back to `OFF`.
* Add a placeholder entry for the next release in `CHANGES` with date
text *not released yet*.
* Add a placeholder entry for the next release in `CHANGES-*` with date
text *not released yet*. See the text below, "Placeholder Release".
Add the placeholder to the right file for the release-stream.
* Commit and push that, usually with the message
*Changes: post-release housekeeping*.
```
# 3.2.XX (unreleased) #
This release contains contributions from (alphabetically by first name):
- No external contributors yet
## Core ##
- No core changes yet
## Modules ##
- No module changes yet
```
# Related Material
> This section isn't directly related to any specific release,
@@ -139,3 +128,18 @@ ssb rsa3072/0xCFDDC96F12B1915C
- Upload that public key to the relevant GitHub profile.
- Upload that public key to the Calamares site.
## Placeholder Release Notes
```
# 3.2.XX (unreleased) #
This release contains contributions from (alphabetically by first name):
- No external contributors yet
## Core ##
- No core changes yet
## Modules ##
- No module changes yet
```

0
ci/configvalidator.py Normal file → Executable file
View File

0
ci/txcheck.sh Normal file → Executable file
View File

View File

@@ -108,6 +108,21 @@ awk '
skip=0; print $0;
}}' < calamares.desktop > calamares.desktop.new
mv calamares.desktop.new calamares.desktop
# Now group translated key-names (Name, Icon, Description, ..) by sorted
# language key rather than random-ish language-key order (which shuffles
# entries around).
#
# First, the non-translated lines
grep -v '\[.*\]=' calamares.desktop > calamares.desktop.new
# The translated lines:
# - replace (the first) [] by | so we have a consistent field separator
# - sort based on field 2, then 1 (language code, then reversed key-name)
# - replace the first | by [, the first (remaining) | by ]
# Effectively this puts the fields in this order: Name, Icon, Generic Name,
# Comment -- within each language key. This keeps churn down since the
# language codes and key-names are constant.
grep '\[.*\]=' calamares.desktop | sed -e 's/\[/|/' -e 's/\]/|/' | sort -t '|' -k 2,2 -k 1,1r | sed -e 's/|/\[/' | sed -e 's/|/\]/' >> calamares.desktop.new
mv calamares.desktop.new calamares.desktop
git add --verbose calamares.desktop
git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true
@@ -116,6 +131,19 @@ git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true
# PO-Created line). This applies only to modules which use po-files.
git diff --numstat src/modules | awk '($1==1 && $2==1){print $3}' | xargs git checkout --
# sed either wants -i'' (GNU sed) or -i '' (BSD sed) to
# replace in a file, with no backup extension. Define
# a `reinplace` command to deal with the difference.
if test FreeBSD = `uname` ; then
reinplace() {
sed -i '' "$@"
}
else
reinplace() {
sed -i'' "$@"
}
fi
# Go through the Python modules; those with a lang/ subdir have their
# own complete gettext-based setup.
for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
@@ -125,7 +153,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
if [ -d ${MODULE_DIR}/lang ]; then
# Convert PO files to MO files
for POFILE in $(find ${MODULE_DIR} -name "*.po") ; do
sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
# msgfmt -o ${POFILE%.po}.mo $POFILE
done
git add --verbose ${MODULE_DIR}/lang/*
@@ -135,7 +163,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
done
for POFILE in $(find lang -name "python.po") ; do
sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
# msgfmt -o ${POFILE%.po}.mo $POFILE
done
git add --verbose lang/python*

0
ci/txreduce.py Normal file → Executable file
View File

View File

@@ -1,37 +0,0 @@
# $FreeBSD$
#
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <adridg@FreeBSD.org>
# SPDX-License-Identifier: BSD-2-Clause
PORTNAME= calamares
DISTVERSION= 3.2.25
CATEGORIES= sysutils
MASTER_SITES= https://github.com/${PORTNAME}/${PORTNAME}/releases/download/v${DISTVERSION}/
MAINTAINER= adridg@FreeBSD.org
COMMENT= GUI System installer and OEM configurator
LICENSE= GPLv3
LICENSE_FILE= ${WRKSRC}/LICENSE
LIB_DEPENDS= libyaml-cpp.so:devel/yaml-cpp \
libpwquality.so:security/libpwquality \
libboost_python${PYTHON_SUFFIX}.so:devel/boost-python-libs
USES= cmake compiler:c++17-lang gettext kde:5 pkgconfig \
python:3.3+ qt:5
USE_QT= concurrent core dbus declarative gui \
network quickcontrols2 svg widgets xml \
buildtools_build linguist_build qmake_build
USE_KDE= coreaddons dbusaddons parts service \
ecm_build
USE_LDCONFIG= yes
CMAKE_OFF= WITH_KF5Crash \
INSTALL_CONFIG \
INSTALL_COMPLETION \
INSTALL_POLKIT
CMAKE_ON= CMAKE_DISABLE_FIND_PACKAGE_KPMcore
CMAKE_ARGS= -DSKIP_MODULES="webview"
.include <bsd.port.mk>

View File

@@ -1,3 +0,0 @@
TIMESTAMP = 1592339404
SHA256 (calamares-3.2.25.tar.gz) = 797ce33db7d4e4c06bbccef95f6c4023f7628e91bd142896695565fed4ae8c4b
SIZE (calamares-3.2.25.tar.gz) = 3580197

View File

@@ -1,14 +0,0 @@
Calamares is an installer framework. By design it is very customizable,
in order to satisfy a wide variety of needs and use cases.
Calamares aims to be easy, usable, beautiful, pragmatic, inclusive and
distribution-agnostic.
Got a Linux distribution but no system installer? Grab Calamares, mix
and match any number of Calamares modules (or write your own in Python
or C++), throw together some branding, package it up and you are ready
to ship!
(The above applies to FreeBSD as well)
WWW: https://calamares.io/

View File

@@ -1,224 +0,0 @@
bin/calamares
include/libcalamares/CalamaresConfig.h
include/libcalamares/CppJob.h
include/libcalamares/DllMacro.h
include/libcalamares/GlobalStorage.h
include/libcalamares/Job.h
include/libcalamares/JobExample.h
include/libcalamares/JobQueue.h
include/libcalamares/ProcessJob.h
include/libcalamares/PythonHelper.h
include/libcalamares/PythonJob.h
include/libcalamares/PythonJobApi.h
include/libcalamares/Settings.h
include/libcalamares/utils/BoostPython.h
include/libcalamares/utils/CalamaresUtilsSystem.h
include/libcalamares/utils/CommandList.h
include/libcalamares/utils/Dirs.h
include/libcalamares/utils/Entropy.h
include/libcalamares/utils/Logger.h
include/libcalamares/utils/NamedEnum.h
include/libcalamares/utils/NamedSuffix.h
include/libcalamares/utils/PluginFactory.h
include/libcalamares/utils/RAII.h
include/libcalamares/utils/Retranslator.h
include/libcalamares/utils/String.h
include/libcalamares/utils/Tests.h
include/libcalamares/utils/UMask.h
include/libcalamares/utils/Units.h
include/libcalamares/utils/Variant.h
include/libcalamares/utils/Yaml.h
include/libcalamares/utils/moc-warnings.h
lib/calamares/libcalamares.so
lib/calamares/modules/bootloader/main.py
lib/calamares/modules/bootloader/module.desc
lib/calamares/modules/bootloader/test.yaml
lib/calamares/modules/contextualprocess/libcalamares_job_contextualprocess.so
lib/calamares/modules/contextualprocess/module.desc
lib/calamares/modules/displaymanager/main.py
lib/calamares/modules/displaymanager/module.desc
lib/calamares/modules/dracut/main.py
lib/calamares/modules/dracut/module.desc
lib/calamares/modules/dracutlukscfg/libcalamares_job_dracutlukscfg.so
lib/calamares/modules/dracutlukscfg/module.desc
lib/calamares/modules/dummycpp/libcalamares_job_dummycpp.so
lib/calamares/modules/dummycpp/module.desc
lib/calamares/modules/dummyprocess/module.desc
lib/calamares/modules/dummypython/main.py
lib/calamares/modules/dummypython/module.desc
lib/calamares/modules/finished/libcalamares_viewmodule_finished.so
lib/calamares/modules/finished/module.desc
lib/calamares/modules/fstab/main.py
lib/calamares/modules/fstab/module.desc
lib/calamares/modules/fstab/test.yaml
lib/calamares/modules/grubcfg/main.py
lib/calamares/modules/grubcfg/module.desc
lib/calamares/modules/hostinfo/libcalamares_job_hostinfo.so
lib/calamares/modules/hostinfo/module.desc
lib/calamares/modules/hwclock/main.py
lib/calamares/modules/hwclock/module.desc
lib/calamares/modules/initcpio/libcalamares_job_initcpio.so
lib/calamares/modules/initcpio/module.desc
lib/calamares/modules/initcpiocfg/main.py
lib/calamares/modules/initcpiocfg/module.desc
lib/calamares/modules/initramfs/libcalamares_job_initramfs.so
lib/calamares/modules/initramfs/module.desc
lib/calamares/modules/initramfscfg/encrypt_hook
lib/calamares/modules/initramfscfg/encrypt_hook_nokey
lib/calamares/modules/initramfscfg/main.py
lib/calamares/modules/initramfscfg/module.desc
lib/calamares/modules/interactiveterminal/libcalamares_viewmodule_interactiveterminal.so
lib/calamares/modules/interactiveterminal/module.desc
lib/calamares/modules/keyboard/libcalamares_viewmodule_keyboard.so
lib/calamares/modules/keyboard/module.desc
lib/calamares/modules/keyboardq/libcalamares_viewmodule_keyboardq.so
lib/calamares/modules/keyboardq/module.desc
lib/calamares/modules/license/libcalamares_viewmodule_license.so
lib/calamares/modules/license/module.desc
lib/calamares/modules/locale/libcalamares_viewmodule_locale.so
lib/calamares/modules/locale/module.desc
lib/calamares/modules/localecfg/main.py
lib/calamares/modules/localecfg/module.desc
lib/calamares/modules/localeq/libcalamares_viewmodule_localeq.so
lib/calamares/modules/localeq/module.desc
lib/calamares/modules/luksbootkeyfile/libcalamares_job_luksbootkeyfile.so
lib/calamares/modules/luksbootkeyfile/module.desc
lib/calamares/modules/luksopenswaphookcfg/main.py
lib/calamares/modules/luksopenswaphookcfg/module.desc
lib/calamares/modules/machineid/libcalamares_job_machineid.so
lib/calamares/modules/machineid/module.desc
lib/calamares/modules/mount/main.py
lib/calamares/modules/mount/module.desc
lib/calamares/modules/mount/test.yaml
lib/calamares/modules/netinstall/libcalamares_viewmodule_netinstall.so
lib/calamares/modules/netinstall/module.desc
lib/calamares/modules/networkcfg/main.py
lib/calamares/modules/networkcfg/module.desc
lib/calamares/modules/notesqml/libcalamares_viewmodule_notesqml.so
lib/calamares/modules/notesqml/module.desc
lib/calamares/modules/oemid/libcalamares_viewmodule_oemid.so
lib/calamares/modules/oemid/module.desc
lib/calamares/modules/openrcdmcryptcfg/main.py
lib/calamares/modules/openrcdmcryptcfg/module.desc
lib/calamares/modules/packagechooser/libcalamares_viewmodule_packagechooser.so
lib/calamares/modules/packagechooser/module.desc
lib/calamares/modules/packages/main.py
lib/calamares/modules/packages/module.desc
lib/calamares/modules/packages/test.yaml
lib/calamares/modules/plymouthcfg/main.py
lib/calamares/modules/plymouthcfg/module.desc
lib/calamares/modules/preservefiles/libcalamares_job_preservefiles.so
lib/calamares/modules/preservefiles/module.desc
lib/calamares/modules/rawfs/main.py
lib/calamares/modules/rawfs/module.desc
lib/calamares/modules/removeuser/libcalamares_job_removeuser.so
lib/calamares/modules/removeuser/module.desc
lib/calamares/modules/services-openrc/main.py
lib/calamares/modules/services-openrc/module.desc
lib/calamares/modules/services-systemd/main.py
lib/calamares/modules/services-systemd/module.desc
lib/calamares/modules/shellprocess/libcalamares_job_shellprocess.so
lib/calamares/modules/shellprocess/module.desc
lib/calamares/modules/summary/libcalamares_viewmodule_summary.so
lib/calamares/modules/summary/module.desc
lib/calamares/modules/tracking/libcalamares_viewmodule_tracking.so
lib/calamares/modules/tracking/module.desc
lib/calamares/modules/umount/main.py
lib/calamares/modules/umount/module.desc
lib/calamares/modules/unpackfs/main.py
lib/calamares/modules/unpackfs/module.desc
lib/calamares/modules/unpackfs/runtests.sh
lib/calamares/modules/users/libcalamares_viewmodule_users.so
lib/calamares/modules/users/module.desc
lib/calamares/modules/welcome/libcalamares_viewmodule_welcome.so
lib/calamares/modules/welcome/module.desc
lib/calamares/modules/welcomeq/libcalamares_viewmodule_welcomeq.so
lib/calamares/modules/welcomeq/module.desc
lib/cmake/Calamares/CMakeColors.cmake
lib/cmake/Calamares/CalamaresAddBrandingSubdirectory.cmake
lib/cmake/Calamares/CalamaresAddLibrary.cmake
lib/cmake/Calamares/CalamaresAddModuleSubdirectory.cmake
lib/cmake/Calamares/CalamaresAddPlugin.cmake
lib/cmake/Calamares/CalamaresAddTest.cmake
lib/cmake/Calamares/CalamaresAddTranslations.cmake
lib/cmake/Calamares/CalamaresAutomoc.cmake
lib/cmake/Calamares/CalamaresConfig.cmake
lib/cmake/Calamares/CalamaresConfigVersion.cmake
lib/cmake/Calamares/CalamaresLibraryDepends-%%CMAKE_BUILD_TYPE%%.cmake
lib/cmake/Calamares/CalamaresLibraryDepends.cmake
lib/cmake/Calamares/CalamaresUse.cmake
lib/libcalamares.so
lib/libcalamares.so.3.2.25
lib/libcalamaresui.so
lib/libcalamaresui.so.3.2.25
man/man8/calamares.8.gz
share/applications/calamares.desktop
%%DATADIR%%/branding/default/banner.png
%%DATADIR%%/branding/default/branding.desc
%%DATADIR%%/branding/default/lang/calamares-default_ar.qm
%%DATADIR%%/branding/default/lang/calamares-default_en.qm
%%DATADIR%%/branding/default/lang/calamares-default_eo.qm
%%DATADIR%%/branding/default/lang/calamares-default_fr.qm
%%DATADIR%%/branding/default/lang/calamares-default_nl.qm
%%DATADIR%%/branding/default/languages.png
%%DATADIR%%/branding/default/show.qml
%%DATADIR%%/branding/default/squid.png
%%DATADIR%%/branding/default/stylesheet.qss
%%DATADIR%%/qml/calamares/slideshow/BackButton.qml
%%DATADIR%%/qml/calamares/slideshow/ForwardButton.qml
%%DATADIR%%/qml/calamares/slideshow/NavButton.qml
%%DATADIR%%/qml/calamares/slideshow/Presentation.qml
%%DATADIR%%/qml/calamares/slideshow/Slide.qml
%%DATADIR%%/qml/calamares/slideshow/SlideCounter.qml
%%DATADIR%%/qml/calamares/slideshow/qmldir
share/icons/hicolor/scalable/apps/calamares.svg
share/locale/ar/LC_MESSAGES/calamares-python.mo
share/locale/as/LC_MESSAGES/calamares-python.mo
share/locale/ast/LC_MESSAGES/calamares-python.mo
share/locale/be/LC_MESSAGES/calamares-python.mo
share/locale/bg/LC_MESSAGES/calamares-python.mo
share/locale/ca/LC_MESSAGES/calamares-python.mo
share/locale/cs_CZ/LC_MESSAGES/calamares-python.mo
share/locale/da/LC_MESSAGES/calamares-python.mo
share/locale/de/LC_MESSAGES/calamares-python.mo
share/locale/el/LC_MESSAGES/calamares-python.mo
share/locale/en_GB/LC_MESSAGES/calamares-python.mo
share/locale/eo/LC_MESSAGES/calamares-python.mo
share/locale/es/LC_MESSAGES/calamares-python.mo
share/locale/es_MX/LC_MESSAGES/calamares-python.mo
share/locale/es_PR/LC_MESSAGES/calamares-python.mo
share/locale/et/LC_MESSAGES/calamares-python.mo
share/locale/eu/LC_MESSAGES/calamares-python.mo
share/locale/fi_FI/LC_MESSAGES/calamares-python.mo
share/locale/fr/LC_MESSAGES/calamares-python.mo
share/locale/gl/LC_MESSAGES/calamares-python.mo
share/locale/he/LC_MESSAGES/calamares-python.mo
share/locale/hi/LC_MESSAGES/calamares-python.mo
share/locale/hr/LC_MESSAGES/calamares-python.mo
share/locale/hu/LC_MESSAGES/calamares-python.mo
share/locale/id/LC_MESSAGES/calamares-python.mo
share/locale/is/LC_MESSAGES/calamares-python.mo
share/locale/it_IT/LC_MESSAGES/calamares-python.mo
share/locale/ja/LC_MESSAGES/calamares-python.mo
share/locale/ko/LC_MESSAGES/calamares-python.mo
share/locale/lt/LC_MESSAGES/calamares-python.mo
share/locale/ml/LC_MESSAGES/calamares-python.mo
share/locale/mr/LC_MESSAGES/calamares-python.mo
share/locale/nb/LC_MESSAGES/calamares-python.mo
share/locale/nl/LC_MESSAGES/calamares-python.mo
share/locale/pl/LC_MESSAGES/calamares-python.mo
share/locale/pt_BR/LC_MESSAGES/calamares-python.mo
share/locale/pt_PT/LC_MESSAGES/calamares-python.mo
share/locale/ro/LC_MESSAGES/calamares-python.mo
share/locale/ru/LC_MESSAGES/calamares-python.mo
share/locale/sk/LC_MESSAGES/calamares-python.mo
share/locale/sl/LC_MESSAGES/calamares-python.mo
share/locale/sq/LC_MESSAGES/calamares-python.mo
share/locale/sr/LC_MESSAGES/calamares-python.mo
share/locale/sr@latin/LC_MESSAGES/calamares-python.mo
share/locale/sv/LC_MESSAGES/calamares-python.mo
share/locale/th/LC_MESSAGES/calamares-python.mo
share/locale/tr_TR/LC_MESSAGES/calamares-python.mo
share/locale/uk/LC_MESSAGES/calamares-python.mo
share/locale/zh_CN/LC_MESSAGES/calamares-python.mo
share/locale/zh_TW/LC_MESSAGES/calamares-python.mo

View File

@@ -689,27 +689,27 @@ Bu proqramdan çıxılacaq və bütün dəyişikliklər itiriləcəkdir.</transl
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>%1 uğurla ayrıldı.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>%1 mübadilə bölməsi uğurla söndürüldü.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>%1 mübadilə bölməsi uğurla təmizləndi</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation>Yerləşdirmə cihazı %1 uğurla bağlandı</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation>Tutum qrupu %1, uğurla söndürüldü</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -689,27 +689,27 @@ Bu proqramdan çıxılacaq və bütün dəyişikliklər itiriləcəkdir.</transl
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>%1 uğurla ayrıldı.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>%1 mübadilə bölməsi uğurla söndürüldü.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>%1 mübadilə bölməsi uğurla təmizləndi</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation>Yerləşdirmə cihazı %1 uğurla bağlandı</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation>Tutum qrupu %1, uğurla söndürüldü</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

File diff suppressed because it is too large Load Diff

View File

@@ -687,27 +687,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

@@ -689,27 +689,27 @@ O instalador será fechado e todas as alterações serão perdidas.</translation
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>%1 desmontado com sucesso.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>Swap %1 desativada com sucesso.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>Swap %1 limpa com sucesso.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
<source>Successfully closed mapper device %1.</source>
<translation type="unfinished"/>
<translation>Dispositivo de mapeamento %1 fechado com sucesso.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
<source>Successfully disabled volume group %1.</source>
<translation type="unfinished"/>
<translation>Grupo de volume %1 desativado com sucesso.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -789,7 +789,7 @@ O instalador será encerrado e todas as alterações serão perdidas.</translati
<message>
<location filename="../src/modules/locale/Config.cpp" line="380"/>
<source>The system language will be set to %1.</source>
<translation>A linguagem do sistema será definida para %1.</translation>
<translation>O idioma do sistema será definido para %1.</translation>
</message>
<message>
<location filename="../src/modules/locale/Config.cpp" line="387"/>
@@ -1684,7 +1684,7 @@ O instalador será encerrado e todas as alterações serão perdidas.</translati
<message>
<location filename="../src/modules/hostinfo/HostInfoJob.cpp" line="42"/>
<source>Collecting information about your machine.</source>
<translation>A recolher informação acerca da sua máquina.</translation>
<translation>A recolher informação sobre a sua máquina.</translation>
</message>
</context>
<context>
@@ -3988,7 +3988,7 @@ Saída de Dados:
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="228"/>
<source>%1 support</source>
<translation>%1 suporte</translation>
<translation>Suporte do %1</translation>
</message>
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="235"/>
@@ -3998,7 +3998,7 @@ Saída de Dados:
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="235"/>
<source>About %1 installer</source>
<translation>Acerca %1 instalador</translation>
<translation>Acerca do instalador %1</translation>
</message>
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="238"/>

View File

@@ -189,7 +189,7 @@
<message>
<location filename="../src/libcalamares/ProcessJob.cpp" line="43"/>
<source>Run command '%1' in target system.</source>
<translation>Запустить комманду'%1'в целевой системе.</translation>
<translation>Запустить команду '%1' в целевой системе.</translation>
</message>
<message>
<location filename="../src/libcalamares/ProcessJob.cpp" line="43"/>
@@ -274,10 +274,10 @@
<location filename="../src/libcalamares/modulesystem/RequirementsChecker.cpp" line="116"/>
<source>(%n second(s))</source>
<translation>
<numerusform>(% секунда)</numerusform>
<numerusform>(% секунд)</numerusform>
<numerusform>(% секунд)</numerusform>
<numerusform>(%n секунда)</numerusform>
<numerusform>(%n секунды)</numerusform>
<numerusform>(%n секунд)</numerusform>
<numerusform>(%n секунд(ы))</numerusform>
</translation>
</message>
<message>
@@ -2673,7 +2673,7 @@ The installer will quit and all changes will be lost.</source>
<message>
<location filename="../src/modules/partition/gui/PartitionLabelsView.cpp" line="203"/>
<source>EFI system</source>
<translation>Система EFI</translation>
<translation>Системный раздел EFI</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/PartitionLabelsView.cpp" line="207"/>

File diff suppressed because it is too large Load Diff

View File

@@ -688,27 +688,27 @@ Alla ändringar kommer att gå förlorade.</translation>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>Framgångsrikt avmonterade %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>Framgångsrikt inaktiverade 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>Framgångsrikt rensade 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>Framgångsrikt stängde krypterad enhet %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>Framgångsrikt inaktiverade volymgrupp %1.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>

View File

@@ -690,27 +690,27 @@ Yükleyiciden çıkınca tüm değişiklikler kaybedilecek.</translation>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
<source>Successfully unmounted %1.</source>
<translation type="unfinished"/>
<translation>%1 bağlantısı başarıyla kaldırıldı.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
<source>Successfully disabled swap %1.</source>
<translation type="unfinished"/>
<translation>%1 takas alanı başarıyla devre dışı bırakıldı.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
<source>Successfully cleared swap %1.</source>
<translation type="unfinished"/>
<translation>%1 takas alanı başarıyla temizlendi.</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 eşleyici aygıtı başarıyla kapatıldı.</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 birim grubu başarıyla devre dışı bırakıldı.</translation>
</message>
<message>
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>
@@ -862,17 +862,17 @@ Kurulum devam edebilir fakat bazı özellikler devre dışı kalabilir.</transla
<message>
<location filename="../src/modules/welcome/Config.cpp" line="251"/>
<source>&lt;h1&gt;Welcome to %1 setup&lt;/h1&gt;</source>
<translation>&lt;h1&gt;%1 kurulumuna hoşgeldiniz&lt;/h1&gt;</translation>
<translation>&lt;h1&gt;%1 kurulumuna hoş geldiniz&lt;/h1&gt;</translation>
</message>
<message>
<location filename="../src/modules/welcome/Config.cpp" line="255"/>
<source>&lt;h1&gt;Welcome to the Calamares installer for %1&lt;/h1&gt;</source>
<translation>&lt;h1&gt;%1 Calamares Sistem Yükleyiciye Hoşgeldiniz&lt;/h1&gt;</translation>
<translation>&lt;h1&gt;%1 Calamares Sistem Yükleyiciye Hoş Geldiniz&lt;/h1&gt;</translation>
</message>
<message>
<location filename="../src/modules/welcome/Config.cpp" line="256"/>
<source>&lt;h1&gt;Welcome to the %1 installer&lt;/h1&gt;</source>
<translation>&lt;h1&gt;%1 Sistem Yükleyiciye Hoşgeldiniz&lt;/h1&gt;</translation>
<translation>&lt;h1&gt;%1 Sistem Yükleyiciye Hoş Geldiniz&lt;/h1&gt;</translation>
</message>
<message>
<location filename="../src/modules/users/Config.cpp" line="217"/>
@@ -3978,7 +3978,7 @@ Output:
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="217"/>
<source>&lt;h1&gt;Welcome to %1 setup.&lt;/h1&gt;</source>
<translation>&lt;h1&gt;%1 Kurulumuna Hoşgeldiniz.&lt;/h1&gt;</translation>
<translation>&lt;h1&gt;%1 Kurulumuna Hoş Geldiniz.&lt;/h1&gt;</translation>
</message>
<message>
<location filename="../src/modules/welcome/WelcomePage.cpp" line="222"/>
@@ -4016,7 +4016,7 @@ Output:
<message>
<location filename="../src/modules/welcomeq/WelcomeQmlViewStep.cpp" line="40"/>
<source>Welcome</source>
<translation>Hoşgeldiniz</translation>
<translation>Hoş geldiniz</translation>
</message>
</context>
<context>
@@ -4024,7 +4024,7 @@ Output:
<message>
<location filename="../src/modules/welcome/WelcomeViewStep.cpp" line="46"/>
<source>Welcome</source>
<translation>Hoşgeldiniz</translation>
<translation>Hoş geldiniz</translation>
</message>
</context>
<context>

View File

@@ -323,7 +323,7 @@ msgstr "<code>{name!s}</code> systemd hədəfi aktiv edilmədi"
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "<code>{name!s}</code> systemd taymeri aktiv edilə bilmir."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -407,6 +407,7 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Unsquashfs tapılmadı, squashfs-tools paketinin quraşdırıldığına əmin olun."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -323,7 +323,7 @@ msgstr "<code>{name!s}</code> systemd hədəfi aktiv edilmədi"
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "<code>{name!s}</code> systemd taymeri aktiv edilə bilmir."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -407,6 +407,7 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Unsquashfs tapılmadı, squashfs-tools paketinin quraşdırıldığına əmin olun."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -327,6 +327,7 @@ msgstr "No es pot habilitar la destinació de systemd <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
"No es pot habilitar el temporitzador de systemd <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -406,6 +407,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"No s'ha pogut trobar unsquashfs, assegureu-vos que tingueu instal·lat el "
"paquet squashfs-tools."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -329,7 +329,7 @@ msgstr "Das systemd-Ziel <code>{name!s}</code> kann nicht aktiviert werden."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Systemd-Timer <code>{name!s}</code> kann nicht aktiviert werden."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -412,6 +412,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Unsquashfs nicht gefunden, stellen Sie sicher, dass das Paket squashfs-tools"
" installiert ist."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -6,6 +6,7 @@
# Translators:
# Danial Behzadi <dani.behzi@ubuntu.com>, 2020
# alireza jamshidi <alirezajam98@gmail.com>, 2020
# Mahdy Mirzade <me@mahdym.ir>, 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: alireza jamshidi <alirezajam98@gmail.com>, 2020\n"
"Last-Translator: Mahdy Mirzade <me@mahdym.ir>, 2021\n"
"Language-Team: Persian (https://www.transifex.com/calamares/teams/20061/fa/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -62,13 +63,15 @@ msgstr "نصب بارکنندهٔ راه‌اندازی."
#: src/modules/bootloader/main.py:508
msgid "Bootloader installation error"
msgstr ""
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 ""
"بوت لودر نتوانست نصب شود. دستور <pre>{!s}</pre> برای نصب با خطای {!s} مواجه "
"شد."
#: src/modules/fstab/main.py:29
msgid "Writing fstab."
@@ -77,6 +80,7 @@ msgstr "در حال نوشتن fstab."
#: src/modules/fstab/main.py:389
msgid "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use."
msgstr ""
"هیچ تنظیمات <pre>{!s}</pre> برای استفاده برای <pre>{!s}</pre> داده نشده است."
#: src/modules/dracut/main.py:27
msgid "Creating initramfs with dracut."
@@ -139,6 +143,8 @@ msgid ""
"The displaymanagers list is empty or undefined in both globalstorage and "
"displaymanager.conf."
msgstr ""
"فهرست مدیریت صفحه نمایش ها خالی بوده یا در محل ذخیره داده و "
"displaymanager.conf تعریف نشده است."
#: src/modules/displaymanager/main.py:989
msgid "Display manager configuration was incomplete"
@@ -161,6 +167,8 @@ msgid ""
"Unknown service-action <code>{arg!s}</code> for service {name!s} in run-"
"level {level!s}."
msgstr ""
"دستور سرویس <code>{arg!s}</code> برای سرویس {name!s} در سطح اجرای {level!s}"
" ناشناخته است."
#: src/modules/services-openrc/main.py:93
#: src/modules/services-systemd/main.py:59
@@ -171,6 +179,8 @@ msgstr "نمی‌توان خدمت را دستکاری کرد"
msgid ""
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
msgstr ""
"فراخوانی <code>rc-update {arg!s}</code> در chroot کد خطای {num!s} را "
"برگرداند."
#: src/modules/services-openrc/main.py:101
msgid "Target runlevel does not exist"
@@ -181,6 +191,8 @@ msgid ""
"The path for runlevel {level!s} is <code>{path!s}</code>, which does not "
"exist."
msgstr ""
"مسیر برای سطح اجرای {level!s} برابر <code>{path!s}</code> است، که وجود "
"ندارد."
#: src/modules/services-openrc/main.py:110
msgid "Target service does not exist"
@@ -191,6 +203,7 @@ msgid ""
"The path for service {name!s} is <code>{path!s}</code>, which does not "
"exist."
msgstr ""
"مسیر برای سرویس {name!s} برابر <code>{path!s}</code> است، که وجود ندارد."
#: src/modules/networkcfg/main.py:29
msgid "Saving network configuration."
@@ -223,25 +236,31 @@ msgstr[1] "در حال برداشتن %(num)d بسته."
#: src/modules/packages/main.py:638 src/modules/packages/main.py:650
#: src/modules/packages/main.py:678
msgid "Package Manager error"
msgstr ""
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 ""
"مدیر بسته نتوانست برای بروزرسانی ها آماده شود، دستور <pre>{!s}</pre> با خطای"
" {!s} مواجه شد."
#: 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 ""
"مدیر بسته نتوانست سامانه را بروز کند. دستور <pre>{!s}</pre> با خطای {!s} "
"مواجه شد."
#: 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 ""
"مدیر بسته نتوانست تغییرات را برای نصب سامانه انجام دهد. دستور "
"<pre>{!s}</pre> با خطای {!s} مواجه شد."
#: src/modules/plymouthcfg/main.py:27
msgid "Configure Plymouth theme"
@@ -306,7 +325,7 @@ msgstr "نمی‌توان هدف سیستم‌دی <code>{name!s}</code> را ب
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "نمی‌توان تایمر سیستم‌دی <code>{name!s}</code> را به کار انداخت."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -326,11 +345,11 @@ msgstr ""
#: src/modules/mkinitfs/main.py:27
msgid "Creating initramfs with mkinitfs."
msgstr ""
msgstr "درحال ایجاد initramfs با mkinitfs."
#: src/modules/mkinitfs/main.py:49
msgid "Failed to run mkinitfs on the target"
msgstr ""
msgstr "شکست در اجرا mkinitfs روی هدف"
#: src/modules/unpackfs/main.py:34
msgid "Filling up filesystems."
@@ -385,7 +404,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

@@ -325,7 +325,7 @@ msgstr "Ne mogu omogućiti systemd cilj <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Nije moguće omogućiti systemd timer <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -405,6 +405,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Neuspješno pronalaženje unsquashfs, provjerite imate li instaliran paket "
"squashfs-tools."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -307,7 +307,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 "시스템 타이머 <code>{name!s}</code>를 활성화할 수 없습니다."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -386,7 +386,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

@@ -330,7 +330,7 @@ msgstr "Não é possível habilitar o alvo <code>{name!s}</code> do systemd."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Não foi possível ativar o cronômetro systemd <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -410,6 +410,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Não foi possível encontrar o unsquashfs, certifique-se de que o pacote "
"squashfs-tools foi instalado."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -329,7 +329,7 @@ msgstr "Não é possível ativar o destino do systemd <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Não é possível ativar o temporizador systemd <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -411,6 +411,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Falha ao localizar o unsquashfs, certifique-se de que tem o pacote squashfs-"
"tools instalado."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -5,6 +5,7 @@
#
# Translators:
# හෙළබස, 2021
# Sandaruwan Samaraweera, 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: හෙළබස, 2021\n"
"Last-Translator: Sandaruwan Samaraweera, 2021\n"
"Language-Team: Sinhala (https://www.transifex.com/calamares/teams/20061/si/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -23,7 +24,7 @@ msgstr ""
#: src/modules/initramfscfg/main.py:32
msgid "Configuring initramfs."
msgstr ""
msgstr "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
@@ -35,161 +36,169 @@ msgstr ""
#: src/modules/luksopenswaphookcfg/main.py:86
#: src/modules/luksopenswaphookcfg/main.py:90
msgid "Configuration Error"
msgstr ""
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 ""
msgstr "{!s} සඳහා භාවිතා කිරීමට කිසිදු කොටස් නිර්වචනය කර නොමැත."
#: 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 "{!s} සඳහා භාවිතා කිරීමට root mount point ලබා දී නොමැත."
#: src/modules/grubcfg/main.py:28
msgid "Configure GRUB."
msgstr ""
msgstr "GRUB වින්‍යාස කරන්න."
#: src/modules/bootloader/main.py:43
msgid "Install bootloader."
msgstr ""
msgstr "bootloader ස්ථාපනය කරන්න."
#: src/modules/bootloader/main.py:508
msgid "Bootloader installation error"
msgstr ""
msgstr "Bootloader ස්ථාපනය කිරීමේ දෝෂයකි"
#: src/modules/bootloader/main.py:509
msgid ""
"The bootloader could not be installed. The installation command "
"<pre>{!s}</pre> returned error code {!s}."
msgstr ""
"ඇරඹුම් කාරකය ස්ථාපනය කල නොහැක. ස්ථාපන විධානය <pre>{!s}</pre> දෝෂ කේතය {!s} "
"ලබා දුන්නේය."
#: src/modules/fstab/main.py:29
msgid "Writing fstab."
msgstr ""
msgstr "fstab ලියමින්."
#: src/modules/fstab/main.py:389
msgid "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use."
msgstr ""
"භාවිතා කිරීමට <pre>{!s}</pre> සඳහා <pre>{!s}</pre> වින්‍යාසයක් ලබා දී නොමැත."
#: src/modules/dracut/main.py:27
msgid "Creating initramfs with dracut."
msgstr ""
msgstr "dracut සමඟ initramfs නිර්මාණය කිරීම."
#: src/modules/dracut/main.py:49
msgid "Failed to run dracut on the target"
msgstr ""
msgstr "ඉලක්කය මත ඩ්‍රැකට් ධාවනය කිරීමට අපොහොසත් විය"
#: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50
msgid "The exit code was {}"
msgstr ""
msgstr "පිටවීමේ කේතය වූයේ {}"
#: src/modules/displaymanager/main.py:526
msgid "Cannot write KDM configuration file"
msgstr ""
msgstr "KDM වින්‍යාස ගොනුව ලිවිය නොහැක"
#: src/modules/displaymanager/main.py:527
msgid "KDM config file {!s} does not exist"
msgstr ""
msgstr "KDM වින්‍යාස ගොනුව {!s} නොපවතී"
#: src/modules/displaymanager/main.py:588
msgid "Cannot write LXDM configuration file"
msgstr ""
msgstr "LXDM වින්‍යාස ගොනුව ලිවිය නොහැක"
#: src/modules/displaymanager/main.py:589
msgid "LXDM config file {!s} does not exist"
msgstr ""
msgstr "LXDM වින්‍යාස ගොනුව {!s} නොපවතී"
#: src/modules/displaymanager/main.py:672
msgid "Cannot write LightDM configuration file"
msgstr ""
msgstr "LightDM වින්‍යාස ගොනුව ලිවිය නොහැක"
#: src/modules/displaymanager/main.py:673
msgid "LightDM config file {!s} does not exist"
msgstr ""
msgstr "LightDM වින්‍යාස ගොනුව {!s} නොපවතී"
#: src/modules/displaymanager/main.py:747
msgid "Cannot configure LightDM"
msgstr ""
msgstr "LightDM වින්‍යාස කළ නොහැක"
#: src/modules/displaymanager/main.py:748
msgid "No LightDM greeter installed."
msgstr ""
msgstr "LightDM ග්‍රීටර් ස්ථාපනය කර නැත."
#: src/modules/displaymanager/main.py:779
msgid "Cannot write SLIM configuration file"
msgstr ""
msgstr "SLIM වින්‍යාස ගොනුව ලිවිය නොහැක"
#: src/modules/displaymanager/main.py:780
msgid "SLIM config file {!s} does not exist"
msgstr ""
msgstr "SLIM වින්‍යාස ගොනුව {!s} නොපවතී"
#: src/modules/displaymanager/main.py:906
msgid "No display managers selected for the displaymanager module."
msgstr ""
msgstr "සංදර්ශක කළමනාකරු මොඩියුලය සඳහා සංදර්ශක කළමනාකරුවන් තෝරාගෙන නොමැත."
#: src/modules/displaymanager/main.py:907
msgid ""
"The displaymanagers list is empty or undefined in both globalstorage and "
"displaymanager.conf."
msgstr ""
"ගෝලීය ගබඩාව සහ displaymanager.conf යන දෙකෙහිම සංදර්ශක කළමනාකරු ලැයිස්තුව "
"හිස් හෝ අර්ථ දක්වා නොමැත."
#: src/modules/displaymanager/main.py:989
msgid "Display manager configuration was incomplete"
msgstr ""
msgstr "සංදර්ශක කළමනාකරු වින්‍යාසය අසම්පූර්ණ විය"
#: src/modules/services-openrc/main.py:29
msgid "Configure OpenRC services"
msgstr ""
msgstr "OpenRC සේවා වින්‍යාස කරන්න"
#: src/modules/services-openrc/main.py:57
msgid "Cannot add service {name!s} to run-level {level!s}."
msgstr ""
msgstr "ධාවන මට්ටම {level!s} වෙත සේවාව {name!s} එක් කළ නොහැක."
#: src/modules/services-openrc/main.py:59
msgid "Cannot remove service {name!s} from run-level {level!s}."
msgstr ""
msgstr "ධාවන මට්ටමේ {level!s} වෙතින් සේවාව {name!s} ඉවත් කළ නොහැක."
#: 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 ""
"{name!s} සේවාව සඳහා නොදන්නා සේවා-ක්‍රියාව <code>{arg!s}</code> ධාවන මට්ටමේ "
"{level!s}."
#: src/modules/services-openrc/main.py:93
#: src/modules/services-systemd/main.py:59
msgid "Cannot modify service"
msgstr ""
msgstr "සේවාව වෙනස් කළ නොහැක"
#: src/modules/services-openrc/main.py:94
msgid ""
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
msgstr ""
"<code>rc-update {arg!s}</code> chroot හි ඇමතුම {num!s} දෝෂ කේතය ලබා දුන්නේය."
#: src/modules/services-openrc/main.py:101
msgid "Target runlevel does not exist"
msgstr ""
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 ""
msgstr "ධාවන මට්ටම {level!s} සඳහා මාර්ගය <code>{path!s}</code>, එය නොපවතී."
#: src/modules/services-openrc/main.py:110
msgid "Target service does not exist"
msgstr ""
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 ""
msgstr "සේවාව සඳහා {name!s} මාර්ගය <code>{path!s}</code>, එය නොපවතී."
#: src/modules/networkcfg/main.py:29
msgid "Saving network configuration."
@@ -203,7 +212,7 @@ msgstr "ඇසුරුම් ස්ථාපනය කරන්න."
#: src/modules/packages/main.py:57
#, python-format
msgid "Processing packages (%(count)d / %(total)d)"
msgstr ""
msgstr "පැකේජ සැකසීම (%(count)d / %(total)d)"
#: src/modules/packages/main.py:62
#, python-format
@@ -222,41 +231,47 @@ msgstr[1] "ඇසුරුම් %(num)d ක් ඉවත් වෙමින්.
#: src/modules/packages/main.py:638 src/modules/packages/main.py:650
#: src/modules/packages/main.py:678
msgid "Package Manager error"
msgstr ""
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 ""
"පැකේජ කළමනාකරුට යාවත්කාලීන සකස් කිරීමට නොහැකි විය. විධානය <pre>{!s}</pre> "
"දෝෂ කේතය {!s} ලබා දුන්නේය."
#: 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 ""
"පැකේජ කළමනාකරුට පද්ධතිය යාවත්කාලීන කළ නොහැකි විය. විධානය <pre>{!s}</pre> දෝෂ"
" කේතය {!s} ලබා දුන්නේය."
#: 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 ""
"පැකේජ කළමනාකරුට ස්ථාපිත පද්ධතියට වෙනස්කම් සිදු කළ නොහැක. විධානය "
"<pre>{!s}</pre> දෝෂ කේතය {!s} ලබා දුන්නේය."
#: src/modules/plymouthcfg/main.py:27
msgid "Configure Plymouth theme"
msgstr ""
msgstr "Plymouth තේමාව වින්‍යාස කරන්න"
#: src/modules/initcpiocfg/main.py:28
msgid "Configuring mkinitcpio."
msgstr ""
msgstr "mkinitcpio වින්‍යාස කරමින්."
#: src/modules/localecfg/main.py:30
msgid "Configuring locales."
msgstr ""
msgstr "ස්ථාන වින්‍යාස කිරීම."
#: src/modules/mount/main.py:30
msgid "Mounting partitions."
msgstr ""
msgstr "කොටස් සවි කිරීම."
#: src/modules/rawfs/main.py:26
msgid "Installing data."
@@ -264,12 +279,12 @@ msgstr "දත්ත ස්ථාපනය වෙමින්."
#: src/modules/dummypython/main.py:35
msgid "Dummy python job."
msgstr ""
msgstr "ඩමි python වැඩසටහන."
#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93
#: src/modules/dummypython/main.py:94
msgid "Dummy python step {}"
msgstr ""
msgstr "ව්‍යාජ python පියවර {}"
#: src/modules/hwclock/main.py:26
msgid "Setting hardware clock."
@@ -277,115 +292,120 @@ msgstr "දෘඩාංග ඔරලෝසුව සැකසෙමින්."
#: src/modules/umount/main.py:31
msgid "Unmount file systems."
msgstr ""
msgstr "ගොනු පද්ධති ඉවත් කරන්න."
#: src/modules/openrcdmcryptcfg/main.py:26
msgid "Configuring OpenRC dmcrypt service."
msgstr ""
msgstr "OpenRC dmcrypt සේවාව වින්‍යාස කරමින්."
#: src/modules/services-systemd/main.py:26
msgid "Configure systemd services"
msgstr ""
msgstr "systemd සේවා වින්‍යාස කරන්න"
#: src/modules/services-systemd/main.py:60
msgid ""
"<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}."
msgstr ""
"<code>systemctl {arg!s}</code> chroot වෙත ඇමතුමක් ලබා දුන් දෝෂ කේතය {num!s}."
#: src/modules/services-systemd/main.py:63
#: src/modules/services-systemd/main.py:69
msgid "Cannot enable systemd service <code>{name!s}</code>."
msgstr ""
msgstr "systemd සේවාව <code>{name!s}</code> සබල කළ නොහැක."
#: src/modules/services-systemd/main.py:65
msgid "Cannot enable systemd target <code>{name!s}</code>."
msgstr ""
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>."
msgstr ""
msgstr "systemd ඉලක්කය <code>{name!s}</code> අක්‍රිය කළ නොහැක."
#: src/modules/services-systemd/main.py:73
msgid "Cannot mask systemd unit <code>{name!s}</code>."
msgstr ""
msgstr "systemd ඒකකය <code>{name!s}</code> වසන් කළ නොහැක."
#: 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 ""
"{name!s} ඒකකය සඳහා නොදන්නා systemd විධාන <code>{command!s}</code> සහ "
"<code>{suffix!s}</code>."
#: src/modules/mkinitfs/main.py:27
msgid "Creating initramfs with mkinitfs."
msgstr ""
msgstr "mkinitfs සමඟ initramfs නිර්මාණය කිරීම."
#: src/modules/mkinitfs/main.py:49
msgid "Failed to run mkinitfs on the target"
msgstr ""
msgstr "ඉලක්කය මත mkinitfs ධාවනය කිරීමට අසමත් විය"
#: src/modules/unpackfs/main.py:34
msgid "Filling up filesystems."
msgstr ""
msgstr "ගොනු පද්ධති පිරවීම."
#: src/modules/unpackfs/main.py:254
msgid "rsync failed with error code {}."
msgstr ""
msgstr "දෝෂ කේතය {} සමඟ rsync අසාර්ථක විය."
#: src/modules/unpackfs/main.py:299
msgid "Unpacking image {}/{}, file {}/{}"
msgstr ""
msgstr "රූපය {}/{}, ගොනුව {}/{} අසුරමින්"
#: src/modules/unpackfs/main.py:314
msgid "Starting to unpack {}"
msgstr ""
msgstr "ඉවත් කිරීමට පටන් ගනියි {}"
#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:465
msgid "Failed to unpack image \"{}\""
msgstr ""
msgstr "\"{}\" රූපය ඉවත් කිරීමට අසමත් විය"
#: src/modules/unpackfs/main.py:430
msgid "No mount point for root partition"
msgstr ""
msgstr "root කොටස සඳහා සවි කිරීමේ ලක්ෂ්‍යයක් නොමැත"
#: src/modules/unpackfs/main.py:431
msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing"
msgstr ""
msgstr "ගෝලීය ගබඩාවේ \"rootMountPoint\" යතුරක් අඩංගු නොවේ, කිසිවක් නොකරයි"
#: src/modules/unpackfs/main.py:436
msgid "Bad mount point for root partition"
msgstr ""
msgstr "මූල කොටස සඳහා නරක සවි කිරීමේ ලක්ෂ්‍යය"
#: src/modules/unpackfs/main.py:437
msgid "rootMountPoint is \"{}\", which does not exist, doing nothing"
msgstr ""
msgstr "rootMountPoint යනු \"{}\", එය නොපවතින, කිසිවක් නොකරයි"
#: 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 ""
msgstr "නරක unsquash වින්‍යාසය"
#: src/modules/unpackfs/main.py:454
msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel"
msgstr ""
msgstr "\"{}\" ({}) සඳහා ගොනු පද්ධතිය ඔබගේ වත්මන් කර්නලයෙන් සහය නොදක්වයි"
#: src/modules/unpackfs/main.py:458
msgid "The source filesystem \"{}\" does not exist"
msgstr ""
msgstr "මූලාශ්‍ර ගොනු පද්ධතිය \"{}\" නොපවතී"
#: src/modules/unpackfs/main.py:464
msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Unsquashfs සොයා ගැනීමට අපොහොසත් විය, ඔබ squashfs-tools පැකේජය ස්ථාපනය කර ඇති"
" බවට වග බලා ගන්න."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"
msgstr ""
msgstr "ඉලක්ක පද්ධතියේ \"{}\" ගමනාන්තය නාමාවලියක් නොවේ"
#: src/modules/luksopenswaphookcfg/main.py:26
msgid "Configuring encrypted swap."
msgstr ""
msgstr "සංකේතාත්මක swap වින්‍යාස කිරීම."

View File

@@ -327,7 +327,7 @@ msgstr "Kunde inte aktivera systemd målsystem <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "Kunde inte aktivera systemd timer <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -407,6 +407,8 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Kunde inte hitta unsquashfs, se till att du har paketet squashfs-tools "
"installerat"
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -322,7 +322,7 @@ msgstr "Systemd hedefi etkinleştirilemiyor <code>{name!s}</code>."
#: src/modules/services-systemd/main.py:67
msgid "Cannot enable systemd timer <code>{name!s}</code>."
msgstr ""
msgstr "<code>{name!s}</code> sistem zamanlayıcısı etkinleştirilemiyor."
#: src/modules/services-systemd/main.py:71
msgid "Cannot disable systemd target <code>{name!s}</code>."
@@ -403,6 +403,7 @@ msgid ""
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
"installed."
msgstr ""
"Unsquashfs bulunamadı, squashfs-tools paketinin kurulu olduğundan emin olun."
#: src/modules/unpackfs/main.py:479
msgid "The destination \"{}\" in the target system is not a directory"

View File

@@ -5,6 +5,7 @@
#
# Translators:
# T. Tran <transifex@emiu.net>, 2020
# Th1nhhdk, 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: T. Tran <transifex@emiu.net>, 2020\n"
"Last-Translator: Th1nhhdk, 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"
@@ -61,13 +62,15 @@ msgstr "Đang cài đặt bộ khởi động."
#: src/modules/bootloader/main.py:508
msgid "Bootloader installation error"
msgstr ""
msgstr "Lỗi cài đặt trình khởi động(bootloader)"
#: src/modules/bootloader/main.py:509
msgid ""
"The bootloader could not be installed. The installation command "
"<pre>{!s}</pre> returned error code {!s}."
msgstr ""
"Trình khởi động(bootloader) không thể được cài đặt. Lệnh cài đặt "
"<pre>{!s}</pre>đã trả mã lỗi {!s}."
#: src/modules/fstab/main.py:29
msgid "Writing fstab."

View File

@@ -127,6 +127,7 @@ sequence:
# - dummyprocess
# - dummypython
- partition
# - zfs
- mount
- unpackfs
- machineid

View File

@@ -132,6 +132,11 @@ public:
void setEmergency( bool e ) { m_emergency = e; }
signals:
/** @brief Signals that the job has made progress
*
* The parameter @p percent should be between 0 (0%) and 1 (100%).
* Values outside of this range will be clamped.
*/
void progress( qreal percent );
private:

View File

@@ -26,6 +26,11 @@ namespace CalamaresPython
boost::python::object
variantToPyObject( const QVariant& variant )
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
// 49 enumeration values not handled
switch ( variant.type() )
{
case QVariant::Map:
@@ -62,6 +67,9 @@ variantToPyObject( const QVariant& variant )
default:
return bp::object();
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}

View File

@@ -23,6 +23,11 @@ static const char* s_preScript = nullptr;
namespace bp = boost::python;
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#endif
BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, CalamaresPython::mount, 2, 4 );
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, CalamaresPython::target_env_call, 1, 3 );
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_list_overloads, CalamaresPython::target_env_call, 1, 3 );
@@ -42,6 +47,10 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_process_output_overloads,
4 );
BOOST_PYTHON_FUNCTION_OVERLOADS( host_env_process_output_overloads, CalamaresPython::host_env_process_output, 1, 4 );
#ifdef __clang__
#pragma clang diagnostic pop
#endif
BOOST_PYTHON_MODULE( libcalamares )
{
bp::object package = bp::scope();
@@ -79,13 +88,25 @@ BOOST_PYTHON_MODULE( libcalamares )
bp::scope utilsScope = utilsModule;
Q_UNUSED( utilsScope )
// .. Logging functions
bp::def(
"debug", &CalamaresPython::debug, bp::args( "s" ), "Writes the given string to the Calamares debug stream." );
bp::def( "warning",
&CalamaresPython::warning,
bp::args( "s" ),
"Writes the given string to the Calamares warning stream." );
bp::def( "warn",
&CalamaresPython::warning,
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." );
// .. YAML functions
bp::def( "load_yaml", &CalamaresPython::load_yaml, bp::args( "path" ), "Loads YAML from a file." );
// .. Filesystem functions
bp::def( "mount",
&CalamaresPython::mount,
mount_overloads( bp::args( "device_path", "mount_point", "filesystem_name", "options" ),
@@ -94,6 +115,8 @@ BOOST_PYTHON_MODULE( libcalamares )
"-1 = QProcess crash\n"
"-2 = QProcess cannot start\n"
"-3 = bad arguments" ) );
// .. Process functions
bp::def(
"target_env_call",
static_cast< int ( * )( const std::string&, const std::string&, int ) >( &CalamaresPython::target_env_call ),
@@ -152,6 +175,7 @@ BOOST_PYTHON_MODULE( libcalamares )
host_env_process_output_overloads( bp::args( "command", "callback", "stdin", "timeout" ),
"Runs the specified command in the host system." ) );
// .. String functions
bp::def( "obscure",
&CalamaresPython::obscure,
bp::args( "s" ),
@@ -160,7 +184,7 @@ BOOST_PYTHON_MODULE( libcalamares )
"Applying the function to a string obscured by this function will result "
"in the original string." );
// .. Translation functions
bp::def( "gettext_languages",
&CalamaresPython::gettext_languages,
"Returns list of languages (most to least-specific) for gettext." );

View File

@@ -19,6 +19,7 @@
#include "utils/RAII.h"
#include "utils/Runner.h"
#include "utils/String.h"
#include "utils/Yaml.h"
#include <QCoreApplication>
#include <QDir>
@@ -139,19 +140,44 @@ check_target_env_output( const bp::list& args, const std::string& stdin, int tim
}
static const char output_prefix[] = "[PYTHON JOB]:";
static inline void
log_action( unsigned int level, const std::string& s )
{
Logger::CDebug( level ) << output_prefix << QString::fromStdString( s );
}
void
debug( const std::string& s )
{
Logger::CDebug( Logger::LOGDEBUG ) << output_prefix << QString::fromStdString( s );
log_action( Logger::LOGDEBUG, s );
}
void
warning( const std::string& s )
{
Logger::CDebug( Logger::LOGWARNING ) << output_prefix << QString::fromStdString( s );
log_action( Logger::LOGWARNING, s );
}
void
error( const std::string& s )
{
log_action( Logger::LOGERROR, s );
}
boost::python::dict
load_yaml( const std::string& path )
{
const QString filePath = QString::fromStdString( path );
bool ok = false;
auto map = CalamaresUtils::loadYaml( filePath, &ok );
if ( !ok )
{
cWarning() << "Loading YAML from" << filePath << "failed.";
}
return variantMapToPyDict( map );
}
PythonJobInterface::PythonJobInterface( Calamares::PythonJob* parent )
: m_parent( parent )
{

View File

@@ -60,6 +60,12 @@ boost::python::list gettext_languages();
void debug( const std::string& s );
void warning( const std::string& s );
void error( const std::string& s );
/** @brief Loads YAML and returns (nested) dicts representing it
*
*/
boost::python::dict load_yaml( const std::string& path );
class PythonJobInterface
{

View File

@@ -22,6 +22,11 @@ namespace Partition
QString
prettyNameForFileSystemType( FileSystem::Type t )
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
// 13 enumeration values not handled
switch ( t )
{
case FileSystem::Unknown:
@@ -60,11 +65,19 @@ prettyNameForFileSystemType( FileSystem::Type t )
default:
return FileSystem::nameForType( t );
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
QString
untranslatedFS( FileSystem::Type t )
{
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
#endif
// 34 enumeration values not handled
switch ( t )
{
case FileSystem::Type::ReiserFS:
@@ -72,6 +85,9 @@ untranslatedFS( FileSystem::Type t )
default:
return FileSystem::nameForType( t, { QStringLiteral( "C" ) } );
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif
}
} // namespace Partition

View File

@@ -115,12 +115,14 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
QString completePath = targetPath( path );
if ( completePath.isEmpty() )
{
cWarning() << "No target path for" << path;
return CreationResult( CreationResult::Code::Invalid );
}
QFile f( completePath );
if ( ( mode == WriteMode::KeepExisting ) && f.exists() )
{
cWarning() << "Target file" << completePath << "already exists";
return CreationResult( CreationResult::Code::AlreadyExists );
}
@@ -133,13 +135,16 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
if ( !f.open( m ) )
{
cWarning() << "Could not open target file" << completePath;
return CreationResult( CreationResult::Code::Failed );
}
if ( f.write( contents ) != contents.size() )
auto written = f.write( contents );
if ( written != contents.size() )
{
f.close();
f.remove();
cWarning() << "Short write (" << written << "out of" << contents.size() << "bytes) to" << completePath;
return CreationResult( CreationResult::Code::Failed );
}
@@ -147,6 +152,30 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
return CreationResult( QFileInfo( f ).canonicalFilePath() );
}
QStringList
System::readTargetFile( const QString& path ) const
{
const QString completePath = targetPath( path );
if ( completePath.isEmpty() )
{
return QStringList();
}
QFile f( completePath );
if ( !f.open( QIODevice::ReadOnly ) )
{
return QStringList();
}
QTextStream in( &f );
QStringList l;
while ( !f.atEnd() )
{
l << in.readLine();
}
return l;
}
void
System::removeTargetFile( const QString& path ) const
{

View File

@@ -287,6 +287,24 @@ public:
*/
DLLEXPORT void removeTargetFile( const QString& path ) const;
/** @brief Reads a file from the target system.
*
* @param path Path to the file; this is interpreted from the root of
* the target system (@see targetPath()).
*
* Does no error checking, and returns an empty list if the file does
* not exist.
*
* NOTE: This function is now basically the same as QFile::readAll(),
* splitting into lines, but Calamares may need to change
* permissions or raise privileges to actually read the file,
* which is why there is an API.
*
* NOTE: Since this buffers the whole file in memory, reading big files
* is not recommended.
*/
DLLEXPORT QStringList readTargetFile( const QString& path ) const;
/** @brief Ensure that the directory @p path exists
*
* @param path a full pathname to a desired directory.

View File

@@ -20,6 +20,8 @@
#include <QDir>
#include <QFileInfo>
#include <QMutex>
#include <QRandomGenerator>
#include <QTextStream>
#include <QTime>
#include <QVariant>
@@ -229,7 +231,7 @@ toString( const QVariant& v )
}
QDebug&
operator<<( QDebug& s, const Redacted& l )
operator<<( QDebug& s, const RedactedCommand& l )
{
// Special case logging: don't log the (encrypted) password.
if ( l.list.contains( "usermod" ) )
@@ -252,4 +254,33 @@ operator<<( QDebug& s, const Redacted& l )
return s;
}
/** @brief Returns a stable-but-private hash of @p context and @p s
*
* Identical strings with the same context will be hashed the same,
* so that they can be logged and still recognized as the-same.
*/
static uint insertRedactedName( const QString& context, const QString& s )
{
static uint salt = QRandomGenerator::global()->generate(); // Just once
uint val = qHash(context, salt);
return qHash(s, val);
}
RedactedName::RedactedName( const QString& context, const QString& s )
: m_id( insertRedactedName(context, s) ),
m_context(context)
{
}
RedactedName::RedactedName(const char *context, const QString& s )
: RedactedName( QString::fromLatin1( context ), s )
{
}
RedactedName::operator QString() const
{
return QString( m_context + '$' + QString::number( m_id, 16 ) );
}
} // namespace Logger

View File

@@ -145,8 +145,8 @@ public:
{
}
const T& first;
const U& second;
const T first;
const U second;
};
/**
@@ -214,9 +214,9 @@ public:
* since the log may get posted to bug reports, or stored in
* the target system.
*/
struct Redacted
struct RedactedCommand
{
Redacted( const QStringList& l )
RedactedCommand( const QStringList& l )
: list( l )
{
}
@@ -224,7 +224,30 @@ struct Redacted
const QStringList& list;
};
QDebug& operator<<( QDebug& s, const Redacted& l );
QDebug& operator<<( QDebug& s, const RedactedCommand& l );
/** @brief When logging "private" identifiers, keep them consistent but private
*
* Send a string to a logger in such a way that each time it is logged,
* it logs the same way, but without revealing the actual contents.
* This can be applied to user names, UUIDs, etc.
*/
struct RedactedName
{
RedactedName( const char* context, const QString& s );
RedactedName( const QString& context, const QString& s );
operator QString() const;
private:
const uint m_id;
const QString m_context;
};
inline QDebug& operator<<( QDebug& s, const RedactedName& n )
{
return s << NoQuote << QString( n ) << Quote;
}
/**
* @brief Formatted logging of a pointer

View File

@@ -163,7 +163,7 @@ Calamares::Utils::Runner::run()
} );
}
cDebug() << Logger::SubEntry << "Running" << Logger::Redacted( m_command );
cDebug() << Logger::SubEntry << "Running" << Logger::RedactedCommand( m_command );
process.start();
if ( !process.waitForStarted() )
{
@@ -225,13 +225,13 @@ Calamares::Utils::Runner::run()
{
if ( !output.isEmpty() )
{
cDebug() << Logger::SubEntry << "Target cmd:" << Logger::Redacted( m_command ) << "Exit code:" << r
cDebug() << Logger::SubEntry << "Target cmd:" << Logger::RedactedCommand( m_command ) << "Exit code:" << r
<< "output:\n"
<< Logger::NoQuote << output;
}
else
{
cDebug() << Logger::SubEntry << "Target cmd:" << Logger::Redacted( m_command ) << "Exit code:" << r
cDebug() << Logger::SubEntry << "Target cmd:" << Logger::RedactedCommand( m_command ) << "Exit code:" << r
<< "(no output)";
}
}

View File

@@ -224,5 +224,26 @@ truncateMultiLine( const QString& string, CalamaresUtils::LinesStartEnd lines, C
return front + back.right( chars.total / 2 );
}
void
removeLeading( QString& string, QChar c )
{
int count = 0;
while ( string.length() > count && string[ count ] == c )
{
count++;
}
string.remove( 0, count );
}
void
removeTrailing( QString& string, QChar c )
{
int lastIndex = string.length();
while ( lastIndex > 0 && string[ lastIndex - 1 ] == c )
{
lastIndex--;
}
string.remove( lastIndex, string.length() );
}
} // namespace CalamaresUtils

View File

@@ -100,6 +100,19 @@ DLLEXPORT QString truncateMultiLine( const QString& string,
LinesStartEnd lines = LinesStartEnd { 3, 5 },
CharCount chars = CharCount { 812 } );
/** @brief Remove all @p c at the beginning of @p string
*
* Modifies the @p string in-place. If @p c is not the first character
* of @p string, the string is left unchanged; otherwise the first character
* is removed and the process repeats.
*/
DLLEXPORT void removeLeading( QString& string, QChar c );
/** @brief Remove all @p c at the end of @p string
*
* Like removeLeading(), but at the end of the string.
*/
DLLEXPORT void removeTrailing( QString& string, QChar c );
} // namespace CalamaresUtils
#endif

View File

@@ -70,12 +70,19 @@ private Q_SLOTS:
void testStringTruncation();
void testStringTruncationShorter();
void testStringTruncationDegenerate();
void testStringRemoveLeading_data();
void testStringRemoveLeading();
void testStringRemoveTrailing_data();
void testStringRemoveTrailing();
/** @section Test Runner directory-manipulation. */
void testRunnerDirs();
void testCalculateWorkingDirectory();
void testRunnerOutput();
/** @section Test file-functions */
void testReadWriteFile();
private:
void recursiveCompareMap( const QVariantMap& a, const QVariantMap& b, int depth );
};
@@ -751,6 +758,64 @@ LibCalamaresTests::testStringTruncationDegenerate()
}
}
void
LibCalamaresTests::testStringRemoveLeading_data()
{
QTest::addColumn< QString >( "string" );
QTest::addColumn< char >( "c" );
QTest::addColumn< QString >( "result" );
QTest::newRow( "empty" ) << QString() << '/' << QString();
QTest::newRow( "one-slash" ) << QStringLiteral( "/tmp" ) << '/' << QStringLiteral( "tmp" );
QTest::newRow( "two-slash" ) << QStringLiteral( "//tmp" ) << '/' << QStringLiteral( "tmp" );
QTest::newRow( "multi-slash" ) << QStringLiteral( "/tmp/p" ) << '/' << QStringLiteral( "tmp/p" );
QTest::newRow( "later-slash" ) << QStringLiteral( "@/tmp" ) << '/' << QStringLiteral( "@/tmp" );
QTest::newRow( "all-one-slash" ) << QStringLiteral( "/" ) << '/' << QString();
QTest::newRow( "all-many-slash" ) << QStringLiteral( "////////////////////" ) << '/' << QString();
QTest::newRow( "trailing" ) << QStringLiteral( "tmp/" ) << '/' << QStringLiteral( "tmp/" );
}
void
LibCalamaresTests::testStringRemoveLeading()
{
QFETCH( QString, string );
QFETCH( char, c );
QFETCH( QString, result );
const QString initial = string;
CalamaresUtils::removeLeading( string, c );
QCOMPARE( string, result );
}
void
LibCalamaresTests::testStringRemoveTrailing_data()
{
QTest::addColumn< QString >( "string" );
QTest::addColumn< char >( "c" );
QTest::addColumn< QString >( "result" );
QTest::newRow( "empty" ) << QString() << '/' << QString();
QTest::newRow( "one-slash" ) << QStringLiteral( "/tmp" ) << '/' << QStringLiteral( "/tmp" );
QTest::newRow( "two-slash" ) << QStringLiteral( "//tmp" ) << '/' << QStringLiteral( "//tmp" );
QTest::newRow( "multi-slash" ) << QStringLiteral( "/tmp//p/" ) << '/' << QStringLiteral( "/tmp//p" );
QTest::newRow( "later-slash" ) << QStringLiteral( "@/tmp/@" ) << '/' << QStringLiteral( "@/tmp/@" );
QTest::newRow( "later-slash2" ) << QStringLiteral( "@/tmp/@//" ) << '/' << QStringLiteral( "@/tmp/@" );
QTest::newRow( "all-one-slash" ) << QStringLiteral( "/" ) << '/' << QString();
QTest::newRow( "all-many-slash" ) << QStringLiteral( "////////////////////" ) << '/' << QString();
QTest::newRow( "trailing" ) << QStringLiteral( "tmp/" ) << '/' << QStringLiteral( "tmp" );
}
void
LibCalamaresTests::testStringRemoveTrailing()
{
QFETCH( QString, string );
QFETCH( char, c );
QFETCH( QString, result );
const QString initial = string;
CalamaresUtils::removeTrailing( string, c );
QCOMPARE( string, result );
}
static QString
dirname( const QTemporaryDir& d )
@@ -950,6 +1015,84 @@ LibCalamaresTests::testRunnerOutput()
}
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;
}
void
LibCalamaresTests::testReadWriteFile()
{
static const QByteArray otherContents( "derp\n" );
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
auto* ss = file_setup( tempRoot );
QVERIFY( ss );
{
auto fullPath = ss->createTargetFile( "test0", QByteArray(), CalamaresUtils::System::WriteMode::Overwrite );
QVERIFY( fullPath );
QVERIFY( !fullPath.path().isEmpty() );
QFileInfo fi( fullPath.path() );
QVERIFY( fi.exists() );
QVERIFY( fi.isFile() );
QCOMPARE( fi.size(), 0 );
}
// It won't overwrite unless you ask for it
{
auto fullPath = ss->createTargetFile( "test0", otherContents );
QVERIFY( !fullPath ); // Failed, because it won't overwrite
QCOMPARE( fullPath.code(), decltype( fullPath )::Code::AlreadyExists );
QVERIFY( fullPath.path().isEmpty() ); // Because it wasn't written
QFileInfo fi( tempRoot.filePath( "test0" ) ); // Compute the name some other way
QVERIFY( fi.exists() );
QVERIFY( fi.isFile() );
QCOMPARE( fi.size(), 0 );
}
// But it will if you say so explicitly
{
auto fullPath = ss->createTargetFile( "test0", otherContents, CalamaresUtils::System::WriteMode::Overwrite );
QVERIFY( fullPath );
QVERIFY( !fullPath.path().isEmpty() );
QFileInfo fi( fullPath.path() );
QVERIFY( fi.exists() );
QVERIFY( fi.isFile() );
QCOMPARE( fi.size(), 5 );
}
// Now it's been written, we can read it, too
{
auto contents = ss->readTargetFile( "test0" );
QVERIFY( !contents.isEmpty() );
QCOMPARE( contents.count(), 1 );
QCOMPARE( contents[ 0 ], QStringLiteral( "derp" ) ); // No trailing \n
}
}
QTEST_GUILESS_MAIN( LibCalamaresTests )
#include "utils/moc-warnings.h"

View File

@@ -162,14 +162,15 @@ uploadServerFromMap( const QVariantMap& map )
if ( typestring.isEmpty() || urlstring.isEmpty() )
{
return Branding::UploadServerInfo( Branding::UploadServerType::None, QUrl(), 0 );
return Branding::UploadServerInfo { Branding::UploadServerType::None, QUrl(), 0 };
}
bool bogus = false; // we don't care about type-name lookup success here
return Branding::UploadServerInfo(
return Branding::UploadServerInfo {
names.find( typestring, bogus ),
QUrl( urlstring, QUrl::ParsingMode::StrictMode ),
sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1 );
sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1
};
}
/** @brief Load the @p map with strings from @p config

View File

@@ -227,7 +227,14 @@ public:
* is irrelevant and usually empty), the URL for the upload and the size limit of upload
* in bytes (for configuration value < 0, it serves -1, which stands for having no limit).
*/
using UploadServerInfo = std::tuple< UploadServerType, QUrl, qint64 >;
struct UploadServerInfo
{
UploadServerType type;
QUrl url;
qint64 size;
operator bool() const { return type != Calamares::Branding::UploadServerType::None && size != 0; }
};
UploadServerInfo uploadServer() const { return m_uploadServer; }
/**

View File

@@ -27,6 +27,7 @@ set( calamaresui_SOURCES
viewpages/ViewStep.cpp
widgets/ClickableLabel.cpp
widgets/ErrorDialog.cpp
widgets/FixedAspectRatioLabel.cpp
widgets/PrettyRadioButton.cpp
widgets/TranslationFix.cpp
@@ -39,8 +40,6 @@ set( calamaresui_SOURCES
# Don't warn about third-party sources
mark_thirdparty_code(
${CMAKE_SOURCE_DIR}/3rdparty/qjsonitem.cpp
${CMAKE_SOURCE_DIR}/3rdparty/qjsonmodel.cpp
${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp
)
@@ -75,6 +74,8 @@ calamares_add_library( calamaresui
Qt5::Svg
RESOURCES libcalamaresui.qrc
EXPORT Calamares
UI
utils/ErrorDialog/ErrorDialog.ui
VERSION ${CALAMARES_VERSION_SHORT}
)
target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp )

View File

@@ -24,11 +24,13 @@
#include "viewpages/BlankViewStep.h"
#include "viewpages/ExecutionViewStep.h"
#include "viewpages/ViewStep.h"
#include "widgets/ErrorDialog.h"
#include "widgets/TranslationFix.h"
#include <QApplication>
#include <QBoxLayout>
#include <QClipboard>
#include <QDialogButtonBox>
#include <QFile>
#include <QMessageBox>
#include <QMetaObject>
@@ -150,56 +152,32 @@ ViewManager::insertViewStep( int before, ViewStep* step )
void
ViewManager::onInstallationFailed( const QString& message, const QString& details )
{
bool shouldOfferWebPaste = std::get< 0 >( Calamares::Branding::instance()->uploadServer() )
!= Calamares::Branding::UploadServerType::None
and std::get< 2 >( Calamares::Branding::instance()->uploadServer() ) != 0;
cError() << "Installation failed:" << message;
cDebug() << Logger::SubEntry << "- message:" << message;
cDebug() << Logger::SubEntry << "- details:" << Logger::NoQuote << details;
QString heading
= Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" );
QString pasteMsg = tr( "Would you like to paste the install log to the web?" );
QString text = "<p>" + message + "</p>";
if ( !details.isEmpty() )
{
text += "<p>"
+ CalamaresUtils::truncateMultiLine( details, CalamaresUtils::LinesStartEnd { 6, 2 } )
.replace( '\n', QStringLiteral( "<br/>" ) )
+ "</p>";
}
if ( shouldOfferWebPaste )
{
text += "<p>" + pasteMsg + "</p>";
}
QMessageBox* msgBox = new QMessageBox();
msgBox->setIcon( QMessageBox::Critical );
msgBox->setWindowTitle( tr( "Error" ) );
msgBox->setText( "<strong>" + heading + "</strong>" );
msgBox->setInformativeText( text );
if ( shouldOfferWebPaste )
{
msgBox->setStandardButtons( QMessageBox::Yes | QMessageBox::No );
msgBox->setDefaultButton( QMessageBox::No );
}
else
{
msgBox->setStandardButtons( QMessageBox::Close );
msgBox->setDefaultButton( QMessageBox::Close );
}
Calamares::fixButtonLabels( msgBox );
msgBox->show();
ErrorDialog* errorDialog = new ErrorDialog();
errorDialog->setWindowTitle( tr( "Error" ) );
errorDialog->setHeading( "<strong>" + heading + "</strong>" );
errorDialog->setInformativeText( message );
errorDialog->setShouldOfferWebPaste( Calamares::Branding::instance()->uploadServer() );
errorDialog->setDetails( details );
errorDialog->show();
cDebug() << "Calamares will quit when the dialog closes.";
connect( msgBox, &QMessageBox::buttonClicked, [msgBox]( QAbstractButton* button ) {
if ( msgBox->buttonRole( button ) == QMessageBox::ButtonRole::YesRole )
{
CalamaresUtils::Paste::doLogUploadUI( msgBox );
}
QApplication::quit();
} );
connect( errorDialog,
&QDialog::finished,
[ errorDialog ]( int result )
{
if ( result == QDialog::Accepted && errorDialog->shouldOfferWebPaste() )
{
CalamaresUtils::Paste::doLogUploadUI( errorDialog );
}
QApplication::quit();
} );
}

View File

@@ -69,7 +69,8 @@ STATICTEST QString
ficheLogUpload( const QByteArray& pasteData, const QUrl& serverUrl, QObject* parent )
{
QTcpSocket* socket = new QTcpSocket( parent );
socket->connectToHost( serverUrl.host(), serverUrl.port() );
// 16 bits of port-number
socket->connectToHost( serverUrl.host(), quint16( serverUrl.port() ) );
if ( !socket->waitForConnected() )
{

View File

@@ -0,0 +1,106 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Artem Grinev <agrinev@manjaro.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#include "ErrorDialog.h"
#include "ui_ErrorDialog.h"
#include "widgets/TranslationFix.h"
#include <QDialogButtonBox>
#include <QIcon>
namespace Calamares
{
ErrorDialog::ErrorDialog( QWidget* parent )
: QDialog( parent )
, ui( new Ui::ErrorDialog )
{
ui->setupUi( this );
ui->iconLabel->setPixmap( QIcon::fromTheme( "dialog-error" ).pixmap( 64 ) );
ui->detailsWidget->hide();
ui->offerWebPasteLabel->hide();
}
ErrorDialog::~ErrorDialog()
{
delete ui;
}
QString
ErrorDialog::heading() const
{
return ui->headingLabel->text();
}
QString
ErrorDialog::informativeText() const
{
return ui->informativeTextLabel->text();
}
QString
ErrorDialog::details() const
{
return ui->detailsBrowser->toPlainText();
}
void
ErrorDialog::setHeading( const QString& newHeading )
{
if ( ui->headingLabel->text() != newHeading )
{
ui->headingLabel->setText( newHeading );
emit headingChanged();
}
}
void
ErrorDialog::setInformativeText( const QString& newInformativeText )
{
if ( ui->informativeTextLabel->text() != newInformativeText )
{
ui->informativeTextLabel->setText( newInformativeText );
emit informativeTextChanged();
}
}
void
ErrorDialog::setDetails( const QString& newDetails )
{
if ( ui->detailsBrowser->toPlainText() != newDetails )
{
ui->detailsBrowser->setPlainText( newDetails );
ui->detailsWidget->setVisible( !ui->detailsBrowser->toPlainText().trimmed().isEmpty() );
emit detailsChanged();
}
}
bool
ErrorDialog::shouldOfferWebPaste() const
{
return m_shouldOfferWebPaste;
}
void
ErrorDialog::setShouldOfferWebPaste( bool newShouldOfferWebPaste )
{
if ( m_shouldOfferWebPaste != newShouldOfferWebPaste )
{
m_shouldOfferWebPaste = newShouldOfferWebPaste;
ui->offerWebPasteLabel->setVisible( m_shouldOfferWebPaste );
ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? ( QDialogButtonBox::Yes | QDialogButtonBox::No )
: QDialogButtonBox::Close );
fixButtonLabels( ui->buttonBox );
emit shouldOfferWebPasteChanged();
}
}
} // namespace Calamares

View File

@@ -0,0 +1,83 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2021 Artem Grinev <agrinev@manjaro.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
#ifndef LIBCALAMARESUI_ERRORDIALOG_H
#define LIBCALAMARESUI_ERRORDIALOG_H
#include <QDialog>
namespace Ui
{
class ErrorDialog;
}
namespace Calamares
{
class ErrorDialog : public QDialog
{
Q_OBJECT
Q_PROPERTY( QString heading READ heading WRITE setHeading NOTIFY headingChanged )
Q_PROPERTY( QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged )
Q_PROPERTY( QString details READ details WRITE setDetails NOTIFY detailsChanged )
Q_PROPERTY( bool shouldOfferWebPaste READ shouldOfferWebPaste WRITE setShouldOfferWebPaste NOTIFY
shouldOfferWebPasteChanged )
public:
explicit ErrorDialog( QWidget* parent = nullptr );
~ErrorDialog() override;
/** @brief The heading (title) of the error dialog
*
* This is a short (one-line) title. It is human-readable, so should
* be translated at the time it is set.
*/
QString heading() const;
void setHeading( const QString& newHeading );
/** @brief The description of the problem
*
* Longer, human-readable, description of the problem. This text
* is word-wrapped as necessary.
*/
QString informativeText() const;
void setInformativeText( const QString& newInformativeText );
/** @brief Details of the problem
*
* This is generally command-output; it might not be translated
* when set. It should be considered "background to the informative
* text", or maybe "the reasons". Write the informative text for
* the end-user.
*/
QString details() const;
void setDetails( const QString& newDetails );
/** @brief Enable web-paste button
*
* The web-paste button can be configured at a global level,
* but each individual error dialog can be set separately.
*/
bool shouldOfferWebPaste() const;
void setShouldOfferWebPaste( bool newShouldOfferWebPaste );
signals:
void headingChanged();
void informativeTextChanged();
void detailsChanged();
void shouldOfferWebPasteChanged();
private:
Ui::ErrorDialog* ui;
bool m_shouldOfferWebPaste = false;
};
}; // namespace Calamares
#endif // LIBCALAMARESUI_ERRORDIALOG_H

View File

@@ -0,0 +1,133 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ErrorDialog</class>
<widget class="QDialog" name="ErrorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>425</width>
<height>262</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0" colspan="2">
<widget class="QWidget" name="detailsWidget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLabel" name="informativeTextLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Details:</string>
</property>
</widget>
</item>
<item>
<widget class="QTextBrowser" name="detailsBrowser"/>
</item>
</layout>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="offerWebPasteLabel">
<property name="toolTip">
<string/>
</property>
<property name="text">
<string>Would you like to paste the install log to the web?</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="iconLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="headingLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ErrorDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ErrorDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -11,30 +11,34 @@
#include <QAbstractButton>
#include <QCoreApplication>
#include <QDialogButtonBox>
#include <QMessageBox>
#include <QPushButton>
namespace Calamares
{
//Using QMessageBox's StandardButton enum here but according to headers they should be kept in-sync between multiple classes.
static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = {
{ QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) },
{ QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) },
{ QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) },
{ QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) },
{ QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) },
};
template < typename TButtonBox >
void
fixButtonLabels( QMessageBox* box )
fixButtonLabels( TButtonBox* box )
{
if ( !box )
{
return;
}
static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = {
{ QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) },
{ QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) },
{ QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) },
{ QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) },
{ QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) },
};
for ( auto [ sb, label ] : maps )
{
auto* button = box->button( sb );
auto* button = box->button( static_cast< typename TButtonBox::StandardButton >( int( sb ) ) );
if ( button )
{
button->setText( QCoreApplication::translate( "StandardButtons", label ) );
@@ -42,4 +46,16 @@ fixButtonLabels( QMessageBox* box )
}
}
void
fixButtonLabels( QMessageBox* box )
{
fixButtonLabels< QMessageBox >( box );
}
void
fixButtonLabels( QDialogButtonBox* box )
{
fixButtonLabels< QDialogButtonBox >( box );
}
} // namespace Calamares

View File

@@ -13,6 +13,7 @@
#include "DllMacro.h"
class QMessageBox;
class QDialogButtonBox;
namespace Calamares
{
@@ -26,6 +27,8 @@ namespace Calamares
* guess the context.
*/
void UIDLLEXPORT fixButtonLabels( QMessageBox* );
void UIDLLEXPORT fixButtonLabels( QDialogButtonBox* );
} // namespace Calamares
#endif

View File

@@ -398,7 +398,9 @@ target_env_process_output(["ls"])
```
The functions return 0. If the exit code of *command* is not 0, an exception
is raised instead of returning 0.
is raised instead of returning 0. The exception is `subprocess.CalledProcessError`
(as if the *subprocess* module had been used), and the `returncode` member
of the exception object can be used to determine the exit code.
Parameter *stdin* may be a string which is fed to the command as standard input.
The *timeout* is in seconds, with 0 (or a negative number) treated as no-timeout.

View File

@@ -92,6 +92,50 @@ def get_kernel_line(kernel_type):
return ""
def get_zfs_root():
"""
Looks in global storage to find the zfs root
:return: A string containing the path to the zfs root or None if it is not found
"""
zfs = libcalamares.globalstorage.value("zfsDatasets")
if not zfs:
libcalamares.utils.warning("Failed to locate zfs dataset list")
return None
# Find the root dataset
for dataset in zfs:
try:
if dataset["mountpoint"] == "/":
return dataset["zpool"] + "/" + dataset["dsName"]
except KeyError:
# This should be impossible
libcalamares.utils.warning("Internal error handling zfs dataset")
raise
return None
def is_btrfs_root(partition):
""" Returns True if the partition object refers to a btrfs root filesystem
:param partition: A partition map from global storage
:return: True if btrfs and root, False otherwise
"""
return partition["mountPoint"] == "/" and partition["fs"] == "btrfs"
def is_zfs_root(partition):
""" Returns True if the partition object refers to a zfs root filesystem
:param partition: A partition map from global storage
:return: True if zfs and root, False otherwise
"""
return partition["mountPoint"] == "/" and partition["fs"] == "zfs"
def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, kernel_type):
"""
Creates systemd-boot configuration files based on given parameters.
@@ -133,11 +177,24 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker
"root=/dev/mapper/"
+ partition["luksMapperName"]]
# systemd-boot with a BTRFS root filesystem needs to be told
# about the root subvolume.
for partition in partitions:
if partition["mountPoint"] == "/" and partition["fs"] == "btrfs":
kernel_params.append("rootflags=subvol=@")
# systemd-boot with a BTRFS root filesystem needs to be told abouut the root subvolume.
# If a btrfs root subvolume wasn't set, it means the root is directly on the partition
# and this option isn't needed
if is_btrfs_root(partition):
btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume")
if btrfs_root_subvolume:
kernel_params.append("rootflags=subvol=" + btrfs_root_subvolume)
# zfs needs to be told the location of the root dataset
if is_zfs_root(partition):
zfs_root_path = get_zfs_root()
if zfs_root_path is not None:
kernel_params.append("zfs=" + zfs_root_path)
else:
# Something is really broken if we get to this point
libcalamares.utils.warning("Internal error handling zfs dataset")
raise Exception("Internal zfs data missing, please contact your distribution")
if cryptdevice_params:
kernel_params.extend(cryptdevice_params)
@@ -167,7 +224,7 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker
# Copy kernel and initramfs to a subdirectory of /efi partition
files_dir = os.path.join(install_path + efi_dir, entry_name)
os.mkdir(files_dir)
os.makedirs(files_dir, exist_ok=True)
kernel_path = install_path + kernel
kernel_name = os.path.basename(kernel_path)
@@ -314,6 +371,76 @@ def get_grub_efi_parameters():
return None
def run_grub_mkconfig(partitions, output_file):
"""
Runs grub-mkconfig in the target environment
:param partitions: The partitions list from global storage
:param output_file: A string containing the path to the generating grub config file
:return:
"""
# zfs needs an environment variable set for grub-mkconfig
if any([is_zfs_root(partition) for partition in partitions]):
check_target_env_call(["sh", "-c", "ZPOOL_VDEV_NAME_PATH=1 " +
libcalamares.job.configuration["grubMkconfig"] + " -o " + output_file])
else:
# The input file /etc/default/grub should already be filled out by the
# grubcfg job module.
check_target_env_call([libcalamares.job.configuration["grubMkconfig"], "-o", output_file])
def run_grub_install(fw_type, partitions, efi_directory=None):
"""
Runs grub-install in the target environment
:param fw_type: A string which is "efi" for UEFI installs. Any other value results in a BIOS install
:param partitions: The partitions list from global storage
:param efi_directory: The path of the efi directory relative to the root of the install
:return:
"""
is_zfs = any([is_zfs_root(partition) for partition in partitions])
# zfs needs an environment variable set for grub
if is_zfs:
check_target_env_call(["sh", "-c", "echo ZPOOL_VDEV_NAME_PATH=1 >> /etc/environment"])
if fw_type == "efi":
efi_bootloader_id = efi_label()
efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters()
if is_zfs:
check_target_env_call(["sh", "-c", "ZPOOL_VDEV_NAME_PATH=1 " + libcalamares.job.configuration["grubInstall"]
+ " --target=" + efi_target + " --efi-directory=" + efi_directory
+ " --bootloader-id=" + efi_bootloader_id + " --force"])
else:
check_target_env_call([libcalamares.job.configuration["grubInstall"],
"--target=" + efi_target,
"--efi-directory=" + efi_directory,
"--bootloader-id=" + efi_bootloader_id,
"--force"])
else:
if libcalamares.globalstorage.value("bootLoader") is None:
return
boot_loader = libcalamares.globalstorage.value("bootLoader")
if boot_loader["installPath"] is None:
return
if is_zfs:
check_target_env_call(["sh", "-c", "ZPOOL_VDEV_NAME_PATH=1 "
+ libcalamares.job.configuration["grubInstall"]
+ " --target=i386-pc --recheck --force "
+ boot_loader["installPath"]])
else:
check_target_env_call([libcalamares.job.configuration["grubInstall"],
"--target=i386-pc",
"--recheck",
"--force",
boot_loader["installPath"]])
def install_grub(efi_directory, fw_type):
"""
Installs grub as bootloader, either in pc or efi mode.
@@ -321,6 +448,12 @@ def install_grub(efi_directory, fw_type):
:param efi_directory:
:param fw_type:
"""
# get the partition from global storage
partitions = libcalamares.globalstorage.value("partitions")
if not partitions:
libcalamares.utils.warning(_("Failed to install grub, no partitions defined in global storage"))
return
if fw_type == "efi":
libcalamares.utils.debug("Bootloader: grub (efi)")
install_path = libcalamares.globalstorage.value("rootMountPoint")
@@ -333,11 +466,7 @@ def install_grub(efi_directory, fw_type):
efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters()
check_target_env_call([libcalamares.job.configuration["grubInstall"],
"--target=" + efi_target,
"--efi-directory=" + efi_directory,
"--bootloader-id=" + efi_bootloader_id,
"--force"])
run_grub_install(fw_type, partitions, efi_directory)
# VFAT is weird, see issue CAL-385
install_efi_directory_firmware = (vfat_correct_case(
@@ -356,36 +485,21 @@ def install_grub(efi_directory, fw_type):
os.makedirs(install_efi_boot_directory)
# Workaround for some UEFI firmwares
FALLBACK = "installEFIFallback"
libcalamares.utils.debug("UEFI Fallback: " + str(libcalamares.job.configuration.get(FALLBACK, "<unset>")))
if libcalamares.job.configuration.get(FALLBACK, True):
fallback = "installEFIFallback"
libcalamares.utils.debug("UEFI Fallback: " + str(libcalamares.job.configuration.get(fallback, "<unset>")))
if libcalamares.job.configuration.get(fallback, True):
libcalamares.utils.debug(" .. installing '{!s}' fallback firmware".format(efi_boot_file))
efi_file_source = os.path.join(install_efi_directory_firmware,
efi_bootloader_id,
efi_grub_file)
efi_file_target = os.path.join(install_efi_boot_directory,
efi_boot_file)
efi_bootloader_id,
efi_grub_file)
efi_file_target = os.path.join(install_efi_boot_directory, efi_boot_file)
shutil.copy2(efi_file_source, efi_file_target)
else:
libcalamares.utils.debug("Bootloader: grub (bios)")
if libcalamares.globalstorage.value("bootLoader") is None:
return
run_grub_install(fw_type, partitions)
boot_loader = libcalamares.globalstorage.value("bootLoader")
if boot_loader["installPath"] is None:
return
check_target_env_call([libcalamares.job.configuration["grubInstall"],
"--target=i386-pc",
"--recheck",
"--force",
boot_loader["installPath"]])
# The input file /etc/default/grub should already be filled out by the
# grubcfg job module.
check_target_env_call([libcalamares.job.configuration["grubMkconfig"],
"-o", libcalamares.job.configuration["grubCfg"]])
run_grub_mkconfig(partitions, libcalamares.job.configuration["grubCfg"])
def install_secureboot(efi_directory):

View File

@@ -23,6 +23,7 @@ displaymanagers:
- mdm
- lxdm
- kdm
- greetd
# Enable the following settings to force a desktop environment
# in your displaymanager configuration file. This will attempt

View File

@@ -10,7 +10,7 @@ properties:
type: array
items:
type: string
enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm]
enum: [slim, sddm, lightdm, gdm, mdm, lxdm, kdm, greetd]
minItems: 1 # Must be non-empty, if present at all
defaultDesktopEnvironment:
type: object

View File

@@ -17,9 +17,7 @@
import abc
import os
import re
import libcalamares
import configparser
from libcalamares.utils import gettext_path, gettext_languages
@@ -796,6 +794,8 @@ class DMsddm(DisplayManager):
executable = "sddm"
def set_autologin(self, username, do_autologin, default_desktop_environment):
import configparser
# Systems with Sddm as Desktop Manager
sddm_conf_path = os.path.join(self.root_mount_point, "etc/sddm.conf")
@@ -835,6 +835,91 @@ class DMsddm(DisplayManager):
pass
class DMgreetd(DisplayManager):
name = "greetd"
executable = "greetd"
greeter_user = "greeter"
greeter_group = "greetd"
config_data = {}
def os_path(self, path):
return os.path.join(self.root_mount_point, path)
def config_path(self):
return self.os_path("etc/greetd/config.toml")
def environments_path(self):
return self.os_path("etc/greetd/environments")
def config_load(self):
import toml
if (os.path.exists(self.config_path())):
with open(self.config_path(), "r") as f:
self.config_data = toml.load(f)
self.config_data['terminal'] = dict(vt = "next")
default_session_group = self.config_data.get('default_session', None)
if not default_session_group:
self.config_data['default_session'] = {}
self.config_data['default_session']['user'] = self.greeter_user
return self.config_data
def config_write(self):
import toml
with open(self.config_path(), "w") as f:
toml.dump(self.config_data, f)
def basic_setup(self):
if libcalamares.utils.target_env_call(
['getent', 'group', self.greeter_group]
) != 0:
libcalamares.utils.target_env_call(
['groupadd', self.greeter_group]
)
if libcalamares.utils.target_env_call(
['getent', 'passwd', self.greeter_user]
) != 0:
libcalamares.utils.target_env_call(
['useradd',
'-c', '"Greeter User"',
'-g', self.greeter_group,
'-s', '/bin/bash',
self.greeter_user
]
)
def desktop_environment_setup(self, default_desktop_environment):
with open(self.environments_path(), 'w') as envs_file:
envs_file.write(default_desktop_environment)
def greeter_setup(self):
pass
def set_autologin(self, username, do_autologin, default_desktop_environment):
self.config_load()
de_command = default_desktop_environment.executable
if os.path.exists(self.os_path("usr/bin/gtkgreed")) and os.path.exists(self.os_path("usr/bin/cage")):
self.config_data['default_session']['command'] = "cage -s -- gtkgreet"
elif os.path.exists(self.os_path("usr/bin/tuigreet")):
tuigreet_base_cmd = "tuigreet --remember --time --issue --asterisks --cmd "
self.config_data['default_session']['command'] = tuigreet_base_cmd + de_command
elif os.path.exists(self.os_path("usr/bin/ddlm")):
self.config_data['default_session']['command'] = "ddlm --target " + de_command
else:
self.config_data['default_session']['command'] = "agreety --cmd " + de_command
if do_autologin == True:
self.config_data['initial_session'] = dict(command = de_command, user = username)
self.config_write()
class DMsysconfig(DisplayManager):
name = "sysconfig"
executable = None

View File

@@ -0,0 +1,3 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
rootMountPoint: /tmp

View File

@@ -0,0 +1,13 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# We have tests to load (some) of the DMs specifically, to test their
# configuration code. Those tests conventionally live in Python
# files here in the tests/ directory. Add them.
foreach(_dmname greetd sddm)
add_test(
NAME configure-displaymanager-${_dmname}
COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-dm-${_dmname}.py
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
endforeach()

View File

@@ -0,0 +1,25 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Calamares Boilerplate
import libcalamares
libcalamares.globalstorage = libcalamares.GlobalStorage(None)
libcalamares.globalstorage.insert("testing", True)
# Module prep-work
from src.modules.displaymanager import main
default_desktop_environment = main.DesktopEnvironment("startplasma-x11", "kde-plasma.desktop")
import os
os.makedirs("/tmp/etc/greetd/", exist_ok=True)
try:
os.remove("/tmp/etc/greetd/config.toml")
except FileNotFoundError as e:
pass
# Specific DM test
d = main.DMgreetd("/tmp")
d.set_autologin("d", True, default_desktop_environment)
# .. and again (this time checks load/save)
d.set_autologin("d", True, default_desktop_environment)
d.set_autologin("d", True, default_desktop_environment)

View File

@@ -0,0 +1,18 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Calamares Boilerplate
import libcalamares
libcalamares.globalstorage = libcalamares.GlobalStorage(None)
libcalamares.globalstorage.insert("testing", True)
# Module prep-work
from src.modules.displaymanager import main
default_desktop_environment = main.DesktopEnvironment("startplasma-x11", "kde-plasma.desktop")
# Specific DM test
d = main.DMsddm("/tmp")
d.set_autologin("d", True, default_desktop_environment)
# .. and again (this time checks load/save)
d.set_autologin("d", True, default_desktop_environment)
d.set_autologin("d", True, default_desktop_environment)

View File

@@ -0,0 +1,121 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
* SPDX-License-Identifier: GPL-3.0-or-later
* License-Filename: LICENSE
*
* Calamares is Free Software: see the License-Identifier above.
*
*/
import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.3
import org.kde.kirigami 2.7 as Kirigami
import QtGraphicalEffects 1.0
import QtQuick.Window 2.3
Page {
id: finished
width: parent.width
height: parent.height
header: Kirigami.Heading {
width: parent.width
height: 100
id: header
Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter
color: Kirigami.Theme.textColor
level: 1
text: qsTr("Installation Completed")
Text {
anchors.top: header.bottom
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
font.pointSize: 12
text: qsTr("%1 has been installed on your computer.<br/>
You may now restart your device.").arg(Branding.string(Branding.ProductName))
}
Image {
source: "seedling.svg"
anchors.top: header.bottom
anchors.topMargin: 80
anchors.horizontalCenter: parent.horizontalCenter
width: 64
height: 64
mipmap: true
}
}
RowLayout {
Layout.alignment: Qt.AlignRight|Qt.AlignVCenter
anchors.centerIn: parent
spacing: 6
Button {
id: button
text: qsTr("Close")
icon.name: "application-exit"
onClicked: { ViewManager.quit(); }
}
Button {
text: qsTr("Restart")
icon.name: "system-reboot"
onClicked: { config.doRestart(true); }
}
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
anchors.bottom: parent.bottom
anchors.bottomMargin : 100
anchors.horizontalCenter: parent.horizontalCenter
ProgressBar {
id: autoRestartBar
value: 1.0
anchors.horizontalCenter: parent.horizontalCenter
}
Timer {
id: autoRestartTimer
// This is in milliseconds and should be less than 1000 (because of logic in onTriggered)
interval: 100
repeat: true
running: false
// Whenever the timer fires (1000 / interval times a second) count the progress bar down
// by 1%. When the bar is empty, try to restart normally; as a backup, when the bar
// is empty change settings and schedule it to quit 1000 milliseconds (1s) later.
onTriggered: {
autoRestartBar.value -= 0.01;
if (autoRestartBar.value <= 0.0) {
// First time through here, set the interval to 1000 so that the
// second time (1 second later) goes to quit().
if ( interval > 999) { ViewManager.quit(); }
else { config.doRestart(true); running = false; interval = 1000; repeat = false; start(); }
}
}
}
}
function onActivate()
{
autoRestartTimer.running = true
}
function onLeave()
{
}
}

View File

@@ -11,9 +11,23 @@
# Mount options to use for all filesystems. If a specific filesystem
# is listed here, use those options, otherwise use the *default*
# options from this mapping.
#
# With kernels 5.15 and newer be cautious of adding the option space_cache
# to the btrfs mount options. The default in 5.15 changed to space_cache=v2.
# If space_cache or space_cache=v1 are specified, it may fail to remount.
#
# btrfs_swap options are used when a swapfile is chosen with a btrfs root
# the options are applied to the subvolume which holds the swap partition
#
# The settings shown here apply only the btrfs defaults; these
# are generally the right ones. Commented-out lines show other
# options wich **might** be applicable for specific situations.
mountOptions:
default: defaults,noatime
btrfs: defaults,noatime,space_cache,autodefrag,compress=zstd
# btrfs: defaults,noatime,autodefrag,compress=zstd
btrfs: defaults
# btrfs_swap: defaults,noatime
btrfs_swap: defaults
# Mount options to use for the EFI System Partition. If not defined, the
# *mountOptions* for *vfat* are used, or if that is not set either,

View File

@@ -22,6 +22,7 @@ properties:
xfs: { type: string }
swap: { type: string }
btrfs: { type: string }
btrfs_swap: { type: string }
efiMountOptions: { type: string }
crypttabOptions: { type: string }
required: [ mountOptions ]

View File

@@ -196,7 +196,7 @@ class FstabGenerator(object):
dct = self.generate_fstab_line_info(mount_entry)
if dct:
self.print_fstab_line(dct, file=fstab_file)
else:
elif partition["fs"] != "zfs": # zfs partitions don't need an entry in fstab
dct = self.generate_fstab_line_info(partition)
if dct:
self.print_fstab_line(dct, file=fstab_file)
@@ -236,7 +236,11 @@ class FstabGenerator(object):
libcalamares.utils.debug("Ignoring foreign swap {!s} {!s}".format(disk_name, partition.get("uuid", None)))
return None
options = self.get_mount_options(filesystem, mount_point)
# If this is btrfs subvol a dedicated to a swapfile, use different options than a normal btrfs subvol
if filesystem == "btrfs" and partition.get("subvol", None) == "/@swap":
options = self.get_mount_options("btrfs_swap", mount_point)
else:
options = self.get_mount_options(filesystem, mount_point)
if is_ssd:
extra = self.ssd_extra_mount_options.get(filesystem)
@@ -254,7 +258,8 @@ class FstabGenerator(object):
if mount_point == "/":
self.root_is_ssd = is_ssd
if filesystem == "btrfs" and "subvol" in partition:
# If there's a set-and-not-empty subvolume set, add it
if filesystem == "btrfs" and partition.get("subvol",None):
options = "subvol={},".format(partition["subvol"]) + options
if has_luks:

View File

@@ -55,6 +55,32 @@ def get_grub_config_path(root_mount_point):
return os.path.join(default_dir, default_config_file)
def get_zfs_root():
"""
Looks in global storage to find the zfs root
:return: A string containing the path to the zfs root or None if it is not found
"""
zfs = libcalamares.globalstorage.value("zfsDatasets")
if not zfs:
libcalamares.utils.warning("Failed to locate zfs dataset list")
return None
# Find the root dataset
for dataset in zfs:
try:
if dataset["mountpoint"] == "/":
return dataset["zpool"] + "/" + dataset["dsName"]
except KeyError:
# This should be impossible
libcalamares.utils.warning("Internal error handling zfs dataset")
raise
return None
def modify_grub_default(partitions, root_mount_point, distributor):
"""
Configures '/etc/default/grub' for hibernation and plymouth.
@@ -91,6 +117,8 @@ def modify_grub_default(partitions, root_mount_point, distributor):
swap_outer_mappername = None
no_save_default = False
unencrypted_separate_boot = any(p["mountPoint"] == "/boot" and "luksMapperName" not in p for p in partitions)
# If there is no dracut, and the root partition is ZFS, this gets set below
zfs_root_path = None
for partition in partitions:
if partition["mountPoint"] in ("/", "/boot") and partition["fs"] in ("btrfs", "f2fs"):
@@ -141,8 +169,15 @@ def modify_grub_default(partitions, root_mount_point, distributor):
)
]
if partition["fs"] == "zfs" and partition["mountPoint"] == "/":
zfs_root_path = get_zfs_root()
kernel_params = ["quiet"]
# Currently, grub doesn't detect this properly so it must be set manually
if zfs_root_path:
kernel_params.insert(0, "zfs=" + zfs_root_path)
if cryptdevice_params:
kernel_params.extend(cryptdevice_params)

View File

@@ -150,6 +150,7 @@ def find_initcpio_features(partitions, root_mount_point):
swap_uuid = ""
uses_btrfs = False
uses_zfs = False
uses_lvm2 = False
encrypt_hook = False
openswap_hook = False
@@ -172,6 +173,9 @@ def find_initcpio_features(partitions, root_mount_point):
if partition["fs"] == "btrfs":
uses_btrfs = True
if partition["fs"] == "zfs":
uses_zfs = True
if "lvm2" in partition["fs"]:
uses_lvm2 = True
@@ -198,6 +202,9 @@ def find_initcpio_features(partitions, root_mount_point):
if uses_lvm2:
hooks.append("lvm2")
if uses_zfs:
hooks.append("zfs")
if swap_uuid != "":
if encrypt_hook and openswap_hook:
hooks.extend(["openswap"])

View File

@@ -18,6 +18,7 @@
#include <KParts/ReadOnlyPart>
#include <KParts/kde_terminal_interface.h>
#include <KService>
#include <kcoreaddons_version.h>
#include <QApplication>
#include <QDir>
@@ -41,8 +42,10 @@ InteractiveTerminalPage::InteractiveTerminalPage( QWidget* parent )
void
InteractiveTerminalPage::errorKonsoleNotInstalled()
{
QMessageBox mb(QMessageBox::Critical,
tr( "Konsole not installed" ), tr( "Please install KDE Konsole and try again!" ), QMessageBox::Ok );
QMessageBox mb( QMessageBox::Critical,
tr( "Konsole not installed" ),
tr( "Please install KDE Konsole and try again!" ),
QMessageBox::Ok );
Calamares::fixButtonLabels( &mb );
mb.exec();
}
@@ -54,20 +57,30 @@ InteractiveTerminalPage::onActivate()
{
return;
}
// For whatever reason, instead of simply linking against a library we
// need to do a runtime query to KService just to get a sodding terminal
// widget.
#if KCOREADDONS_VERSION_MAJOR != 5
#error Incompatible with not-KF5
#endif
#if KCOREADDONS_VERSION_MINOR >= 86
// 5.86 deprecated a bunch of KService and PluginFactory and related methods
auto md = KPluginMetaData::findPluginById( QString(), "konsolepart" );
if ( !md.isValid() )
{
errorKonsoleNotInstalled();
return;
}
auto* p = KPluginFactory::instantiatePlugin< KParts::ReadOnlyPart >( md, this ).plugin;
#else
KService::Ptr service = KService::serviceByDesktopName( "konsolepart" );
if ( !service )
{
// And all of this hoping the Konsole application is installed. If not,
// tough cookies.
errorKonsoleNotInstalled();
return;
}
// Create one instance of konsolepart.
KParts::ReadOnlyPart* p = service->createInstance< KParts::ReadOnlyPart >( this, this, {} );
#endif
if ( !p )
{
// One more opportunity for the loading operation to fail.
@@ -91,7 +104,6 @@ InteractiveTerminalPage::onActivate()
m_termHostWidget = p->widget();
m_layout->addWidget( m_termHostWidget );
cDebug() << "Part widget ought to be" << m_termHostWidget->metaObject()->className();
t->showShellInDir( QDir::home().path() );
t->sendInput( QString( "%1\n" ).arg( m_command ) );

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -64,6 +64,11 @@ def write_openswap_conf(partitions, root_mount_point, openswap_conf_path):
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")
@@ -84,11 +89,11 @@ def run():
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"))
_("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"))
_("No root mount point is given for <pre>{!s}</pre> to use.").format("luksopenswaphookcfg"))
openswap_conf_path = openswap_conf_path.lstrip('/')

View File

@@ -20,12 +20,24 @@ import os
import libcalamares
import gettext
_ = gettext.translation("calamares-python",
localedir=libcalamares.utils.gettext_path(),
languages=libcalamares.utils.gettext_languages(),
fallback=True).gettext
class ZfsException(Exception):
"""Exception raised when there is a problem with zfs
Attributes:
message -- explanation of the error
"""
def __init__(self, message):
self.message = message
def pretty_name():
return _("Mounting partitions.")
@@ -47,20 +59,85 @@ def get_btrfs_subvolumes(partitions):
if btrfs_subvolumes is None:
libcalamares.utils.warning("No configuration for btrfsSubvolumes")
if not btrfs_subvolumes:
btrfs_subvolumes = [ dict(mountPoint="/", subvolume="/@"), dict(mountPoint="/home", subvolume="/@home") ]
btrfs_subvolumes = [dict(mountPoint="/", subvolume="/@"), dict(mountPoint="/home", subvolume="/@home")]
# Filter out the subvolumes which have a dedicated partition
non_root_partition_mounts = [ m for m in [ p.get("mountPoint", None) for p in partitions ] if m is not None and m != '/' ]
btrfs_subvolumes = list(filter(lambda s : s["mountPoint"] not in non_root_partition_mounts, btrfs_subvolumes))
non_root_partition_mounts = [m for m in [p.get("mountPoint", None) for p in partitions] if
m is not None and m != '/']
btrfs_subvolumes = list(filter(lambda s: s["mountPoint"] not in non_root_partition_mounts, btrfs_subvolumes))
# If we have a swap **file**, give it a separate subvolume.
swap_choice = libcalamares.globalstorage.value( "partitionChoices" )
if swap_choice and swap_choice.get( "swap", None ) == "file":
swap_choice = libcalamares.globalstorage.value("partitionChoices")
if swap_choice and swap_choice.get("swap", None) == "file":
btrfs_subvolumes.append({'mountPoint': '/swap', 'subvolume': '/@swap'})
return btrfs_subvolumes
def mount_zfs(root_mount_point, partition):
""" Mounts a zfs partition at @p root_mount_point
:param root_mount_point: The absolute path to the root of the install
:param partition: The partition map from global storage for this partition
:return:
"""
# Get the list of zpools from global storage
zfs_pool_list = libcalamares.globalstorage.value("zfsPoolInfo")
if not zfs_pool_list:
libcalamares.utils.warning("Failed to locate zfsPoolInfo data in global storage")
raise ZfsException(_("Internal error mounting zfs datasets"))
# Find the zpool matching this partition
for zfs_pool in zfs_pool_list:
if zfs_pool["mountpoint"] == partition["mountPoint"]:
pool_name = zfs_pool["poolName"]
ds_name = zfs_pool["dsName"]
# import the zpool
try:
libcalamares.utils.host_env_process_output(["zpool", "import", "-N", "-R", root_mount_point, pool_name], None)
except subprocess.CalledProcessError:
raise ZfsException(_("Failed to import zpool"))
# Get the encrpytion information from global storage
zfs_info_list = libcalamares.globalstorage.value("zfsInfo")
encrypt = False
if zfs_info_list:
for zfs_info in zfs_info_list:
if zfs_info["mountpoint"] == partition["mountPoint"] and zfs_info["encrypted"] is True:
encrypt = True
passphrase = zfs_info["passphrase"]
if encrypt is True:
# The zpool is encrypted, we need to unlock it
try:
libcalamares.utils.host_env_process_output(["zfs", "load-key", pool_name], None, passphrase)
except subprocess.CalledProcessError:
raise ZfsException(_("Failed to unlock zpool"))
if partition["mountPoint"] == '/':
# Get the zfs dataset list from global storage
zfs = libcalamares.globalstorage.value("zfsDatasets")
if not zfs:
libcalamares.utils.warning("Failed to locate zfs dataset list")
raise ZfsException(_("Internal error mounting zfs datasets"))
zfs.sort(key=lambda x: x["mountpoint"])
for dataset in zfs:
try:
if dataset["canMount"] == "noauto" or dataset["canMount"] is True:
libcalamares.utils.host_env_process_output(["zfs", "mount",
dataset["zpool"] + '/' + dataset["dsName"]])
except subprocess.CalledProcessError:
raise ZfsException(_("Failed to set zfs mountpoint"))
else:
try:
libcalamares.utils.host_env_process_output(["zfs", "mount", pool_name + '/' + ds_name])
except subprocess.CalledProcessError:
raise ZfsException(_("Failed to set zfs mountpoint"))
def mount_partition(root_mount_point, partition, partitions):
"""
Do a single mount of @p partition inside @p root_mount_point.
@@ -96,11 +173,14 @@ def mount_partition(root_mount_point, partition, partitions):
if "luksMapperName" in partition:
device = os.path.join("/dev/mapper", partition["luksMapperName"])
if libcalamares.utils.mount(device,
mount_point,
fstype,
partition.get("options", "")) != 0:
libcalamares.utils.warning("Cannot mount {}".format(device))
if fstype == "zfs":
mount_zfs(root_mount_point, partition)
else: # fstype == "zfs"
if libcalamares.utils.mount(device,
mount_point,
fstype,
partition.get("options", "")) != 0:
libcalamares.utils.warning("Cannot mount {}".format(device))
# Special handling for btrfs subvolumes. Create the subvolumes listed in mount.conf
if fstype == "btrfs" and partition["mountPoint"] == '/':
@@ -111,9 +191,14 @@ def mount_partition(root_mount_point, partition, partitions):
libcalamares.globalstorage.insert("btrfsSubvolumes", btrfs_subvolumes)
# Create the subvolumes that are in the completed list
for s in btrfs_subvolumes:
subprocess.check_call(['btrfs', 'subvolume', 'create',
root_mount_point + s['subvolume']])
if not s["subvolume"]:
continue
os.makedirs(root_mount_point + os.path.dirname(s["subvolume"]), exist_ok=True)
subprocess.check_call(["btrfs", "subvolume", "create",
root_mount_point + s["subvolume"]])
if s["mountPoint"] == "/":
# insert the root subvolume into global storage
libcalamares.globalstorage.insert("btrfsRootSubvolume", s["subvolume"])
subprocess.check_call(["umount", "-v", root_mount_point])
device = partition["device"]
@@ -126,9 +211,9 @@ def mount_partition(root_mount_point, partition, partitions):
mount_option = "subvol={}".format(s['subvolume'])
subvolume_mountpoint = mount_point[:-1] + s['mountPoint']
if libcalamares.utils.mount(device,
subvolume_mountpoint,
fstype,
",".join([mount_option, partition.get("options", "")])) != 0:
subvolume_mountpoint,
fstype,
",".join([mount_option, partition.get("options", "")])) != 0:
libcalamares.utils.warning("Cannot mount {}".format(device))
@@ -142,7 +227,7 @@ def run():
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("mount"))
_("No partitions are defined for <pre>{!s}</pre> to use.").format("mount"))
root_mount_point = tempfile.mkdtemp(prefix="calamares-root-")
@@ -159,10 +244,13 @@ def run():
# This way, we ensure / is mounted before the rest, and every mount point
# is created on the right partition (e.g. if a partition is to be mounted
# under /tmp, we make sure /tmp is mounted before the partition)
mountable_partitions = [ p for p in partitions + extra_mounts if "mountPoint" in p and p["mountPoint"] ]
mountable_partitions = [p for p in partitions + extra_mounts if "mountPoint" in p and p["mountPoint"]]
mountable_partitions.sort(key=lambda x: x["mountPoint"])
for partition in mountable_partitions:
mount_partition(root_mount_point, partition, partitions)
try:
for partition in mountable_partitions:
mount_partition(root_mount_point, partition, partitions)
except ZfsException as ze:
return _("zfs mounting error"), ze.message
libcalamares.globalstorage.insert("rootMountPoint", root_mount_point)

View File

@@ -42,15 +42,24 @@ extraMountsEfi:
mountPoint: /sys/firmware/efi/efivars
# Btrfs subvolumes to create if root filesystem is on btrfs volume.
# If mountpoint is mounted already to another partition, it is ignored.
# If *mountpoint* is mounted already to another partition, it is ignored.
# Separate subvolume for swapfile is handled separately and automatically.
#
# It is possible to prevent subvolume creation -- this is likely only relevant
# for the root (/) subvolume -- by giving an empty string as a subvolume
# name. In this case no subvolume will be created. When using snapper as
# a rollback mechanism, it is recommended to **not** create a subvolume
# for root.
btrfsSubvolumes:
- mountPoint: /
subvolume: /@
# As an alternative:
#
# subvolume: ""
- mountPoint: /home
subvolume: /@home
- mountPoint: /var/cache
subvolume: /@cache
- mountPoint: /var/log
subvolume: /@log
subvolume: /@log

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

@@ -379,6 +379,7 @@ class PMPacman(PackageManager):
def __init__(self):
import re
progress_match = re.compile("^\\((\\d+)/(\\d+)\\)")
def line_cb(line):
if line.startswith(":: "):
self.in_package_changes = "package changes" in line
@@ -396,30 +397,79 @@ class PMPacman(PackageManager):
self.in_package_changes = False
self.line_cb = line_cb
pacman = libcalamares.job.configuration.get("pacman", None)
if pacman is None:
pacman = dict()
if type(pacman) is not dict:
libcalamares.utils.warning("Job configuration *pacman* will be ignored.")
pacman = dict()
self.pacman_num_retries = pacman.get("num_retries", 0)
self.pacman_disable_timeout = pacman.get("disable_download_timeout", False)
self.pacman_needed_only = pacman.get("needed_only", False)
def reset_progress(self):
self.in_package_changes = False
# These are globals
self.progress_fraction = (completed_packages * 1.0 / total_packages)
def run_pacman(self, command, callback=False):
"""
Call pacman in a loop until it is successful or the number of retries is exceeded
:param command: The pacman command to run
:param callback: An optional boolean that indicates if this pacman run should use the callback
:return:
"""
pacman_count = 0
while pacman_count <= self.pacman_num_retries:
pacman_count += 1
try:
if callback is True:
libcalamares.utils.target_env_process_output(command, self.line_cb)
else:
libcalamares.utils.target_env_process_output(command)
return
except subprocess.CalledProcessError:
if pacman_count <= self.pacman_num_retries:
pass
else:
raise
def install(self, pkgs, from_local=False):
command = ["pacman"]
if from_local:
pacman_flags = "-U"
command.append("-U")
else:
pacman_flags = "-S"
command.append("-S")
command.append("--noconfirm")
if self.pacman_needed_only is True:
command.append("--needed")
if self.pacman_disable_timeout is True:
command.append("--disable-download-timeout")
command += pkgs
self.reset_progress()
libcalamares.utils.target_env_process_output(["pacman", pacman_flags,
"--noconfirm"] + pkgs, self.line_cb)
self.run_pacman(command, True)
def remove(self, pkgs):
self.reset_progress()
libcalamares.utils.target_env_process_output(["pacman", "-Rs", "--noconfirm"] + pkgs, self.line_cb)
self.run_pacman(["pacman", "-Rs", "--noconfirm"] + pkgs, True)
def update_db(self):
check_target_env_call(["pacman", "-Sy"])
self.run_pacman(["pacman", "-Sy"])
def update_system(self):
check_target_env_call(["pacman", "-Su", "--noconfirm"])
command = ["pacman", "-Su", "--noconfirm"]
if self.pacman_disable_timeout is True:
command.append("--disable-download-timeout")
self.run_pacman(command)
class PMPamac(PackageManager):

View File

@@ -62,6 +62,23 @@ skip_if_no_internet: false
update_db: true
update_system: false
# pacman specific options
#
# *num_retries* should be a positive integer which specifies the
# number of times the call to pacman will be retried in the event of a
# failure. If it is missing, it will be set to 0.
#
# *disable_download_timeout* is a boolean that, when true, includes
# the flag --disable-download-timeout on calls to pacman. When missing,
# false is assumed.
#
# *needed_only* is a boolean that includes the pacman argument --needed
# when set to true. If missing, false is assumed.
pacman:
num_retries: 0
disable_download_timeout: false
needed_only: false
#
# List of maps with package operations such as install or remove.
# Distro developers can provide a list of packages to remove

View File

@@ -26,6 +26,14 @@ properties:
update_system: { type: boolean, default: false }
skip_if_no_internet: { type: boolean, default: false }
pacman:
additionalProperties: false
type: object
properties:
num_retries: { type: integer, default: 0 }
disable_download_timeout: { type: boolean, default: false }
needed_only: { type: boolean, default: false }
operations:
type: array
items:

View File

@@ -0,0 +1,3 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
rootMountPoint: /tmp

View File

@@ -1,7 +1,6 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
backend: dummy
rootMountPoint: /tmp/mount
operations:
- install:
- pre-script: touch /tmp/foo

View File

@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# We have tests to load (some) of the package-managers specifically, to
# test their configuration code and implementation. Those tests conventionally
# live in Python files here in the tests/ directory. Add them.
# Pacman (Arch) tests
set(_pm pacman)
add_test(
NAME configure-packages-${_pm}
COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_test(
NAME configure-packages-${_pm}-ops-1
COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py ${CMAKE_CURRENT_LIST_DIR}/pm-pacman-1.yaml 4 1 1
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_test(
NAME configure-packages-${_pm}-ops-2
COMMAND env PYTHONPATH=.: python3 ${CMAKE_CURRENT_LIST_DIR}/test-pm-${_pm}.py ${CMAKE_CURRENT_LIST_DIR}/pm-pacman-2.yaml 3 0 0
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
if ( BUILD_TESTING AND BUILD_SCHEMA_TESTING AND PYTHONINTERP_FOUND AND PYTHON_EXECUTABLE )
set( _module packages )
set( _schema_file "${CMAKE_CURRENT_SOURCE_DIR}/${_module}/${_module}.schema.yaml" )
message(STATUS "Schema ${_schema_file}")
foreach( _cf pm-pacman-1.yaml pm-pacman-2.yaml )
set( _conf_file "${CMAKE_CURRENT_SOURCE_DIR}/${_module}/tests/${_cf}" )
if ( EXISTS "${_schema_file}" AND EXISTS "${_conf_file}" )
add_test(
NAME validate-packages-${_cf}
COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_SOURCE_DIR}/ci/configvalidator.py" "${_schema_file}" "${_conf_file}"
)
else()
message(FATAL_ERROR "Missing ${_conf_file}")
endif()
endforeach()
endif()

View File

@@ -0,0 +1,10 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
backend: pacman
operations: []
pacman:
num_retries: 4
disable_download_timeout: true
needed_only: true

View File

@@ -0,0 +1,9 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
backend: pacman
operations: []
# Leave some things unspecified
pacman:
num_retries: 3

View File

@@ -0,0 +1,36 @@
# SPDX-FileCopyrightText: no
# SPDX-License-Identifier: CC0-1.0
#
# Calamares Boilerplate
import libcalamares
libcalamares.globalstorage = libcalamares.GlobalStorage(None)
libcalamares.globalstorage.insert("testing", True)
# Module prep-work
from src.modules.packages import main
# .. we don't have a job in this test, so fake one
class Job(object):
def __init__(self, filename):
self.configuration = libcalamares.utils.load_yaml(filename) if filename is not None else dict()
import sys
if len(sys.argv) > 4:
filename = sys.argv[1]
retry = int(sys.argv[2])
timeout = bool(int(sys.argv[3]))
needed = bool(int(sys.argv[4]))
else:
filename = None
retry = 0
timeout = False
needed = False
libcalamares.utils.warning("Expecting {!s} retry={!s} timeout={!s} needed={!s}".format(filename, retry, timeout, needed))
# Specific PM test
libcalamares.job = Job(filename)
p = main.PMPacman()
assert p.pacman_num_retries == retry, "{!r} vs {!r}".format(p.pacman_num_retries, retry)
assert p.pacman_disable_timeout == timeout, "{!r} vs {!r}".format(p.pacman_disable_timeout, timeout)
assert p.pacman_needed_only == needed, "{!r} vs {!r}".format(p.pacman_needed_only, needed)

View File

@@ -146,15 +146,12 @@ modeDescription( Config::InstallChoice choice )
case Config::InstallChoice::Alongside:
return QCoreApplication::translate( context, "Install %1 <strong>alongside</strong> another operating system." )
.arg( branding->shortVersionedName() );
break;
case Config::InstallChoice::Erase:
return QCoreApplication::translate( context, "<strong>Erase</strong> disk and install %1." )
.arg( branding->shortVersionedName() );
break;
case Config::InstallChoice::Replace:
return QCoreApplication::translate( context, "<strong>Replace</strong> a partition with %1." )
.arg( branding->shortVersionedName() );
break;
case Config::InstallChoice::NoChoice:
case Config::InstallChoice::Manual:
return QCoreApplication::translate( context, "<strong>Manual</strong> partitioning." );
@@ -187,21 +184,18 @@ diskDescription( int listLength, const PartitionCoreModule::SummaryInfo& info, C
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case Config::Erase:
return QCoreApplication::translate( context,
"<strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1." )
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case Config::Replace:
return QCoreApplication::translate(
context, "<strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1." )
.arg( branding->shortVersionedName() )
.arg( info.deviceNode )
.arg( info.deviceName );
break;
case Config::NoChoice:
case Config::Manual:
return QCoreApplication::translate(
@@ -558,7 +552,7 @@ PartitionViewStep::onLeave()
if ( !okSize )
{
cDebug() << o << "ESP too small";
const auto atLeastBytes = PartUtils::efiFilesystemMinimumSize();
const qint64 atLeastBytes = static_cast< qint64 >( PartUtils::efiFilesystemMinimumSize() );
const auto atLeastMiB = CalamaresUtils::BytesToMiB( atLeastBytes );
description.append( ' ' );
description.append( tr( "The filesystem must be at least %1 MiB in size." ).arg( atLeastMiB ) );

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>
@@ -43,11 +44,9 @@ hasRootPartition( Device* device )
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" );
}
static bool

View File

@@ -8,9 +8,10 @@
* Calamares is Free Software: see the License-Identifier above.
*
*/
#include "core/DeviceModel.h"
#include "DeviceModel.h"
#include "core/PartitionModel.h"
#include "core/SizeUtils.h"
#include "utils/CalamaresUtilsGui.h"
#include "utils/Logger.h"
@@ -18,9 +19,6 @@
// KPMcore
#include <kpmcore/core/device.h>
// KF5
#include <KFormat>
#include <QIcon>
#include <QStandardItemModel>
@@ -83,7 +81,7 @@ DeviceModel::data( const QModelIndex& index, int role ) const
//: device[name] - size[number] (device-node[name])
return tr( "%1 - %2 (%3)" )
.arg( device->name() )
.arg( KFormat().formatByteSize( device->capacity() ) )
.arg( formatByteSize( device->capacity() ) )
.arg( device->deviceNode() );
}
else

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,12 +11,15 @@
#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 <QVector>
#include <functional>
@@ -35,6 +38,8 @@ class PartitionRole;
#define KPM_PARTITION_FLAG_ESP PartitionTable::FlagEsp
#endif
using PartitionVector = QVector< const Partition* >;
/**
* Helper functions to manipulate partitions
*/
@@ -72,6 +77,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

@@ -451,6 +451,8 @@ isEfiFilesystemSuitableType( const Partition* candidate )
{
auto type = candidate->fileSystem().type();
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" )
switch ( type )
{
case FileSystem::Type::Fat32:
@@ -465,6 +467,7 @@ isEfiFilesystemSuitableType( const Partition* candidate )
cWarning() << "EFI boot partition must be FAT32";
return false;
}
QT_WARNING_POP
}
bool
@@ -526,14 +529,15 @@ efiFilesystemMinimumSize()
{
using CalamaresUtils::Units::operator""_MiB;
auto uefisys_part_sizeB = 300_MiB;
size_t uefisys_part_sizeB = 300_MiB;
// The default can be overridden; the key used here comes
// from the partition module Config.cpp
auto* gs = Calamares::JobQueue::instance()->globalStorage();
if ( gs->contains( "efiSystemPartitionSize_i" ) )
{
uefisys_part_sizeB = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
qint64 v = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
uefisys_part_sizeB = v > 0 ? static_cast< size_t >( v ) : 0;
}
// There is a lower limit of what can be configured
if ( uefisys_part_sizeB < 32_MiB )

View File

@@ -71,15 +71,15 @@ swapSuggestion( const qint64 availableSpaceB, Config::SwapChoice swap )
// Allow for a fudge factor
suggestedSwapSizeB *= overestimationFactor;
suggestedSwapSizeB = qRound64( suggestedSwapSizeB * overestimationFactor );
// don't use more than 10% of available space
if ( !ensureSuspendToDisk )
{
suggestedSwapSizeB = qMin( suggestedSwapSizeB, qint64( 0.10 * availableSpaceB ) );
suggestedSwapSizeB = qMin( suggestedSwapSizeB, availableSpaceB / 10 /* 10% is 0.1 */ );
}
cDebug() << "Suggested swap size:" << suggestedSwapSizeB / 1024. / 1024. / 1024. << "GiB";
cDebug() << "Suggested swap size:" << CalamaresUtils::BytesToGiB( suggestedSwapSizeB ) << "GiB";
return suggestedSwapSizeB;
}

View File

@@ -257,14 +257,14 @@ PartitionCoreModule::doInit()
cDebug() << Logger::SubEntry << "node\tcapacity\tname\tprettyName";
for ( auto device : devices )
{
cDebug() << Logger::SubEntry << Logger::Pointer( device );
if ( device )
{
// Gives ownership of the Device* to the DeviceInfo object
auto deviceInfo = new DeviceInfo( device );
m_deviceInfos << deviceInfo;
cDebug() << Logger::SubEntry << device->deviceNode() << device->capacity() << device->name()
<< device->prettyName();
cDebug() << Logger::SubEntry << device->deviceNode() << device->capacity()
<< Logger::RedactedName( "DevName", device->name() )
<< Logger::RedactedName( "DevNamePretty", device->prettyName() );
}
else
{
@@ -358,7 +358,12 @@ PartitionModel*
PartitionCoreModule::partitionModelForDevice( const Device* device ) const
{
DeviceInfo* info = infoForDevice( device );
Q_ASSERT( info );
if ( !info )
{
cWarning() << "No DeviceInfo for" << Logger::Pointer( device )
<< ( device ? device->deviceNode() : QStringLiteral( "<null>" ) );
return nullptr;
}
return info->partitionModel.data();
}
@@ -409,15 +414,16 @@ PartitionCoreModule::createPartition( Device* device, Partition* partition, Part
}
void
PartitionCoreModule::createVolumeGroup( QString& vgName, QVector< const Partition* > pvList, qint32 peSize )
PartitionCoreModule::createVolumeGroup( const QString& vgName, const PartitionVector& pvList, qint32 peSize )
{
QString actualName( vgName );
// Appending '_' character in case of repeated VG name
while ( hasVGwithThisName( vgName ) )
while ( hasVGwithThisName( actualName ) )
{
vgName.append( '_' );
actualName.append( '_' );
}
LvmDevice* device = new LvmDevice( vgName );
LvmDevice* device = new LvmDevice( actualName );
for ( const Partition* p : pvList )
{
device->physicalVolumes() << p;
@@ -428,12 +434,12 @@ PartitionCoreModule::createVolumeGroup( QString& vgName, QVector< const Partitio
m_deviceModel->addDevice( device );
m_deviceInfos << deviceInfo;
deviceInfo->makeJob< CreateVolumeGroupJob >( vgName, pvList, peSize );
deviceInfo->makeJob< CreateVolumeGroupJob >( actualName, pvList, peSize );
refreshAfterModelChange();
}
void
PartitionCoreModule::resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList )
PartitionCoreModule::resizeVolumeGroup( LvmDevice* device, const PartitionVector& pvList )
{
auto* deviceInfo = infoForDevice( device );
Q_ASSERT( deviceInfo );
@@ -674,7 +680,7 @@ PartitionCoreModule::efiSystemPartitions() const
return m_efiSystemPartitions;
}
QVector< const Partition* >
PartitionVector
PartitionCoreModule::lvmPVs() const
{
return m_lvmPVs;
@@ -707,10 +713,10 @@ PartitionCoreModule::dumpQueue() const
cDebug() << "# Queue:";
for ( auto info : m_deviceInfos )
{
cDebug() << Logger::SubEntry << "## Device:" << info->device->name();
cDebug() << Logger::SubEntry << "## Device:" << info->device->deviceNode();
for ( const auto& job : info->jobs() )
{
cDebug() << Logger::SubEntry << "-" << job->prettyName();
cDebug() << Logger::SubEntry << "-" << job->metaObject()->className();
}
}
}

View File

@@ -136,25 +136,18 @@ public:
*/
void
createPartition( Device* device, Partition* partition, PartitionTable::Flags flags = KPM_PARTITION_FLAG( None ) );
void deletePartition( Device* device, Partition* partition );
void formatPartition( Device* device, Partition* partition );
void resizePartition( Device* device, Partition* partition, qint64 first, qint64 last );
void setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags );
void createVolumeGroup( QString& vgName, QVector< const Partition* > pvList, qint32 peSize );
void resizeVolumeGroup( LvmDevice* device, QVector< const Partition* >& pvList );
void createVolumeGroup( const QString& vgName, const PartitionVector& pvList, qint32 peSize );
void resizeVolumeGroup( LvmDevice* device, const PartitionVector& pvList );
void deactivateVolumeGroup( LvmDevice* device );
void removeVolumeGroup( LvmDevice* device );
void deletePartition( Device* device, Partition* partition );
void formatPartition( Device* device, Partition* partition );
void setFilesystemLabel( Device* device, Partition* partition, const QString& newLabel );
void resizePartition( Device* device, Partition* partition, qint64 first, qint64 last );
void setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags );
/// @brief Retrieve the path where the bootloader will be installed
QString bootLoaderInstallPath() const { return m_bootLoaderInstallPath; }
/// @brief Set the path where the bootloader will be installed
@@ -185,7 +178,7 @@ public:
QList< Partition* > efiSystemPartitions() const;
QVector< const Partition* > lvmPVs() const;
PartitionVector lvmPVs() const;
bool hasVGwithThisName( const QString& name ) const;
@@ -255,7 +248,7 @@ private:
QList< DeviceInfo* > m_deviceInfos;
QList< Partition* > m_efiSystemPartitions;
QVector< const Partition* > m_lvmPVs;
PartitionVector m_lvmPVs;
DeviceModel* m_deviceModel;
BootLoaderModel* m_bootLoaderModel;

View File

@@ -141,6 +141,8 @@ void
PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType )
{
using FileSystem = FileSystem::Type;
QT_WARNING_PUSH
QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" )
switch ( defaultFsType )
{
case FileSystem::Unknown:
@@ -196,6 +198,7 @@ PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType )
<< "Using ext4 instead.";
defaultFsType = FileSystem::Ext4;
}
QT_WARNING_POP
m_defaultFsType = defaultFsType;
}
@@ -296,7 +299,9 @@ PartitionLayout::createPartitions( Device* dev,
}
Partition* part = nullptr;
if ( luksPassphrase.isEmpty() )
// Encryption for zfs is handled in the zfs module
if ( luksPassphrase.isEmpty() || correctFS( entry.partFileSystem ) == FileSystem::Zfs )
{
part = KPMHelpers::createNewPartition( parent,
*dev,
@@ -319,6 +324,24 @@ PartitionLayout::createPartitions( Device* dev,
luksPassphrase,
KPM_PARTITION_FLAG( None ) );
}
// For zfs, we need to make the passphrase available to later modules
if ( correctFS( entry.partFileSystem ) == FileSystem::Zfs )
{
Calamares::GlobalStorage* storage = Calamares::JobQueue::instance()->globalStorage();
QList< QVariant > zfsInfoList;
QVariantMap zfsInfo;
// Save the information subsequent modules will need
zfsInfo[ "encrypted" ] = !luksPassphrase.isEmpty();
zfsInfo[ "passphrase" ] = luksPassphrase;
zfsInfo[ "mountpoint" ] = entry.partMountPoint;
// Add it to the list and insert it into global storage
zfsInfoList.append( zfsInfo );
storage->insert( "zfsInfo", zfsInfoList );
}
PartitionInfo::setFormat( part, true );
PartitionInfo::setMountPoint( part, entry.partMountPoint );
if ( !entry.partLabel.isEmpty() )

Some files were not shown because too many files have changed in this diff Show More