Compare commits
143 Commits
v3.2.47
...
issue-1847
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3aa4b7368c | ||
![]() |
288674a924 | ||
![]() |
30b5be0fd4 | ||
![]() |
10334ab14f | ||
![]() |
46d69b04d4 | ||
![]() |
f1185d38d8 | ||
![]() |
2c16d812cd | ||
![]() |
7a071207a2 | ||
![]() |
3edfa5ebb5 | ||
![]() |
898f4498e8 | ||
![]() |
e2d5f01aa1 | ||
![]() |
8d7c08612f | ||
![]() |
febc5f5b41 | ||
![]() |
35a4273127 | ||
![]() |
4402ebd8e8 | ||
![]() |
587a18a6fa | ||
![]() |
043619cd4b | ||
![]() |
f04394d014 | ||
![]() |
07354a26a9 | ||
![]() |
fdf0f208f0 | ||
![]() |
6680584724 | ||
![]() |
c5573a1997 | ||
![]() |
b8ce21d572 | ||
![]() |
1356012fb4 | ||
![]() |
8bb2c5fc6b | ||
![]() |
dc7a1e43b7 | ||
![]() |
53c90516b2 | ||
![]() |
d3ed5663d0 | ||
![]() |
778c2855f4 | ||
![]() |
445ed870cc | ||
![]() |
3be52f8b37 | ||
![]() |
a1b7ba0dc5 | ||
![]() |
8b5e49d980 | ||
![]() |
90f6ea1fc8 | ||
![]() |
238672ef78 | ||
![]() |
b1ecbb4151 | ||
![]() |
795b2c88e8 | ||
![]() |
becb1d5710 | ||
![]() |
5b225cf960 | ||
![]() |
6261f8a5cb | ||
![]() |
132ebd2c2d | ||
![]() |
db86c24638 | ||
![]() |
03da766b39 | ||
![]() |
adaed52818 | ||
![]() |
7ac42b5f40 | ||
![]() |
3cdb019de7 | ||
![]() |
b4afedc79e | ||
![]() |
c834a5066d | ||
![]() |
1d96c5af46 | ||
![]() |
bc2713ccbb | ||
![]() |
bb948c47dc | ||
![]() |
fa29ae2c5e | ||
![]() |
043bdc36d6 | ||
![]() |
f0eb7ffbda | ||
![]() |
e8ca298712 | ||
![]() |
13700b18c8 | ||
![]() |
1197d8c750 | ||
![]() |
09f47b5762 | ||
![]() |
4611545f93 | ||
![]() |
6e715205d7 | ||
![]() |
09a03fbbc0 | ||
![]() |
bb3f4442f5 | ||
![]() |
5b05110351 | ||
![]() |
eda85c176a | ||
![]() |
32da51b44c | ||
![]() |
0b6239a996 | ||
![]() |
79ae3cd00f | ||
![]() |
c2e63f4a6b | ||
![]() |
8b804c4ae0 | ||
![]() |
3030a710cc | ||
![]() |
b07c9bb4af | ||
![]() |
3234de5753 | ||
![]() |
2f9edb3e08 | ||
![]() |
ca7f288488 | ||
![]() |
49890acd04 | ||
![]() |
dc11dd2203 | ||
![]() |
6e59177f54 | ||
![]() |
d2ac201b98 | ||
![]() |
c8ea3bccf7 | ||
![]() |
8e4c9b8bd6 | ||
![]() |
13196ed2e2 | ||
![]() |
eb2cf60466 | ||
![]() |
149f3ff3fe | ||
![]() |
d89553a777 | ||
![]() |
890c17cd71 | ||
![]() |
6ef7acc108 | ||
![]() |
baf8297cc4 | ||
![]() |
47f2dd3c18 | ||
![]() |
6e08da6c8d | ||
![]() |
b8c02587ae | ||
![]() |
aa332477fd | ||
![]() |
d9f7726f7d | ||
![]() |
2f2a418cc4 | ||
![]() |
2dd77ee828 | ||
![]() |
bfa7b9a792 | ||
![]() |
32c5e18db0 | ||
![]() |
003e7949e3 | ||
![]() |
e8936392e3 | ||
![]() |
6bf0da7230 | ||
![]() |
6e8779cbce | ||
![]() |
ceb9ec4115 | ||
![]() |
c22bbea528 | ||
![]() |
5277892e4f | ||
![]() |
5b767e147d | ||
![]() |
0178fe6782 | ||
![]() |
209c48d67f | ||
![]() |
310d67cf27 | ||
![]() |
f26c81700d | ||
![]() |
96ccf256b2 | ||
![]() |
951ddfb72a | ||
![]() |
3845e05834 | ||
![]() |
7cea1cb56e | ||
![]() |
cdc3a9aad2 | ||
![]() |
86ec0a6bd2 | ||
![]() |
dfd13b4948 | ||
![]() |
28bd737062 | ||
![]() |
ec1b73be2b | ||
![]() |
864dcdb2c2 | ||
![]() |
61e0d538e9 | ||
![]() |
474aaf7603 | ||
![]() |
65488ca174 | ||
![]() |
1260d3fcb9 | ||
![]() |
3e0c9ba056 | ||
![]() |
fcbe8d3a3e | ||
![]() |
7f643010b2 | ||
![]() |
e9970474f5 | ||
![]() |
8a1e5d35fa | ||
![]() |
90459e434f | ||
![]() |
bd07db544f | ||
![]() |
6b838bbf3d | ||
![]() |
df3e049e1c | ||
![]() |
bb24ee1b3b | ||
![]() |
c80b4ff4c2 | ||
![]() |
596e471276 | ||
![]() |
e1e29780f2 | ||
![]() |
fa10bb8dd3 | ||
![]() |
01d55254f2 | ||
![]() |
180b12fbaf | ||
![]() |
dc8901113e | ||
![]() |
f947c072e1 | ||
![]() |
ee032b43fe | ||
![]() |
f37a775977 | ||
![]() |
855391b31d |
74
CHANGES-3.2
74
CHANGES-3.2
@@ -7,6 +7,80 @@ 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):
|
||||
|
@@ -41,11 +41,14 @@
|
||||
# TODO:3.3: Require CMake 3.12
|
||||
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
|
||||
project( CALAMARES
|
||||
VERSION 3.2.47
|
||||
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 de fi_FI he hr ja ko lt pt_PT si sq
|
||||
tr_TR uk zh_TW )
|
||||
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 fa gl hu id is mr
|
||||
nb pl ro sl sr sr@latin th )
|
||||
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 )
|
||||
|
||||
|
@@ -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
|
||||
|
32
ci/txpull.sh
32
ci/txpull.sh
@@ -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*
|
||||
|
@@ -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>
|
@@ -1,3 +0,0 @@
|
||||
TIMESTAMP = 1592339404
|
||||
SHA256 (calamares-3.2.25.tar.gz) = 797ce33db7d4e4c06bbccef95f6c4023f7628e91bd142896695565fed4ae8c4b
|
||||
SIZE (calamares-3.2.25.tar.gz) = 3580197
|
@@ -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/
|
@@ -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
|
File diff suppressed because it is too large
Load Diff
@@ -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"/>
|
||||
|
@@ -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"/>
|
||||
|
@@ -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"/>
|
||||
|
@@ -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"/>
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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 වින්යාස කිරීම."
|
||||
|
@@ -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"
|
||||
|
@@ -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"
|
||||
|
@@ -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."
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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." );
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
{
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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"
|
||||
|
@@ -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
|
||||
|
@@ -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; }
|
||||
|
||||
/**
|
||||
|
@@ -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 )
|
||||
|
@@ -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();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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() )
|
||||
{
|
||||
|
106
src/libcalamaresui/widgets/ErrorDialog.cpp
Normal file
106
src/libcalamaresui/widgets/ErrorDialog.cpp
Normal 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
|
83
src/libcalamaresui/widgets/ErrorDialog.h
Normal file
83
src/libcalamaresui/widgets/ErrorDialog.h
Normal 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
|
133
src/libcalamaresui/widgets/ErrorDialog.ui
Normal file
133
src/libcalamaresui/widgets/ErrorDialog.ui
Normal 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>
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -224,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)
|
||||
|
@@ -15,9 +15,19 @@
|
||||
# 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,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,
|
||||
|
@@ -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 ]
|
||||
|
@@ -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:
|
||||
|
@@ -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 |
@@ -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('/')
|
||||
|
||||
|
@@ -191,6 +191,9 @@ 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:
|
||||
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"] == "/":
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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):
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
3
src/modules/packages/tests/1.global
Normal file
3
src/modules/packages/tests/1.global
Normal file
@@ -0,0 +1,3 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
rootMountPoint: /tmp
|
@@ -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
|
42
src/modules/packages/tests/CMakeTests.txt
Normal file
42
src/modules/packages/tests/CMakeTests.txt
Normal 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()
|
||||
|
10
src/modules/packages/tests/pm-pacman-1.yaml
Normal file
10
src/modules/packages/tests/pm-pacman-1.yaml
Normal 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
|
||||
|
9
src/modules/packages/tests/pm-pacman-2.yaml
Normal file
9
src/modules/packages/tests/pm-pacman-2.yaml
Normal 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
|
||||
|
36
src/modules/packages/tests/test-pm-pacman.py
Normal file
36
src/modules/packages/tests/test-pm-pacman.py
Normal 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)
|
@@ -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 ) );
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 )
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -262,11 +262,9 @@ PartitionCoreModule::doInit()
|
||||
// Gives ownership of the Device* to the DeviceInfo object
|
||||
auto deviceInfo = new DeviceInfo( device );
|
||||
m_deviceInfos << deviceInfo;
|
||||
cDebug() << Logger::SubEntry
|
||||
<< device->deviceNode()
|
||||
<< device->capacity()
|
||||
<< Logger::RedactedName( "DevName", device->name() )
|
||||
<< Logger::RedactedName( "DevNamePretty", device->prettyName() );
|
||||
cDebug() << Logger::SubEntry << device->deviceNode() << device->capacity()
|
||||
<< Logger::RedactedName( "DevName", device->name() )
|
||||
<< Logger::RedactedName( "DevNamePretty", device->prettyName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -360,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();
|
||||
}
|
||||
|
||||
@@ -411,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;
|
||||
@@ -430,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 );
|
||||
@@ -676,7 +680,7 @@ PartitionCoreModule::efiSystemPartitions() const
|
||||
return m_efiSystemPartitions;
|
||||
}
|
||||
|
||||
QVector< const Partition* >
|
||||
PartitionVector
|
||||
PartitionCoreModule::lvmPVs() const
|
||||
{
|
||||
return m_lvmPVs;
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -8,11 +8,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/PartitionModel.h"
|
||||
#include "PartitionModel.h"
|
||||
|
||||
#include "core/ColorUtils.h"
|
||||
#include "core/KPMHelpers.h"
|
||||
#include "core/PartitionInfo.h"
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
#include "partition/FileSystem.h"
|
||||
#include "partition/PartitionQuery.h"
|
||||
@@ -24,9 +25,6 @@
|
||||
#include <kpmcore/core/partitiontable.h>
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
// KF5
|
||||
#include <KFormat>
|
||||
|
||||
// Qt
|
||||
#include <QColor>
|
||||
|
||||
@@ -178,7 +176,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const
|
||||
if ( col == SizeColumn )
|
||||
{
|
||||
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
|
||||
return KFormat().formatByteSize( size );
|
||||
return formatByteSize( size );
|
||||
}
|
||||
cDebug() << "Unknown column" << col;
|
||||
return QVariant();
|
||||
@@ -210,7 +208,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const
|
||||
QString prettyFileSystem
|
||||
= CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
|
||||
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
|
||||
QString prettySize = KFormat().formatByteSize( size );
|
||||
QString prettySize = formatByteSize( size );
|
||||
return QVariant( name + " " + prettyFileSystem + " " + prettySize );
|
||||
}
|
||||
case SizeRole:
|
||||
|
27
src/modules/partition/core/SizeUtils.h
Normal file
27
src/modules/partition/core/SizeUtils.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PARTITION_CORE_SIZEUTILS_H
|
||||
#define PARTITION_CORE_SIZEUTILS_H
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
|
||||
/** @brief Helper function for printing sizes consistently.
|
||||
*
|
||||
* Most of Calamares uses a qint64 for partition sizes, so use that
|
||||
* parameter type. However, the human-visible formatting doesn't need
|
||||
* to bother with one-byte accuracy (and anyway, a double has at least 50 bits
|
||||
* at which point we're printing giga (or gibi) bytes).
|
||||
*/
|
||||
static inline QString formatByteSize( qint64 sizeValue )
|
||||
{
|
||||
return Capacity::formatByteSize( static_cast< double >( sizeValue ) );
|
||||
}
|
||||
|
||||
#endif // PARTITION_CORE_SIZEUTILS_H
|
@@ -66,19 +66,22 @@ CreatePartitionDialog::CreatePartitionDialog( Device* device,
|
||||
m_ui->encryptWidget->setText( tr( "En&crypt" ) );
|
||||
m_ui->encryptWidget->hide();
|
||||
|
||||
if ( m_device->type() != Device::Type::LVM_Device )
|
||||
{
|
||||
m_ui->lvNameLabel->hide();
|
||||
m_ui->lvNameLineEdit->hide();
|
||||
}
|
||||
if ( m_device->type() == Device::Type::LVM_Device )
|
||||
{
|
||||
m_ui->lvNameLabel->show();
|
||||
m_ui->lvNameLineEdit->show();
|
||||
/* LVM logical volume name can consist of: letters numbers _ . - +
|
||||
* It cannot start with underscore _ and must not be equal to . or .. or any entry in /dev/
|
||||
* QLineEdit accepts QValidator::Intermediate, so we just disable . at the beginning */
|
||||
QRegularExpression re( QStringLiteral( R"(^(?!_|\.)[\w\-.+]+)" ) );
|
||||
QRegularExpressionValidator* validator = new QRegularExpressionValidator( re, this );
|
||||
m_ui->lvNameLineEdit->setValidator( validator );
|
||||
connect( m_ui->lvNameLineEdit, &QLineEdit::textChanged, this, &CreatePartitionDialog::updateOkButton );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->lvNameLabel->hide();
|
||||
m_ui->lvNameLineEdit->hide();
|
||||
}
|
||||
|
||||
if ( device->partitionTable()->type() == PartitionTable::msdos
|
||||
@@ -347,3 +350,13 @@ CreatePartitionDialog::initPartResizerWidget( Partition* partition )
|
||||
m_partitionSizeController->setPartResizerWidget( m_ui->partResizerWidget );
|
||||
m_partitionSizeController->setSpinBox( m_ui->sizeSpinBox );
|
||||
}
|
||||
|
||||
void
|
||||
CreatePartitionDialog::updateOkButton()
|
||||
{
|
||||
if ( m_device->type() == Device::Type::LVM_Device )
|
||||
{
|
||||
QString lvName = m_ui->lvNameLineEdit->text();
|
||||
cDebug() << "LVName" << lvName << m_ui->lvNameLineEdit->hasAcceptableInput();
|
||||
}
|
||||
}
|
||||
|
@@ -45,10 +45,12 @@ private:
|
||||
QWidget* parentWidget );
|
||||
|
||||
public:
|
||||
/// @brief Tag-type for creating partition from free space
|
||||
struct FreeSpace
|
||||
{
|
||||
Partition* p;
|
||||
};
|
||||
/// @brief Tag-type for editing (re-creating) a new partition
|
||||
struct FreshPartition
|
||||
{
|
||||
Partition* p;
|
||||
@@ -81,6 +83,7 @@ public:
|
||||
private Q_SLOTS:
|
||||
void updateMountPointUi();
|
||||
void checkMountPointSelection();
|
||||
void updateOkButton(); // Check if dialog can be accepted
|
||||
|
||||
private:
|
||||
QScopedPointer< Ui_CreatePartitionDialog > m_ui;
|
||||
|
@@ -16,32 +16,13 @@
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
|
||||
CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName,
|
||||
QVector< const Partition* >& selectedPVs,
|
||||
QVector< const Partition* > pvList,
|
||||
qint64& pSize,
|
||||
CreateVolumeGroupDialog::CreateVolumeGroupDialog( const PartitionVector& pvList,
|
||||
qint32 physicalExtentSize,
|
||||
QWidget* parent )
|
||||
: VolumeGroupBaseDialog( vgName, pvList, parent )
|
||||
, m_selectedPVs( selectedPVs )
|
||||
, m_peSize( pSize )
|
||||
: VolumeGroupBaseDialog( parent, QString(), pvList )
|
||||
{
|
||||
setWindowTitle( tr( "Create Volume Group" ) );
|
||||
|
||||
peSize()->setValue( pSize );
|
||||
|
||||
vgType()->setEnabled( false );
|
||||
}
|
||||
|
||||
void
|
||||
CreateVolumeGroupDialog::accept()
|
||||
{
|
||||
QString& name = vgNameValue();
|
||||
name = vgName()->text();
|
||||
|
||||
m_selectedPVs << checkedItems();
|
||||
|
||||
qint64& pe = m_peSize;
|
||||
pe = peSize()->value();
|
||||
|
||||
QDialog::accept();
|
||||
peSizeWidget()->setValue( physicalExtentSize );
|
||||
vgTypeWidget()->setEnabled( false );
|
||||
}
|
||||
|
@@ -16,18 +16,7 @@ class CreateVolumeGroupDialog : public VolumeGroupBaseDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CreateVolumeGroupDialog( QString& vgName,
|
||||
QVector< const Partition* >& selectedPVs,
|
||||
QVector< const Partition* > pvList,
|
||||
qint64& pSize,
|
||||
QWidget* parent );
|
||||
|
||||
void accept() override;
|
||||
|
||||
private:
|
||||
QVector< const Partition* >& m_selectedPVs;
|
||||
|
||||
qint64& m_peSize;
|
||||
CreateVolumeGroupDialog( const PartitionVector& pvList, qint32 physicalExtentSize, QWidget* parent );
|
||||
};
|
||||
|
||||
#endif // CREATEVOLUMEGROUPDIALOG_H
|
||||
|
@@ -68,7 +68,8 @@ DeviceInfoWidget::setPartitionTableType( PartitionTable::TableType type )
|
||||
void
|
||||
DeviceInfoWidget::retranslateUi()
|
||||
{
|
||||
QString typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper();
|
||||
QString typeString;
|
||||
QString toolTipString;
|
||||
|
||||
// fix up if the name shouldn't be uppercase:
|
||||
switch ( m_tableType )
|
||||
@@ -76,38 +77,34 @@ DeviceInfoWidget::retranslateUi()
|
||||
case PartitionTable::msdos:
|
||||
case PartitionTable::msdos_sectorbased:
|
||||
typeString = "MBR";
|
||||
toolTipString += tr( "<br><br>This partition table type is only advisable on older "
|
||||
"systems which start from a <strong>BIOS</strong> boot "
|
||||
"environment. GPT is recommended in most other cases.<br><br>"
|
||||
"<strong>Warning:</strong> the MBR partition table "
|
||||
"is an obsolete MS-DOS era standard.<br>"
|
||||
"Only 4 <em>primary</em> partitions may be created, and of "
|
||||
"those 4, one can be an <em>extended</em> partition, which "
|
||||
"may in turn contain many <em>logical</em> partitions." );
|
||||
break;
|
||||
case PartitionTable::gpt:
|
||||
// TypeString is ok
|
||||
toolTipString += tr( "<br><br>This is the recommended partition table type for modern "
|
||||
"systems which start from an <strong>EFI</strong> boot "
|
||||
"environment." );
|
||||
break;
|
||||
case PartitionTable::loop:
|
||||
typeString = "loop";
|
||||
break;
|
||||
case PartitionTable::mac:
|
||||
typeString = "Mac";
|
||||
break;
|
||||
case PartitionTable::amiga:
|
||||
typeString = "Amiga";
|
||||
break;
|
||||
case PartitionTable::sun:
|
||||
typeString = "Sun";
|
||||
break;
|
||||
case PartitionTable::unknownTableType:
|
||||
typeString = " ? ";
|
||||
}
|
||||
|
||||
|
||||
QString toolTipString = tr( "This device has a <strong>%1</strong> partition "
|
||||
"table." )
|
||||
.arg( typeString );
|
||||
|
||||
switch ( m_tableType )
|
||||
{
|
||||
case PartitionTable::loop:
|
||||
toolTipString = tr( "This is a <strong>loop</strong> "
|
||||
"device.<br><br>"
|
||||
"It is a pseudo-device with no partition table "
|
||||
"that makes a file accessible as a block device. "
|
||||
"This kind of setup usually only contains a single filesystem." );
|
||||
break;
|
||||
#if defined( WITH_KPMCORE42API )
|
||||
case PartitionTable::none:
|
||||
#endif
|
||||
case PartitionTable::unknownTableType:
|
||||
typeString = " ? ";
|
||||
toolTipString = tr( "This installer <strong>cannot detect a partition table</strong> on the "
|
||||
"selected storage device.<br><br>"
|
||||
"The device either has no partition "
|
||||
@@ -117,21 +114,35 @@ DeviceInfoWidget::retranslateUi()
|
||||
"either automatically, or through the manual partitioning "
|
||||
"page." );
|
||||
break;
|
||||
case PartitionTable::gpt:
|
||||
toolTipString += tr( "<br><br>This is the recommended partition table type for modern "
|
||||
"systems which start from an <strong>EFI</strong> boot "
|
||||
"environment." );
|
||||
// The next ones need to have the name adjusted, but the default tooltip is OK
|
||||
case PartitionTable::mac:
|
||||
typeString = "Mac";
|
||||
break;
|
||||
case PartitionTable::msdos:
|
||||
case PartitionTable::msdos_sectorbased:
|
||||
toolTipString += tr( "<br><br>This partition table type is only advisable on older "
|
||||
"systems which start from a <strong>BIOS</strong> boot "
|
||||
"environment. GPT is recommended in most other cases.<br><br>"
|
||||
"<strong>Warning:</strong> the MBR partition table "
|
||||
"is an obsolete MS-DOS era standard.<br>"
|
||||
"Only 4 <em>primary</em> partitions may be created, and of "
|
||||
"those 4, one can be an <em>extended</em> partition, which "
|
||||
"may in turn contain many <em>logical</em> partitions." );
|
||||
case PartitionTable::amiga:
|
||||
typeString = "Amiga";
|
||||
break;
|
||||
case PartitionTable::sun:
|
||||
typeString = "Sun";
|
||||
break;
|
||||
// Peculiar tables, do nothing and use default type and tooltip strings
|
||||
case PartitionTable::aix:
|
||||
case PartitionTable::bsd:
|
||||
case PartitionTable::dasd:
|
||||
case PartitionTable::dvh:
|
||||
case PartitionTable::pc98:
|
||||
case PartitionTable::vmd:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( typeString.isEmpty() )
|
||||
{
|
||||
typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper();
|
||||
}
|
||||
if ( toolTipString.isEmpty() )
|
||||
{
|
||||
toolTipString = tr( "This device has a <strong>%1</strong> partition "
|
||||
"table." )
|
||||
.arg( typeString );
|
||||
}
|
||||
|
||||
m_ptLabel->setText( typeString );
|
||||
|
@@ -9,11 +9,10 @@
|
||||
|
||||
#include "ListPhysicalVolumeWidgetItem.h"
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
ListPhysicalVolumeWidgetItem::ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked )
|
||||
: QListWidgetItem(
|
||||
QString( "%1 | %2" ).arg( partition->deviceNode(), Capacity::formatByteSize( partition->capacity() ) ) )
|
||||
: QListWidgetItem( QString( "%1 | %2" ).arg( partition->deviceNode(), formatByteSize( partition->capacity() ) ) )
|
||||
, m_partition( partition )
|
||||
{
|
||||
setToolTip( partition->deviceNode() );
|
||||
@@ -26,3 +25,5 @@ ListPhysicalVolumeWidgetItem::partition() const
|
||||
{
|
||||
return m_partition;
|
||||
}
|
||||
|
||||
ListPhysicalVolumeWidgetItem::~ListPhysicalVolumeWidgetItem() {}
|
||||
|
@@ -18,6 +18,7 @@ class ListPhysicalVolumeWidgetItem : public QListWidgetItem
|
||||
{
|
||||
public:
|
||||
ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked );
|
||||
~ListPhysicalVolumeWidgetItem() override;
|
||||
|
||||
const Partition* partition() const;
|
||||
|
||||
|
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "core/ColorUtils.h"
|
||||
#include "core/PartitionModel.h"
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
@@ -20,8 +21,6 @@
|
||||
#include <kpmcore/core/device.h>
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
#include <KFormat>
|
||||
|
||||
// Qt
|
||||
#include <QGuiApplication>
|
||||
#include <QMouseEvent>
|
||||
@@ -39,7 +38,7 @@ static QStringList
|
||||
buildUnknownDisklabelTexts( Device* dev )
|
||||
{
|
||||
QStringList texts = { QObject::tr( "Unpartitioned space or unknown partition table" ),
|
||||
KFormat().formatByteSize( dev->totalLogical() * dev->logicalSize() ) };
|
||||
formatByteSize( dev->totalLogical() * dev->logicalSize() ) };
|
||||
return texts;
|
||||
}
|
||||
|
||||
|
@@ -278,26 +278,30 @@ PartitionPage::checkCanCreate( Device* device )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PartitionPage::onNewVolumeGroupClicked()
|
||||
static inline PartitionVector
|
||||
availablePVs( PartitionCoreModule* core )
|
||||
{
|
||||
QString vgName;
|
||||
QVector< const Partition* > selectedPVs;
|
||||
qint64 peSize = 4;
|
||||
PartitionVector availablePVs;
|
||||
|
||||
QVector< const Partition* > availablePVs;
|
||||
|
||||
for ( const Partition* p : m_core->lvmPVs() )
|
||||
if ( !m_core->isInVG( p ) )
|
||||
for ( const Partition* p : core->lvmPVs() )
|
||||
{
|
||||
if ( !core->isInVG( p ) )
|
||||
{
|
||||
availablePVs << p;
|
||||
}
|
||||
}
|
||||
return availablePVs;
|
||||
}
|
||||
|
||||
QPointer< CreateVolumeGroupDialog > dlg
|
||||
= new CreateVolumeGroupDialog( vgName, selectedPVs, availablePVs, peSize, this );
|
||||
|
||||
void
|
||||
PartitionPage::onNewVolumeGroupClicked()
|
||||
{
|
||||
QPointer< CreateVolumeGroupDialog > dlg = new CreateVolumeGroupDialog( availablePVs( m_core ), 4, this );
|
||||
|
||||
if ( dlg->exec() == QDialog::Accepted )
|
||||
{
|
||||
const PartitionVector selectedPVs = dlg->selectedPVs();
|
||||
QModelIndex partitionIndex = m_ui->partitionTreeView->currentIndex();
|
||||
|
||||
if ( partitionIndex.isValid() )
|
||||
@@ -321,7 +325,7 @@ PartitionPage::onNewVolumeGroupClicked()
|
||||
QVariant previousIndexDeviceData = m_core->deviceModel()->data( deviceIndex, Qt::ToolTipRole );
|
||||
|
||||
// Creating new VG
|
||||
m_core->createVolumeGroup( vgName, selectedPVs, peSize );
|
||||
m_core->createVolumeGroup( dlg->volumeGroupName(), selectedPVs, dlg->physicalExtentSize() );
|
||||
|
||||
// As createVolumeGroup method call resets deviceModel,
|
||||
// is needed to set the current index in deviceComboBox as the previous one
|
||||
@@ -342,20 +346,11 @@ PartitionPage::onResizeVolumeGroupClicked()
|
||||
|
||||
Q_ASSERT( device && device->type() == Device::Type::LVM_Device );
|
||||
|
||||
QVector< const Partition* > availablePVs;
|
||||
QVector< const Partition* > selectedPVs;
|
||||
|
||||
for ( const Partition* p : m_core->lvmPVs() )
|
||||
if ( !m_core->isInVG( p ) )
|
||||
{
|
||||
availablePVs << p;
|
||||
}
|
||||
|
||||
QPointer< ResizeVolumeGroupDialog > dlg = new ResizeVolumeGroupDialog( device, availablePVs, selectedPVs, this );
|
||||
QPointer< ResizeVolumeGroupDialog > dlg = new ResizeVolumeGroupDialog( device, availablePVs( m_core ), this );
|
||||
|
||||
if ( dlg->exec() == QDialog::Accepted )
|
||||
{
|
||||
m_core->resizeVolumeGroup( device, selectedPVs );
|
||||
m_core->resizeVolumeGroup( device, dlg->selectedPVs() );
|
||||
}
|
||||
|
||||
delete dlg;
|
||||
|
@@ -212,7 +212,8 @@ ReplaceWidget::onPartitionSelected()
|
||||
}
|
||||
}
|
||||
|
||||
if ( partition->capacity() < requiredSpaceB )
|
||||
// The loss of precision is ok; we're not going to fall over from a single byte
|
||||
if ( static_cast< double >( partition->capacity() ) < requiredSpaceB )
|
||||
{
|
||||
updateStatus( CalamaresUtils::Fail,
|
||||
tr( "<strong>%4</strong><br/><br/>"
|
||||
|
@@ -22,38 +22,28 @@
|
||||
|
||||
ResizeVolumeGroupDialog::ResizeVolumeGroupDialog( LvmDevice* device,
|
||||
const PartitionVector& availablePVs,
|
||||
PartitionVector& selectedPVs,
|
||||
QWidget* parent )
|
||||
: VolumeGroupBaseDialog( device->name(), device->physicalVolumes(), parent )
|
||||
, m_selectedPVs( selectedPVs )
|
||||
: VolumeGroupBaseDialog( parent, device->name(), device->physicalVolumes() )
|
||||
{
|
||||
setWindowTitle( tr( "Resize Volume Group" ) );
|
||||
|
||||
for ( int i = 0; i < pvList()->count(); i++ )
|
||||
for ( int i = 0; i < pvListWidget()->count(); i++ )
|
||||
{
|
||||
pvList()->item( i )->setCheckState( Qt::Checked );
|
||||
pvListWidget()->item( i )->setCheckState( Qt::Checked );
|
||||
}
|
||||
|
||||
for ( const Partition* p : availablePVs )
|
||||
{
|
||||
pvList()->addItem( new ListPhysicalVolumeWidgetItem( p, false ) );
|
||||
pvListWidget()->addItem( new ListPhysicalVolumeWidgetItem( p, false ) );
|
||||
}
|
||||
|
||||
peSize()->setValue(
|
||||
peSizeWidget()->setValue(
|
||||
static_cast< int >( device->peSize() / Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB ) ) );
|
||||
|
||||
vgName()->setEnabled( false );
|
||||
peSize()->setEnabled( false );
|
||||
vgType()->setEnabled( false );
|
||||
vgNameWidget()->setEnabled( false );
|
||||
peSizeWidget()->setEnabled( false );
|
||||
vgTypeWidget()->setEnabled( false );
|
||||
|
||||
setUsedSizeValue( device->allocatedPE() * device->peSize() );
|
||||
setLVQuantity( device->partitionTable()->children().count() );
|
||||
}
|
||||
|
||||
void
|
||||
ResizeVolumeGroupDialog::accept()
|
||||
{
|
||||
m_selectedPVs << checkedItems();
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
@@ -19,17 +19,7 @@ class ResizeVolumeGroupDialog : public VolumeGroupBaseDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
using PartitionVector = QVector< const Partition* >;
|
||||
|
||||
ResizeVolumeGroupDialog( LvmDevice* device,
|
||||
const PartitionVector& availablePVs,
|
||||
PartitionVector& selectedPVs,
|
||||
QWidget* parent );
|
||||
|
||||
void accept() override;
|
||||
|
||||
private:
|
||||
PartitionVector& m_selectedPVs;
|
||||
ResizeVolumeGroupDialog( LvmDevice* device, const PartitionVector& availablePVs, QWidget* parent );
|
||||
};
|
||||
|
||||
#endif // RESIZEVOLUMEGROUPDIALOG_H
|
||||
|
@@ -10,10 +10,10 @@
|
||||
#include "VolumeGroupBaseDialog.h"
|
||||
#include "ui_VolumeGroupBaseDialog.h"
|
||||
|
||||
#include "core/PartitionCoreModule.h"
|
||||
#include "core/SizeUtils.h"
|
||||
#include "gui/ListPhysicalVolumeWidgetItem.h"
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
@@ -21,10 +21,11 @@
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
|
||||
VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, QWidget* parent )
|
||||
// Keeping the sources consistent
|
||||
VolumeGroupBaseDialog::VolumeGroupBaseDialog( QWidget* parent, const QString& vgName, PartitionVector pvList )
|
||||
: QDialog( parent )
|
||||
, ui( new Ui::VolumeGroupBaseDialog )
|
||||
, m_vgNameValue( vgName )
|
||||
, m_volumeGroupName( vgName )
|
||||
, m_totalSizeValue( 0 )
|
||||
, m_usedSizeValue( 0 )
|
||||
{
|
||||
@@ -35,13 +36,12 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Pa
|
||||
ui->pvList->addItem( new ListPhysicalVolumeWidgetItem( p, false ) );
|
||||
}
|
||||
|
||||
ui->vgType->addItems( QStringList() << "LVM"
|
||||
<< "RAID" );
|
||||
ui->vgType->addItems( { "LVM", "RAID" } );
|
||||
ui->vgType->setCurrentIndex( 0 );
|
||||
|
||||
QRegularExpression re( R"(^(?!_|\.)[\w\-.+]+)" );
|
||||
ui->vgName->setValidator( new QRegularExpressionValidator( re, this ) );
|
||||
ui->vgName->setText( m_vgNameValue );
|
||||
ui->vgName->setText( vgName );
|
||||
|
||||
updateOkButton();
|
||||
updateTotalSize();
|
||||
@@ -56,7 +56,10 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Pa
|
||||
updateOkButton();
|
||||
} );
|
||||
|
||||
connect( ui->vgName, &QLineEdit::textChanged, this, [&]( const QString& ) { updateOkButton(); } );
|
||||
connect( ui->vgName, &QLineEdit::textChanged, this, [&]( const QString& s ) {
|
||||
m_volumeGroupName = s;
|
||||
updateOkButton();
|
||||
} );
|
||||
}
|
||||
|
||||
VolumeGroupBaseDialog::~VolumeGroupBaseDialog()
|
||||
@@ -64,10 +67,10 @@ VolumeGroupBaseDialog::~VolumeGroupBaseDialog()
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QVector< const Partition* >
|
||||
VolumeGroupBaseDialog::checkedItems() const
|
||||
PartitionVector
|
||||
VolumeGroupBaseDialog::selectedPVs() const
|
||||
{
|
||||
QVector< const Partition* > items;
|
||||
PartitionVector items;
|
||||
|
||||
for ( int i = 0; i < ui->pvList->count(); i++ )
|
||||
{
|
||||
@@ -91,8 +94,8 @@ VolumeGroupBaseDialog::isSizeValid() const
|
||||
void
|
||||
VolumeGroupBaseDialog::updateOkButton()
|
||||
{
|
||||
okButton()->setEnabled( isSizeValid() && !checkedItems().empty() && !ui->vgName->text().isEmpty()
|
||||
&& ui->peSize->value() > 0 );
|
||||
okButtonWidget()->setEnabled( isSizeValid() && !selectedPVs().empty() && !ui->vgName->text().isEmpty()
|
||||
&& ui->peSize->value() > 0 );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -100,7 +103,7 @@ VolumeGroupBaseDialog::setUsedSizeValue( qint64 usedSize )
|
||||
{
|
||||
m_usedSizeValue = usedSize;
|
||||
|
||||
ui->usedSize->setText( Capacity::formatByteSize( m_usedSizeValue ) );
|
||||
ui->usedSize->setText( formatByteSize( m_usedSizeValue ) );
|
||||
}
|
||||
|
||||
void
|
||||
@@ -112,16 +115,17 @@ VolumeGroupBaseDialog::setLVQuantity( qint32 lvQuantity )
|
||||
void
|
||||
VolumeGroupBaseDialog::updateTotalSize()
|
||||
{
|
||||
m_physicalExtentSize = peSizeWidget()->value();
|
||||
m_totalSizeValue = 0;
|
||||
|
||||
for ( const Partition* p : checkedItems() )
|
||||
for ( const Partition* p : selectedPVs() )
|
||||
{
|
||||
m_totalSizeValue += p->capacity()
|
||||
- p->capacity()
|
||||
% ( ui->peSize->value() * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB ) );
|
||||
% ( m_physicalExtentSize * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB ) );
|
||||
}
|
||||
|
||||
ui->totalSize->setText( Capacity::formatByteSize( m_totalSizeValue ) );
|
||||
ui->totalSize->setText( formatByteSize( m_totalSizeValue ) );
|
||||
|
||||
updateTotalSectors();
|
||||
}
|
||||
@@ -129,9 +133,10 @@ VolumeGroupBaseDialog::updateTotalSize()
|
||||
void
|
||||
VolumeGroupBaseDialog::updateTotalSectors()
|
||||
{
|
||||
qint64 totalSectors = 0;
|
||||
m_physicalExtentSize = peSizeWidget()->value();
|
||||
|
||||
qint64 extentSize = ui->peSize->value() * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB );
|
||||
qint64 totalSectors = 0;
|
||||
qint64 extentSize = m_physicalExtentSize * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB );
|
||||
|
||||
if ( extentSize > 0 )
|
||||
{
|
||||
@@ -141,38 +146,32 @@ VolumeGroupBaseDialog::updateTotalSectors()
|
||||
ui->totalSectors->setText( QString::number( totalSectors ) );
|
||||
}
|
||||
|
||||
QString&
|
||||
VolumeGroupBaseDialog::vgNameValue() const
|
||||
{
|
||||
return m_vgNameValue;
|
||||
}
|
||||
|
||||
QLineEdit*
|
||||
VolumeGroupBaseDialog::vgName() const
|
||||
VolumeGroupBaseDialog::vgNameWidget() const
|
||||
{
|
||||
return ui->vgName;
|
||||
}
|
||||
|
||||
QComboBox*
|
||||
VolumeGroupBaseDialog::vgType() const
|
||||
VolumeGroupBaseDialog::vgTypeWidget() const
|
||||
{
|
||||
return ui->vgType;
|
||||
}
|
||||
|
||||
QSpinBox*
|
||||
VolumeGroupBaseDialog::peSize() const
|
||||
VolumeGroupBaseDialog::peSizeWidget() const
|
||||
{
|
||||
return ui->peSize;
|
||||
}
|
||||
|
||||
QListWidget*
|
||||
VolumeGroupBaseDialog::pvList() const
|
||||
VolumeGroupBaseDialog::pvListWidget() const
|
||||
{
|
||||
return ui->pvList;
|
||||
}
|
||||
|
||||
QPushButton*
|
||||
VolumeGroupBaseDialog::okButton() const
|
||||
VolumeGroupBaseDialog::okButtonWidget() const
|
||||
{
|
||||
return ui->buttonBox->button( QDialogButtonBox::StandardButton::Ok );
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#ifndef VOLUMEGROUPBASEDIALOG_H
|
||||
#define VOLUMEGROUPBASEDIALOG_H
|
||||
|
||||
#include <kpmcore/core/partition.h>
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
@@ -29,43 +29,46 @@ class VolumeGroupBaseDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit VolumeGroupBaseDialog( QString& vgName, QVector< const Partition* > pvList, QWidget* parent = nullptr );
|
||||
explicit VolumeGroupBaseDialog( QWidget* parent, const QString& vgName, PartitionVector pvList );
|
||||
~VolumeGroupBaseDialog() override;
|
||||
|
||||
qint32 physicalExtentSize() const { return m_physicalExtentSize; }
|
||||
QString volumeGroupName() const { return m_volumeGroupName; }
|
||||
/** @brief Which PVs (partitions) are selected for this VG
|
||||
*
|
||||
* The vector contains non-owned pointers.
|
||||
*/
|
||||
PartitionVector selectedPVs() const;
|
||||
|
||||
protected:
|
||||
virtual void updateOkButton();
|
||||
|
||||
void setUsedSizeValue( qint64 usedSize );
|
||||
|
||||
void setLVQuantity( qint32 lvQuantity );
|
||||
|
||||
void updateTotalSize();
|
||||
|
||||
void updateTotalSectors();
|
||||
|
||||
QVector< const Partition* > checkedItems() const;
|
||||
|
||||
bool isSizeValid() const;
|
||||
|
||||
QString& vgNameValue() const;
|
||||
void updateTotalSize();
|
||||
void updateTotalSectors();
|
||||
|
||||
QLineEdit* vgName() const;
|
||||
|
||||
QComboBox* vgType() const;
|
||||
|
||||
QSpinBox* peSize() const;
|
||||
|
||||
QListWidget* pvList() const;
|
||||
|
||||
QPushButton* okButton() const;
|
||||
/** @section UI-widget accessors
|
||||
*
|
||||
* These methods get UI internal widgets, so that subclasses
|
||||
* can manipulate the values in those widgets.
|
||||
*/
|
||||
QLineEdit* vgNameWidget() const;
|
||||
QComboBox* vgTypeWidget() const;
|
||||
QSpinBox* peSizeWidget() const;
|
||||
QListWidget* pvListWidget() const;
|
||||
QPushButton* okButtonWidget() const;
|
||||
|
||||
private:
|
||||
Ui::VolumeGroupBaseDialog* ui;
|
||||
|
||||
QString& m_vgNameValue;
|
||||
|
||||
QString m_volumeGroupName;
|
||||
qint64 m_totalSizeValue;
|
||||
qint64 m_usedSizeValue;
|
||||
qint32 m_physicalExtentSize;
|
||||
};
|
||||
|
||||
#endif // VOLUMEGROUPBASEDIALOG_H
|
||||
|
@@ -243,14 +243,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
#if ( QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 ) )
|
||||
// TODO: 3.3 remove because newer Qt does support constness
|
||||
const char* m_message = nullptr;
|
||||
QString m_path;
|
||||
#else
|
||||
const char* const m_message = nullptr;
|
||||
QString const m_path;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATICTEST inline QDebug&
|
||||
|
@@ -11,7 +11,9 @@
|
||||
|
||||
#include "CreatePartitionJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
#include "core/PartitionInfo.h"
|
||||
|
||||
#include "partition/FileSystem.h"
|
||||
#include "partition/PartitionQuery.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
@@ -60,24 +62,24 @@ createZfs( Partition* partition, Device* device )
|
||||
// Now we need to do some things that would normally be done by kpmcore
|
||||
|
||||
// First we get the device node from the output and set it as the partition path
|
||||
QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) );
|
||||
QRegularExpressionMatch rem = re.match( r.getOutput() );
|
||||
|
||||
QString deviceNode;
|
||||
if ( rem.hasMatch() )
|
||||
{
|
||||
if ( partition->devicePath().back().isDigit() )
|
||||
QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) );
|
||||
QRegularExpressionMatch rem = re.match( r.getOutput() );
|
||||
|
||||
if ( rem.hasMatch() )
|
||||
{
|
||||
deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceNode = partition->devicePath() + rem.captured( 1 );
|
||||
if ( partition->devicePath().back().isDigit() )
|
||||
{
|
||||
deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceNode = partition->devicePath() + rem.captured( 1 );
|
||||
}
|
||||
}
|
||||
partition->setPartitionPath( deviceNode );
|
||||
}
|
||||
|
||||
partition->setPartitionPath( deviceNode );
|
||||
|
||||
// If it is a gpt device, set the partition UUID
|
||||
if ( device->partitionTable()->type() == PartitionTable::gpt && partition->uuid().isEmpty() )
|
||||
{
|
||||
@@ -273,17 +275,9 @@ CreatePartitionJob::exec()
|
||||
return createZfs( m_partition, m_device );
|
||||
}
|
||||
|
||||
Report report( nullptr );
|
||||
NewOperation op( *m_device, m_partition );
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() );
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute(
|
||||
NewOperation( *m_device, m_partition ),
|
||||
tr( "The installer failed to create partition on disk '%1'." ).arg( m_device->name() ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -12,9 +12,11 @@
|
||||
#include "CreatePartitionTableJob.h"
|
||||
|
||||
#include "partition/PartitionIterator.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
// KPMcore
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include <kpmcore/core/device.h>
|
||||
#include <kpmcore/core/partition.h>
|
||||
#include <kpmcore/core/partitiontable.h>
|
||||
@@ -63,8 +65,6 @@ CreatePartitionTableJob::prettyStatusMessage() const
|
||||
Calamares::JobResult
|
||||
CreatePartitionTableJob::exec()
|
||||
{
|
||||
Report report( nullptr );
|
||||
QString message = tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() );
|
||||
|
||||
PartitionTable* table = m_device->partitionTable();
|
||||
|
||||
@@ -76,30 +76,16 @@ CreatePartitionTableJob::exec()
|
||||
cDebug() << Logger::SubEntry << ( ( *it ) ? ( *it )->deviceNode() : QString( "<null device>" ) );
|
||||
}
|
||||
|
||||
QProcess lsblk;
|
||||
lsblk.setProgram( "lsblk" );
|
||||
lsblk.setProcessChannelMode( QProcess::MergedChannels );
|
||||
lsblk.start();
|
||||
lsblk.waitForFinished();
|
||||
cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblk.readAllStandardOutput();
|
||||
auto lsblkResult = CalamaresUtils::System::runCommand( { "lsblk" }, std::chrono::seconds( 30 ) );
|
||||
cDebug() << Logger::SubEntry << "lsblk output:\n" << Logger::NoQuote << lsblkResult.getOutput();
|
||||
|
||||
QProcess mount;
|
||||
mount.setProgram( "mount" ); // Debug output only, not mounting something
|
||||
mount.setProcessChannelMode( QProcess::MergedChannels );
|
||||
mount.start();
|
||||
mount.waitForFinished();
|
||||
cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mount.readAllStandardOutput();
|
||||
auto mountResult = CalamaresUtils::System::runCommand( { "mount" }, std::chrono::seconds( 30 ) );
|
||||
cDebug() << Logger::SubEntry << "mount output:\n" << Logger::NoQuote << mountResult.getOutput();
|
||||
}
|
||||
|
||||
CreatePartitionTableOperation op( *m_device, table );
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute(
|
||||
CreatePartitionTableOperation( *m_device, table ),
|
||||
tr( "The installer failed to create a partition table on %1." ).arg( m_device->name() ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -9,19 +9,20 @@
|
||||
|
||||
#include "CreateVolumeGroupJob.h"
|
||||
|
||||
// KPMcore
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include <kpmcore/core/lvmdevice.h>
|
||||
#include <kpmcore/core/partition.h>
|
||||
#include <kpmcore/ops/createvolumegroupoperation.h>
|
||||
#include <kpmcore/util/report.h>
|
||||
|
||||
CreateVolumeGroupJob::CreateVolumeGroupJob( Device*,
|
||||
QString& vgName,
|
||||
QVector< const Partition* > pvList,
|
||||
const QString& vgName,
|
||||
const PartitionVector& pvList,
|
||||
const qint32 peSize )
|
||||
: m_vgName( vgName )
|
||||
, m_pvList( pvList )
|
||||
, m_peSize( peSize )
|
||||
, m_physicalExtentSize( peSize )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -46,19 +47,8 @@ CreateVolumeGroupJob::prettyStatusMessage() const
|
||||
Calamares::JobResult
|
||||
CreateVolumeGroupJob::exec()
|
||||
{
|
||||
Report report( nullptr );
|
||||
|
||||
CreateVolumeGroupOperation op( m_vgName, m_pvList, m_peSize );
|
||||
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName );
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute( CreateVolumeGroupOperation( m_vgName, m_pvList, m_physicalExtentSize ),
|
||||
tr( "The installer failed to create a volume group named '%1'." ).arg( m_vgName ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -10,19 +10,23 @@
|
||||
#ifndef CREATEVOLUMEGROUPJOB_H
|
||||
#define CREATEVOLUMEGROUPJOB_H
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include "Job.h"
|
||||
#include "partition/KPMManager.h"
|
||||
|
||||
#include <QVector>
|
||||
|
||||
class Device;
|
||||
class Partition;
|
||||
|
||||
class CreateVolumeGroupJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CreateVolumeGroupJob( Device*, QString& vgName, QVector< const Partition* > pvList, const qint32 peSize );
|
||||
/** @brief Make a job that will create a volume group
|
||||
*
|
||||
* The @p physicalExtentSize is given in MiB; typically this is 4 (MiB).
|
||||
*/
|
||||
CreateVolumeGroupJob( Device*,
|
||||
const QString& vgName,
|
||||
const PartitionVector& pvList,
|
||||
const qint32 physicalExtentSize );
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyDescription() const override;
|
||||
@@ -35,8 +39,8 @@ public:
|
||||
private:
|
||||
CalamaresUtils::Partition::KPMManager m_kpmcore;
|
||||
QString m_vgName;
|
||||
QVector< const Partition* > m_pvList;
|
||||
qint32 m_peSize;
|
||||
PartitionVector m_pvList;
|
||||
qint32 m_physicalExtentSize;
|
||||
};
|
||||
|
||||
#endif // CREATEVOLUMEGROUPJOB_H
|
||||
|
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "DeactivateVolumeGroupJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include <kpmcore/core/lvmdevice.h>
|
||||
#include <kpmcore/ops/deactivatevolumegroupoperation.h>
|
||||
#include <kpmcore/util/report.h>
|
||||
@@ -39,18 +41,12 @@ DeactivateVolumeGroupJob::prettyStatusMessage() const
|
||||
Calamares::JobResult
|
||||
DeactivateVolumeGroupJob::exec()
|
||||
{
|
||||
Report report( nullptr );
|
||||
|
||||
DeactivateVolumeGroupOperation op( *m_device );
|
||||
|
||||
op.setStatus( Operation::OperationStatus::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() );
|
||||
if ( op.execute( report ) )
|
||||
auto r = KPMHelpers::execute(
|
||||
op, tr( "The installer failed to deactivate a volume group named %1." ).arg( m_device->name() ) );
|
||||
if ( r )
|
||||
{
|
||||
op.preview();
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return r;
|
||||
}
|
||||
|
@@ -10,9 +10,11 @@
|
||||
*/
|
||||
|
||||
#include "DeletePartitionJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
|
||||
// KPMcore
|
||||
#include <kpmcore/core/device.h>
|
||||
#include <kpmcore/core/partition.h>
|
||||
#include <kpmcore/core/partitiontable.h>
|
||||
@@ -45,7 +47,7 @@ removePartition( Partition* partition )
|
||||
auto r = CalamaresUtils::System::instance()->runCommand(
|
||||
{ "sfdisk", "--delete", "--force", partition->devicePath(), QString::number( partition->number() ) },
|
||||
std::chrono::seconds( 5 ) );
|
||||
if ( r.getExitCode() !=0 || r.getOutput().contains("failed") )
|
||||
if ( r.getExitCode() != 0 || r.getOutput().contains( "failed" ) )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
QCoreApplication::translate( DeletePartitionJob::staticMetaObject.className(), "Deletion Failed" ),
|
||||
@@ -96,17 +98,8 @@ DeletePartitionJob::exec()
|
||||
return removePartition( m_partition );
|
||||
}
|
||||
|
||||
Report report( nullptr );
|
||||
DeleteOperation op( *m_device, m_partition );
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() );
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute( DeleteOperation( *m_device, m_partition ),
|
||||
tr( "The installer failed to delete partition %1." ).arg( m_partition->devicePath() ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "FormatPartitionJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include "partition/FileSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
@@ -65,17 +67,7 @@ FormatPartitionJob::prettyStatusMessage() const
|
||||
Calamares::JobResult
|
||||
FormatPartitionJob::exec()
|
||||
{
|
||||
Report report( nullptr ); // Root of the report tree, no parent
|
||||
CreateFileSystemOperation op( *m_device, *m_partition, m_partition->fileSystem().type() );
|
||||
op.setStatus( Operation::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to format partition %1 on disk '%2'." )
|
||||
.arg( m_partition->partitionPath(), m_device->name() );
|
||||
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute( CreateFileSystemOperation( *m_device, *m_partition, m_partition->fileSystem().type() ),
|
||||
tr( "The installer failed to format partition %1 on disk '%2'." )
|
||||
.arg( m_partition->partitionPath(), m_device->name() ) );
|
||||
}
|
||||
|
@@ -9,6 +9,8 @@
|
||||
|
||||
#include "RemoveVolumeGroupJob.h"
|
||||
|
||||
#include "core/KPMHelpers.h"
|
||||
|
||||
#include <kpmcore/core/lvmdevice.h>
|
||||
#include <kpmcore/ops/removevolumegroupoperation.h>
|
||||
#include <kpmcore/util/report.h>
|
||||
@@ -39,17 +41,7 @@ RemoveVolumeGroupJob::prettyStatusMessage() const
|
||||
Calamares::JobResult
|
||||
RemoveVolumeGroupJob::exec()
|
||||
{
|
||||
Report report( nullptr );
|
||||
|
||||
RemoveVolumeGroupOperation op( *m_device );
|
||||
|
||||
op.setStatus( Operation::OperationStatus::StatusRunning );
|
||||
|
||||
QString message = tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() );
|
||||
if ( op.execute( report ) )
|
||||
{
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::error( message, report.toText() );
|
||||
return KPMHelpers::execute(
|
||||
RemoveVolumeGroupOperation( *m_device ),
|
||||
tr( "The installer failed to remove a volume group named '%1'." ).arg( m_device->name() ) );
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user