Merge branch 'master' into fix-swap-ui

This commit is contained in:
Adriaan de Groot 2018-10-08 13:56:28 -04:00
commit 779542a5d1
45 changed files with 720 additions and 256 deletions

16
CHANGES
View File

@ -10,15 +10,31 @@ This release contains contributions from (alphabetically by first name):
- Caio Carvalho - Caio Carvalho
- Kevin Kofler - Kevin Kofler
- Philip Mueller - Philip Mueller
- Scott Harvey
## Core ## ## Core ##
* The Calamares application now recognizes the `-X` or `--xdg-config`
option, which adds XDG_DATA_DIRS to the places used to find QML
and branding directories, and XDG_CONFIG_DIRS to the places used
to find the global settings and module configurations. This allows
a more fine-grained, and more layered, approach to setting up
Calamares configurations (in particular, distro's can **add**
configuration files and give them priority, instead of **forking**
configuration files).
## Modules ## ## Modules ##
* The *partition* module supports RAID devices, but only when Calamares * The *partition* module supports RAID devices, but only when Calamares
is compiled with the newest KPMCore release. is compiled with the newest KPMCore release.
* The calculation of required space -- including swap -- has been simplified,
and Calamares no longer reserves 2GiB of space in calculations for internal
use (this means that it no longer mysteriously drops swap when the disk
size is close to the required installation size).
* The *keyboard* module now handles the (bogus) Austrian keymap for * The *keyboard* module now handles the (bogus) Austrian keymap for
the system console properly. the system console properly.
* The *preservefiles* module now has a mechanism for setting the permissions
(and ownership) of preserved files.
* New module *fsresizer* can be used to resize filesystems. It is intended * New module *fsresizer* can be used to resize filesystems. It is intended
for use in OEM installs where an image of fixed size is created, for use in OEM installs where an image of fixed size is created,
and then sized to the actual SD card the user has used. and then sized to the actual SD card the user has used.

View File

@ -237,6 +237,11 @@ set_package_properties(
find_package(ECM ${ECM_VERSION} NO_MODULE) find_package(ECM ${ECM_VERSION} NO_MODULE)
if( ECM_FOUND ) if( ECM_FOUND )
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH})
if ( BUILD_TESTING )
# ECM implies that we can build the tests, too
find_package( Qt5 COMPONENTS Test REQUIRED )
include( ECMAddTests )
endif()
endif() endif()
find_package( KF5 COMPONENTS CoreAddons Crash ) find_package( KF5 COMPONENTS CoreAddons Crash )

View File

@ -14,165 +14,165 @@ Categories=Qt;System;
X-AppStream-Ignore=true X-AppStream-Ignore=true
Name[ar]=نظام التثبيت Name[ar]=نظام التثبيت
Icon[be]=calamares
GenericName[be]=Усталёўшчык сістэмы
Comment[be]=Calamares усталёўшчык сістэмы Comment[be]=Calamares усталёўшчык сістэмы
Icon[be]=calamares
Name[be]=Усталяваць сістэму Name[be]=Усталяваць сістэму
Icon[bg]=calamares GenericName[be]=Усталёўшчык сістэмы
GenericName[bg]=Системен Инсталатор
Comment[bg]=Calamares Системен Инсталатор Comment[bg]=Calamares Системен Инсталатор
Icon[bg]=calamares
Name[bg]=Инсталирай системата Name[bg]=Инсталирай системата
Icon[ca]=calamares GenericName[bg]=Системен Инсталатор
GenericName[ca]=Instal·lador de sistema
Comment[ca]=Calamares Instal·lador de sistema Comment[ca]=Calamares Instal·lador de sistema
Icon[ca]=calamares
Name[ca]=Instal·la el sistema Name[ca]=Instal·la el sistema
Icon[da]=calamares GenericName[ca]=Instal·lador de sistema
GenericName[da]=Systeminstallationsprogram
Comment[da]=Calamares Systeminstallationsprogram Comment[da]=Calamares Systeminstallationsprogram
Icon[da]=calamares
Name[da]=Installér system Name[da]=Installér system
Icon[de]=calamares GenericName[da]=Systeminstallationsprogram
GenericName[de]=Installation des Betriebssystems
Comment[de]=Calamares - Installation des Betriebssystems Comment[de]=Calamares - Installation des Betriebssystems
Icon[de]=calamares
Name[de]=System installieren Name[de]=System installieren
Icon[el]=calamares GenericName[de]=Installation des Betriebssystems
GenericName[el]=Εγκατάσταση συστήματος
Comment[el]=Calamares Εγκατάσταση συστήματος Comment[el]=Calamares Εγκατάσταση συστήματος
Icon[el]=calamares
Name[el]=Εγκατάσταση συστήματος Name[el]=Εγκατάσταση συστήματος
Icon[en_GB]=calamares GenericName[el]=Εγκατάσταση συστήματος
GenericName[en_GB]=System Installer
Comment[en_GB]=Calamares System Installer Comment[en_GB]=Calamares System Installer
Icon[en_GB]=calamares
Name[en_GB]=Install System Name[en_GB]=Install System
Icon[es]=calamares GenericName[en_GB]=System Installer
GenericName[es]=Instalador del Sistema
Comment[es]=Calamares Instalador del Sistema Comment[es]=Calamares Instalador del Sistema
Icon[es]=calamares
Name[es]=Instalar Sistema Name[es]=Instalar Sistema
Icon[et]=calamares GenericName[es]=Instalador del Sistema
GenericName[et]=Süsteemipaigaldaja
Comment[et]=Calamares süsteemipaigaldaja Comment[et]=Calamares süsteemipaigaldaja
Icon[et]=calamares
Name[et]=Paigalda süsteem Name[et]=Paigalda süsteem
GenericName[et]=Süsteemipaigaldaja
Name[eu]=Sistema instalatu Name[eu]=Sistema instalatu
Name[es_PR]=Instalar el sistema Name[es_PR]=Instalar el sistema
Icon[fr]=calamares
GenericName[fr]=Installateur système
Comment[fr]=Calamares - Installateur système Comment[fr]=Calamares - Installateur système
Icon[fr]=calamares
Name[fr]=Installer le système Name[fr]=Installer le système
GenericName[fr]=Installateur système
Name[gl]=Instalación do Sistema Name[gl]=Instalación do Sistema
Icon[he]=calamares
GenericName[he]=אשף התקנה
Comment[he]=Calamares - אשף התקנה Comment[he]=Calamares - אשף התקנה
Icon[he]=calamares
Name[he]=התקנת מערכת Name[he]=התקנת מערכת
Icon[hi]=calamares GenericName[he]=אשף התקנה
GenericName[hi]=ि
Comment[hi]=Calamares ि Comment[hi]=Calamares ि
Icon[hi]=calamares
Name[hi]=ि Name[hi]=ि
Icon[hr]=calamares GenericName[hi]=ि
GenericName[hr]=Instalacija sustava
Comment[hr]=Calamares Instalacija sustava Comment[hr]=Calamares Instalacija sustava
Icon[hr]=calamares
Name[hr]=Instaliraj sustav Name[hr]=Instaliraj sustav
Icon[hu]=calamares GenericName[hr]=Instalacija sustava
GenericName[hu]=Rendszer Telepítő
Comment[hu]=Calamares Rendszer Telepítő Comment[hu]=Calamares Rendszer Telepítő
Icon[hu]=calamares
Name[hu]=Rendszer telepítése Name[hu]=Rendszer telepítése
Icon[id]=calamares GenericName[hu]=Rendszer Telepítő
GenericName[id]=Pemasang
Comment[id]=Calamares Pemasang Sistem Comment[id]=Calamares Pemasang Sistem
Icon[id]=calamares
Name[id]=Instal Sistem Name[id]=Instal Sistem
Icon[is]=calamares GenericName[id]=Pemasang
GenericName[is]=Kerfis uppsetning
Comment[is]=Calamares Kerfis uppsetning Comment[is]=Calamares Kerfis uppsetning
Icon[is]=calamares
Name[is]=Setja upp kerfið Name[is]=Setja upp kerfið
Icon[cs_CZ]=calamares GenericName[is]=Kerfis uppsetning
GenericName[cs_CZ]=Instalátor systému
Comment[cs_CZ]=Calamares instalátor operačních systémů Comment[cs_CZ]=Calamares instalátor operačních systémů
Icon[cs_CZ]=calamares
Name[cs_CZ]=Nainstalovat Name[cs_CZ]=Nainstalovat
Icon[ja]=calamares GenericName[cs_CZ]=Instalátor systému
GenericName[ja]=
Comment[ja]=Calamares Comment[ja]=Calamares
Icon[ja]=calamares
Name[ja]= Name[ja]=
Icon[ko]= GenericName[ja]=
GenericName[ko]=
Comment[ko]= Comment[ko]=
Icon[ko]=
Name[ko]= Name[ko]=
Icon[lt]=calamares GenericName[ko]=
GenericName[lt]=Sistemos diegimas į kompiuterį
Comment[lt]=Calamares Sistemos diegimo programa Comment[lt]=Calamares Sistemos diegimo programa
Icon[lt]=calamares
Name[lt]=Įdiegti Sistemą Name[lt]=Įdiegti Sistemą
Icon[it_IT]=calamares GenericName[lt]=Sistemos diegimas į kompiuterį
GenericName[it_IT]=Programma d'installazione del sistema
Comment[it_IT]=Calamares Programma d'installazione del sistema Comment[it_IT]=Calamares Programma d'installazione del sistema
Icon[it_IT]=calamares
Name[it_IT]=Installa il sistema Name[it_IT]=Installa il sistema
Icon[nb]=calamares GenericName[it_IT]=Programma d'installazione del sistema
GenericName[nb]=Systeminstallatør
Comment[nb]=Calamares-systeminstallatør Comment[nb]=Calamares-systeminstallatør
Icon[nb]=calamares
Name[nb]=Installer System Name[nb]=Installer System
Icon[nl]=calamares GenericName[nb]=Systeminstallatør
GenericName[nl]=Installatieprogramma
Comment[nl]=Calamares Installatieprogramma Comment[nl]=Calamares Installatieprogramma
Icon[nl]=calamares
Name[nl]=Installeer systeem Name[nl]=Installeer systeem
Icon[pl]=calamares GenericName[nl]=Installatieprogramma
GenericName[pl]=Instalator systemu
Comment[pl]=Calamares Instalator systemu Comment[pl]=Calamares Instalator systemu
Icon[pl]=calamares
Name[pl]=Zainstaluj system Name[pl]=Zainstaluj system
Icon[pt_BR]=calamares GenericName[pl]=Instalator systemu
GenericName[pt_BR]=Instalador de Sistema
Comment[pt_BR]=Calamares Instalador de Sistema Comment[pt_BR]=Calamares Instalador de Sistema
Icon[pt_BR]=calamares
Name[pt_BR]=Sistema de Instalação Name[pt_BR]=Sistema de Instalação
Icon[ro]=calamares GenericName[pt_BR]=Instalador de Sistema
GenericName[ro]=Instalator de sistem
Comment[ro]=Calamares Instalator de sistem Comment[ro]=Calamares Instalator de sistem
Icon[ro]=calamares
Name[ro]=Instalează sistemul Name[ro]=Instalează sistemul
Icon[ru]=calamares GenericName[ro]=Instalator de sistem
GenericName[ru]=Установщик системы
Comment[ru]=Calamares - Установщик системы Comment[ru]=Calamares - Установщик системы
Icon[ru]=calamares
Name[ru]=Установить систему Name[ru]=Установить систему
Icon[sk]=calamares GenericName[ru]=Установщик системы
GenericName[sk]=Inštalátor systému
Comment[sk]=Calamares Inštalátor systému Comment[sk]=Calamares Inštalátor systému
Icon[sk]=calamares
Name[sk]=Inštalovať systém Name[sk]=Inštalovať systém
GenericName[sk]=Inštalátor systému
Name[sl]=Namesti sistem Name[sl]=Namesti sistem
Icon[sq]=calamares
GenericName[sq]=Instalues Sistemi
Comment[sq]=Calamares Instalues Sistemi Comment[sq]=Calamares Instalues Sistemi
Icon[sq]=calamares
Name[sq]=Instalo Sistemin Name[sq]=Instalo Sistemin
Icon[fi_FI]=calamares GenericName[sq]=Instalues Sistemi
GenericName[fi_FI]=Järjestelmän Asennusohjelma
Comment[fi_FI]=Calamares Järjestelmän Asentaja Comment[fi_FI]=Calamares Järjestelmän Asentaja
Icon[fi_FI]=calamares
Name[fi_FI]=Asenna Järjestelmä Name[fi_FI]=Asenna Järjestelmä
GenericName[fi_FI]=Järjestelmän Asennusohjelma
Name[sr@latin]=Instaliraj sistem Name[sr@latin]=Instaliraj sistem
Name[sr]=Инсталирај систем Name[sr]=Инсталирај систем
Icon[sv]=calamares
GenericName[sv]=Systeminstallerare
Comment[sv]=Calamares Systeminstallerare Comment[sv]=Calamares Systeminstallerare
Icon[sv]=calamares
Name[sv]=Installera system Name[sv]=Installera system
GenericName[sv]=Systeminstallerare
Name[th]= Name[th]=
GenericName[uk]=Встановлювач системи
Comment[uk]=Calamares - Встановлювач системи Comment[uk]=Calamares - Встановлювач системи
Name[uk]=Встановити Систему Name[uk]=Встановити Систему
Icon[zh_CN]=calamares GenericName[uk]=Встановлювач системи
GenericName[zh_CN]=
Comment[zh_CN]=Calamares Comment[zh_CN]=Calamares
Icon[zh_CN]=calamares
Name[zh_CN]= Name[zh_CN]=
Icon[zh_TW]=calamares GenericName[zh_CN]=
GenericName[zh_TW]=
Comment[zh_TW]=Calamares Comment[zh_TW]=Calamares
Icon[zh_TW]=calamares
Name[zh_TW]= Name[zh_TW]=
Icon[ast]=calamares GenericName[zh_TW]=
GenericName[ast]=Instalador del sistema
Comment[ast]=Calamares Instalador del sistema Comment[ast]=Calamares Instalador del sistema
Icon[ast]=calamares
Name[ast]=Instalar sistema Name[ast]=Instalar sistema
Icon[eo]=calamares GenericName[ast]=Instalador del sistema
GenericName[eo]=Sistema Instalilo
Comment[eo]=Calamares Sistema Instalilo Comment[eo]=Calamares Sistema Instalilo
Icon[eo]=calamares
Name[eo]=Instali Sistemo Name[eo]=Instali Sistemo
Icon[es_MX]=calamares GenericName[eo]=Sistema Instalilo
GenericName[es_MX]=Instalador del sistema
Comment[es_MX]=Calamares - Instalador del sistema Comment[es_MX]=Calamares - Instalador del sistema
Icon[es_MX]=calamares
Name[es_MX]=Instalar el Sistema Name[es_MX]=Instalar el Sistema
Icon[pt_PT]=calamares GenericName[es_MX]=Instalador del sistema
GenericName[pt_PT]=Instalador de Sistema
Comment[pt_PT]=Calamares - Instalador de Sistema Comment[pt_PT]=Calamares - Instalador de Sistema
Icon[pt_PT]=calamares
Name[pt_PT]=Instalar Sistema Name[pt_PT]=Instalar Sistema
Icon[tr_TR]=calamares GenericName[pt_PT]=Instalador de Sistema
GenericName[tr_TR]=Sistem Yükleyici
Comment[tr_TR]=Calamares Sistem Yükleyici Comment[tr_TR]=Calamares Sistem Yükleyici
Icon[tr_TR]=calamares
Name[tr_TR]=Sistemi Yükle Name[tr_TR]=Sistemi Yükle
GenericName[tr_TR]=Sistem Yükleyici

View File

@ -1693,7 +1693,7 @@ Installationsprogrammet vil stoppe og alle ændringer vil gå tabt.</translation
<message> <message>
<location filename="../src/modules/partition/gui/PartitionPage.cpp" line="196"/> <location filename="../src/modules/partition/gui/PartitionPage.cpp" line="196"/>
<source>The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead.</source> <source>The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead.</source>
<translation>Partitionstabellen %1 har allerede %2 primære partitioner, og der kan ikke tilføjes flere. Fjern venligst en primær partition og tilføj i stedet en udviddet partition.</translation> <translation>Partitionstabellen %1 har allerede %2 primære partitioner, og der kan ikke tilføjes flere. Fjern venligst en primær partition og tilføj i stedet en udvidet partition.</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -4,7 +4,7 @@
<message> <message>
<location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="69"/> <location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="69"/>
<source>The &lt;strong&gt;boot environment&lt;/strong&gt; of this system.&lt;br&gt;&lt;br&gt;Older x86 systems only support &lt;strong&gt;BIOS&lt;/strong&gt;.&lt;br&gt;Modern systems usually use &lt;strong&gt;EFI&lt;/strong&gt;, but may also show up as BIOS if started in compatibility mode.</source> <source>The &lt;strong&gt;boot environment&lt;/strong&gt; of this system.&lt;br&gt;&lt;br&gt;Older x86 systems only support &lt;strong&gt;BIOS&lt;/strong&gt;.&lt;br&gt;Modern systems usually use &lt;strong&gt;EFI&lt;/strong&gt;, but may also show up as BIOS if started in compatibility mode.</source>
<translation>L&apos;&lt;strong&gt;environnement de démarrage&lt;/strong&gt; de ce système.&lt;br&gt;&lt;br&gt;Les anciens systèmes x86 supportent uniquement le &lt;strong&gt;BIOS&lt;/strong&gt;.&lt;br&gt;Les systèmes récents utilisent habituellement &lt;strong&gt;EFI&lt;/strong&gt;, mais peuvent également afficher BIOS s&apos;ils sont démarrés en mode de compatibilité.</translation> <translation>L&apos;&lt;strong&gt;environnement de démarrage&lt;/strong&gt; de ce système.&lt;br&gt;&lt;br&gt;Les anciens systèmes x86 supportent uniquement &lt;strong&gt;BIOS&lt;/strong&gt;.&lt;br&gt;Les systèmes récents utilisent habituellement &lt;strong&gt;EFI&lt;/strong&gt;, mais peuvent également afficher BIOS s&apos;ils sont démarrés en mode de compatibilité.</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="79"/> <location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="79"/>

View File

@ -521,7 +521,7 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/modules/contextualprocess/ContextualProcessJob.cpp" line="117"/> <location filename="../src/modules/contextualprocess/ContextualProcessJob.cpp" line="117"/>
<source>Contextual Processes Job</source> <source>Contextual Processes Job</source>
<translation type="unfinished"/> <translation>משימת תהליכי הקשר</translation>
</message> </message>
</context> </context>
<context> <context>
@ -2358,7 +2358,7 @@ Output:
<message> <message>
<location filename="../src/modules/shellprocess/ShellProcessJob.cpp" line="51"/> <location filename="../src/modules/shellprocess/ShellProcessJob.cpp" line="51"/>
<source>Shell Processes Job</source> <source>Shell Processes Job</source>
<translation type="unfinished"/> <translation>משימת תהליכי מעטפת</translation>
</message> </message>
</context> </context>
<context> <context>

View File

@ -207,7 +207,7 @@
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/>
<source>&amp;Install</source> <source>&amp;Install</source>
<translation type="unfinished"/> <translation>&amp;Telepítés</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="325"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="325"/>
@ -229,7 +229,7 @@ Minden változtatás elveszik, ha kilépsz a telepítőből.</translation>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="332"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="332"/>
<source>&amp;No</source> <source>&amp;No</source>
<translation>@Nem</translation> <translation>&amp;Nem</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="163"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="163"/>
@ -944,7 +944,7 @@ Telepítés nem folytatható. &lt;a href=&quot;#details&quot;&gt;Részletek...&l
<message> <message>
<location filename="../src/modules/finished/FinishedPage.ui" line="98"/> <location filename="../src/modules/finished/FinishedPage.ui" line="98"/>
<source>&amp;Restart now</source> <source>&amp;Restart now</source>
<translation>jraindítás most</translation> <translation>Új&amp;raindítás most</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/finished/FinishedPage.cpp" line="51"/> <location filename="../src/modules/finished/FinishedPage.cpp" line="51"/>

View File

@ -244,7 +244,7 @@ Diegimo programa užbaigs darbą ir visi pakeitimai bus prarasti.</translation>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="238"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="238"/>
<source>The %1 installer is about to make changes to your disk in order to install %2.&lt;br/&gt;&lt;strong&gt;You will not be able to undo these changes.&lt;/strong&gt;</source> <source>The %1 installer is about to make changes to your disk in order to install %2.&lt;br/&gt;&lt;strong&gt;You will not be able to undo these changes.&lt;/strong&gt;</source>
<translation>%1 diegimo programa, siekdama įdiegti %2, ketina atlikti pakeitimus diske.&lt;br/&gt;&lt;strong&gt;Š pakeitimų atšaukti nebegalėsite.&lt;/strong&gt;</translation> <translation>%1 diegimo programa, siekdama įdiegti %2, ketina atlikti pakeitimus diske.&lt;br/&gt;&lt;strong&gt;Š pakeitimų nebegalėsite atšaukti.&lt;/strong&gt;</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="243"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="243"/>

View File

@ -50,7 +50,7 @@
<message> <message>
<location filename="../src/libcalamaresui/viewpages/BlankViewStep.cpp" line="69"/> <location filename="../src/libcalamaresui/viewpages/BlankViewStep.cpp" line="69"/>
<source>Blank Page</source> <source>Blank Page</source>
<translation type="unfinished"/> <translation>Lege pagina</translation>
</message> </message>
</context> </context>
<context> <context>
@ -192,7 +192,7 @@
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="179"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="179"/>
<source>Calamares Initialization Failed</source> <source>Calamares Initialization Failed</source>
<translation type="unfinished"/> <translation>Calamares Initialisatie mislukt</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="180"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="180"/>
@ -202,7 +202,7 @@
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="185"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="185"/>
<source>&lt;br/&gt;The following modules could not be loaded:</source> <source>&lt;br/&gt;The following modules could not be loaded:</source>
<translation type="unfinished"/> <translation>&lt;br/&gt;The volgende modules konden niet worden geladen:</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/>
@ -1244,7 +1244,7 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan.
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="151"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="151"/>
<source>Password is too weak</source> <source>Password is too weak</source>
<translation type="unfinished"/> <translation>Wachtwoord is te zwak</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="158"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="158"/>
@ -1259,12 +1259,12 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan.
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="164"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="164"/>
<source>The password is the same as the old one</source> <source>The password is the same as the old one</source>
<translation type="unfinished"/> <translation>Het wachtwoord is hetzelfde als het oude wachtwoord</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="166"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="166"/>
<source>The password is a palindrome</source> <source>The password is a palindrome</source>
<translation type="unfinished"/> <translation>Het wachtwoord is een palindroom</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="168"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="168"/>
@ -1274,12 +1274,12 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan.
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="170"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="170"/>
<source>The password is too similar to the old one</source> <source>The password is too similar to the old one</source>
<translation type="unfinished"/> <translation>Het wachtwoord lijkt te veel op het oude wachtwoord</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="172"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="172"/>
<source>The password contains the user name in some form</source> <source>The password contains the user name in some form</source>
<translation type="unfinished"/> <translation>Het wachtwoord bevat de gebruikersnaam op een of andere manier</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/users/CheckPWQuality.cpp" line="174"/> <location filename="../src/modules/users/CheckPWQuality.cpp" line="174"/>

View File

@ -9,7 +9,7 @@
<message> <message>
<location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="79"/> <location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="79"/>
<source>This system was started with an &lt;strong&gt;EFI&lt;/strong&gt; boot environment.&lt;br&gt;&lt;br&gt;To configure startup from an EFI environment, this installer must deploy a boot loader application, like &lt;strong&gt;GRUB&lt;/strong&gt; or &lt;strong&gt;systemd-boot&lt;/strong&gt; on an &lt;strong&gt;EFI System Partition&lt;/strong&gt;. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own.</source> <source>This system was started with an &lt;strong&gt;EFI&lt;/strong&gt; boot environment.&lt;br&gt;&lt;br&gt;To configure startup from an EFI environment, this installer must deploy a boot loader application, like &lt;strong&gt;GRUB&lt;/strong&gt; or &lt;strong&gt;systemd-boot&lt;/strong&gt; on an &lt;strong&gt;EFI System Partition&lt;/strong&gt;. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own.</source>
<translation>&lt;strong&gt;EFI&lt;/strong&gt; &lt;br&gt;&lt;br&gt;使 EFI使 GPT &lt;br&gt; EFI &lt;strong&gt;GRUB&lt;/strong&gt; &lt;strong&gt;systemd-boot&lt;/strong&gt; &lt;strong&gt;EFI &lt;/strong&gt;</translation> <translation>&lt;strong&gt;EFI&lt;/strong&gt; &lt;br&gt;&lt;br&gt;使 EFI使 GPT &lt;br&gt; EFI &lt;strong&gt;GRUB&lt;/strong&gt; &lt;strong&gt;systemd-boot&lt;/strong&gt; &lt;strong&gt;EFI &lt;/strong&gt;EFIEFI</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="91"/> <location filename="../src/modules/partition/gui/BootInfoWidget.cpp" line="91"/>
@ -51,7 +51,7 @@
<message> <message>
<location filename="../src/libcalamaresui/viewpages/BlankViewStep.cpp" line="69"/> <location filename="../src/libcalamaresui/viewpages/BlankViewStep.cpp" line="69"/>
<source>Blank Page</source> <source>Blank Page</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -193,17 +193,17 @@
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="179"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="179"/>
<source>Calamares Initialization Failed</source> <source>Calamares Initialization Failed</source>
<translation type="unfinished"/> <translation>Calamares安装失败</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="180"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="180"/>
<source>%1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution.</source> <source>%1 can not be installed. Calamares was unable to load all of the configured modules. This is a problem with the way Calamares is being used by the distribution.</source>
<translation type="unfinished"/> <translation>1 Calamares无法加载所有已配置的模块使Calamares的方式的问题</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="185"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="185"/>
<source>&lt;br/&gt;The following modules could not be loaded:</source> <source>&lt;br/&gt;The following modules could not be loaded:</source>
<translation type="unfinished"/> <translation>&lt;br/&gt;</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="277"/>
@ -265,7 +265,7 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="284"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="284"/>
<source>The installation is complete. Close the installer.</source> <source>The installation is complete. Close the installer.</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamaresui/ViewManager.cpp" line="160"/> <location filename="../src/libcalamaresui/ViewManager.cpp" line="160"/>
@ -334,7 +334,7 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/modules/welcome/checker/CheckerWidget.cpp" line="174"/> <location filename="../src/modules/welcome/checker/CheckerWidget.cpp" line="174"/>
<source>For best results, please ensure that this computer:</source> <source>For best results, please ensure that this computer:</source>
<translation>: </translation> <translation>: </translation>
</message> </message>
<message> <message>
<location filename="../src/modules/welcome/checker/CheckerWidget.cpp" line="202"/> <location filename="../src/modules/welcome/checker/CheckerWidget.cpp" line="202"/>
@ -509,12 +509,12 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/libcalamares/utils/CommandList.cpp" line="128"/> <location filename="../src/libcalamares/utils/CommandList.cpp" line="128"/>
<source>The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined.</source> <source>The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined.</source>
<translation type="unfinished"/> <translation>root挂载点</translation>
</message> </message>
<message> <message>
<location filename="../src/libcalamares/utils/CommandList.cpp" line="139"/> <location filename="../src/libcalamares/utils/CommandList.cpp" line="139"/>
<source>The command needs to know the user&apos;s name, but no username is defined.</source> <source>The command needs to know the user&apos;s name, but no username is defined.</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
</context> </context>
<context> <context>
@ -1665,7 +1665,7 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/modules/partition/gui/PartitionPage.ui" line="107"/> <location filename="../src/modules/partition/gui/PartitionPage.ui" line="107"/>
<source>Cre&amp;ate</source> <source>Cre&amp;ate</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/modules/partition/gui/PartitionPage.ui" line="114"/> <location filename="../src/modules/partition/gui/PartitionPage.ui" line="114"/>
@ -1690,12 +1690,12 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/modules/partition/gui/PartitionPage.cpp" line="195"/> <location filename="../src/modules/partition/gui/PartitionPage.cpp" line="195"/>
<source>Can not create new partition</source> <source>Can not create new partition</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
<message> <message>
<location filename="../src/modules/partition/gui/PartitionPage.cpp" line="196"/> <location filename="../src/modules/partition/gui/PartitionPage.cpp" line="196"/>
<source>The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead.</source> <source>The partition table on %1 already has %2 primary partitions, and no more can be added. Please remove one primary partition and add an extended partition, instead.</source>
<translation type="unfinished"/> <translation>12</translation>
</message> </message>
</context> </context>
<context> <context>
@ -1841,17 +1841,17 @@ The installer will quit and all changes will be lost.</source>
<message> <message>
<location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="83"/> <location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="83"/>
<source>Saving files for later ...</source> <source>Saving files for later ...</source>
<translation type="unfinished"/> <translation>使</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="89"/> <location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="89"/>
<source>No files configured to save for later.</source> <source>No files configured to save for later.</source>
<translation type="unfinished"/> <translation>使</translation>
</message> </message>
<message> <message>
<location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="145"/> <location filename="../src/modules/preservefiles/PreserveFiles.cpp" line="145"/>
<source>Not all of the configured files could be preserved.</source> <source>Not all of the configured files could be preserved.</source>
<translation type="unfinished"/> <translation></translation>
</message> </message>
</context> </context>
<context> <context>

Binary file not shown.

View File

@ -10,7 +10,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-06-18 07:46-0400\n" "POT-Creation-Date: 2018-06-18 07:46-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: miku84, 2017\n" "Last-Translator: Adriaan de Groot <groot@kde.org>, 2018\n"
"Language-Team: Hungarian (https://www.transifex.com/calamares/teams/20061/hu/)\n" "Language-Team: Hungarian (https://www.transifex.com/calamares/teams/20061/hu/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -20,7 +20,7 @@ msgstr ""
#: src/modules/umount/main.py:40 #: src/modules/umount/main.py:40
msgid "Unmount file systems." msgid "Unmount file systems."
msgstr "" msgstr "Fájlrendszerek leválasztása."
#: src/modules/dummypython/main.py:44 #: src/modules/dummypython/main.py:44
msgid "Dummy python job." msgid "Dummy python job."
@ -47,12 +47,12 @@ msgstr "Csomagok telepítése."
#, python-format #, python-format
msgid "Installing one package." msgid "Installing one package."
msgid_plural "Installing %(num)d packages." msgid_plural "Installing %(num)d packages."
msgstr[0] "" msgstr[0] "Egy csomag telepítése."
msgstr[1] "" msgstr[1] "%(num)d csomag telepítése."
#: src/modules/packages/main.py:70 #: src/modules/packages/main.py:70
#, python-format #, python-format
msgid "Removing one package." msgid "Removing one package."
msgid_plural "Removing %(num)d packages." msgid_plural "Removing %(num)d packages."
msgstr[0] "" msgstr[0] "Egy csomag eltávolítása."
msgstr[1] "" msgstr[1] "%(num)d csomag eltávolítása."

View File

@ -145,6 +145,9 @@ qmlDirCandidates( bool assumeBuilddir )
{ {
if ( assumeBuilddir ) if ( assumeBuilddir )
qmlDirs << QDir::current().absoluteFilePath( "src/qml" ); // In build-dir qmlDirs << QDir::current().absoluteFilePath( "src/qml" ); // In build-dir
if ( CalamaresUtils::haveExtraDirs() )
for ( auto s : CalamaresUtils::extraDataDirs() )
qmlDirs << ( s + QML );
qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML ); qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML );
} }
@ -164,6 +167,9 @@ settingsFileCandidates( bool assumeBuilddir )
{ {
if ( assumeBuilddir ) if ( assumeBuilddir )
settingsPaths << QDir::current().absoluteFilePath( settings ); settingsPaths << QDir::current().absoluteFilePath( settings );
if ( CalamaresUtils::haveExtraDirs() )
for ( auto s : CalamaresUtils::extraConfigDirs() )
settingsPaths << ( s + settings );
settingsPaths << CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf"; // String concat settingsPaths << CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf"; // String concat
settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings ); settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings );
} }
@ -182,6 +188,9 @@ brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename )
{ {
if ( assumeBuilddir ) if ( assumeBuilddir )
brandingPaths << ( QDir::currentPath() + QStringLiteral( "/src/" ) + brandingFilename ); brandingPaths << ( QDir::currentPath() + QStringLiteral( "/src/" ) + brandingFilename );
if ( CalamaresUtils::haveExtraDirs() )
for ( auto s : CalamaresUtils::extraDataDirs() )
brandingPaths << ( s + brandingFilename );
brandingPaths << QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ).absoluteFilePath( brandingFilename ); brandingPaths << QDir( CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/" ).absoluteFilePath( brandingFilename );
brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename); brandingPaths << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename);
} }

View File

@ -44,6 +44,8 @@ handle_args( CalamaresApplication& a )
"Verbose output for debugging purposes (0-8).", "level" ); "Verbose output for debugging purposes (0-8).", "level" );
QCommandLineOption configOption( QStringList{ "c", "config"}, QCommandLineOption configOption( QStringList{ "c", "config"},
"Configuration directory to use, for testing purposes.", "config" ); "Configuration directory to use, for testing purposes.", "config" );
QCommandLineOption xdgOption( QStringList{"X", "xdg-config"},
"Use XDG_{CONFIG,DATA}_DIRS as well." );
QCommandLineParser parser; QCommandLineParser parser;
parser.setApplicationDescription( "Distribution-independent installer framework" ); parser.setApplicationDescription( "Distribution-independent installer framework" );
@ -53,6 +55,7 @@ handle_args( CalamaresApplication& a )
parser.addOption( debugOption ); parser.addOption( debugOption );
parser.addOption( debugLevelOption ); parser.addOption( debugLevelOption );
parser.addOption( configOption ); parser.addOption( configOption );
parser.addOption( xdgOption );
parser.process( a ); parser.process( a );
@ -72,6 +75,8 @@ handle_args( CalamaresApplication& a )
} }
if ( parser.isSet( configOption ) ) if ( parser.isSet( configOption ) )
CalamaresUtils::setAppDataDir( QDir( parser.value( configOption ) ) ); CalamaresUtils::setAppDataDir( QDir( parser.value( configOption ) ) );
if ( parser.isSet( xdgOption ) )
CalamaresUtils::setXdgDirs();
} }
int int

View File

@ -105,6 +105,19 @@ install( TARGETS calamares
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
) )
if ( ECM_FOUND AND BUILD_TESTING )
ecm_add_test(
Tests.cpp
TEST_NAME
libcalamarestest
LINK_LIBRARIES
calamares
Qt5::Core
Qt5::Test
)
set_target_properties( libcalamarestest PROPERTIES AUTOMOC TRUE )
endif()
# Make symlink lib/calamares/libcalamares.so to lib/libcalamares.so.VERSION so # Make symlink lib/calamares/libcalamares.so to lib/libcalamares.so.VERSION so
# lib/calamares can be used as module path for the Python interpreter. # lib/calamares can be used as module path for the Python interpreter.
install( CODE " install( CODE "

View File

@ -0,0 +1,59 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Tests.h"
#include "utils/Logger.h"
#include <QtTest/QtTest>
QTEST_GUILESS_MAIN( LibCalamaresTests )
LibCalamaresTests::LibCalamaresTests()
{
}
LibCalamaresTests::~LibCalamaresTests()
{
}
void
LibCalamaresTests::initTestCase()
{
}
void
LibCalamaresTests::testDebugLevels()
{
Logger::setupLogLevel( Logger::LOG_DISABLE );
QCOMPARE( Logger::logLevel(), static_cast<unsigned int>( Logger::LOG_DISABLE ) );
for ( unsigned int level = 0; level <= Logger::LOGVERBOSE ; ++level )
{
Logger::setupLogLevel( level );
QCOMPARE( Logger::logLevel(), level );
QVERIFY( Logger::logLevelEnabled( level ) );
for ( unsigned int xlevel = 0; xlevel <= Logger::LOGVERBOSE; ++xlevel )
{
QCOMPARE( Logger::logLevelEnabled( xlevel ), xlevel <= level );
}
}
}

36
src/libcalamares/Tests.h Normal file
View File

@ -0,0 +1,36 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright 2018, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TESTS_H
#define TESTS_H
#include <QObject>
class LibCalamaresTests : public QObject
{
Q_OBJECT
public:
LibCalamaresTests();
~LibCalamaresTests() override;
private Q_SLOTS:
void initTestCase();
void testDebugLevels();
};
#endif

View File

@ -49,6 +49,9 @@ static QTranslator* s_brandingTranslator = nullptr;
static QTranslator* s_translator = nullptr; static QTranslator* s_translator = nullptr;
static QString s_translatorLocaleName; static QString s_translatorLocaleName;
static bool s_haveExtraDirs = false;
static QStringList s_extraConfigDirs;
static QStringList s_extraDataDirs;
static bool static bool
isWritableDir( const QDir& dir ) isWritableDir( const QDir& dir )
@ -94,6 +97,46 @@ setAppDataDir( const QDir& dir )
s_isAppDataDirOverridden = true; s_isAppDataDirOverridden = true;
} }
/* Split $ENV{@p name} on :, append to @p l, making sure each ends in / */
static void
mungeEnvironment( QStringList& l, const char *name )
{
for ( auto s : QString( qgetenv( name ) ).split(':') )
if ( s.endsWith( '/' ) )
l << s;
else
l << ( s + '/' );
}
void
setXdgDirs()
{
s_haveExtraDirs = true;
mungeEnvironment( s_extraConfigDirs, "XDG_CONFIG_DIRS" );
mungeEnvironment( s_extraDataDirs, "XDG_DATA_DIRS" );
}
QStringList
extraConfigDirs()
{
if ( s_haveExtraDirs )
return s_extraConfigDirs;
return QStringList();
}
QStringList
extraDataDirs()
{
if ( s_haveExtraDirs )
return s_extraDataDirs;
return QStringList();
}
bool
haveExtraDirs()
{
return s_haveExtraDirs && ( !s_extraConfigDirs.isEmpty() || !s_extraDataDirs.isEmpty() );
}
bool bool
isAppDataDirOverridden() isAppDataDirOverridden()

View File

@ -79,6 +79,16 @@ namespace CalamaresUtils
DLLEXPORT void setQmlModulesDir( const QDir& dir ); DLLEXPORT void setQmlModulesDir( const QDir& dir );
/** @brief Setup extra config and data dirs from the XDG variables.
*/
DLLEXPORT void setXdgDirs();
/** @brief Are any extra directories configured? */
DLLEXPORT bool haveExtraDirs();
/** @brief XDG_CONFIG_DIRS, each guaranteed to end with / */
DLLEXPORT QStringList extraConfigDirs();
/** @brief XDG_DATA_DIRS, each guaranteed to end with / */
DLLEXPORT QStringList extraDataDirs();
/** /**
* @brief removeDiacritics replaces letters with diacritics and ligatures with * @brief removeDiacritics replaces letters with diacritics and ligatures with
* alternative forms and digraphs. * alternative forms and digraphs.

View File

@ -55,6 +55,18 @@ setupLogLevel(unsigned int level)
s_threshold = level + 1; // Comparison is < in log() function s_threshold = level + 1; // Comparison is < in log() function
} }
bool
logLevelEnabled(unsigned int level)
{
return level < s_threshold;
}
unsigned int
logLevel()
{
return s_threshold > 0 ? s_threshold - 1 : 0;
}
static void static void
log( const char* msg, unsigned int debugLevel, bool toDisk = true ) log( const char* msg, unsigned int debugLevel, bool toDisk = true )
{ {

View File

@ -89,6 +89,12 @@ namespace Logger
*/ */
DLLEXPORT void setupLogLevel( unsigned int level ); DLLEXPORT void setupLogLevel( unsigned int level );
/** @brief Return the configured log-level. */
DLLEXPORT unsigned int logLevel();
/** @brief Would the given @p level really be logged? */
DLLEXPORT bool logLevelEnabled( unsigned int level );
/** /**
* @brief Row-oriented formatted logging. * @brief Row-oriented formatted logging.
* *

View File

@ -155,6 +155,10 @@ moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, c
if ( assumeBuildDir && configFileName.contains( '/' ) ) if ( assumeBuildDir && configFileName.contains( '/' ) )
paths << QDir().absoluteFilePath( configFileName ); paths << QDir().absoluteFilePath( configFileName );
if ( CalamaresUtils::haveExtraDirs() )
for ( auto s : CalamaresUtils::extraConfigDirs() )
paths << ( s + QString( "modules/%1" ).arg( configFileName ) );
paths << QString( "/etc/calamares/modules/%1" ).arg( configFileName ); paths << QString( "/etc/calamares/modules/%1" ).arg( configFileName );
paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); paths << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) );
} }

View File

@ -8,10 +8,7 @@ calamares_add_plugin( contextualprocess
SHARED_LIB SHARED_LIB
) )
if( ECM_FOUND ) if( ECM_FOUND AND BUILD_TESTING )
find_package( Qt5 COMPONENTS Test REQUIRED )
include( ECMAddTests )
ecm_add_test( ecm_add_test(
Tests.cpp Tests.cpp
ContextualProcessJob.cpp # Builds it a second time ContextualProcessJob.cpp # Builds it a second time

View File

@ -8,9 +8,9 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-09-04 08:16-0400\n" "POT-Creation-Date: 2018-06-18 07:46-0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Mingcong Bai <jeffbai@aosc.xyz>, 2017\n" "Last-Translator: soenggam <senggemg@gmail.com>, 2017\n"
"Language-Team: Chinese (China) (https://www.transifex.com/calamares/teams/20061/zh_CN/)\n" "Language-Team: Chinese (China) (https://www.transifex.com/calamares/teams/20061/zh_CN/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -24,7 +24,7 @@ msgstr "按我按我!"
#: src/modules/dummypythonqt/main.py:94 #: src/modules/dummypythonqt/main.py:94
msgid "A new QLabel." msgid "A new QLabel."
msgstr "一个平淡无奇的 QLabel。" msgstr "一个新的QLabel。"
#: src/modules/dummypythonqt/main.py:97 #: src/modules/dummypythonqt/main.py:97
msgid "Dummy PythonQt ViewStep" msgid "Dummy PythonQt ViewStep"

View File

@ -20,10 +20,7 @@ if ( KPMcore_FOUND )
SHARED_LIB SHARED_LIB
) )
if( ECM_FOUND ) if( ECM_FOUND AND BUILD_TESTING )
find_package( Qt5 COMPONENTS Test REQUIRED )
include( ECMAddTests )
ecm_add_test( ecm_add_test(
Tests.cpp Tests.cpp
TEST_NAME TEST_NAME

View File

@ -33,6 +33,7 @@
#include "JobQueue.h" #include "JobQueue.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
#include "utils/CalamaresUtils.h"
#include "utils/Logger.h" #include "utils/Logger.h"
#include "utils/Units.h" #include "utils/Units.h"
@ -48,11 +49,11 @@ ResizeFSJob::RelativeSize::RelativeSize()
template<int N> template<int N>
void matchUnitSuffix( void matchUnitSuffix(
const QString& s, const QString& s,
const char (&suffix)[N], const char ( &suffix )[N],
ResizeFSJob::RelativeSize::Unit matchedUnit, ResizeFSJob::RelativeSize::Unit matchedUnit,
int& value, int& value,
ResizeFSJob::RelativeSize::Unit& unit ResizeFSJob::RelativeSize::Unit& unit
) )
{ {
if ( s.endsWith( suffix ) ) if ( s.endsWith( suffix ) )
{ {
@ -62,7 +63,7 @@ void matchUnitSuffix(
} }
ResizeFSJob::RelativeSize::RelativeSize( const QString& s) ResizeFSJob::RelativeSize::RelativeSize( const QString& s )
: m_value( 0 ) : m_value( 0 )
, m_unit( None ) , m_unit( None )
{ {
@ -81,14 +82,14 @@ ResizeFSJob::RelativeSize::RelativeSize( const QString& s)
} }
qint64 qint64
ResizeFSJob::RelativeSize::apply( qint64 totalSectors , qint64 sectorSize ) ResizeFSJob::RelativeSize::apply( qint64 totalSectors, qint64 sectorSize )
{ {
if ( !isValid() ) if ( !isValid() )
return -1; return -1;
if ( sectorSize < 1 ) if ( sectorSize < 1 )
return -1; return -1;
switch( m_unit ) switch ( m_unit )
{ {
case None: case None:
return -1; return -1;
@ -113,6 +114,7 @@ ResizeFSJob::RelativeSize::apply( Device* d )
ResizeFSJob::ResizeFSJob( QObject* parent ) ResizeFSJob::ResizeFSJob( QObject* parent )
: Calamares::CppJob( parent ) : Calamares::CppJob( parent )
, m_required( false )
{ {
} }
@ -136,14 +138,14 @@ ResizeFSJob::findPartition( CoreBackend* backend )
cDebug() << "ResizeFSJob found" << devices.count() << "devices."; cDebug() << "ResizeFSJob found" << devices.count() << "devices.";
for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it ) for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it )
{ {
if ( ! (*dev_it) ) if ( ! ( *dev_it ) )
continue; continue;
cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode();
for ( auto part_it = PartitionIterator::begin( *dev_it ); part_it != PartitionIterator::end( *dev_it ); ++part_it ) for ( auto part_it = PartitionIterator::begin( *dev_it ); part_it != PartitionIterator::end( *dev_it ); ++part_it )
{ {
cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode();
if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) || if ( ( !m_fsname.isEmpty() && ( *part_it )->mountPoint() == m_fsname ) ||
( !m_devicename.isEmpty() && ( *part_it )->deviceNode() == m_devicename ) ) ( !m_devicename.isEmpty() && ( *part_it )->deviceNode() == m_devicename ) )
{ {
cDebug() << ".. matched configuration dev=" << m_devicename << "fs=" << m_fsname; cDebug() << ".. matched configuration dev=" << m_devicename << "fs=" << m_fsname;
return PartitionMatch( *dev_it, *part_it ); return PartitionMatch( *dev_it, *part_it );
@ -164,7 +166,7 @@ ResizeFSJob::findPartition( CoreBackend* backend )
* by occupied space after it). * by occupied space after it).
*/ */
qint64 qint64
ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) ResizeFSJob::findGrownEnd( ResizeFSJob::PartitionMatch m )
{ {
if ( !m.first || !m.second ) if ( !m.first || !m.second )
return -1; // Missing device data return -1; // Missing device data
@ -193,7 +195,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m)
continue; continue;
} }
cDebug() << ".. comparing" << next_start << '-' << next_end; cDebug() << ".. comparing" << next_start << '-' << next_end;
if ( (next_start > last_currently) && (next_start < last_available) ) if ( ( next_start > last_currently ) && ( next_start < last_available ) )
{ {
cDebug() << " .. shrunk last available to" << next_start; cDebug() << " .. shrunk last available to" << next_start;
last_available = next_start - 1; // Before that one starts last_available = next_start - 1; // Before that one starts
@ -202,7 +204,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m)
if ( !( last_available > last_currently ) ) if ( !( last_available > last_currently ) )
{ {
cDebug() << "Partition can not grow larger."; cDebug() << "Partition cannot grow larger.";
return 0; return 0;
} }
@ -234,13 +236,12 @@ ResizeFSJob::exec()
if ( !isValid() ) if ( !isValid() )
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "Invalid configuration" ), tr( "Invalid configuration" ),
tr( "The file-system resize job has an invalid configuration " tr( "The file-system resize job has an invalid configuration and will not run." ) );
"and will not run." ) );
// Get KPMCore // Get KPMCore
auto backend_p = CoreBackendManager::self()->backend(); auto backend_p = CoreBackendManager::self()->backend();
if ( backend_p ) if ( backend_p )
cDebug() << "KPMCore backend @" << (void *)backend_p << backend_p->id() << backend_p->version(); cDebug() << "KPMCore backend @" << ( void* )backend_p << backend_p->id() << backend_p->version();
else else
{ {
cDebug() << "No KPMCore backend loaded yet"; cDebug() << "No KPMCore backend loaded yet";
@ -269,8 +270,8 @@ ResizeFSJob::exec()
if ( !m.first || !m.second ) if ( !m.first || !m.second )
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "Resize Failed" ), tr( "Resize Failed" ),
!m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and can not be resized." ).arg(m_fsname) !m_fsname.isEmpty() ? tr( "The filesystem %1 could not be found in this system, and cannot be resized." ).arg( m_fsname )
: tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); : tr( "The device %1 could not be found in this system, and cannot be resized." ).arg( m_devicename ) );
m.second->fileSystem().init(); // Initialize support for specific FS m.second->fileSystem().init(); // Initialize support for specific FS
if ( !ResizeOperation::canGrow( m.second ) ) if ( !ResizeOperation::canGrow( m.second ) )
@ -278,26 +279,31 @@ ResizeFSJob::exec()
cDebug() << "canGrow() returned false."; cDebug() << "canGrow() returned false.";
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "Resize Failed" ), tr( "Resize Failed" ),
!m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg( m_fsname )
: tr( "The device %1 can not be resized." ).arg(m_devicename) ); : tr( "The device %1 cannot be resized." ).arg( m_devicename ) );
} }
qint64 new_end = findGrownEnd( m ); qint64 new_end = findGrownEnd( m );
cDebug() << "Resize from" cDebug() << "Resize from"
<< m.second->firstSector() << '-' << m.second->lastSector() << m.second->firstSector() << '-' << m.second->lastSector()
<< '(' << m.second->length() << ')' << '(' << m.second->length() << ')'
<< "to -" << new_end; << "to -" << new_end;
if ( new_end < 0 ) if ( new_end < 0 )
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "Resize Failed" ), tr( "Resize Failed" ),
!m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg( m_fsname )
: tr( "The device %1 can not be resized." ).arg(m_devicename) ); : tr( "The device %1 cannot be resized." ).arg( m_devicename ) );
if ( new_end == 0 ) if ( new_end == 0 )
{ {
// TODO: is that a bad thing? is the resize required?
cWarning() << "Resize operation on" << m_fsname << m_devicename cWarning() << "Resize operation on" << m_fsname << m_devicename
<< "skipped as not-useful."; << "skipped as not-useful.";
if ( m_required )
return Calamares::JobResult::error(
tr( "Resize Failed" ),
!m_fsname.isEmpty() ? tr( "The filesystem %1 must be resized, but cannot." ).arg( m_fsname )
: tr( "The device %1 must be resized, but cannot" ).arg( m_fsname ) );
return Calamares::JobResult::ok(); return Calamares::JobResult::ok();
} }
@ -311,8 +317,8 @@ ResizeFSJob::exec()
{ {
cDebug() << "Resize failed." << op_report.output(); cDebug() << "Resize failed." << op_report.output();
return Calamares::JobResult::error( return Calamares::JobResult::error(
tr( "Resize Failed" ), tr( "Resize Failed" ),
op_report.toText() ); op_report.toText() );
} }
} }
@ -334,6 +340,8 @@ ResizeFSJob::setConfigurationMap( const QVariantMap& configurationMap )
m_size = RelativeSize( configurationMap["size"].toString() ); m_size = RelativeSize( configurationMap["size"].toString() );
m_atleast = RelativeSize( configurationMap["atleast"].toString() ); m_atleast = RelativeSize( configurationMap["atleast"].toString() );
m_required = CalamaresUtils::getBool( configurationMap, "required", false );
} }
CALAMARES_PLUGIN_FACTORY_DEFINITION( ResizeFSJobFactory, registerPlugin<ResizeFSJob>(); ) CALAMARES_PLUGIN_FACTORY_DEFINITION( ResizeFSJobFactory, registerPlugin<ResizeFSJob>(); )

View File

@ -107,6 +107,7 @@ private:
RelativeSize m_atleast; RelativeSize m_atleast;
QString m_fsname; // Either this, or devicename, is set, not both QString m_fsname; // Either this, or devicename, is set, not both
QString m_devicename; QString m_devicename;
bool m_required;
using PartitionMatch = QPair<Device*, Partition*>; using PartitionMatch = QPair<Device*, Partition*>;
/** @brief Find the configured FS using KPMCore @p backend */ /** @brief Find the configured FS using KPMCore @p backend */

View File

@ -33,5 +33,17 @@ size: 100%
# size, as above. If missing, then it's assumed to be 0, # size, as above. If missing, then it's assumed to be 0,
# which means resizing is always worthwhile. # which means resizing is always worthwhile.
# #
# If *atleast* is not zero, then the setting *required*,
# below, becomes relevant.
#
# Percentages apply to **total device size**. # Percentages apply to **total device size**.
atleast: 1000MiB #atleast: 1000MiB
# When *atleast* is not zero, then the resize may be
# recommended (the default) or **required**. If the
# resize is required and cannot be carried out (because
# there's not enough space), then that is a fatal
# error for the installer. By default, resize is only
# recommended and it is not an error for no resize to be
# carried out.
required: false

View File

@ -1,9 +1,3 @@
find_package(ECM ${ECM_VERSION} NO_MODULE)
if( ECM_FOUND AND BUILD_TESTING )
include( ECMAddTests )
find_package( Qt5 COMPONENTS Core Test REQUIRED )
endif()
# When debugging the timezone widget, add this debugging definition # When debugging the timezone widget, add this debugging definition
# to have a debugging-friendly timezone widget, debug logging, # to have a debugging-friendly timezone widget, debug logging,
# and no intrusive timezone-setting while clicking around. # and no intrusive timezone-setting while clicking around.

View File

@ -113,28 +113,32 @@ QList< Device* > getDevices( DeviceType which, qint64 minimumSize )
// Remove the device which contains / from the list // Remove the device which contains / from the list
for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) for ( DeviceList::iterator it = devices.begin(); it != devices.end(); )
if ( ! ( *it ) || if ( !( *it ) )
( *it )->deviceNode().startsWith( "/dev/zram" ) {
cDebug() << " .. Skipping nullptr device";
it = erase( devices, it);
}
else if ( ( *it )->deviceNode().startsWith( "/dev/zram" )
) )
{ {
cDebug() << " .. Removing zram" << it; cDebug() << " .. Removing zram" << it;
it = erase(devices, it ); it = erase( devices, it );
} }
else if ( writableOnly && hasRootPartition( *it ) ) else if ( writableOnly && hasRootPartition( *it ) )
{ {
cDebug() << " .. Removing device with root filesystem (/) on it" << it; cDebug() << " .. Removing device with root filesystem (/) on it" << it;
it = erase(devices, it ); it = erase( devices, it );
} }
else if ( writableOnly && isIso9660( *it ) ) else if ( writableOnly && isIso9660( *it ) )
{ {
cDebug() << " .. Removing device with iso9660 filesystem (probably a CD) on it" << it; cDebug() << " .. Removing device with iso9660 filesystem (probably a CD) on it" << it;
it = erase(devices, it ); it = erase( devices, it );
} }
else if ( (minimumSize >= 0) && !( (*it)->capacity() > minimumSize ) ) else if ( (minimumSize >= 0) && !( (*it)->capacity() > minimumSize ) )
{ {
cDebug() << " .. Removing too-small" << it; cDebug() << " .. Removing too-small" << it;
it = erase(devices, it ); it = erase( devices, it );
} }
else else
++it; ++it;

View File

@ -509,17 +509,8 @@ PartitionCoreModule::jobs() const
lst << info->jobs; lst << info->jobs;
devices << info->device.data(); devices << info->device.data();
} }
cDebug() << "Creating FillGlobalStorageJob with bootLoader path" << m_bootLoaderInstallPath;
lst << Calamares::job_ptr( new FillGlobalStorageJob( devices, m_bootLoaderInstallPath ) ); lst << Calamares::job_ptr( new FillGlobalStorageJob( devices, m_bootLoaderInstallPath ) );
QStringList jobsDebug;
foreach ( auto job, lst )
jobsDebug.append( job->prettyName() );
cDebug() << "PartitionCodeModule has been asked for jobs. About to return:"
<< jobsDebug.join( "\n" );
return lst; return lst;
} }

View File

@ -1209,6 +1209,13 @@ force_uncheck(QButtonGroup* grp, PrettyRadioButton* button)
grp->setExclusive( true ); grp->setExclusive( true );
} }
static inline QDebug&
operator <<( QDebug& s, PartitionIterator& it )
{
s << ( ( *it ) ? ( *it )->deviceNode() : QString( "<null device>" ) );
return s;
}
/** /**
* @brief ChoicePage::setupActions happens every time a new Device* is selected in the * @brief ChoicePage::setupActions happens every time a new Device* is selected in the
* device picker. Sets up the text and visibility of the partitioning actions based * device picker. Sets up the text and visibility of the partitioning actions based
@ -1222,6 +1229,9 @@ ChoicePage::setupActions()
OsproberEntryList osproberEntriesForCurrentDevice = OsproberEntryList osproberEntriesForCurrentDevice =
getOsproberEntriesForDevice( currentDevice ); getOsproberEntriesForDevice( currentDevice );
cDebug() << "Setting up actions for" << currentDevice->deviceNode()
<< "with" << osproberEntriesForCurrentDevice.count() << "entries.";
if ( currentDevice->partitionTable() ) if ( currentDevice->partitionTable() )
m_deviceInfoWidget->setPartitionTableType( currentDevice->partitionTable()->type() ); m_deviceInfoWidget->setPartitionTableType( currentDevice->partitionTable()->type() );
else else
@ -1238,18 +1248,30 @@ ChoicePage::setupActions()
#ifdef WITH_KPMCOREGT33 #ifdef WITH_KPMCOREGT33
if ( currentDevice->type() == Device::Type::SoftwareRAID_Device && if ( currentDevice->type() == Device::Type::SoftwareRAID_Device &&
static_cast< SoftwareRAID* >(currentDevice)->status() == SoftwareRAID::Status::Inactive ) static_cast< SoftwareRAID* >(currentDevice)->status() == SoftwareRAID::Status::Inactive )
{
cDebug() << ".. part of an inactive RAID device";
isInactiveRAID = true; isInactiveRAID = true;
}
#endif #endif
for ( auto it = PartitionIterator::begin( currentDevice ); for ( auto it = PartitionIterator::begin( currentDevice );
it != PartitionIterator::end( currentDevice ); ++it ) it != PartitionIterator::end( currentDevice ); ++it )
{ {
if ( PartUtils::canBeResized( *it ) ) if ( PartUtils::canBeResized( *it ) )
{
cDebug() << ".. contains resizable" << it;
atLeastOneCanBeResized = true; atLeastOneCanBeResized = true;
}
if ( PartUtils::canBeReplaced( *it ) ) if ( PartUtils::canBeReplaced( *it ) )
{
cDebug() << ".. contains replacable" << it;
atLeastOneCanBeReplaced = true; atLeastOneCanBeReplaced = true;
}
if ( (*it)->isMounted() ) if ( (*it)->isMounted() )
{
cDebug() << ".. contains mounted" << it;
atLeastOneIsMounted = true; atLeastOneIsMounted = true;
}
} }
if ( osproberEntriesForCurrentDevice.count() == 0 ) if ( osproberEntriesForCurrentDevice.count() == 0 )
@ -1366,7 +1388,12 @@ ChoicePage::setupActions()
if ( !atLeastOneIsMounted && !isInactiveRAID ) if ( !atLeastOneIsMounted && !isInactiveRAID )
m_eraseButton->show(); // None mounted m_eraseButton->show(); // None mounted
else else
{
cDebug() << "Erase button suppressed"
<< "mount?" << atLeastOneIsMounted
<< "raid?" << isInactiveRAID;
force_uncheck( m_grp, m_eraseButton ); force_uncheck( m_grp, m_eraseButton );
}
bool isEfi = PartUtils::isEfiSystem(); bool isEfi = PartUtils::isEfiSystem();
bool efiSystemPartitionFound = !m_core->efiSystemPartitions().isEmpty(); bool efiSystemPartitionFound = !m_core->efiSystemPartitions().isEmpty();

View File

@ -20,6 +20,8 @@
#include "jobs/CreatePartitionTableJob.h" #include "jobs/CreatePartitionTableJob.h"
#include "core/PartitionIterator.h"
#include "utils/Logger.h" #include "utils/Logger.h"
// KPMcore // KPMcore
@ -65,6 +67,14 @@ CreatePartitionTableJob::prettyStatusMessage() const
} }
static inline QDebug&
operator <<( QDebug& s, PartitionIterator& it )
{
s << ( ( *it ) ? ( *it )->deviceNode() : QString( "<null device>" ) );
return s;
}
Calamares::JobResult Calamares::JobResult
CreatePartitionTableJob::exec() CreatePartitionTableJob::exec()
{ {
@ -73,21 +83,28 @@ CreatePartitionTableJob::exec()
PartitionTable* table = m_device->partitionTable(); PartitionTable* table = m_device->partitionTable();
cDebug() << "Creating new partition table of type" << table->typeName() cDebug() << "Creating new partition table of type" << table->typeName()
<< ", uncommitted yet:\n" << table; << ", uncommitted yet:";
QProcess lsblk; if ( Logger::logLevelEnabled( Logger::LOGDEBUG ) )
lsblk.setProgram( "lsblk" ); {
lsblk.setProcessChannelMode( QProcess::MergedChannels ); for ( auto it = PartitionIterator::begin( table );
lsblk.start(); it != PartitionIterator::end( table ); ++it )
lsblk.waitForFinished(); cDebug() << *it;
cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput();
QProcess mount; QProcess lsblk;
mount.setProgram( "mount" ); lsblk.setProgram( "lsblk" );
mount.setProcessChannelMode( QProcess::MergedChannels ); lsblk.setProcessChannelMode( QProcess::MergedChannels );
mount.start(); lsblk.start();
mount.waitForFinished(); lsblk.waitForFinished();
cDebug() << "mount:\n" << mount.readAllStandardOutput(); cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput();
QProcess mount;
mount.setProgram( "mount" );
mount.setProcessChannelMode( QProcess::MergedChannels );
mount.start();
mount.waitForFinished();
cDebug() << "mount:\n" << mount.readAllStandardOutput();
}
CreatePartitionTableOperation op(*m_device, table); CreatePartitionTableOperation op(*m_device, table);
op.setStatus(Operation::StatusRunning); op.setStatus(Operation::StatusRunning);

View File

@ -56,9 +56,12 @@ findPartitionUuids( QList < Device* > devices )
QString path = p->partitionPath(); QString path = p->partitionPath();
QString uuid = p->fileSystem().readUUID( p->partitionPath() ); QString uuid = p->fileSystem().readUUID( p->partitionPath() );
hash.insert( path, uuid ); hash.insert( path, uuid );
cDebug() << ".. added path=" << path << "UUID=" << uuid;
} }
} }
cDebug() << hash;
if ( hash.isEmpty() )
cDebug() << ".. no UUIDs found.";
return hash; return hash;
} }
@ -90,10 +93,16 @@ mapForPartition( Partition* partition, const QString& uuid )
dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ) dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() )
map[ "fs" ] = dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS()->name(); map[ "fs" ] = dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS()->name();
map[ "uuid" ] = uuid; map[ "uuid" ] = uuid;
cDebug() << partition->partitionPath()
<< "mtpoint:" << PartitionInfo::mountPoint( partition ) // Debugging for inside the loop in createPartitionList(),
<< "fs:" << map[ "fs" ] << '(' << map[ "fsName" ] << ')' // so indent a bit
<< uuid; Logger::CLog deb = cDebug();
using TR = Logger::DebugRow<const char *const, const QString&>;
deb << " .. mapping for" << partition->partitionPath() << partition->deviceNode()
<< TR( "mtpoint:", PartitionInfo::mountPoint( partition ) )
<< TR( "fs:", map[ "fs" ].toString() )
<< TR( "fsname", map[ "fsName" ].toString() )
<< TR( "uuid", uuid );
if ( partition->roles().has( PartitionRole::Luks ) ) if ( partition->roles().has( PartitionRole::Luks ) )
{ {
@ -104,7 +113,7 @@ mapForPartition( Partition* partition, const QString& uuid )
map[ "luksMapperName" ] = luksFs->mapperName().split( "/" ).last(); map[ "luksMapperName" ] = luksFs->mapperName().split( "/" ).last();
map[ "luksUuid" ] = getLuksUuid( partition->partitionPath() ); map[ "luksUuid" ] = getLuksUuid( partition->partitionPath() );
map[ "luksPassphrase" ] = luksFs->passphrase(); map[ "luksPassphrase" ] = luksFs->passphrase();
cDebug() << "luksMapperName:" << map[ "luksMapperName" ]; deb << TR( "luksMapperName:", map[ "luksMapperName" ].toString() );
} }
} }
@ -215,9 +224,11 @@ FillGlobalStorageJob::createPartitionList() const
cDebug() << "Writing to GlobalStorage[\"partitions\"]"; cDebug() << "Writing to GlobalStorage[\"partitions\"]";
for ( auto device : m_devices ) for ( auto device : m_devices )
{ {
cDebug() << ".. partitions on" << device->deviceNode();
for ( auto it = PartitionIterator::begin( device ); for ( auto it = PartitionIterator::begin( device );
it != PartitionIterator::end( device ); ++it ) it != PartitionIterator::end( device ); ++it )
{ {
// Debug-logging is done when creating the map
lst << mapForPartition( *it, hash.value( ( *it )->partitionPath() ) ); lst << mapForPartition( *it, hash.value( ( *it )->partitionPath() ) );
} }
} }

View File

@ -132,6 +132,10 @@ SetPartFlagsJob::prettyStatusMessage() const
Calamares::JobResult Calamares::JobResult
SetPartFlagsJob::exec() SetPartFlagsJob::exec()
{ {
cDebug() << "Setting flags on" << m_device->deviceNode()
<< "partition" << partition()->deviceNode()
<< "to" << m_flags;
Report report ( nullptr ); Report report ( nullptr );
SetPartFlagsOperation op( *m_device, *partition(), m_flags ); SetPartFlagsOperation op( *m_device, *partition(), m_flags );
op.setStatus( Operation::StatusRunning ); op.setStatus( Operation::StatusRunning );

View File

@ -1,6 +1,4 @@
find_package( Qt5 COMPONENTS Gui Test REQUIRED ) find_package( Qt5 COMPONENTS Gui REQUIRED )
include( ECMAddTests )
set( PartitionModule_SOURCE_DIR .. ) set( PartitionModule_SOURCE_DIR .. )
@ -23,13 +21,15 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}
) )
ecm_add_test( ${partitionjobtests_SRCS} if( ECM_FOUND AND BUILD_TESTING )
TEST_NAME partitionjobtests ecm_add_test( ${partitionjobtests_SRCS}
LINK_LIBRARIES TEST_NAME partitionjobtests
${CALAMARES_LIBRARIES} LINK_LIBRARIES
kpmcore ${CALAMARES_LIBRARIES}
Qt5::Core kpmcore
Qt5::Test Qt5::Core
) Qt5::Test
)
set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE ) set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE )
endif()

View File

@ -4,6 +4,7 @@ calamares_add_plugin( preservefiles
TYPE job TYPE job
EXPORT_MACRO PLUGINDLLEXPORT_PRO EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES SOURCES
permissions.cpp
PreserveFiles.cpp PreserveFiles.cpp
LINK_PRIVATE_LIBRARIES LINK_PRIVATE_LIBRARIES
calamares calamares

View File

@ -18,6 +18,8 @@
#include "PreserveFiles.h" #include "PreserveFiles.h"
#include "permissions.h"
#include "CalamaresVersion.h" #include "CalamaresVersion.h"
#include "JobQueue.h" #include "JobQueue.h"
#include "GlobalStorage.h" #include "GlobalStorage.h"
@ -83,6 +85,38 @@ PreserveFiles::prettyName() const
return tr( "Saving files for later ..." ); return tr( "Saving files for later ..." );
} }
static bool
copy_file( const QString& source, const QString& dest )
{
QFile sourcef( source );
if ( !sourcef.open( QFile::ReadOnly ) )
{
cWarning() << "Could not read" << source;
return false;
}
QFile destf( dest );
if ( !destf.open( QFile::WriteOnly ) )
{
sourcef.close();
cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source;
return false;
}
QByteArray b;
do
{
b = sourcef.read( 1_MiB );
destf.write( b );
}
while ( b.count() > 0 );
sourcef.close();
destf.close();
return true;
}
Calamares::JobResult PreserveFiles::exec() Calamares::JobResult PreserveFiles::exec()
{ {
if ( m_items.isEmpty() ) if ( m_items.isEmpty() )
@ -96,7 +130,8 @@ Calamares::JobResult PreserveFiles::exec()
for ( const auto& it : m_items ) for ( const auto& it : m_items )
{ {
QString source = it.source; QString source = it.source;
QString dest = prefix + atReplacements( it.dest ); QString bare_dest = atReplacements( it.dest );
QString dest = prefix + bare_dest;
if ( it.type == ItemType::Log ) if ( it.type == ItemType::Log )
source = Logger::logFile(); source = Logger::logFile();
@ -111,32 +146,29 @@ Calamares::JobResult PreserveFiles::exec()
cWarning() << "Skipping unnamed source file for" << dest; cWarning() << "Skipping unnamed source file for" << dest;
else else
{ {
QFile sourcef( source ); if ( copy_file( source, dest ) )
if ( !sourcef.open( QFile::ReadOnly ) )
{ {
cWarning() << "Could not read" << source; if ( it.perm.isValid() )
continue; {
} auto s_p = CalamaresUtils::System::instance();
QFile destf( dest ); int r;
if ( !destf.open( QFile::WriteOnly ) )
{
sourcef.close();
cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source;
continue;
}
QByteArray b; r = s_p->targetEnvCall( QStringList{ "chown", it.perm.username(), bare_dest } );
do if ( r )
{ cWarning() << "Could not chown target" << bare_dest;
b = sourcef.read( 1_MiB );
destf.write( b );
}
while ( b.count() > 0 );
sourcef.close(); r = s_p->targetEnvCall( QStringList{ "chgrp", it.perm.group(), bare_dest } );
destf.close(); if ( r )
++count; cWarning() << "Could not chgrp target" << bare_dest;
r = s_p->targetEnvCall( QStringList{ "chmod", it.perm.octal(), bare_dest } );
if ( r )
cWarning() << "Could not chmod target" << bare_dest;
}
++count;
}
} }
} }
@ -160,6 +192,10 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap)
return; return;
} }
QString defaultPermissions = configurationMap[ "perm" ].toString();
if ( defaultPermissions.isEmpty() )
defaultPermissions = QStringLiteral( "root:root:0400" );
QVariantList l = files.toList(); QVariantList l = files.toList();
unsigned int c = 0; unsigned int c = 0;
for ( const auto& li : l ) for ( const auto& li : l )
@ -168,7 +204,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap)
{ {
QString filename = li.toString(); QString filename = li.toString();
if ( !filename.isEmpty() ) if ( !filename.isEmpty() )
m_items.append( Item{ filename, filename, ItemType::Path } ); m_items.append( Item{ filename, filename, Permissions( defaultPermissions ), ItemType::Path } );
else else
cDebug() << "Empty filename for preservefiles, item" << c; cDebug() << "Empty filename for preservefiles, item" << c;
} }
@ -181,6 +217,9 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap)
( from == "log" ) ? ItemType::Log : ( from == "log" ) ? ItemType::Log :
( from == "config" ) ? ItemType::Config : ( from == "config" ) ? ItemType::Config :
ItemType::None; ItemType::None;
QString perm = map[ "perm" ].toString();
if ( perm.isEmpty() )
perm = defaultPermissions;
if ( dest.isEmpty() ) if ( dest.isEmpty() )
{ {
@ -192,7 +231,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap)
} }
else else
{ {
m_items.append( Item{ QString(), dest, t } ); m_items.append( Item{ QString(), dest, Permissions( perm ), t } );
} }
} }
else else

View File

@ -24,11 +24,11 @@
#include <QVariantMap> #include <QVariantMap>
#include "CppJob.h" #include "CppJob.h"
#include "PluginDllMacro.h"
#include "utils/PluginFactory.h" #include "utils/PluginFactory.h"
#include "PluginDllMacro.h" #include "permissions.h"
class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob
{ {
@ -46,6 +46,7 @@ class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob
{ {
QString source; QString source;
QString dest; QString dest;
Permissions perm;
ItemType type; ItemType type;
} ; } ;

View File

@ -0,0 +1,75 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright (C) 2018 Scott Harvey <scott@spharvey.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <QString>
#include <QStringList>
#include "permissions.h"
Permissions::Permissions() :
m_username(),
m_group(),
m_valid(false),
m_value(0)
{
}
Permissions::Permissions(QString p) : Permissions()
{
parsePermissions(p);
}
void Permissions::parsePermissions(const QString& p) {
QStringList segments = p.split(":");
if (segments.length() != 3) {
m_valid = false;
return;
}
if (segments[0].isEmpty() || segments[1].isEmpty()) {
m_valid = false;
return;
}
bool ok;
int octal = segments[2].toInt(&ok, 8);
if (!ok || octal == 0) {
m_valid = false;
return;
} else {
m_value = octal;
}
// We have exactly three segments and the third is valid octal,
// so we can declare the string valid and set the user and group names
m_valid = true;
m_username = segments[0];
m_group = segments[1];
return;
}

View File

@ -0,0 +1,62 @@
/* === This file is part of Calamares - <https://github.com/calamares> ===
*
* Copyright (C) 2018 Scott Harvey <scott@spharvey.me>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PERMISSIONS_H
#define PERMISSIONS_H
#include <QString>
/**
* @brief The Permissions class takes a QString @p in the form of
* <user>:<group>:<permissions>, checks it for validity, and makes the three
* components available indivdually.
*/
class Permissions
{
public:
/** @brief Constructor
*
* Splits the string @p at the colon (":") into separate elements for
* <user>, <group>, and <value> (permissions), where <value> is returned as
* an **octal** integer.
*/
Permissions(QString p);
/** @brief Default constructor of an invalid Permissions. */
Permissions();
bool isValid() const { return m_valid; }
QString username() const { return m_username; }
QString group() const { return m_group; }
int value() const { return m_value; }
QString octal() const { return QString::number( m_value, 8 ); }
private:
void parsePermissions(QString const &p);
QString m_username;
QString m_group;
bool m_valid;
int m_value;
};
#endif // PERMISSIONS_H

View File

@ -9,13 +9,18 @@
# as the source). # as the source).
# - a map with a *dest* key. The *dest* value is a path interpreted in the # - a map with a *dest* key. The *dest* value is a path interpreted in the
# target system (if dontChroot is true, in the host system). Relative paths # target system (if dontChroot is true, in the host system). Relative paths
# are not recommended. There are two possible other keys in the map: # are not recommended. There are three possible other keys in the map:
# - *from*, which must have one of the values, below; it is used to # - *from*, which must have one of the values, below; it is used to
# preserve files whose pathname is known to Calamares internally. # preserve files whose pathname is known to Calamares internally.
# - *src*, to refer to a path interpreted in the host system. Relative # - *src*, to refer to a path interpreted in the host system. Relative
# paths are not recommended, and are interpreted relative to where # paths are not recommended, and are interpreted relative to where
# Calamares is being run. # Calamares is being run.
# Only one of the two other keys (either *from* or *src*) may be set. # - *perm*, is a colon-separated tuple of <user>:<group>:<mode>
# where <mode> is in octal (e.g. 4777 for wide-open, 0400 for read-only
# by owner). If set, the file's ownership and permissions are set to
# those values within the target system; if not set, no permissions
# are changed.
# Only one of the two source keys (either *from* or *src*) may be set.
# #
# The target filename is modified as follows: # The target filename is modified as follows:
# - `@@ROOT@@` is replaced by the path to the target root (may be /) # - `@@ROOT@@` is replaced by the path to the target root (may be /)
@ -32,5 +37,13 @@ files:
- /etc/oem-information - /etc/oem-information
- from: log - from: log
dest: /root/install.log dest: /root/install.log
perm: root:wheel:644
- from: config - from: config
dest: /root/install.cfg dest: /root/install.cfg
perm: root:wheel:400
# The *perm* key contains a default value to apply to all files listed
# above that do not have a *perm* key of their own. If not set,
# root:root:0400 (highly restrictive) is used.
#
# perm: "root:root:0400"

View File

@ -8,10 +8,7 @@ calamares_add_plugin( shellprocess
SHARED_LIB SHARED_LIB
) )
if( ECM_FOUND ) if( ECM_FOUND AND BUILD_TESTING )
find_package( Qt5 COMPONENTS Test REQUIRED )
include( ECMAddTests )
ecm_add_test( ecm_add_test(
Tests.cpp Tests.cpp
TEST_NAME TEST_NAME

View File

@ -1,9 +1,4 @@
find_package(ECM ${ECM_VERSION} NO_MODULE) find_package( Qt5 COMPONENTS Core REQUIRED )
if( ECM_FOUND )
include( ECMAddTests )
endif()
find_package( Qt5 COMPONENTS Core Test REQUIRED )
find_package( Crypt REQUIRED ) find_package( Crypt REQUIRED )
# Add optional libraries here # Add optional libraries here
@ -44,7 +39,7 @@ calamares_add_plugin( users
SHARED_LIB SHARED_LIB
) )
if( ECM_FOUND ) if( ECM_FOUND AND BUILD_TESTING )
ecm_add_test( ecm_add_test(
PasswordTests.cpp PasswordTests.cpp
SetPasswordJob.cpp SetPasswordJob.cpp