From 21f6ff0e60371074f1fe99c34506b5269a37ee02 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 7 Jun 2019 10:44:01 +0200 Subject: [PATCH 01/17] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_es_MX.ts | 12 ++-- lang/calamares_fi_FI.ts | 148 ++++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/lang/calamares_es_MX.ts b/lang/calamares_es_MX.ts index 5b1556a12..f3411597f 100644 --- a/lang/calamares_es_MX.ts +++ b/lang/calamares_es_MX.ts @@ -854,17 +854,17 @@ El instalador terminará y se perderán todos los cambios. Deactivate volume group named %1. - + Desactivar el grupo de volúmenes llamado%1. Deactivate volume group named <strong>%1</strong>. - + Desactivar el grupo de volúmenes llamado<strong>% 1</strong>. The installer failed to deactivate a volume group named %1. - + El instalador no pudo desactivar un grupo de volúmenes llamado%1. @@ -1098,7 +1098,7 @@ El instalador terminará y se perderán todos los cambios. <Restart checkbox tooltip> - + <Restart checkbox tooltip> @@ -1108,12 +1108,12 @@ El instalador terminará y se perderán todos los cambios. <h1>All done.</h1><br/>%1 has been set up on your computer.<br/>You may now start using your new system. - + <h1>Todo listo.</h1><br/>% 1 se ha configurado en su computadora. <br/>Ahora puede comenzar a usar su nuevo sistema. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> - + <html><head/><body><p>Cuando esta casilla está marcada, su sistema se reiniciará inmediatamente cuando haga clic en <span style="font-style:italic;">Listo</span> o cierre el programa de instalación.</p></body></html> diff --git a/lang/calamares_fi_FI.ts b/lang/calamares_fi_FI.ts index e85ee3b06..c2868130d 100644 --- a/lang/calamares_fi_FI.ts +++ b/lang/calamares_fi_FI.ts @@ -63,7 +63,7 @@ GlobalStorage - + Globaali-tallennus @@ -1392,63 +1392,63 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. <strong>%1 driver</strong><br/>by %2 %1 is an untranslatable product name, example: Creative Audigy driver - + <strong>%1 ajuri</strong><br/>- %2 <strong>%1 graphics driver</strong><br/><font color="Grey">by %2</font> %1 is usually a vendor name, example: Nvidia graphics driver - + <strong>%1 näytönohjaimet</strong><br/><font color="Grey">- %2</font> <strong>%1 browser plugin</strong><br/><font color="Grey">by %2</font> - + <strong>%1 selaimen laajennus</strong><br/><font color="Grey">- %2</font> <strong>%1 codec</strong><br/><font color="Grey">by %2</font> - + <strong>%1 kodekki</strong><br/><font color="Grey">- %2</font> <strong>%1 package</strong><br/><font color="Grey">by %2</font> - + <strong>%1 paketti</strong><br/><font color="Grey">- %2</font> <strong>%1</strong><br/><font color="Grey">by %2</font> - + <strong>%1</strong><br/><font color="Grey">- %2</font> Shows the complete license text - + Näyttää täydellisen lisenssin tekstin Hide license text - + Piilota lisenssin teksti Show license agreement - + Näytä lisenssisopimus Hide license agreement - + Piilota lisenssisopimus Opens the license agreement in a browser window. - + Avaa lisenssisopimus selaimessa. <a href="%1">View license agreement</a> - + <a href="%1">Näytä lisenssisopimus</a> @@ -1456,12 +1456,12 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. The system language will be set to %1. - + Järjestelmän kielen asetuksena on %1. The numbers and dates locale will be set to %1. - + Numerot ja päivämäärät, paikallinen asetus on %1. @@ -1513,12 +1513,12 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Network Installation. (Disabled: Unable to fetch package lists, check your network connection) - + Verkkoasennus. (Ei käytössä: Pakettiluetteloita ei voi hakea, tarkista verkkoyhteys) Network Installation. (Disabled: Received invalid groups data) - + Verkkoasennus. (Ei käytössä: Vastaanotettiin virheellisiä ryhmän tietoja) @@ -1534,17 +1534,17 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Ba&tch: - + Ba&tch: <html><head/><body><p>Enter a batch-identifier here. This will be stored in the target system.</p></body></html> - + <html><head/><body><p>Syötä erän tunniste tähän. Tämä tallennetaan kohdejärjestelmään.</p></body></html> <html><head/><body><h1>OEM Configuration</h1><p>Calamares will use OEM settings while configuring the target system.</p></body></html> - + <html><head/><body><h1>OEM asetukset</h1><p>Calamares käyttää OEM-asetuksia määritettäessä kohdejärjestelmää.</p></body></html> @@ -1557,7 +1557,7 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Set the OEM Batch Identifier to <code>%1</code>. - + Aseta OEM valmistajan erän tunnus <code>%1</code>. @@ -1580,92 +1580,92 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Memory allocation error when setting '%1' - + Muistin varausvirhe asetettaessa '%1' Memory allocation error - + Muistin varausvirhe The password is the same as the old one - + Salasana on sama kuin vanha The password is a palindrome - + Salasana on palindromi The password differs with case changes only - + Salasana eroaa vain vähäisin muutoksin The password is too similar to the old one - + Salasana on liian samanlainen kuin vanha The password contains the user name in some form - + Salasana sisältää jonkin käyttäjänimen The password contains words from the real name of the user in some form - + Salasana sisältää sanoja käyttäjän todellisesta nimestä jossain muodossa The password contains forbidden words in some form - + Salasana sisältää kiellettyjä sanoja The password contains less than %1 digits - + Salasana sisältää vähemmän kuin %1 numeroa The password contains too few digits - + Salasana sisältää liian vähän numeroita The password contains less than %1 uppercase letters - + Salasana sisältää vähemmän kuin %1 isoja kirjaimia The password contains too few uppercase letters - + Salasana sisältää liian vähän isoja kirjaimia The password contains less than %1 lowercase letters - + Salasana sisältää vähemmän kuin %1 pieniä kirjaimia The password contains too few lowercase letters - + Salasana sisältää liian vähän pieniä kirjaimia The password contains less than %1 non-alphanumeric characters - + Salasanassa on vähemmän kuin %1 erikoismerkkiä The password contains too few non-alphanumeric characters - + Salasana sisältää liian vähän erikoismerkkejä The password is shorter than %1 characters - + Salasana on lyhyempi kuin %1 merkkiä @@ -1675,47 +1675,47 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. The password is just rotated old one - + Salasana on vain vanhan pyöritystä The password contains less than %1 character classes - + Salasana sisältää vähemmän kuin %1 merkkiluokkaa The password does not contain enough character classes - + Salasana ei sisällä tarpeeksi merkkiluokkia The password contains more than %1 same characters consecutively - + Salasana sisältää enemmän kuin %1 samaa merkkiä peräkkäin The password contains too many same characters consecutively - + Salasana sisältää liian monta samaa merkkiä peräkkäin The password contains more than %1 characters of the same class consecutively - + Salasana sisältää enemmän kuin %1 merkkiä samasta luokasta peräkkäin The password contains too many characters of the same class consecutively - + Salasana sisältää liian monta saman luokan merkkiä peräkkäin The password contains monotonic sequence longer than %1 characters - + Salasana sisältää monotonisen merkkijonon, joka on pidempi kuin %1 merkkiä The password contains too long of a monotonic character sequence - + Salasanassa on liian pitkä monotoninen merkkijono @@ -1725,72 +1725,72 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Cannot obtain random numbers from the RNG device - + Satunnaislukuja ei voi saada RNG-laitteesta Password generation failed - required entropy too low for settings - + Salasanojen luonti epäonnistui - pakollinen vähimmäistaso liian alhainen asetuksia varten The password fails the dictionary check - %1 - + Salasana epäonnistui sanaston tarkistuksessa -%1 The password fails the dictionary check - + Salasana epäonnistui sanaston tarkistuksessa Unknown setting - %1 - + Tuntematon asetus - %1 Unknown setting - + Tuntematon asetus Bad integer value of setting - %1 - + Asetuksen virheellinen kokonaisluku - %1 Bad integer value - + Virheellinen kokonaisluku Setting %1 is not of integer type - + Asetus %1 ei ole kokonaisluku Setting is not of integer type - + Asetus ei ole kokonaisluku Setting %1 is not of string type - + Asetus %1 ei ole merkkijono Setting is not of string type - + Asetus ei ole merkkijono Opening the configuration file failed - + Määritystiedoston avaaminen epäonnistui The configuration file is malformed - + Määritystiedosto on väärin muotoiltu @@ -1861,12 +1861,12 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Log in automatically without asking for the password. - + Kirjaudu automaattisesti ilman salasanaa. Use the same password for the administrator account. - + Käytä pääkäyttäjän tilillä samaa salasanaa. @@ -1968,7 +1968,7 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Storage de&vice: - + Tallennus&laite: @@ -1983,7 +1983,7 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Cre&ate - + Luo& @@ -1998,27 +1998,27 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. New Volume Group - + Uusi aseman ryhmä Resize Volume Group - + Muuta kokoa aseman-ryhmässä Deactivate Volume Group - + Poista asemaryhmä käytöstä Remove Volume Group - + Poista asemaryhmä I&nstall boot loader on: - + A&senna käynnistyslatain: @@ -2028,12 +2028,12 @@ Asennusohjelma sulkeutuu ja kaikki muutoksesi katoavat. Can not create new partition - + Ei voi luoda uutta osiota 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. - + %1 osio-taulukossa on jo %2 ensisijaista osiota, eikä sitä voi lisätä. Poista yksi ensisijainen osio ja lisää laajennettu osio. @@ -2518,7 +2518,7 @@ Ulostulo: Resize Volume Group - + Muuta kokoa aseman-ryhmässä From bbc0edecd3b65b05d26090609d901a6f915c1d7b Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 7 Jun 2019 10:44:01 +0200 Subject: [PATCH 02/17] i18n: [dummypythonqt] Automatic merge of Transifex translations --- .../lang/be/LC_MESSAGES/dummypythonqt.mo | Bin 1118 -> 1118 bytes .../lang/be/LC_MESSAGES/dummypythonqt.po | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/dummypythonqt/lang/be/LC_MESSAGES/dummypythonqt.mo b/src/modules/dummypythonqt/lang/be/LC_MESSAGES/dummypythonqt.mo index 42cb16abd89b83fccdabd2a929ca6310f2605303..2a7ecc372f48d28bb36e268d93b0a2eb66209172 100644 GIT binary patch delta 24 fcmcb|agSreBS!AL#Nv#SoYLIH, YEAR. # # Translators: -# Zmicer Turok , 2018 +# Zmicer Turok , 2018 # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2018-10-05 11:34-0400\n" +"POT-Creation-Date: 2019-05-10 19:18-0400\n" "PO-Revision-Date: 2016-12-16 12:18+0000\n" -"Last-Translator: Zmicer Turok , 2018\n" +"Last-Translator: Zmicer Turok , 2018\n" "Language-Team: Belarusian (https://www.transifex.com/calamares/teams/20061/be/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" From a7e5488f77aa2672963489d7a8ed1053f330137a Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 7 Jun 2019 10:44:02 +0200 Subject: [PATCH 03/17] i18n: [python] Automatic merge of Transifex translations --- lang/python/fi_FI/LC_MESSAGES/python.mo | Bin 1309 -> 2126 bytes lang/python/fi_FI/LC_MESSAGES/python.po | 20 ++++++++++---------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lang/python/fi_FI/LC_MESSAGES/python.mo b/lang/python/fi_FI/LC_MESSAGES/python.mo index cc21c37d47137a9ff7e2c90b27323aaa09535ba3..02ef2d1f4f60884793171cc5ed03c87c770811f1 100644 GIT binary patch literal 2126 zcmZ{k%WoS+9LEO;FH>Fx#9RCtaY#zmc0vWIOAu}26q7oQ(xiwJ8oXnByt^~Y%&c9j zlq*LN65`6iXAT^CK;nWqaiV_!75oz*aX@@$*WM%rMw@O%Q9+-jF6b8*y_F*Y65Kuu$`Ddz-T+B>*V zJuqHXHRoHS#svaegRMK@)sjF;L+BD{4O1R=ZVeZmA;+CZ9=p>DW6Kspal8~H+ zNh+kd_g%Y!^N}E%89`&6QJ)V5xjts{@N{k9w2m#J*NLD8GOgn=WE~NiDZffG@f#Lz z++1W^GLF5yS(=BS@X1zLt2phKLhg8#wSA`iu*?p2?dW;fsb>VtH-~DgY}e?Hu$Bs! z*paB`y6DC!dy_&fEcr}|>(V-Qpo%Nu^FgIG#*S5oxT<4b+pQ5Ze6f%xUw;K+B9feCW)r)Y=EgOqqhhiz@GUVme?)|DS_wQ9?icB|by^m(;fuizFtpfEcQsr;sm@WS z&y5vs<6wU)SU=q7wRMFFnz)4_Qrw{RkEAPYZXjFGRoRVEdvUO(O=26Q(tKz)*3MD! zyRoF`)CR3CpR2HUGp#g5();PgHbrVhUfh93pi$Yy29ZuDY1R)>0+Eg|pK_(ytdc32 zPNowS?AQ*a=?k{Y&TjqzJWjy4)8@GtkmG&RP2|k@N9% zGAr*R6Z85`3$?C1ES#63j@9_ibTW3+TdI$egVS6cafoy*Da|tHgz&3Ev8JSWdTZ>) zYV3~H_>h|f!Qv|<9Mq7NDvM)ITK&7uBW#hxtxyVonc{3a8$xrMnTRJ|5BUIVf7e_l zi-O2YPB>Y zFGh>Hm&dgKf0puRU?v5U5^gPLE!4N;|7GBG;wUPj?aisO;&C|UX?|aDpF+HDJbxhm E0S(24^Z)<= delta 349 zcmX}nu}eZx6vy%7eflgLe43J!#3KU1!9AiO8k-ah8Y7e5ppSabz{%0k;Uct%OaFnB zLz6=Y)#hl>AJEWJEkWN~j}H9!z`6IHd+)O|O7&i{@u5&_q)0-NA&(YSj89Sj3z;i6F||Ty3FCe%6}gJ$v)nHUDTySbg@2CD+HF5{TYkf9cHQ9O`o=rg sSL#rIs=gjr`N@a%5Yt(^pzHR5UfSdI>1D$U!r7hc2c92R^mnrQ0~l8>cK`qY diff --git a/lang/python/fi_FI/LC_MESSAGES/python.po b/lang/python/fi_FI/LC_MESSAGES/python.po index 3905c909a..4348bb437 100644 --- a/lang/python/fi_FI/LC_MESSAGES/python.po +++ b/lang/python/fi_FI/LC_MESSAGES/python.po @@ -120,7 +120,7 @@ msgstr "" #: src/modules/unpackfs/main.py:326 msgid "Bad mount point for root partition" -msgstr "" +msgstr "Huono kiinnityspiste root-osioon" #: src/modules/unpackfs/main.py:327 msgid "rootMountPoint is \"{}\", which does not exist, doing nothing" @@ -129,7 +129,7 @@ msgstr "" #: src/modules/unpackfs/main.py:340 src/modules/unpackfs/main.py:347 #: src/modules/unpackfs/main.py:352 msgid "Bad unsquash configuration" -msgstr "" +msgstr "Huono epäpuhdas kokoonpano" #: src/modules/unpackfs/main.py:341 msgid "The filesystem for \"{}\" ({}) is not supported" @@ -169,19 +169,19 @@ msgstr "" #: src/modules/displaymanager/main.py:602 msgid "Cannot configure LightDM" -msgstr "" +msgstr "LightDM määritysvirhe" #: src/modules/displaymanager/main.py:603 msgid "No LightDM greeter installed." -msgstr "" +msgstr "LightDM ei ole asennettu." #: src/modules/displaymanager/main.py:634 msgid "Cannot write SLIM configuration file" -msgstr "" +msgstr "SLIM-määritystiedostoa ei voi kirjoittaa" #: src/modules/displaymanager/main.py:635 msgid "SLIM config file {!s} does not exist" -msgstr "" +msgstr "SLIM-määritystiedostoa {!s} ei ole olemassa" #: src/modules/displaymanager/main.py:750 msgid "No display managers selected for the displaymanager module." @@ -195,11 +195,11 @@ msgstr "" #: src/modules/displaymanager/main.py:831 msgid "Display manager configuration was incomplete" -msgstr "" +msgstr "Näytönhallinnan kokoonpano oli puutteellinen" #: src/modules/initcpiocfg/main.py:36 msgid "Configuring mkinitcpio." -msgstr "" +msgstr "Määritetään mkinitcpio." #: src/modules/initcpiocfg/main.py:192 #: src/modules/luksopenswaphookcfg/main.py:100 @@ -215,7 +215,7 @@ msgstr "" #: src/modules/initcpio/main.py:47 msgid "Process Failed" -msgstr "" +msgstr "Prosessi epäonnistui" #: src/modules/initcpio/main.py:48 msgid "" @@ -229,7 +229,7 @@ msgstr "" #: src/modules/rawfs/main.py:35 msgid "Installing data." -msgstr "" +msgstr "Asennetaan tietoja." #: src/modules/services-openrc/main.py:38 msgid "Configure OpenRC services" From 0619f1953645e90e3ae3c38506efb22e146adb2c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 10:45:53 +0200 Subject: [PATCH 04/17] CMake: post-release housekeeping --- CHANGES | 10 ++++++++++ CMakeLists.txt | 4 ++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGES b/CHANGES index cf963361c..d1a43c258 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,16 @@ 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.10 (unreleased) # + +This release contains contributions from (alphabetically by first name): + +## Core ## + +## Modules ## + + + # 3.2.9 (2019-06-03) # This release contains contributions from (alphabetically by first name): diff --git a/CMakeLists.txt b/CMakeLists.txt index 11e613710..b1b762172 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,10 +37,10 @@ cmake_minimum_required( VERSION 3.2 FATAL_ERROR ) project( CALAMARES - VERSION 3.2.9 + VERSION 3.2.10 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 ### OPTIONS # From e49beaea91ac2c2842626654f9051fba9dab3cd0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 10:55:03 +0200 Subject: [PATCH 05/17] CMake: switch WITH_PYTHONQT default to OFF --- CHANGES | 6 ++++++ CMakeLists.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index d1a43c258..1ba7ab907 100644 --- a/CHANGES +++ b/CHANGES @@ -9,6 +9,12 @@ This release contains contributions from (alphabetically by first name): ## Core ## + - With this release, option *WITH_PYTHONQT* changes default to **off**. + There does not seem to be any serious use of the PythonQt API and + the UI opportunities it offers, so begin the process of deprecating + and removing that. Sometime in the future, QML pages will fill the + gap for easily-prototyped-yet-slick UI elements. + ## Modules ## diff --git a/CMakeLists.txt b/CMakeLists.txt index b1b762172..882aafe6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ option( INSTALL_CONFIG "Install configuration files" OFF ) option( INSTALL_POLKIT "Install Polkit configuration" ON ) option( BUILD_TESTING "Build the testing tree." ON ) option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON ) -option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." ON ) +option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF ) option( WITH_KF5Crash "Enable crash reporting with KCrash." ON ) From 61b78d88953f01ec0933c50f21a6fb92df16446a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 11:46:08 +0200 Subject: [PATCH 06/17] [libcalamares] Stop job threads before exit - This solves a crash where the thread is destroyed while still running (e.g. cancelling during install). - The thread might not cooperate in being terminated, but then we have a bigger problem anyway (and Calamares will still crash on exit). FIXES #1164 --- src/libcalamares/JobQueue.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/JobQueue.cpp b/src/libcalamares/JobQueue.cpp index 6ef055ffc..3a76aa099 100644 --- a/src/libcalamares/JobQueue.cpp +++ b/src/libcalamares/JobQueue.cpp @@ -44,7 +44,7 @@ public: } virtual ~JobThread() override; - + void setJobs( const JobList& jobs ) { m_jobs = jobs; @@ -157,6 +157,14 @@ JobQueue::JobQueue( QObject* parent ) JobQueue::~JobQueue() { + if ( m_thread->isRunning() ) + { + m_thread->terminate(); + if ( !m_thread->wait(300) ) + cError() << "Could not terminate job thread (expect a crash now)."; + delete m_thread; + } + delete m_storage; } From 92d03c2cf7af34487c3a46f83671dbcc54506f95 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 12:10:22 +0200 Subject: [PATCH 07/17] [libcalamares] Introduce enum class for special process exit values - Replace magic numbers like -3 with named enum values (NoWorkingDirectory, for -3). - Downside is big-ugly static_casts, but that's what you get for having an int as return value for processes. --- .../utils/CalamaresUtilsSystem.cpp | 26 +++++++++---------- src/libcalamares/utils/CalamaresUtilsSystem.h | 24 +++++++++++------ 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 1b603a7e7..0d227c88f 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -114,14 +114,14 @@ System::mount( const QString& devicePath, const QString& options ) { if ( devicePath.isEmpty() || mountPoint.isEmpty() ) - return -3; + return static_cast(ProcessResult::Code::NoWorkingDirectory); QDir mountPointDir( mountPoint ); if ( !mountPointDir.exists() ) { bool ok = mountPointDir.mkpath( mountPoint ); if ( !ok ) - return -3; + return static_cast(ProcessResult::Code::NoWorkingDirectory); } QString program( "mount" ); @@ -147,14 +147,14 @@ System::runCommand( QString output; if ( !Calamares::JobQueue::instance() ) - return -3; + return ProcessResult::Code::NoWorkingDirectory; Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); if ( ( location == System::RunLocation::RunInTarget ) && ( !gs || !gs->contains( "rootMountPoint" ) ) ) { cWarning() << "No rootMountPoint in global storage"; - return -3; + return ProcessResult::Code::NoWorkingDirectory; } QProcess process; @@ -167,7 +167,7 @@ System::runCommand( if ( !QDir( destDir ).exists() ) { cWarning() << "rootMountPoint points to a dir which does not exist"; - return -3; + return ProcessResult::Code::NoWorkingDirectory; } program = "chroot"; @@ -190,7 +190,7 @@ System::runCommand( process.setWorkingDirectory( QDir( workingPath ).absolutePath() ); else cWarning() << "Invalid working directory:" << workingPath; - return -3; + return ProcessResult::Code::NoWorkingDirectory; } cDebug() << "Running" << program << RedactedList( arguments ); @@ -198,7 +198,7 @@ System::runCommand( if ( !process.waitForStarted() ) { cWarning() << "Process failed to start" << process.error(); - return -2; + return ProcessResult::Code::FailedToStart; } if ( !stdInput.isEmpty() ) @@ -211,7 +211,7 @@ System::runCommand( { cWarning().noquote().nospace() << "Timed out. Output so far:\n" << process.readAllStandardOutput(); - return -4; + return ProcessResult::Code::TimedOut; } output.append( QString::fromLocal8Bit( process.readAllStandardOutput() ).trimmed() ); @@ -219,7 +219,7 @@ System::runCommand( if ( process.exitStatus() == QProcess::CrashExit ) { cWarning().noquote().nospace() << "Process crashed. Output so far:\n" << output; - return -1; + return ProcessResult::Code::Crashed; } auto r = process.exitCode(); @@ -306,22 +306,22 @@ ProcessResult::explainProcess( int ec, const QString& command, const QString& ou ? QCoreApplication::translate( "ProcessResult", "\nThere was no output from the command.") : (QCoreApplication::translate( "ProcessResult", "\nOutput:\n") + output); - if ( ec == -1 ) //Crash! + if ( ec == static_cast(ProcessResult::Code::Crashed) ) //Crash! return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command crashed." ), QCoreApplication::translate( "ProcessResult", "Command %1 crashed." ) .arg( command ) + outputMessage ); - if ( ec == -2 ) + if ( ec == static_cast(ProcessResult::Code::FailedToStart) ) return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to start." ), QCoreApplication::translate( "ProcessResult", "Command %1 failed to start." ) .arg( command ) ); - if ( ec == -3 ) + if ( ec == static_cast(ProcessResult::Code::NoWorkingDirectory) ) return JobResult::error( QCoreApplication::translate( "ProcessResult", "Internal error when starting command." ), QCoreApplication::translate( "ProcessResult", "Bad parameters for process job call." ) ); - if ( ec == -4 ) + if ( ec == static_cast(ProcessResult::Code::TimedOut) ) return JobResult::error( QCoreApplication::translate( "ProcessResult", "External command failed to finish." ), QCoreApplication::translate( "ProcessResult", "Command %1 failed to finish in %2 seconds." ) .arg( command ) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.h b/src/libcalamares/utils/CalamaresUtilsSystem.h index 6809859ee..c17d52e93 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.h +++ b/src/libcalamares/utils/CalamaresUtilsSystem.h @@ -32,8 +32,16 @@ namespace CalamaresUtils class ProcessResult : public QPair< int, QString > { public: + enum class Code : int + { + Crashed = -1, // Must match special return values from QProcess + FailedToStart = -2, // Must match special return values from QProcess + NoWorkingDirectory = -3, + TimedOut = -4 + } ; + /** @brief Implicit one-argument constructor has no output, only a return code */ - ProcessResult( int r ) : QPair< int, QString >( r, QString() ) {} + ProcessResult( Code r ) : QPair< int, QString >( static_cast(r), QString() ) {} ProcessResult( int r, QString s ) : QPair< int, QString >( r, s ) {} int getExitCode() const { return first; } @@ -93,9 +101,9 @@ public: * @param filesystemName the name of the filesystem (optional). * @param options any additional options as passed to mount -o (optional). * @returns the program's exit code, or: - * -1 = QProcess crash - * -2 = QProcess cannot start - * -3 = bad arguments + * Crashed = QProcess crash + * FailedToStart = QProcess cannot start + * NoWorkingDirectory = bad arguments */ DLLEXPORT int mount( const QString& devicePath, const QString& mountPoint, @@ -120,10 +128,10 @@ public: * * @returns the program's exit code and its output (if any). Special * exit codes (which will never have any output) are: - * -1 = QProcess crash - * -2 = QProcess cannot start - * -3 = bad arguments - * -4 = QProcess timeout + * Crashed = QProcess crash + * FailedToStart = QProcess cannot start + * NoWorkingDirectory = bad arguments + * TimedOut = QProcess timeout */ static DLLEXPORT ProcessResult runCommand( RunLocation location, From 6055f08affb3e17085044fd14e7d157e558c0637 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 12:30:38 +0200 Subject: [PATCH 08/17] [libcalamares] Refactor ProcessJob - Use the system runCommand() instead of a 90% copy of it. This **does** change the overall command to `env /bin/sh -c` rather than running only `/bin/sh -c`, though. --- src/libcalamares/ProcessJob.cpp | 86 +++++---------------------------- src/libcalamares/ProcessJob.h | 7 +-- 2 files changed, 14 insertions(+), 79 deletions(-) diff --git a/src/libcalamares/ProcessJob.cpp b/src/libcalamares/ProcessJob.cpp index 3cf4eec49..bfdf19860 100644 --- a/src/libcalamares/ProcessJob.cpp +++ b/src/libcalamares/ProcessJob.cpp @@ -67,83 +67,23 @@ ProcessJob::prettyStatusMessage() const JobResult ProcessJob::exec() { - int ec = 0; - QString output; + using CalamaresUtils::System; + if ( m_runInChroot ) - ec = CalamaresUtils::System::instance()-> - targetEnvOutput( m_command, - output, + return CalamaresUtils::System::instance()-> + targetEnvCommand( { m_command }, m_workingPath, QString(), - m_timeoutSec ); + m_timeoutSec ) + .explainProcess( m_command, m_timeoutSec ); else - ec = callOutput( m_command, - output, - m_workingPath, - QString(), - m_timeoutSec ); - - return CalamaresUtils::ProcessResult::explainProcess( ec, m_command, output, m_timeoutSec ); -} - - -int -ProcessJob::callOutput( const QString& command, - QString& output, - const QString& workingPath, - const QString& stdInput, - int timeoutSec ) -{ - output.clear(); - - QProcess process; - process.setProgram( "/bin/sh" ); - process.setArguments( { "-c", command } ); - process.setProcessChannelMode( QProcess::MergedChannels ); - - if ( !workingPath.isEmpty() ) - { - if ( QDir( workingPath ).exists() ) - process.setWorkingDirectory( QDir( workingPath ).absolutePath() ); - else - { - cWarning() << "Invalid working directory:" << workingPath; - return -3; - } - } - - cDebug() << "Running" << command; - process.start(); - if ( !process.waitForStarted() ) - { - cWarning() << "Process failed to start" << process.error(); - return -2; - } - - if ( !stdInput.isEmpty() ) - { - process.write( stdInput.toLocal8Bit() ); - process.closeWriteChannel(); - } - - if ( !process.waitForFinished( timeoutSec ? ( timeoutSec * 1000 ) : -1 ) ) - { - cWarning() << "Timed out. output so far:"; - output.append( QString::fromLocal8Bit( process.readAllStandardOutput() ).trimmed() ); - cWarning() << output; - return -4; - } - - output.append( QString::fromLocal8Bit( process.readAllStandardOutput() ).trimmed() ); - - if ( process.exitStatus() == QProcess::CrashExit ) - { - cWarning() << "Process crashed"; - return -1; - } - - cDebug() << "Finished. Exit code:" << process.exitCode(); - return process.exitCode(); + return + System::runCommand( System::RunLocation::RunInHost, + { "/bin/sh", "-c", m_command }, + m_workingPath, + QString(), + m_timeoutSec ) + .explainProcess( m_command, m_timeoutSec ); } } // namespace Calamares diff --git a/src/libcalamares/ProcessJob.h b/src/libcalamares/ProcessJob.h index d01dbb676..224ebdaf0 100644 --- a/src/libcalamares/ProcessJob.h +++ b/src/libcalamares/ProcessJob.h @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014, Teo Mrnjavac - * Copyright 2017-2018, Adriaan de Groot + * Copyright 2017-2019, Adriaan de Groot * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,11 +40,6 @@ public: JobResult exec() override; private: - int callOutput( const QString& command, - QString& output, - const QString& workingPath = QString(), - const QString& stdInput = QString(), - int timeoutSec = 0 ); QString m_command; QString m_workingPath; bool m_runInChroot; From b587d77e31a7e95589918cbcef6654176216eb92 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 12:33:31 +0200 Subject: [PATCH 09/17] [libcalamares] Fix untranslatable string. - This would substitue an untranslated "in chroot" into the translated string, which is weird. --- src/libcalamares/ProcessJob.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcalamares/ProcessJob.cpp b/src/libcalamares/ProcessJob.cpp index bfdf19860..47fcee05d 100644 --- a/src/libcalamares/ProcessJob.cpp +++ b/src/libcalamares/ProcessJob.cpp @@ -48,10 +48,8 @@ ProcessJob::~ProcessJob() QString ProcessJob::prettyName() const { - //TODO: show something more meaningful - return tr( "Run command %1 %2" ) - .arg( m_command ) - .arg( m_runInChroot ? "in chroot." : " ." ); + return ( m_runInChroot ? tr( "Run command '%1' in target system." ) : tr( " Run command '%1'." ) ) + .arg( m_command ); } From d7f513412168a8fc614c2c93609fb54e131b34e2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 13:32:31 +0200 Subject: [PATCH 10/17] [libcalamares] Be more verbose in error situations - runCommand can return NoWorkingDirectory in multiple places, make sure the log contains a more specific reason. --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 0d227c88f..c74243ecc 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -114,14 +114,24 @@ System::mount( const QString& devicePath, const QString& options ) { if ( devicePath.isEmpty() || mountPoint.isEmpty() ) + { + if ( devicePath.isEmpty() ) + cWarning() << "Can't mount an empty device."; + if ( mountPoint.isEmpty() ) + cWarning() << "Can't mount on an empty mountpoint."; + return static_cast(ProcessResult::Code::NoWorkingDirectory); + } QDir mountPointDir( mountPoint ); if ( !mountPointDir.exists() ) { bool ok = mountPointDir.mkpath( mountPoint ); if ( !ok ) + { + cWarning() << "Could not create mountpoint" << mountPoint; return static_cast(ProcessResult::Code::NoWorkingDirectory); + } } QString program( "mount" ); @@ -147,7 +157,10 @@ System::runCommand( QString output; if ( !Calamares::JobQueue::instance() ) + { + cError() << "No JobQueue"; return ProcessResult::Code::NoWorkingDirectory; + } Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); if ( ( location == System::RunLocation::RunInTarget ) && From 07a59bd09cb3ec5c4737164d62f8a51cfcd4ec6e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 13:37:46 +0200 Subject: [PATCH 11/17] [libcalamares] All commands with workingDirectory failed - This is the same as EFAIL: a block is indented as if it's a multi- line else block. This isn't Python though, and the return always applies. - Add the necessary braces. - Apparently noone uses this code path (until ProcessJob was re- factored to do so). --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index c74243ecc..739249cd0 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -202,8 +202,10 @@ System::runCommand( if ( QDir( workingPath ).exists() ) process.setWorkingDirectory( QDir( workingPath ).absolutePath() ); else + { cWarning() << "Invalid working directory:" << workingPath; return ProcessResult::Code::NoWorkingDirectory; + } } cDebug() << "Running" << program << RedactedList( arguments ); From 5a835f32b8e9190dafc72b904f76ec7a474200dd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 13:56:16 +0200 Subject: [PATCH 12/17] [libcalamares] Start extending tests to runCommand() --- src/libcalamares/Tests.cpp | 21 +++++++++++++++++++++ src/libcalamares/Tests.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/libcalamares/Tests.cpp b/src/libcalamares/Tests.cpp index 615cb51a7..40cb480e9 100644 --- a/src/libcalamares/Tests.cpp +++ b/src/libcalamares/Tests.cpp @@ -18,9 +18,12 @@ #include "Tests.h" +#include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" #include "utils/Yaml.h" +#include + #include QTEST_GUILESS_MAIN( LibCalamaresTests ) @@ -113,3 +116,21 @@ LibCalamaresTests::testLoadSaveYamlExtended() } QFile::remove( "out.yaml" ); } + +void +LibCalamaresTests::testCommands() +{ + using CalamaresUtils::System; + auto r = System::runCommand( + System::RunLocation::RunInHost, + { "/bin/ls", "/tmp" } + ); + + QVERIFY( r.getExitCode() == 0 ); + + QTemporaryFile tf( "/tmp/calamares-test-XXXXXX" ); + QVERIFY( tf.open() ); + QVERIFY( !tf.fileName().isEmpty() ); + + QVERIFY( r.getOutput().contains( tf.fileName() ) ); +} diff --git a/src/libcalamares/Tests.h b/src/libcalamares/Tests.h index 8d0aee1ff..5cdb3912b 100644 --- a/src/libcalamares/Tests.h +++ b/src/libcalamares/Tests.h @@ -34,6 +34,8 @@ private Q_SLOTS: void testLoadSaveYaml(); // Just settings.conf void testLoadSaveYamlExtended(); // Do a find() in the src dir + + void testCommands(); }; #endif From 7be33b8196758c72c023a77f30ce335e4d96b5d2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 15:53:27 +0200 Subject: [PATCH 13/17] [libcalamares] runCommand doesn't need queue or settings - JobQueue is only needed to get global settings, which are needed when running in the target; for host commands, allow running without a queue. - Settings is needed for the value of debugsettings; assume if there's no settings object, that we're in a test and should print debugging information. --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index 739249cd0..e2c6e9dec 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -156,13 +156,8 @@ System::runCommand( { QString output; - if ( !Calamares::JobQueue::instance() ) - { - cError() << "No JobQueue"; - return ProcessResult::Code::NoWorkingDirectory; - } + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr; - Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); if ( ( location == System::RunLocation::RunInTarget ) && ( !gs || !gs->contains( "rootMountPoint" ) ) ) { @@ -239,7 +234,8 @@ System::runCommand( auto r = process.exitCode(); cDebug() << "Finished. Exit code:" << r; - if ( ( r != 0 ) || Calamares::Settings::instance()->debugMode() ) + bool showDebug = ( !Calamares::Settings::instance() ) || ( Calamares::Settings::instance()->debugMode() ); + if ( ( r != 0 ) || showDebug ) { cDebug() << "Target cmd:" << RedactedList( args ); cDebug().noquote().nospace() << "Target output:\n" << output; From 4e13f780f188440c83d7b0c095aec05c93ea636c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 16:00:37 +0200 Subject: [PATCH 14/17] [libcalamares] Expand tests for runCommand - try both with and without a working-directory set, this would have shown up the problem with bad indentation much earlier. --- src/libcalamares/Tests.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/Tests.cpp b/src/libcalamares/Tests.cpp index 40cb480e9..3b7624537 100644 --- a/src/libcalamares/Tests.cpp +++ b/src/libcalamares/Tests.cpp @@ -132,5 +132,29 @@ LibCalamaresTests::testCommands() QVERIFY( tf.open() ); QVERIFY( !tf.fileName().isEmpty() ); - QVERIFY( r.getOutput().contains( tf.fileName() ) ); + QFileInfo tfn( tf.fileName() ); + QVERIFY( !r.getOutput().contains( tfn.fileName() ) ); + + // Run ls again, now that the file exists + r = System::runCommand( + System::RunLocation::RunInHost, + { "/bin/ls", "/tmp" } + ); + QVERIFY( r.getOutput().contains( tfn.fileName() ) ); + + // .. and without a working directory set, assume builddir != /tmp + r = System::runCommand( + System::RunLocation::RunInHost, + { "/bin/ls" } + ); + QVERIFY( !r.getOutput().contains( tfn.fileName() ) ); + + r = System::runCommand( + System::RunLocation::RunInHost, + { "/bin/ls" }, + "/tmp" + ); + QVERIFY( r.getOutput().contains( tfn.fileName() ) ); + + } From 4f221b41d196cc3527cedeabb77a9d1cc0fd1167 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 16:11:54 +0200 Subject: [PATCH 15/17] [libcalamares] Close stdin on process jobs - This avoids processes that wait on stdin, and e.g. improves reaction to having just "cat" (no file) in a command, or a package manager that asks for input. --- src/libcalamares/utils/CalamaresUtilsSystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index e2c6e9dec..5990fbc42 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -214,8 +214,8 @@ System::runCommand( if ( !stdInput.isEmpty() ) { process.write( stdInput.toLocal8Bit() ); - process.closeWriteChannel(); } + process.closeWriteChannel(); if ( !process.waitForFinished( timeoutSec ? ( timeoutSec * 1000 ) : -1 ) ) { From c233bbb23df6464634e9a5ecf307b9729995f158 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 21:54:07 +0200 Subject: [PATCH 16/17] [libcalamaresui] Handle no-finished-page scenarios - From an exec section, next() is called automatically when all the jobs in that section are done. - If there **is** no next section (e.g. there's no finished page to show after the exec), then m_steps.at() would assert on an out-of-range index. - Introdcuce a helper predicate isAtVeryEnd() which handles both out-of-range and normal at-the-end scenarios. - If there's no page following the exec section, stay with the slideshow but update buttons to match the normal last-page behavior, and don't ask about cancel (since we're done). --- src/libcalamaresui/ViewManager.cpp | 33 ++++++++++++++++++++++-------- src/libcalamaresui/ViewManager.h | 7 ++++++- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/libcalamaresui/ViewManager.cpp b/src/libcalamaresui/ViewManager.cpp index 508581b4e..3a5d24feb 100644 --- a/src/libcalamaresui/ViewManager.cpp +++ b/src/libcalamaresui/ViewManager.cpp @@ -283,18 +283,35 @@ ViewManager::next() } m_currentStep++; - m_stack->setCurrentIndex( m_currentStep ); + + m_stack->setCurrentIndex( m_currentStep ); // Does nothing if out of range step->onLeave(); - m_steps.at( m_currentStep )->onActivate(); - executing = qobject_cast< ExecutionViewStep* >( m_steps.at( m_currentStep ) ) != nullptr; - emit currentStepChanged(); + + if ( m_currentStep < m_steps.count() ) + { + m_steps.at( m_currentStep )->onActivate(); + executing = qobject_cast< ExecutionViewStep* >( m_steps.at( m_currentStep ) ) != nullptr; + emit currentStepChanged(); + } + else + { + // Reached the end in a weird state (e.g. no finished step after an exec) + executing = false; + m_next->setEnabled( false ); + m_back->setEnabled( false ); + } updateCancelEnabled( !settings->disableCancel() && !(executing && settings->disableCancelDuringExec() ) ); } else + { step->next(); + } - m_next->setEnabled( !executing && m_steps.at( m_currentStep )->isNextEnabled() ); - m_back->setEnabled( !executing && m_steps.at( m_currentStep )->isBackEnabled() ); + if ( m_currentStep < m_steps.count() ) + { + m_next->setEnabled( !executing && m_steps.at( m_currentStep )->isNextEnabled() ); + m_back->setEnabled( !executing && m_steps.at( m_currentStep )->isBackEnabled() ); + } updateButtonLabels(); } @@ -320,7 +337,7 @@ ViewManager::updateButtonLabels() else m_next->setText( tr( "&Next" ) ); - if ( m_currentStep == m_steps.count() -1 && m_steps.last()->isAtEnd() ) + if ( isAtVeryEnd() ) { m_quit->setText( tr( "&Done" ) ); m_quit->setToolTip( complete ); @@ -368,7 +385,7 @@ bool ViewManager::confirmCancelInstallation() const auto* const settings = Calamares::Settings::instance(); // When we're at the very end, then it's always OK to exit. - if ( m_currentStep == m_steps.count() -1 && m_steps.last()->isAtEnd() ) + if ( isAtVeryEnd() ) return true; // Not at the very end, cancel/quit might be disabled diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index 50e8d1dc4..c9f554ee8 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -130,7 +130,12 @@ private: void insertViewStep( int before, ViewStep* step ); void updateButtonLabels(); void updateCancelEnabled( bool enabled ); - + + bool isAtVeryEnd() const + { + return ( m_currentStep >= m_steps.count() ) || ( m_currentStep == m_steps.count() - 1 && m_steps.last()->isAtEnd() ); + } + static ViewManager* s_instance; ViewStepList m_steps; From 64ef331562001455bcc51d0d1a3e076d2cf9b2b0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 7 Jun 2019 21:58:35 +0200 Subject: [PATCH 17/17] Changes: document bugfix --- CHANGES | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGES b/CHANGES index 1ba7ab907..5fdba303f 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,10 @@ This release contains contributions from (alphabetically by first name): the UI opportunities it offers, so begin the process of deprecating and removing that. Sometime in the future, QML pages will fill the gap for easily-prototyped-yet-slick UI elements. + - A crash when no *finished* page (or rather, no page at all) is + configured after the last *exec* section of the sequence has been + solved. The *finished* page can be left out (but then you don't get + the restart-now functionality). ## Modules ##