From 0b4c0f9c3896930544f89fe7931094042eb75615 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 04:06:01 -0400 Subject: [PATCH 01/31] [fsresizer] Add setting required - If resize is required, fail if it doesn't happen. --- src/modules/fsresizer/ResizeFSJob.cpp | 14 +++++++++----- src/modules/fsresizer/ResizeFSJob.h | 9 +++++---- src/modules/fsresizer/fsresizer.conf | 16 ++++++++++++++-- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 0589e1866..254e80adb 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -33,6 +33,7 @@ #include "JobQueue.h" #include "GlobalStorage.h" +#include "utils/CalamaresUtils.h" #include "utils/Logger.h" #include "utils/Units.h" @@ -68,7 +69,7 @@ ResizeFSJob::RelativeSize::RelativeSize( const QString& s) { matchUnitSuffix( s, "%", Percent, m_value, m_unit ); matchUnitSuffix( s, "MiB", Absolute, m_value, m_unit ); - + if ( ( unit() == Percent ) && ( value() > 100 ) ) { cDebug() << "Percent value" << value() << "is not valid."; @@ -87,7 +88,7 @@ ResizeFSJob::RelativeSize::apply( qint64 totalSectors , qint64 sectorSize ) return -1; if ( sectorSize < 1 ) return -1; - + switch( m_unit ) { case None: @@ -113,6 +114,7 @@ ResizeFSJob::RelativeSize::apply( Device* d ) ResizeFSJob::ResizeFSJob( QObject* parent ) : Calamares::CppJob( parent ) + , m_required( false ) { } @@ -156,7 +158,7 @@ ResizeFSJob::findPartition( CoreBackend* backend ) } /** @brief Returns the last sector the matched partition should occupy. - * + * * Returns a sector number. Returns -1 if something is wrong (e.g. * can't resize at all, or missing data). Returns 0 if the resize * won't fit because it doesn't satisfy the settings for atleast @@ -223,7 +225,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) cDebug() << ".. only growing by" << wanted << "instead of full" << expand; last_available -= ( expand - wanted ); } - + return last_available; } @@ -300,7 +302,7 @@ ResizeFSJob::exec() << "skipped as not-useful."; return Calamares::JobResult::ok(); } - + if ( ( new_end > 0 ) && ( new_end > m.second->lastSector() ) ) { ResizeOperation op( *m.first, *m.second, m.second->firstSector(), new_end ); @@ -334,6 +336,8 @@ ResizeFSJob::setConfigurationMap( const QVariantMap& configurationMap ) m_size = RelativeSize( configurationMap["size"].toString() ); m_atleast = RelativeSize( configurationMap["atleast"].toString() ); + + m_required = CalamaresUtils::getBool( configurationMap, "required", false ); } CALAMARES_PLUGIN_FACTORY_DEFINITION( ResizeFSJobFactory, registerPlugin(); ) diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index 063495e7d..c34ccb865 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -68,19 +68,19 @@ public: * * Each sector has size @p sectorSize , for converting absolute * sizes in MiB to sector counts. - * + * * For invalid sizes, returns -1. * For absolute sizes, returns the number of sectors needed. * For percent sizes, returns that percent of the number of sectors. */ qint64 apply( qint64 totalSectors, qint64 sectorSize ); - + /** @brief Apply this size to the given device. - * + * * Equivalent to apply( d->totalLogical(), d->logicalSize() ) */ qint64 apply( Device* d ); - + private: int m_value; Unit m_unit; @@ -107,6 +107,7 @@ private: RelativeSize m_atleast; QString m_fsname; // Either this, or devicename, is set, not both QString m_devicename; + bool m_required; using PartitionMatch = QPair; /** @brief Find the configured FS using KPMCore @p backend */ diff --git a/src/modules/fsresizer/fsresizer.conf b/src/modules/fsresizer/fsresizer.conf index 06141fc7d..33329248d 100644 --- a/src/modules/fsresizer/fsresizer.conf +++ b/src/modules/fsresizer/fsresizer.conf @@ -12,7 +12,7 @@ # Which FS needs to be grown? Choose one way to identify it: # - *fs* names a mount point which should already be mounted # in the system. -# - *dev* names a device +# - *dev* names a device fs: / # dev: /dev/mmcblk0p1 @@ -33,5 +33,17 @@ size: 100% # size, as above. If missing, then it's assumed to be 0, # which means resizing is always worthwhile. # +# If *atleast* is not zero, then the setting *required*, +# below, becomes relevant. +# # 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 From eb7c6385cdce9c76c27bdb6c6518a4e407e2e357 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 04:14:15 -0400 Subject: [PATCH 02/31] [fsresizer] Bail out if resize required but not feasible --- src/modules/fsresizer/ResizeFSJob.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 254e80adb..886ce803a 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -297,9 +297,14 @@ ResizeFSJob::exec() : tr( "The device %1 can not be resized." ).arg(m_devicename) ); if ( new_end == 0 ) { - // TODO: is that a bad thing? is the resize required? cWarning() << "Resize operation on" << m_fsname << m_devicename << "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 %11 must be resized, but cannot" ).arg(m_fsname) ); + return Calamares::JobResult::ok(); } From 39902d1c3f4dcdea42fa7748723d2d508e45cb70 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 04:15:09 -0400 Subject: [PATCH 03/31] [fsresizer] "can not" -> "cannot" --- src/modules/fsresizer/ResizeFSJob.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 886ce803a..af0cb7bd0 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -204,7 +204,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) if ( !( last_available > last_currently ) ) { - cDebug() << "Partition can not grow larger."; + cDebug() << "Partition cannot grow larger."; return 0; } @@ -271,8 +271,8 @@ ResizeFSJob::exec() if ( !m.first || !m.second ) return Calamares::JobResult::error( 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) - : tr( "The device %1 could not be found in this system, and can not be resized." ).arg(m_devicename) ); + !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 cannot be resized." ).arg(m_devicename) ); m.second->fileSystem().init(); // Initialize support for specific FS if ( !ResizeOperation::canGrow( m.second ) ) @@ -280,8 +280,8 @@ ResizeFSJob::exec() cDebug() << "canGrow() returned false."; return Calamares::JobResult::error( tr( "Resize Failed" ), - !m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) - : tr( "The device %1 can not be resized." ).arg(m_devicename) ); + !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg(m_fsname) + : tr( "The device %1 cannot be resized." ).arg(m_devicename) ); } qint64 new_end = findGrownEnd( m ); @@ -293,8 +293,8 @@ ResizeFSJob::exec() if ( new_end < 0 ) return Calamares::JobResult::error( tr( "Resize Failed" ), - !m_fsname.isEmpty() ? tr( "The filesystem %1 can not be resized." ).arg(m_fsname) - : tr( "The device %1 can not be resized." ).arg(m_devicename) ); + !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg(m_fsname) + : tr( "The device %1 cannot be resized." ).arg(m_devicename) ); if ( new_end == 0 ) { cWarning() << "Resize operation on" << m_fsname << m_devicename From 21fedfce65a5ef7f1f4c41914389e4b4dd91366b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 04:22:25 -0400 Subject: [PATCH 04/31] [fsresizer] Calamares oding style --- src/modules/fsresizer/ResizeFSJob.cpp | 51 +++++++++++++-------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index af0cb7bd0..4320baba1 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -49,11 +49,11 @@ ResizeFSJob::RelativeSize::RelativeSize() template void matchUnitSuffix( const QString& s, - const char (&suffix)[N], + const char ( &suffix )[N], ResizeFSJob::RelativeSize::Unit matchedUnit, int& value, ResizeFSJob::RelativeSize::Unit& unit - ) +) { if ( s.endsWith( suffix ) ) { @@ -63,7 +63,7 @@ void matchUnitSuffix( } -ResizeFSJob::RelativeSize::RelativeSize( const QString& s) +ResizeFSJob::RelativeSize::RelativeSize( const QString& s ) : m_value( 0 ) , m_unit( None ) { @@ -82,14 +82,14 @@ ResizeFSJob::RelativeSize::RelativeSize( const QString& s) } qint64 -ResizeFSJob::RelativeSize::apply( qint64 totalSectors , qint64 sectorSize ) +ResizeFSJob::RelativeSize::apply( qint64 totalSectors, qint64 sectorSize ) { if ( !isValid() ) return -1; if ( sectorSize < 1 ) return -1; - switch( m_unit ) + switch ( m_unit ) { case None: return -1; @@ -138,14 +138,14 @@ ResizeFSJob::findPartition( CoreBackend* backend ) cDebug() << "ResizeFSJob found" << devices.count() << "devices."; for ( DeviceList::iterator dev_it = devices.begin(); dev_it != devices.end(); ++dev_it ) { - if ( ! (*dev_it) ) + if ( ! ( *dev_it ) ) continue; cDebug() << "ResizeFSJob found" << ( *dev_it )->deviceNode(); for ( auto part_it = PartitionIterator::begin( *dev_it ); part_it != PartitionIterator::end( *dev_it ); ++part_it ) { cDebug() << ".." << ( *part_it )->mountPoint() << "on" << ( *part_it )->deviceNode(); 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; return PartitionMatch( *dev_it, *part_it ); @@ -166,7 +166,7 @@ ResizeFSJob::findPartition( CoreBackend* backend ) * by occupied space after it). */ qint64 -ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) +ResizeFSJob::findGrownEnd( ResizeFSJob::PartitionMatch m ) { if ( !m.first || !m.second ) return -1; // Missing device data @@ -195,7 +195,7 @@ ResizeFSJob::findGrownEnd(ResizeFSJob::PartitionMatch m) continue; } 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; last_available = next_start - 1; // Before that one starts @@ -236,13 +236,12 @@ ResizeFSJob::exec() if ( !isValid() ) return Calamares::JobResult::error( tr( "Invalid configuration" ), - tr( "The file-system resize job has an invalid configuration " - "and will not run." ) ); + tr( "The file-system resize job has an invalid configuration and will not run." ) ); // Get KPMCore auto backend_p = CoreBackendManager::self()->backend(); 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 { cDebug() << "No KPMCore backend loaded yet"; @@ -271,8 +270,8 @@ ResizeFSJob::exec() if ( !m.first || !m.second ) return Calamares::JobResult::error( tr( "Resize Failed" ), - !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 cannot be resized." ).arg(m_devicename) ); + !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 cannot be resized." ).arg( m_devicename ) ); m.second->fileSystem().init(); // Initialize support for specific FS if ( !ResizeOperation::canGrow( m.second ) ) @@ -280,30 +279,30 @@ ResizeFSJob::exec() cDebug() << "canGrow() returned false."; return Calamares::JobResult::error( tr( "Resize Failed" ), - !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg(m_fsname) - : tr( "The device %1 cannot be resized." ).arg(m_devicename) ); + !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg( m_fsname ) + : tr( "The device %1 cannot be resized." ).arg( m_devicename ) ); } qint64 new_end = findGrownEnd( m ); cDebug() << "Resize from" - << m.second->firstSector() << '-' << m.second->lastSector() - << '(' << m.second->length() << ')' - << "to -" << new_end; + << m.second->firstSector() << '-' << m.second->lastSector() + << '(' << m.second->length() << ')' + << "to -" << new_end; if ( new_end < 0 ) return Calamares::JobResult::error( tr( "Resize Failed" ), - !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg(m_fsname) - : tr( "The device %1 cannot be resized." ).arg(m_devicename) ); + !m_fsname.isEmpty() ? tr( "The filesystem %1 cannot be resized." ).arg( m_fsname ) + : tr( "The device %1 cannot be resized." ).arg( m_devicename ) ); if ( new_end == 0 ) { 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 %11 must be resized, but cannot" ).arg(m_fsname) ); + !m_fsname.isEmpty() ? tr( "The filesystem %1 must be resized, but cannot." ).arg( m_fsname ) + : tr( "The device %11 must be resized, but cannot" ).arg( m_fsname ) ); return Calamares::JobResult::ok(); } @@ -318,8 +317,8 @@ ResizeFSJob::exec() { cDebug() << "Resize failed." << op_report.output(); return Calamares::JobResult::error( - tr( "Resize Failed" ), - op_report.toText() ); + tr( "Resize Failed" ), + op_report.toText() ); } } From 0d8cf98811bd4d20a408d02d8c70f5da2f35ab51 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 04:27:26 -0400 Subject: [PATCH 05/31] Changelog: nudge closer to release. --- CHANGES | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES b/CHANGES index c7e5432ce..da731b3a6 100644 --- a/CHANGES +++ b/CHANGES @@ -13,10 +13,16 @@ This release contains contributions from (alphabetically by first name): ## Core ## +There are no core changes in this version. + ## Modules ## * The *partition* module supports RAID devices, but only when Calamares 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 system console properly. * New module *fsresizer* can be used to resize filesystems. It is intended From 3ef4842a4d7bb0104c88130f11e0f8da7e182ec1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 10:40:43 +0200 Subject: [PATCH 06/31] [preservefiles] Add permissions-parsing code from Scott Harvey --- CHANGES | 3 + src/modules/preservefiles/permissions.cpp | 70 +++++++++++++++++++++++ src/modules/preservefiles/permissions.h | 58 +++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 src/modules/preservefiles/permissions.cpp create mode 100644 src/modules/preservefiles/permissions.h diff --git a/CHANGES b/CHANGES index da731b3a6..896a9fee2 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,7 @@ This release contains contributions from (alphabetically by first name): - Caio Carvalho - Kevin Kofler - Philip Mueller + - Scott Harvey ## Core ## @@ -25,6 +26,8 @@ There are no core changes in this version. size is close to the required installation size). * The *keyboard* module now handles the (bogus) Austrian keymap for 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 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. diff --git a/src/modules/preservefiles/permissions.cpp b/src/modules/preservefiles/permissions.cpp new file mode 100644 index 000000000..93606f7d8 --- /dev/null +++ b/src/modules/preservefiles/permissions.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 Scott Harvey + * + * 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 . + * + */ + +#include +#include +#include "permissions.h" + +Permissions::Permissions(QString p) : + m_username(), + m_group(), + m_valid(true), + m_value(0) + +{ + parsePermissions(p); +} + +const 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; + +} + + + + + + diff --git a/src/modules/preservefiles/permissions.h b/src/modules/preservefiles/permissions.h new file mode 100644 index 000000000..27224181f --- /dev/null +++ b/src/modules/preservefiles/permissions.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2018 Scott Harvey + * + * 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 . + * + */ + +#ifndef PERMISSIONS_H +#define PERMISSIONS_H + +#include + +/** + * @brief The Permissions class takes a QString @p in the form of + * ::, checks it for validity, and makes the three + * components available indivdually. + */ +class Permissions +{ + +public: + +/** Constructor + * Splits the string @p at the colon (":") into separate elements for + * , , and (permissions), where is returned as + * an **octal** integer. + */ + Permissions(QString p); + + bool isValid() const { return m_valid; } + QString username() const { return m_username; } + QString group() const { return m_group; } + int value() const { return m_value; } + + +private: + + const void parsePermissions(QString const &p); + + QString m_username; + QString m_group; + bool m_valid; + int m_value; + +}; + +#endif // PERMISSIONS_H From 1c85a648a4bf1f3f0a986433c2fbb580e515ce1e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 10:45:39 +0200 Subject: [PATCH 07/31] [preservefiles] Tie permissions into the build, file header --- src/modules/preservefiles/CMakeLists.txt | 1 + src/modules/preservefiles/permissions.cpp | 3 ++- src/modules/preservefiles/permissions.h | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/modules/preservefiles/CMakeLists.txt b/src/modules/preservefiles/CMakeLists.txt index 1ac979d1b..c1021eeda 100644 --- a/src/modules/preservefiles/CMakeLists.txt +++ b/src/modules/preservefiles/CMakeLists.txt @@ -4,6 +4,7 @@ calamares_add_plugin( preservefiles TYPE job EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES + permissions.cpp PreserveFiles.cpp LINK_PRIVATE_LIBRARIES calamares diff --git a/src/modules/preservefiles/permissions.cpp b/src/modules/preservefiles/permissions.cpp index 93606f7d8..e85386292 100644 --- a/src/modules/preservefiles/permissions.cpp +++ b/src/modules/preservefiles/permissions.cpp @@ -1,4 +1,5 @@ -/* +/* === This file is part of Calamares - === + * * Copyright (C) 2018 Scott Harvey * * This program is free software: you can redistribute it and/or modify diff --git a/src/modules/preservefiles/permissions.h b/src/modules/preservefiles/permissions.h index 27224181f..5bbb17fba 100644 --- a/src/modules/preservefiles/permissions.h +++ b/src/modules/preservefiles/permissions.h @@ -1,4 +1,5 @@ -/* +/* === This file is part of Calamares - === + * * Copyright (C) 2018 Scott Harvey * * This program is free software: you can redistribute it and/or modify From 91c94c60220cf5e8885215566dc8762b14aeb267 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 10:51:21 +0200 Subject: [PATCH 08/31] [preservefiles] Tidy up permissions code - superfluous const - add default constructor - Add octal-string accessor to permissions --- src/modules/preservefiles/permissions.cpp | 10 +++++++--- src/modules/preservefiles/permissions.h | 19 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/modules/preservefiles/permissions.cpp b/src/modules/preservefiles/permissions.cpp index e85386292..a3f8ac136 100644 --- a/src/modules/preservefiles/permissions.cpp +++ b/src/modules/preservefiles/permissions.cpp @@ -21,17 +21,21 @@ #include #include "permissions.h" -Permissions::Permissions(QString p) : +Permissions::Permissions() : m_username(), m_group(), - m_valid(true), + m_valid(false), m_value(0) +{ +} + +Permissions::Permissions(QString p) : Permissions() { parsePermissions(p); } -const void Permissions::parsePermissions(const QString& p) { +void Permissions::parsePermissions(const QString& p) { QStringList segments = p.split(":"); diff --git a/src/modules/preservefiles/permissions.h b/src/modules/preservefiles/permissions.h index 5bbb17fba..4cb70a2c2 100644 --- a/src/modules/preservefiles/permissions.h +++ b/src/modules/preservefiles/permissions.h @@ -32,22 +32,25 @@ class Permissions public: -/** Constructor - * Splits the string @p at the colon (":") into separate elements for - * , , and (permissions), where is returned as - * an **octal** integer. - */ + /** @brief Constructor + * + * Splits the string @p at the colon (":") into separate elements for + * , , and (permissions), where 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: - - const void parsePermissions(QString const &p); + void parsePermissions(QString const &p); QString m_username; QString m_group; From d3d08241e2d6779886d41383f7fc0eb33f1355ce Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 11:02:56 +0200 Subject: [PATCH 09/31] [preservefiles] Support perm setting - Use settings from config file - Refactor copy operation - Apply permissions inside target system --- src/modules/preservefiles/PreserveFiles.cpp | 87 ++++++++++++++------- src/modules/preservefiles/PreserveFiles.h | 5 +- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/modules/preservefiles/PreserveFiles.cpp b/src/modules/preservefiles/PreserveFiles.cpp index 0fe1d278b..03387fd24 100644 --- a/src/modules/preservefiles/PreserveFiles.cpp +++ b/src/modules/preservefiles/PreserveFiles.cpp @@ -18,6 +18,8 @@ #include "PreserveFiles.h" +#include "permissions.h" + #include "CalamaresVersion.h" #include "JobQueue.h" #include "GlobalStorage.h" @@ -83,6 +85,38 @@ PreserveFiles::prettyName() const return tr( "Saving files for later ..." ); } +static bool +copy_file( const QString& source, const QString& dest ) +{ + QFile sourcef( source ); + if ( !sourcef.open( QFile::ReadOnly ) ) + { + cWarning() << "Could not read" << source; + return false; + } + + QFile destf( dest ); + if ( !destf.open( QFile::WriteOnly ) ) + { + sourcef.close(); + cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source; + return false; + } + + QByteArray b; + do + { + b = sourcef.read( 1_MiB ); + destf.write( b ); + } + while ( b.count() > 0 ); + + sourcef.close(); + destf.close(); + + return true; +} + Calamares::JobResult PreserveFiles::exec() { if ( m_items.isEmpty() ) @@ -96,7 +130,8 @@ Calamares::JobResult PreserveFiles::exec() for ( const auto& it : m_items ) { 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 ) source = Logger::logFile(); @@ -111,32 +146,29 @@ Calamares::JobResult PreserveFiles::exec() cWarning() << "Skipping unnamed source file for" << dest; else { - QFile sourcef( source ); - if ( !sourcef.open( QFile::ReadOnly ) ) + if ( copy_file( source, dest ) ) { - cWarning() << "Could not read" << source; - continue; + if ( it.perm.isValid() ) + { + auto s_p = CalamaresUtils::System::instance(); + + int r; + + r = s_p->targetEnvCall( QStringList{ "chown", it.perm.username(), bare_dest } ); + if ( r ) + cWarning() << "Could not chown target" << bare_dest; + + r = s_p->targetEnvCall( QStringList{ "chgrp", it.perm.group(), bare_dest } ); + if ( r ) + 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; } - - QFile destf( dest ); - if ( !destf.open( QFile::WriteOnly ) ) - { - sourcef.close(); - cWarning() << "Could not open" << destf.fileName() << "for writing; could not copy" << source; - continue; - } - - QByteArray b; - do - { - b = sourcef.read( 1_MiB ); - destf.write( b ); - } - while ( b.count() > 0 ); - - sourcef.close(); - destf.close(); - ++count; } } @@ -168,7 +200,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) { QString filename = li.toString(); if ( !filename.isEmpty() ) - m_items.append( Item{ filename, filename, ItemType::Path } ); + m_items.append( Item{ filename, filename, Permissions(), ItemType::Path } ); else cDebug() << "Empty filename for preservefiles, item" << c; } @@ -181,6 +213,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) ( from == "log" ) ? ItemType::Log : ( from == "config" ) ? ItemType::Config : ItemType::None; + QString perm = map[ "perm" ].toString(); if ( dest.isEmpty() ) { @@ -192,7 +225,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) } else { - m_items.append( Item{ QString(), dest, t } ); + m_items.append( Item{ QString(), dest, Permissions(perm), t } ); } } else diff --git a/src/modules/preservefiles/PreserveFiles.h b/src/modules/preservefiles/PreserveFiles.h index 0c9216336..ed2fe889c 100644 --- a/src/modules/preservefiles/PreserveFiles.h +++ b/src/modules/preservefiles/PreserveFiles.h @@ -24,11 +24,11 @@ #include #include "CppJob.h" +#include "PluginDllMacro.h" #include "utils/PluginFactory.h" -#include "PluginDllMacro.h" - +#include "permissions.h" class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob { @@ -46,6 +46,7 @@ class PLUGINDLLEXPORT PreserveFiles : public Calamares::CppJob { QString source; QString dest; + Permissions perm; ItemType type; } ; From eb6fc01c0127c21001cf77f65387bce563034833 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 11:06:42 +0200 Subject: [PATCH 10/31] [preservefiles] Document new permissions key --- src/modules/preservefiles/preservefiles.conf | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index ab9114d20..ac8e1f7db 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -9,13 +9,18 @@ # as the source). # - a map with a *dest* key. The *dest* value is a path interpreted in the # target system (if dontChroot is true, in the host system). Relative paths -# are not recommended. There are 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 # preserve files whose pathname is known to Calamares internally. # - *src*, to refer to a path interpreted in the host system. Relative # paths are not recommended, and are interpreted relative to where # Calamares is being run. -# Only one of the two other keys (either *from* or *src*) may be set. +# - *perm*, is a colon-separated tuple of :: +# where 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: # - `@@ROOT@@` is replaced by the path to the target root (may be /) @@ -32,5 +37,7 @@ files: - /etc/oem-information - from: log dest: /root/install.log + perm: root:wheel:644 - from: config dest: /root/install.cfg + perm: root:wheel:400 From 1a248e0574fec04934c88f096b382d202dfec3cd Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 1 Oct 2018 11:31:54 +0200 Subject: [PATCH 11/31] [preservefiles] Apply restrictive default permissions --- src/modules/preservefiles/PreserveFiles.cpp | 10 ++++++++-- src/modules/preservefiles/preservefiles.conf | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/modules/preservefiles/PreserveFiles.cpp b/src/modules/preservefiles/PreserveFiles.cpp index 03387fd24..2c1b85103 100644 --- a/src/modules/preservefiles/PreserveFiles.cpp +++ b/src/modules/preservefiles/PreserveFiles.cpp @@ -192,6 +192,10 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) return; } + QString defaultPermissions = configurationMap[ "perm" ].toString(); + if ( defaultPermissions.isEmpty() ) + defaultPermissions = QStringLiteral( "root:root:0400" ); + QVariantList l = files.toList(); unsigned int c = 0; for ( const auto& li : l ) @@ -200,7 +204,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) { QString filename = li.toString(); if ( !filename.isEmpty() ) - m_items.append( Item{ filename, filename, Permissions(), ItemType::Path } ); + m_items.append( Item{ filename, filename, Permissions( defaultPermissions ), ItemType::Path } ); else cDebug() << "Empty filename for preservefiles, item" << c; } @@ -214,6 +218,8 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) ( from == "config" ) ? ItemType::Config : ItemType::None; QString perm = map[ "perm" ].toString(); + if ( perm.isEmpty() ) + perm = defaultPermissions; if ( dest.isEmpty() ) { @@ -225,7 +231,7 @@ void PreserveFiles::setConfigurationMap(const QVariantMap& configurationMap) } else { - m_items.append( Item{ QString(), dest, Permissions(perm), t } ); + m_items.append( Item{ QString(), dest, Permissions( perm ), t } ); } } else diff --git a/src/modules/preservefiles/preservefiles.conf b/src/modules/preservefiles/preservefiles.conf index ac8e1f7db..671a308cc 100644 --- a/src/modules/preservefiles/preservefiles.conf +++ b/src/modules/preservefiles/preservefiles.conf @@ -41,3 +41,9 @@ files: - from: config 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" From 800f9d34f9f4c4b07fe5279e032894dcd4b3251e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 3 Oct 2018 13:46:08 +0200 Subject: [PATCH 12/31] [partition] In logging, distinguish more cases - While winnowing devices, the zram and nullptr cases were mixed together; split them, for the sake of logging more accurately. - While here, fix up some coding-style issues. --- src/modules/partition/core/DeviceList.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/modules/partition/core/DeviceList.cpp b/src/modules/partition/core/DeviceList.cpp index 4a353efb4..f51eec047 100644 --- a/src/modules/partition/core/DeviceList.cpp +++ b/src/modules/partition/core/DeviceList.cpp @@ -113,28 +113,32 @@ QList< Device* > getDevices( DeviceType which, qint64 minimumSize ) // Remove the device which contains / from the list for ( DeviceList::iterator it = devices.begin(); it != devices.end(); ) - if ( ! ( *it ) || - ( *it )->deviceNode().startsWith( "/dev/zram" ) + if ( !( *it ) ) + { + cDebug() << " .. Skipping nullptr device"; + it = erase( devices, it); + } + else if ( ( *it )->deviceNode().startsWith( "/dev/zram" ) ) { cDebug() << " .. Removing zram" << it; - it = erase(devices, it ); + it = erase( devices, it ); } else if ( writableOnly && hasRootPartition( *it ) ) { cDebug() << " .. Removing device with root filesystem (/) on it" << it; - it = erase(devices, it ); + it = erase( devices, it ); } else if ( writableOnly && isIso9660( *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 ) ) { cDebug() << " .. Removing too-small" << it; - it = erase(devices, it ); + it = erase( devices, it ); } else ++it; From b38316365e1e7feca6c82f32a34d0b0ec6b62198 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 3 Oct 2018 13:58:50 +0200 Subject: [PATCH 13/31] [partition] Be more verbose about why UI buttons appear --- src/modules/partition/gui/ChoicePage.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index abe7795c0..5cbfb69f7 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1174,6 +1174,9 @@ ChoicePage::setupActions() OsproberEntryList osproberEntriesForCurrentDevice = getOsproberEntriesForDevice( currentDevice ); + cDebug() << "Setting up actions for" << currentDevice->deviceNode() + << "with" << osproberEntriesForCurrentDevice.count() << "entries."; + if ( currentDevice->partitionTable() ) m_deviceInfoWidget->setPartitionTableType( currentDevice->partitionTable()->type() ); else @@ -1190,18 +1193,30 @@ ChoicePage::setupActions() #ifdef WITH_KPMCOREGT33 if ( currentDevice->type() == Device::Type::SoftwareRAID_Device && static_cast< SoftwareRAID* >(currentDevice)->status() == SoftwareRAID::Status::Inactive ) + { + cDebug() << ".. part of an inactive RAID device"; isInactiveRAID = true; + } #endif for ( auto it = PartitionIterator::begin( currentDevice ); it != PartitionIterator::end( currentDevice ); ++it ) { if ( PartUtils::canBeResized( *it ) ) + { + cDebug() << ".. contains resizable" << it; atLeastOneCanBeResized = true; + } if ( PartUtils::canBeReplaced( *it ) ) + { + cDebug() << ".. contains replacable" << it; atLeastOneCanBeReplaced = true; + } if ( (*it)->isMounted() ) + { + cDebug() << ".. contains mounted" << it; atLeastOneIsMounted = true; + } } if ( osproberEntriesForCurrentDevice.count() == 0 ) @@ -1318,7 +1333,12 @@ ChoicePage::setupActions() if ( !atLeastOneIsMounted && !isInactiveRAID ) m_eraseButton->show(); // None mounted else + { + cDebug() << "Erase button suppressed" + << "mount?" << atLeastOneIsMounted + << "raid?" << isInactiveRAID; force_uncheck( m_grp, m_eraseButton ); + } bool isEfi = PartUtils::isEfiSystem(); bool efiSystemPartitionFound = !m_core->efiSystemPartitions().isEmpty(); From 292bc57523bca3a374f0661fe5c0de7d3032ad58 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 3 Oct 2018 13:49:52 -0400 Subject: [PATCH 14/31] [partition] Fix build with suitable operator << --- src/modules/partition/gui/ChoicePage.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 5cbfb69f7..9bc571459 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -1161,6 +1161,13 @@ force_uncheck(QButtonGroup* grp, PrettyRadioButton* button) grp->setExclusive( true ); } +static inline QDebug& +operator <<( QDebug& s, PartitionIterator& it ) +{ + s << ( ( *it ) ? ( *it )->deviceNode() : QString( "" ) ); + return s; +} + /** * @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 @@ -1176,7 +1183,7 @@ ChoicePage::setupActions() cDebug() << "Setting up actions for" << currentDevice->deviceNode() << "with" << osproberEntriesForCurrentDevice.count() << "entries."; - + if ( currentDevice->partitionTable() ) m_deviceInfoWidget->setPartitionTableType( currentDevice->partitionTable()->type() ); else From c63ecc8a35a6e515169e5331447713a51dc7a35d Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 5 Oct 2018 07:36:39 -0400 Subject: [PATCH 15/31] i18n: [calamares] Automatic merge of Transifex translations --- lang/calamares_da.ts | 2 +- lang/calamares_fr.ts | 2 +- lang/calamares_he.ts | 4 ++-- lang/calamares_hu.ts | 6 +++--- lang/calamares_lt.ts | 2 +- lang/calamares_nl.ts | 16 ++++++++-------- lang/calamares_zh_CN.ts | 30 +++++++++++++++--------------- 7 files changed, 31 insertions(+), 31 deletions(-) diff --git a/lang/calamares_da.ts b/lang/calamares_da.ts index 7cfef1875..c69150583 100644 --- a/lang/calamares_da.ts +++ b/lang/calamares_da.ts @@ -1693,7 +1693,7 @@ Installationsprogrammet vil stoppe og alle ændringer vil gå tabt. 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. - Partitionstabellen på %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. + Partitionstabellen på %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. diff --git a/lang/calamares_fr.ts b/lang/calamares_fr.ts index 572a4b1df..26062f604 100644 --- a/lang/calamares_fr.ts +++ b/lang/calamares_fr.ts @@ -4,7 +4,7 @@ The <strong>boot environment</strong> of this system.<br><br>Older x86 systems only support <strong>BIOS</strong>.<br>Modern systems usually use <strong>EFI</strong>, but may also show up as BIOS if started in compatibility mode. - L'<strong>environnement de démarrage</strong> de ce système.<br><br>Les anciens systèmes x86 supportent uniquement le <strong>BIOS</strong>.<br>Les systèmes récents utilisent habituellement <strong>EFI</strong>, mais peuvent également afficher BIOS s'ils sont démarrés en mode de compatibilité. + L'<strong>environnement de démarrage</strong> de ce système.<br><br>Les anciens systèmes x86 supportent uniquement <strong>BIOS</strong>.<br>Les systèmes récents utilisent habituellement <strong>EFI</strong>, mais peuvent également afficher BIOS s'ils sont démarrés en mode de compatibilité. diff --git a/lang/calamares_he.ts b/lang/calamares_he.ts index fed3a48f4..cdceb60de 100644 --- a/lang/calamares_he.ts +++ b/lang/calamares_he.ts @@ -521,7 +521,7 @@ The installer will quit and all changes will be lost. Contextual Processes Job - + משימת תהליכי הקשר @@ -2358,7 +2358,7 @@ Output: Shell Processes Job - + משימת תהליכי מעטפת diff --git a/lang/calamares_hu.ts b/lang/calamares_hu.ts index 20ffbb815..75f3457b8 100644 --- a/lang/calamares_hu.ts +++ b/lang/calamares_hu.ts @@ -207,7 +207,7 @@ &Install - + &Telepítés @@ -229,7 +229,7 @@ Minden változtatás elveszik, ha kilépsz a telepítőből. &No - @Nem + &Nem @@ -944,7 +944,7 @@ Telepítés nem folytatható. <a href="#details">Részletek...&l &Restart now - $Újraindítás most + Új&raindítás most diff --git a/lang/calamares_lt.ts b/lang/calamares_lt.ts index 12d53ba11..33191566b 100644 --- a/lang/calamares_lt.ts +++ b/lang/calamares_lt.ts @@ -244,7 +244,7 @@ Diegimo programa užbaigs darbą ir visi pakeitimai bus prarasti. The %1 installer is about to make changes to your disk in order to install %2.<br/><strong>You will not be able to undo these changes.</strong> - %1 diegimo programa, siekdama įdiegti %2, ketina atlikti pakeitimus diske.<br/><strong>Šių pakeitimų atšaukti nebegalėsite.</strong> + %1 diegimo programa, siekdama įdiegti %2, ketina atlikti pakeitimus diske.<br/><strong>Šių pakeitimų nebegalėsite atšaukti.</strong> diff --git a/lang/calamares_nl.ts b/lang/calamares_nl.ts index d20d75630..d1c1a62cc 100644 --- a/lang/calamares_nl.ts +++ b/lang/calamares_nl.ts @@ -50,7 +50,7 @@ Blank Page - + Lege pagina @@ -192,7 +192,7 @@ Calamares Initialization Failed - + Calamares Initialisatie mislukt @@ -202,7 +202,7 @@ <br/>The following modules could not be loaded: - + <br/>The volgende modules konden niet worden geladen: @@ -1244,7 +1244,7 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan. Password is too weak - + Wachtwoord is te zwak @@ -1259,12 +1259,12 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan. The password is the same as the old one - + Het wachtwoord is hetzelfde als het oude wachtwoord The password is a palindrome - + Het wachtwoord is een palindroom @@ -1274,12 +1274,12 @@ Het installatieprogramma zal afsluiten en alle wijzigingen zullen verloren gaan. The password is too similar to the old one - + Het wachtwoord lijkt te veel op het oude wachtwoord The password contains the user name in some form - + Het wachtwoord bevat de gebruikersnaam op een of andere manier diff --git a/lang/calamares_zh_CN.ts b/lang/calamares_zh_CN.ts index 4889eabf1..b69c5f63c 100644 --- a/lang/calamares_zh_CN.ts +++ b/lang/calamares_zh_CN.ts @@ -9,7 +9,7 @@ This system was started with an <strong>EFI</strong> boot environment.<br><br>To configure startup from an EFI environment, this installer must deploy a boot loader application, like <strong>GRUB</strong> or <strong>systemd-boot</strong> on an <strong>EFI System Partition</strong>. This is automatic, unless you choose manual partitioning, in which case you must choose it or create it on your own. - 这个系统从 <strong>EFI</strong> 引导环境启动。<br><br>目前市面上大多数的民用设备都使用 EFI,并同时与之使用 GPT 分区表。<br>要从 EFI 环境引导的话,本安装程序必须部署一个引导器(如 <strong>GRUB</strong> 或 <strong>systemd-boot</strong>)到 <strong>EFI 系统分区</strong>。这个步骤是自动的,除非您选择手动分区——此时您必须自行选择或创建。 + 这个系统是从 <strong>EFI</strong> 引导环境启动的。<br><br>目前市面上大多数的民用设备都使用 EFI,并同时对硬盘使用 GPT 分区表分区。<br>您如果要从 EFI 环境引导这个系统的话,本安装程序必须安装一个引导器(如 <strong>GRUB</strong> 或 <strong>systemd-boot</strong>)到 <strong>EFI 分区</strong>。这个步骤将会由本安装程序自动执行,除非您选择自己创建分区——此时您必须选择让本安装程序自动创建EFI分区或您自己手动创建EFI分区。 @@ -51,7 +51,7 @@ Blank Page - + 空白页 @@ -193,17 +193,17 @@ Calamares Initialization Failed - + Calamares安装失败 %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. - + %1无法安装。 Calamares无法加载所有已配置的模块。这是分配使用Calamares的方式的问题。 <br/>The following modules could not be loaded: - + <br/>无法加载以下模块: @@ -265,7 +265,7 @@ The installer will quit and all changes will be lost. The installation is complete. Close the installer. - 安装过程已完毕。请关闭安装器。 + 安装已完成。请关闭安装程序。 @@ -334,7 +334,7 @@ The installer will quit and all changes will be lost. For best results, please ensure that this computer: - 为了更好的体验,请确定这台电脑: + 为了更好的体验,请确保这台电脑: @@ -509,12 +509,12 @@ The installer will quit and all changes will be lost. The command runs in the host environment and needs to know the root path, but no rootMountPoint is defined. - + 该命令在主机环境中运行,且需要知道根路径,但没有定义root挂载点。 The command needs to know the user's name, but no username is defined. - + 命令行需要知道用户的名字,但用户名没有被设置 @@ -1665,7 +1665,7 @@ The installer will quit and all changes will be lost. Cre&ate - + 创建 @@ -1690,12 +1690,12 @@ The installer will quit and all changes will be lost. Can not create new partition - + 无法创建新分区 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上的分区表已经有%2个主分区,并且不能再添加。请删除一个主分区并添加扩展分区。 @@ -1841,17 +1841,17 @@ The installer will quit and all changes will be lost. Saving files for later ... - + 保存文件以供日后使用 No files configured to save for later. - + 没有已保存且供日后使用的配置文件。 Not all of the configured files could be preserved. - + 并不是所有配置文件都可以被保留 From dfae4a76375de93e6f7b8c9345446debee92463b Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 5 Oct 2018 07:36:39 -0400 Subject: [PATCH 16/31] i18n: [desktop] Automatic merge of Transifex translations --- calamares.desktop | 154 +++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/calamares.desktop b/calamares.desktop index 3cdce6888..46b2e979f 100644 --- a/calamares.desktop +++ b/calamares.desktop @@ -14,165 +14,165 @@ Categories=Qt;System; X-AppStream-Ignore=true Name[ar]=نظام التثبيت -Icon[be]=calamares -GenericName[be]=Усталёўшчык сістэмы Comment[be]=Calamares — усталёўшчык сістэмы +Icon[be]=calamares Name[be]=Усталяваць сістэму -Icon[bg]=calamares -GenericName[bg]=Системен Инсталатор +GenericName[be]=Усталёўшчык сістэмы Comment[bg]=Calamares — Системен Инсталатор +Icon[bg]=calamares Name[bg]=Инсталирай системата -Icon[ca]=calamares -GenericName[ca]=Instal·lador de sistema +GenericName[bg]=Системен Инсталатор Comment[ca]=Calamares — Instal·lador de sistema +Icon[ca]=calamares Name[ca]=Instal·la el sistema -Icon[da]=calamares -GenericName[da]=Systeminstallationsprogram +GenericName[ca]=Instal·lador de sistema Comment[da]=Calamares — Systeminstallationsprogram +Icon[da]=calamares Name[da]=Installér system -Icon[de]=calamares -GenericName[de]=Installation des Betriebssystems +GenericName[da]=Systeminstallationsprogram Comment[de]=Calamares - Installation des Betriebssystems +Icon[de]=calamares Name[de]=System installieren -Icon[el]=calamares -GenericName[el]=Εγκατάσταση συστήματος +GenericName[de]=Installation des Betriebssystems Comment[el]=Calamares — Εγκατάσταση συστήματος +Icon[el]=calamares Name[el]=Εγκατάσταση συστήματος -Icon[en_GB]=calamares -GenericName[en_GB]=System Installer +GenericName[el]=Εγκατάσταση συστήματος Comment[en_GB]=Calamares — System Installer +Icon[en_GB]=calamares Name[en_GB]=Install System -Icon[es]=calamares -GenericName[es]=Instalador del Sistema +GenericName[en_GB]=System Installer Comment[es]=Calamares — Instalador del Sistema +Icon[es]=calamares Name[es]=Instalar Sistema -Icon[et]=calamares -GenericName[et]=Süsteemipaigaldaja +GenericName[es]=Instalador del Sistema Comment[et]=Calamares — süsteemipaigaldaja +Icon[et]=calamares Name[et]=Paigalda süsteem +GenericName[et]=Süsteemipaigaldaja Name[eu]=Sistema instalatu Name[es_PR]=Instalar el sistema -Icon[fr]=calamares -GenericName[fr]=Installateur système Comment[fr]=Calamares - Installateur système +Icon[fr]=calamares Name[fr]=Installer le système +GenericName[fr]=Installateur système Name[gl]=Instalación do Sistema -Icon[he]=calamares -GenericName[he]=אשף התקנה Comment[he]=Calamares - אשף התקנה +Icon[he]=calamares Name[he]=התקנת מערכת -Icon[hi]=calamares -GenericName[hi]=सिस्टम इंस्टॉलर +GenericName[he]=אשף התקנה Comment[hi]=Calamares — सिस्टम इंस्टॉलर +Icon[hi]=calamares Name[hi]=सिस्टम इंस्टॉल करें -Icon[hr]=calamares -GenericName[hr]=Instalacija sustava +GenericName[hi]=सिस्टम इंस्टॉलर Comment[hr]=Calamares — Instalacija sustava +Icon[hr]=calamares Name[hr]=Instaliraj sustav -Icon[hu]=calamares -GenericName[hu]=Rendszer Telepítő +GenericName[hr]=Instalacija sustava Comment[hu]=Calamares — Rendszer Telepítő +Icon[hu]=calamares Name[hu]=Rendszer telepítése -Icon[id]=calamares -GenericName[id]=Pemasang +GenericName[hu]=Rendszer Telepítő Comment[id]=Calamares — Pemasang Sistem +Icon[id]=calamares Name[id]=Instal Sistem -Icon[is]=calamares -GenericName[is]=Kerfis uppsetning +GenericName[id]=Pemasang Comment[is]=Calamares — Kerfis uppsetning +Icon[is]=calamares Name[is]=Setja upp kerfið -Icon[cs_CZ]=calamares -GenericName[cs_CZ]=Instalátor systému +GenericName[is]=Kerfis uppsetning Comment[cs_CZ]=Calamares – instalátor operačních systémů +Icon[cs_CZ]=calamares Name[cs_CZ]=Nainstalovat -Icon[ja]=calamares -GenericName[ja]=システムインストーラー +GenericName[cs_CZ]=Instalátor systému Comment[ja]=Calamares — システムインストーラー +Icon[ja]=calamares Name[ja]=システムをインストール -Icon[ko]=깔라마레스 -GenericName[ko]=시스템 설치 관리자 +GenericName[ja]=システムインストーラー Comment[ko]=깔라마레스 — 시스템 설치 관리자 +Icon[ko]=깔라마레스 Name[ko]=시스템 설치 -Icon[lt]=calamares -GenericName[lt]=Sistemos diegimas į kompiuterį +GenericName[ko]=시스템 설치 관리자 Comment[lt]=Calamares — Sistemos diegimo programa +Icon[lt]=calamares Name[lt]=Įdiegti Sistemą -Icon[it_IT]=calamares -GenericName[it_IT]=Programma d'installazione del sistema +GenericName[lt]=Sistemos diegimas į kompiuterį Comment[it_IT]=Calamares — Programma d'installazione del sistema +Icon[it_IT]=calamares Name[it_IT]=Installa il sistema -Icon[nb]=calamares -GenericName[nb]=Systeminstallatør +GenericName[it_IT]=Programma d'installazione del sistema Comment[nb]=Calamares-systeminstallatør +Icon[nb]=calamares Name[nb]=Installer System -Icon[nl]=calamares -GenericName[nl]=Installatieprogramma +GenericName[nb]=Systeminstallatør Comment[nl]=Calamares — Installatieprogramma +Icon[nl]=calamares Name[nl]=Installeer systeem -Icon[pl]=calamares -GenericName[pl]=Instalator systemu +GenericName[nl]=Installatieprogramma Comment[pl]=Calamares — Instalator systemu +Icon[pl]=calamares Name[pl]=Zainstaluj system -Icon[pt_BR]=calamares -GenericName[pt_BR]=Instalador de Sistema +GenericName[pl]=Instalator systemu Comment[pt_BR]=Calamares — Instalador de Sistema +Icon[pt_BR]=calamares Name[pt_BR]=Sistema de Instalação -Icon[ro]=calamares -GenericName[ro]=Instalator de sistem +GenericName[pt_BR]=Instalador de Sistema Comment[ro]=Calamares — Instalator de sistem +Icon[ro]=calamares Name[ro]=Instalează sistemul -Icon[ru]=calamares -GenericName[ru]=Установщик системы +GenericName[ro]=Instalator de sistem Comment[ru]=Calamares - Установщик системы +Icon[ru]=calamares Name[ru]=Установить систему -Icon[sk]=calamares -GenericName[sk]=Inštalátor systému +GenericName[ru]=Установщик системы Comment[sk]=Calamares — Inštalátor systému +Icon[sk]=calamares Name[sk]=Inštalovať systém +GenericName[sk]=Inštalátor systému Name[sl]=Namesti sistem -Icon[sq]=calamares -GenericName[sq]=Instalues Sistemi Comment[sq]=Calamares — Instalues Sistemi +Icon[sq]=calamares Name[sq]=Instalo Sistemin -Icon[fi_FI]=calamares -GenericName[fi_FI]=Järjestelmän Asennusohjelma +GenericName[sq]=Instalues Sistemi Comment[fi_FI]=Calamares — Järjestelmän Asentaja +Icon[fi_FI]=calamares Name[fi_FI]=Asenna Järjestelmä +GenericName[fi_FI]=Järjestelmän Asennusohjelma Name[sr@latin]=Instaliraj sistem Name[sr]=Инсталирај систем -Icon[sv]=calamares -GenericName[sv]=Systeminstallerare Comment[sv]=Calamares — Systeminstallerare +Icon[sv]=calamares Name[sv]=Installera system +GenericName[sv]=Systeminstallerare Name[th]=ติดตั้งระบบ -GenericName[uk]=Встановлювач системи Comment[uk]=Calamares - Встановлювач системи Name[uk]=Встановити Систему -Icon[zh_CN]=calamares -GenericName[zh_CN]=系统安装程序 +GenericName[uk]=Встановлювач системи Comment[zh_CN]=Calamares — 系统安装程序 +Icon[zh_CN]=calamares Name[zh_CN]=安装系统 -Icon[zh_TW]=calamares -GenericName[zh_TW]=系統安裝程式 +GenericName[zh_CN]=系统安装程序 Comment[zh_TW]=Calamares ── 系統安裝程式 +Icon[zh_TW]=calamares Name[zh_TW]=安裝系統 -Icon[ast]=calamares -GenericName[ast]=Instalador del sistema +GenericName[zh_TW]=系統安裝程式 Comment[ast]=Calamares — Instalador del sistema +Icon[ast]=calamares Name[ast]=Instalar sistema -Icon[eo]=calamares -GenericName[eo]=Sistema Instalilo +GenericName[ast]=Instalador del sistema Comment[eo]=Calamares — Sistema Instalilo +Icon[eo]=calamares Name[eo]=Instali Sistemo -Icon[es_MX]=calamares -GenericName[es_MX]=Instalador del sistema +GenericName[eo]=Sistema Instalilo Comment[es_MX]=Calamares - Instalador del sistema +Icon[es_MX]=calamares Name[es_MX]=Instalar el Sistema -Icon[pt_PT]=calamares -GenericName[pt_PT]=Instalador de Sistema +GenericName[es_MX]=Instalador del sistema Comment[pt_PT]=Calamares - Instalador de Sistema +Icon[pt_PT]=calamares Name[pt_PT]=Instalar Sistema -Icon[tr_TR]=calamares -GenericName[tr_TR]=Sistem Yükleyici +GenericName[pt_PT]=Instalador de Sistema Comment[tr_TR]=Calamares — Sistem Yükleyici +Icon[tr_TR]=calamares Name[tr_TR]=Sistemi Yükle +GenericName[tr_TR]=Sistem Yükleyici From 36161461e2c2fdef1611e9907a41a98968d64a4a Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 5 Oct 2018 07:36:40 -0400 Subject: [PATCH 17/31] i18n: [dummypythonqt] Automatic merge of Transifex translations --- .../lang/zh_CN/LC_MESSAGES/dummypythonqt.mo | Bin 957 -> 945 bytes .../lang/zh_CN/LC_MESSAGES/dummypythonqt.po | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/dummypythonqt/lang/zh_CN/LC_MESSAGES/dummypythonqt.mo b/src/modules/dummypythonqt/lang/zh_CN/LC_MESSAGES/dummypythonqt.mo index 0dac94ca0b57858d43b1639d8f17249e3c21cae4..240d5c4dbabee9bc5843ed7f46132688159761ad 100644 GIT binary patch delta 125 zcmdnXzL9-Gi0N`h28IM67G+>y;9zE8&;ZhMK$;&&y8~%yARP|n7XxWsAisHIrv@XB zg|2~_uAzm3fw`5*B;$d=?YGXnF=;pscC6RiJ1, 2017\n" +"Last-Translator: soenggam , 2017\n" "Language-Team: Chinese (China) (https://www.transifex.com/calamares/teams/20061/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -24,7 +24,7 @@ msgstr "按我按我!" #: src/modules/dummypythonqt/main.py:94 msgid "A new QLabel." -msgstr "一个平淡无奇的 QLabel。" +msgstr "一个新的QLabel。" #: src/modules/dummypythonqt/main.py:97 msgid "Dummy PythonQt ViewStep" From 0e7f97fe491f45be5f3fb2eb971a992922a34945 Mon Sep 17 00:00:00 2001 From: Calamares CI Date: Fri, 5 Oct 2018 07:36:40 -0400 Subject: [PATCH 18/31] i18n: [python] Automatic merge of Transifex translations --- lang/python/hu/LC_MESSAGES/python.mo | Bin 844 -> 1196 bytes lang/python/hu/LC_MESSAGES/python.po | 12 ++++++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lang/python/hu/LC_MESSAGES/python.mo b/lang/python/hu/LC_MESSAGES/python.mo index 94e29ac49162babdd3eaa340eac2199459720694..4cb87d96aeadff36f295cb60d2906b2f856c1f5e 100644 GIT binary patch delta 532 zcmZXOO-lkn7{_PROb-RULQpgXmA$Z86a|IUA){Lf-69y=X)$MKWoH!>qA$=Pk*>iW zJVbWt6U1IU2Hm30b?XcC-_($N;Ky&~ng2X9jYvIq^)?i~C8!vf00!s>br94$7z7_+ z1bnv~)tdcDcpbeJcnLP(1bhRJ!q0FGynFCeK zWx-l7DqowaG`H+xSN5;lO17scot#L^E=ZT2X9cIKq+D((y*i`a&FvXZmN7{UP7fU0 zcIl28Xg6nY-FD36GF?loZap=$V{LxlEYXazEoM@e3!e8MUH@L;m+c3eht+{l^0Xt% mh3k7oTLf`WvHx+}b)NFQ3*m5Ss4{nWjtXA%J;7ADb^iyRp@oqE delta 204 zcmZ3(d4{e2o)F7a1|VPqVi_Rz0b*_-t^r~YSOLU>K)e!&MSyrWl)eC@LE=w=SR07H z193Ma1A{UU3j^8fnHU%(f%IV@tpTL(0%|cz{I;jlT#RVCSPZq%afa#U20*XqhMrUXuf$CQy}AHMHYPk&axP5 diff --git a/lang/python/hu/LC_MESSAGES/python.po b/lang/python/hu/LC_MESSAGES/python.po index 286e27b3b..e2b46349c 100644 --- a/lang/python/hu/LC_MESSAGES/python.po +++ b/lang/python/hu/LC_MESSAGES/python.po @@ -10,7 +10,7 @@ msgstr "" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2018-06-18 07:46-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: miku84, 2017\n" +"Last-Translator: Adriaan de Groot , 2018\n" "Language-Team: Hungarian (https://www.transifex.com/calamares/teams/20061/hu/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -20,7 +20,7 @@ msgstr "" #: src/modules/umount/main.py:40 msgid "Unmount file systems." -msgstr "" +msgstr "Fájlrendszerek leválasztása." #: src/modules/dummypython/main.py:44 msgid "Dummy python job." @@ -47,12 +47,12 @@ msgstr "Csomagok telepítése." #, python-format msgid "Installing one package." msgid_plural "Installing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Egy csomag telepítése." +msgstr[1] "%(num)d csomag telepítése." #: src/modules/packages/main.py:70 #, python-format msgid "Removing one package." msgid_plural "Removing %(num)d packages." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "Egy csomag eltávolítása." +msgstr[1] "%(num)d csomag eltávolítása." From a33b0c4f24d9b798a4a9ba10148c2d3b3ffefa9b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 07:45:05 -0400 Subject: [PATCH 19/31] [partition] Log the flags that are used to create a partition --- src/modules/partition/jobs/SetPartitionFlagsJob.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp index 7f6169bbe..fee987479 100644 --- a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp +++ b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp @@ -132,6 +132,10 @@ SetPartFlagsJob::prettyStatusMessage() const Calamares::JobResult SetPartFlagsJob::exec() { + cDebug() << "Setting flags on" << m_device->deviceNode() + << "partition" << partition()->deviceNode() + << "to" << m_flags; + Report report ( nullptr ); SetPartFlagsOperation op( *m_device, *partition(), m_flags ); op.setStatus( Operation::StatusRunning ); From 7515386cf87fa625b4c9e0f157e8e6a2eb1b125f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 09:19:25 -0400 Subject: [PATCH 20/31] CMake: clean up test setup - Remove redundant searches for ECM and Qt::Test, move them to top-level. --- CMakeLists.txt | 5 ++++ src/modules/contextualprocess/CMakeLists.txt | 5 +--- src/modules/fsresizer/CMakeLists.txt | 5 +--- src/modules/locale/CMakeLists.txt | 6 ----- src/modules/partition/tests/CMakeLists.txt | 24 ++++++++++---------- src/modules/shellprocess/CMakeLists.txt | 5 +--- src/modules/users/CMakeLists.txt | 9 ++------ 7 files changed, 22 insertions(+), 37 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f241cedd0..4fb88420b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -237,6 +237,11 @@ set_package_properties( find_package(ECM ${ECM_VERSION} NO_MODULE) if( ECM_FOUND ) 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() find_package( KF5 COMPONENTS CoreAddons Crash ) diff --git a/src/modules/contextualprocess/CMakeLists.txt b/src/modules/contextualprocess/CMakeLists.txt index 2cf8d3879..f75946b58 100644 --- a/src/modules/contextualprocess/CMakeLists.txt +++ b/src/modules/contextualprocess/CMakeLists.txt @@ -8,10 +8,7 @@ calamares_add_plugin( contextualprocess SHARED_LIB ) -if( ECM_FOUND ) - find_package( Qt5 COMPONENTS Test REQUIRED ) - include( ECMAddTests ) - +if( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( Tests.cpp ContextualProcessJob.cpp # Builds it a second time diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 5de329cad..e339b2799 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -20,10 +20,7 @@ if ( KPMcore_FOUND ) SHARED_LIB ) - if( ECM_FOUND ) - find_package( Qt5 COMPONENTS Test REQUIRED ) - include( ECMAddTests ) - + if( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( Tests.cpp TEST_NAME diff --git a/src/modules/locale/CMakeLists.txt b/src/modules/locale/CMakeLists.txt index 24259d797..576f2e16e 100644 --- a/src/modules/locale/CMakeLists.txt +++ b/src/modules/locale/CMakeLists.txt @@ -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 # to have a debugging-friendly timezone widget, debug logging, # and no intrusive timezone-setting while clicking around. diff --git a/src/modules/partition/tests/CMakeLists.txt b/src/modules/partition/tests/CMakeLists.txt index 68474287e..7b40c34a5 100644 --- a/src/modules/partition/tests/CMakeLists.txt +++ b/src/modules/partition/tests/CMakeLists.txt @@ -1,6 +1,4 @@ -find_package( Qt5 COMPONENTS Gui Test REQUIRED ) - -include( ECMAddTests ) +find_package( Qt5 COMPONENTS Gui REQUIRED ) set( PartitionModule_SOURCE_DIR .. ) @@ -23,13 +21,15 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) -ecm_add_test( ${partitionjobtests_SRCS} - TEST_NAME partitionjobtests - LINK_LIBRARIES - ${CALAMARES_LIBRARIES} - kpmcore - Qt5::Core - Qt5::Test -) +if( ECM_FOUND AND BUILD_TESTING ) + ecm_add_test( ${partitionjobtests_SRCS} + TEST_NAME partitionjobtests + LINK_LIBRARIES + ${CALAMARES_LIBRARIES} + kpmcore + Qt5::Core + Qt5::Test + ) -set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE ) + set_target_properties( partitionjobtests PROPERTIES AUTOMOC TRUE ) +endif() diff --git a/src/modules/shellprocess/CMakeLists.txt b/src/modules/shellprocess/CMakeLists.txt index 51d4c4a4c..82ae8b911 100644 --- a/src/modules/shellprocess/CMakeLists.txt +++ b/src/modules/shellprocess/CMakeLists.txt @@ -8,10 +8,7 @@ calamares_add_plugin( shellprocess SHARED_LIB ) -if( ECM_FOUND ) - find_package( Qt5 COMPONENTS Test REQUIRED ) - include( ECMAddTests ) - +if( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( Tests.cpp TEST_NAME diff --git a/src/modules/users/CMakeLists.txt b/src/modules/users/CMakeLists.txt index 16e235fd5..207ffbb3a 100644 --- a/src/modules/users/CMakeLists.txt +++ b/src/modules/users/CMakeLists.txt @@ -1,9 +1,4 @@ -find_package(ECM ${ECM_VERSION} NO_MODULE) -if( ECM_FOUND ) - include( ECMAddTests ) -endif() - -find_package( Qt5 COMPONENTS Core Test REQUIRED ) +find_package( Qt5 COMPONENTS Core REQUIRED ) find_package( Crypt REQUIRED ) # Add optional libraries here @@ -44,7 +39,7 @@ calamares_add_plugin( users SHARED_LIB ) -if( ECM_FOUND ) +if( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( PasswordTests.cpp SetPasswordJob.cpp From 0b1c969a809f38283320643b3d066ca9fe56890d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 08:43:57 -0400 Subject: [PATCH 21/31] [libcalamares] Allow querying debug settings --- src/libcalamares/utils/Logger.cpp | 12 ++++++++++++ src/libcalamares/utils/Logger.h | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/src/libcalamares/utils/Logger.cpp b/src/libcalamares/utils/Logger.cpp index 735414b85..98aa2121f 100644 --- a/src/libcalamares/utils/Logger.cpp +++ b/src/libcalamares/utils/Logger.cpp @@ -55,6 +55,18 @@ setupLogLevel(unsigned int level) 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 log( const char* msg, unsigned int debugLevel, bool toDisk = true ) { diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h index dba386eae..0cb4b494f 100644 --- a/src/libcalamares/utils/Logger.h +++ b/src/libcalamares/utils/Logger.h @@ -89,6 +89,12 @@ namespace Logger */ 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. * From 5b936f33ecdecf1623b7499299d52069768d6a0d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 09:37:25 -0400 Subject: [PATCH 22/31] [libcalamares] Add tests - Test only the new debug-level query methods --- src/libcalamares/CMakeLists.txt | 13 ++++++++ src/libcalamares/Tests.cpp | 59 +++++++++++++++++++++++++++++++++ src/libcalamares/Tests.h | 36 ++++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/libcalamares/Tests.cpp create mode 100644 src/libcalamares/Tests.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 598d3c313..4bf78176e 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -105,6 +105,19 @@ install( TARGETS calamares 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 # lib/calamares can be used as module path for the Python interpreter. install( CODE " diff --git a/src/libcalamares/Tests.cpp b/src/libcalamares/Tests.cpp new file mode 100644 index 000000000..7595718e4 --- /dev/null +++ b/src/libcalamares/Tests.cpp @@ -0,0 +1,59 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, 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 + * 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 . + */ + +#include "Tests.h" + +#include "utils/Logger.h" + +#include + +QTEST_GUILESS_MAIN( LibCalamaresTests ) + +LibCalamaresTests::LibCalamaresTests() +{ +} + +LibCalamaresTests::~LibCalamaresTests() +{ +} + +void +LibCalamaresTests::initTestCase() +{ +} + +void +LibCalamaresTests::testDebugLevels() +{ + Logger::setupLogLevel( Logger::LOG_DISABLE ); + + QCOMPARE( Logger::logLevel(), 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 ); + } + } +} + diff --git a/src/libcalamares/Tests.h b/src/libcalamares/Tests.h new file mode 100644 index 000000000..123655c6e --- /dev/null +++ b/src/libcalamares/Tests.h @@ -0,0 +1,36 @@ +/* === This file is part of Calamares - === + * + * Copyright 2018, 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 + * 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 . + */ + +#ifndef TESTS_H +#define TESTS_H + +#include + +class LibCalamaresTests : public QObject +{ + Q_OBJECT +public: + LibCalamaresTests(); + ~LibCalamaresTests() override; + +private Q_SLOTS: + void initTestCase(); + void testDebugLevels(); +}; + +#endif From 4757496c3d340bc94bf64629331f4bb89ca9e9c3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 07:59:44 -0400 Subject: [PATCH 23/31] [partition] Improve partition-UUID logging. --- .../partition/jobs/FillGlobalStorageJob.cpp | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp index 43a5f3904..597d62a82 100644 --- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp +++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp @@ -56,9 +56,12 @@ findPartitionUuids( QList < Device* > devices ) QString path = p->partitionPath(); QString uuid = p->fileSystem().readUUID( p->partitionPath() ); hash.insert( path, uuid ); + cDebug() << ".. added path=" << path << "UUID=" << uuid; } } - cDebug() << hash; + + if ( hash.isEmpty() ) + cDebug() << ".. no UUIDs found."; return hash; } @@ -90,10 +93,16 @@ mapForPartition( Partition* partition, const QString& uuid ) dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS() ) map[ "fs" ] = dynamic_cast< FS::luks& >( partition->fileSystem() ).innerFS()->name(); map[ "uuid" ] = uuid; - cDebug() << partition->partitionPath() - << "mtpoint:" << PartitionInfo::mountPoint( partition ) - << "fs:" << map[ "fs" ] << '(' << map[ "fsName" ] << ')' - << uuid; + + // Debugging for inside the loop in createPartitionList(), + // so indent a bit + Logger::CLog deb = cDebug(); + using TR = Logger::DebugRow; + 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 ) ) { @@ -104,7 +113,7 @@ mapForPartition( Partition* partition, const QString& uuid ) map[ "luksMapperName" ] = luksFs->mapperName().split( "/" ).last(); map[ "luksUuid" ] = getLuksUuid( partition->partitionPath() ); 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\"]"; for ( auto device : m_devices ) { + cDebug() << ".. partitions on" << device->deviceNode(); for ( auto it = PartitionIterator::begin( device ); it != PartitionIterator::end( device ); ++it ) { + // Debug-logging is done when creating the map lst << mapForPartition( *it, hash.value( ( *it )->partitionPath() ) ); } } From 02a6b7dd12ca03d4edb5a7af29437e3a7614125b Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 08:23:01 -0400 Subject: [PATCH 24/31] [partition] Log the newly-created partition table - Log individual partitions instead of printing QObject() --- .../partition/jobs/CreatePartitionTableJob.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/modules/partition/jobs/CreatePartitionTableJob.cpp b/src/modules/partition/jobs/CreatePartitionTableJob.cpp index 2aec4a5fc..25bc79da6 100644 --- a/src/modules/partition/jobs/CreatePartitionTableJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionTableJob.cpp @@ -20,6 +20,8 @@ #include "jobs/CreatePartitionTableJob.h" +#include "core/PartitionIterator.h" + #include "utils/Logger.h" // KPMcore @@ -65,6 +67,14 @@ CreatePartitionTableJob::prettyStatusMessage() const } +static inline QDebug& +operator <<( QDebug& s, PartitionIterator& it ) +{ + s << ( ( *it ) ? ( *it )->deviceNode() : QString( "" ) ); + return s; +} + + Calamares::JobResult CreatePartitionTableJob::exec() { @@ -73,7 +83,11 @@ CreatePartitionTableJob::exec() PartitionTable* table = m_device->partitionTable(); cDebug() << "Creating new partition table of type" << table->typeName() - << ", uncommitted yet:\n" << table; + << ", uncommitted yet:"; + + for ( auto it = PartitionIterator::begin( table ); + it != PartitionIterator::end( table ); ++it ) + cDebug() << *it; QProcess lsblk; lsblk.setProgram( "lsblk" ); From 74ab06e20a6238e0ee7a7d05422e4d81ddc5dc2c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 08:29:46 -0400 Subject: [PATCH 25/31] [partition] Drop redundant logging --- src/modules/partition/core/PartitionCoreModule.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index b8011f066..f41142b6a 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -509,17 +509,8 @@ PartitionCoreModule::jobs() const lst << info->jobs; devices << info->device.data(); } - cDebug() << "Creating FillGlobalStorageJob with bootLoader path" << 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; } From bb586de056b076133efba37ea8f30832fcbc23aa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 08:45:10 -0400 Subject: [PATCH 26/31] [partition] Remove some slowdown methods when debugging is off - Running lsblk and mount for debugging purposes can be skipped when the debugging is going to be suppressed anyway. This will speed things up just a little for regular users. --- .../jobs/CreatePartitionTableJob.cpp | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/modules/partition/jobs/CreatePartitionTableJob.cpp b/src/modules/partition/jobs/CreatePartitionTableJob.cpp index 25bc79da6..937b8437d 100644 --- a/src/modules/partition/jobs/CreatePartitionTableJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionTableJob.cpp @@ -85,23 +85,26 @@ CreatePartitionTableJob::exec() cDebug() << "Creating new partition table of type" << table->typeName() << ", uncommitted yet:"; - for ( auto it = PartitionIterator::begin( table ); - it != PartitionIterator::end( table ); ++it ) - cDebug() << *it; + if ( Logger::logLevelEnabled( Logger::LOGDEBUG ) ) + { + for ( auto it = PartitionIterator::begin( table ); + it != PartitionIterator::end( table ); ++it ) + cDebug() << *it; - QProcess lsblk; - lsblk.setProgram( "lsblk" ); - lsblk.setProcessChannelMode( QProcess::MergedChannels ); - lsblk.start(); - lsblk.waitForFinished(); - cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput(); + QProcess lsblk; + lsblk.setProgram( "lsblk" ); + lsblk.setProcessChannelMode( QProcess::MergedChannels ); + lsblk.start(); + lsblk.waitForFinished(); + cDebug() << "lsblk:\n" << lsblk.readAllStandardOutput(); - QProcess mount; - mount.setProgram( "mount" ); - mount.setProcessChannelMode( QProcess::MergedChannels ); - mount.start(); - mount.waitForFinished(); - cDebug() << "mount:\n" << mount.readAllStandardOutput(); + QProcess mount; + mount.setProgram( "mount" ); + mount.setProcessChannelMode( QProcess::MergedChannels ); + mount.start(); + mount.waitForFinished(); + cDebug() << "mount:\n" << mount.readAllStandardOutput(); + } CreatePartitionTableOperation op(*m_device, table); op.setStatus(Operation::StatusRunning); From fc99824c8dd835a5fae6642dfe15c1ddbb02ce61 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Fri, 5 Oct 2018 17:22:12 +0200 Subject: [PATCH 27/31] [fsresizer] Fix string error, thanks Lithuanian translators --- src/modules/fsresizer/ResizeFSJob.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index 4320baba1..4df41a7d4 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -302,7 +302,7 @@ ResizeFSJob::exec() 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 %11 must be resized, but cannot" ).arg( m_fsname ) ); + : tr( "The device %1 must be resized, but cannot" ).arg( m_fsname ) ); return Calamares::JobResult::ok(); } From 4a2ca8bb77c15e90f24c520150e7ef60a00ba67c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 8 Oct 2018 06:46:35 -0400 Subject: [PATCH 28/31] [libcalamares] Fix compilation of tests - QCOMPARE is picky with types, enum vs unsigned int, so just hit it with a hammer. --- src/libcalamares/Tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcalamares/Tests.cpp b/src/libcalamares/Tests.cpp index 7595718e4..acf5b03d3 100644 --- a/src/libcalamares/Tests.cpp +++ b/src/libcalamares/Tests.cpp @@ -42,7 +42,7 @@ LibCalamaresTests::testDebugLevels() { Logger::setupLogLevel( Logger::LOG_DISABLE ); - QCOMPARE( Logger::logLevel(), Logger::LOG_DISABLE ); + QCOMPARE( Logger::logLevel(), static_cast( Logger::LOG_DISABLE ) ); for ( unsigned int level = 0; level <= Logger::LOGVERBOSE ; ++level ) { From c489320af5fab068420a9dbb5cfecca7e4bc1a46 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 8 Oct 2018 06:44:31 -0400 Subject: [PATCH 29/31] [calamares] Add option to obey XDG dirs - Prep-work for #941 - This does nothing, yet, just sets the stage for using XDG_CONFIG_DIRS and XDG_DATA_DIRS as well as the regular directories. --- src/calamares/main.cpp | 5 ++++ src/libcalamares/utils/CalamaresUtils.cpp | 28 +++++++++++++++++++++++ src/libcalamares/utils/CalamaresUtils.h | 7 ++++++ 3 files changed, 40 insertions(+) diff --git a/src/calamares/main.cpp b/src/calamares/main.cpp index 9893e6792..f855b060f 100644 --- a/src/calamares/main.cpp +++ b/src/calamares/main.cpp @@ -44,6 +44,8 @@ handle_args( CalamaresApplication& a ) "Verbose output for debugging purposes (0-8).", "level" ); QCommandLineOption configOption( QStringList{ "c", "config"}, "Configuration directory to use, for testing purposes.", "config" ); + QCommandLineOption xdgOption( QStringList{"X", "xdg-config"}, + "Use XDG_{CONFIG,DATA}_DIRS as well." ); QCommandLineParser parser; parser.setApplicationDescription( "Distribution-independent installer framework" ); @@ -53,6 +55,7 @@ handle_args( CalamaresApplication& a ) parser.addOption( debugOption ); parser.addOption( debugLevelOption ); parser.addOption( configOption ); + parser.addOption( xdgOption ); parser.process( a ); @@ -72,6 +75,8 @@ handle_args( CalamaresApplication& a ) } if ( parser.isSet( configOption ) ) CalamaresUtils::setAppDataDir( QDir( parser.value( configOption ) ) ); + if ( parser.isSet( xdgOption ) ) + CalamaresUtils::setXdgDirs(); } int diff --git a/src/libcalamares/utils/CalamaresUtils.cpp b/src/libcalamares/utils/CalamaresUtils.cpp index 6a892511a..bd8d02d1d 100644 --- a/src/libcalamares/utils/CalamaresUtils.cpp +++ b/src/libcalamares/utils/CalamaresUtils.cpp @@ -49,6 +49,9 @@ static QTranslator* s_brandingTranslator = nullptr; static QTranslator* s_translator = nullptr; static QString s_translatorLocaleName; +static bool s_haveExtraDirs = false; +static QStringList s_extraConfigDirs; +static QStringList s_extraDataDirs; static bool isWritableDir( const QDir& dir ) @@ -94,6 +97,31 @@ setAppDataDir( const QDir& dir ) s_isAppDataDirOverridden = true; } +void +setXdgDirs() +{ + s_haveExtraDirs = true; + s_extraConfigDirs.append( QString( qgetenv( "XDG_CONFIG_DIRS" ) ).split(':') ); + s_extraDataDirs.append( QString( qgetenv( "XDG_DATA_DIRS" ) ).split(':') ); +} + +QStringList +extraConfigDirs() +{ + if ( s_haveExtraDirs ) + return s_extraConfigDirs; + return QStringList(); +} + +QStringList +extraDataDirs() +{ + if ( s_haveExtraDirs ) + return s_extraDataDirs; + return QStringList(); +} + + bool isAppDataDirOverridden() diff --git a/src/libcalamares/utils/CalamaresUtils.h b/src/libcalamares/utils/CalamaresUtils.h index e64fe4eec..78362b01c 100644 --- a/src/libcalamares/utils/CalamaresUtils.h +++ b/src/libcalamares/utils/CalamaresUtils.h @@ -79,6 +79,13 @@ namespace CalamaresUtils DLLEXPORT void setQmlModulesDir( const QDir& dir ); + /** @brief Setup extra config and data dirs from the XDG variables. + * + */ + DLLEXPORT void setXdgDirs(); + DLLEXPORT QStringList extraConfigDirs(); + DLLEXPORT QStringList extraDataDirs(); + /** * @brief removeDiacritics replaces letters with diacritics and ligatures with * alternative forms and digraphs. From 3b8d2835e037edc6269737e4f667da66c684b668 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 8 Oct 2018 10:28:30 -0400 Subject: [PATCH 30/31] [calamares] Use XDG_{DATA,CONFIG}_DIRS as appropriate - Use DATA for the qml and branding directories (looks for qml/ and branding// in those directories). - Use CONFIG for the global settings and module settings (looks for settings.conf and module// in those directories). FIXES #941 --- src/calamares/CalamaresApplication.cpp | 9 +++++++++ src/libcalamares/utils/CalamaresUtils.cpp | 21 ++++++++++++++++++--- src/libcalamares/utils/CalamaresUtils.h | 5 ++++- src/libcalamaresui/modulesystem/Module.cpp | 4 ++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/src/calamares/CalamaresApplication.cpp b/src/calamares/CalamaresApplication.cpp index 018e2b677..0b715d6df 100644 --- a/src/calamares/CalamaresApplication.cpp +++ b/src/calamares/CalamaresApplication.cpp @@ -145,6 +145,9 @@ qmlDirCandidates( bool assumeBuilddir ) { if ( assumeBuilddir ) 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 ); } @@ -164,6 +167,9 @@ settingsFileCandidates( bool assumeBuilddir ) { if ( assumeBuilddir ) 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 << CalamaresUtils::appDataDir().absoluteFilePath( settings ); } @@ -182,6 +188,9 @@ brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename ) { if ( assumeBuilddir ) 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 << CalamaresUtils::appDataDir().absoluteFilePath( brandingFilename); } diff --git a/src/libcalamares/utils/CalamaresUtils.cpp b/src/libcalamares/utils/CalamaresUtils.cpp index bd8d02d1d..3ab758522 100644 --- a/src/libcalamares/utils/CalamaresUtils.cpp +++ b/src/libcalamares/utils/CalamaresUtils.cpp @@ -97,12 +97,23 @@ setAppDataDir( const QDir& dir ) 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; - s_extraConfigDirs.append( QString( qgetenv( "XDG_CONFIG_DIRS" ) ).split(':') ); - s_extraDataDirs.append( QString( qgetenv( "XDG_DATA_DIRS" ) ).split(':') ); + mungeEnvironment( s_extraConfigDirs, "XDG_CONFIG_DIRS" ); + mungeEnvironment( s_extraDataDirs, "XDG_DATA_DIRS" ); } QStringList @@ -121,7 +132,11 @@ extraDataDirs() return QStringList(); } - +bool +haveExtraDirs() +{ + return s_haveExtraDirs && ( !s_extraConfigDirs.isEmpty() || !s_extraDataDirs.isEmpty() ); +} bool isAppDataDirOverridden() diff --git a/src/libcalamares/utils/CalamaresUtils.h b/src/libcalamares/utils/CalamaresUtils.h index 78362b01c..baf7a12dc 100644 --- a/src/libcalamares/utils/CalamaresUtils.h +++ b/src/libcalamares/utils/CalamaresUtils.h @@ -80,10 +80,13 @@ namespace CalamaresUtils 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(); /** diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp index a1349c280..ef629ac4d 100644 --- a/src/libcalamaresui/modulesystem/Module.cpp +++ b/src/libcalamaresui/modulesystem/Module.cpp @@ -155,6 +155,10 @@ moduleConfigurationCandidates( bool assumeBuildDir, const QString& moduleName, c if ( assumeBuildDir && configFileName.contains( '/' ) ) 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 << CalamaresUtils::appDataDir().absoluteFilePath( QString( "modules/%1" ).arg( configFileName ) ); } From 594618f2cc417cd42cfdf8a129b95c9e90e06dd9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 8 Oct 2018 10:34:57 -0400 Subject: [PATCH 31/31] Changes: document -X option --- CHANGES | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 896a9fee2..7094f5866 100644 --- a/CHANGES +++ b/CHANGES @@ -14,7 +14,14 @@ This release contains contributions from (alphabetically by first name): ## Core ## -There are no core changes in this version. + * 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 ##