[merge] with upstream master branch

This commit is contained in:
Philip 2018-01-14 15:45:56 -05:00
commit bff6890358
23 changed files with 280 additions and 140 deletions

View File

@ -45,7 +45,7 @@ if( POLICY CMP0071 )
cmake_policy( SET CMP0071 NEW )
endif()
if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES
list(APPEND CMAKE_AUTOMOC_MACRO_NAMES
"K_PLUGIN_FACTORY_WITH_JSON"
"K_EXPORT_PLASMA_DATAENGINE_WITH_JSON"
"K_EXPORT_PLASMA_RUNNER"
@ -119,6 +119,7 @@ if( CMAKE_COMPILER_IS_GNUCXX )
endif()
include( FeatureSummary )
include( CMakeColors )
set( QT_VERSION 5.6.0 )
@ -313,6 +314,12 @@ add_feature_info(KCrash ${WITH_KF5Crash} "Crash dumps via KCrash")
feature_summary(WHAT ALL)
get_directory_property( SKIPPED_MODULES
DIRECTORY src/modules
DEFINITION LIST_SKIPPED_MODULES
)
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
# Add all targets to the build-tree export set
set( CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files" )
set( CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}" )

View File

@ -1,4 +1,3 @@
include( CMakeColors )
include( CalamaresAddTranslations )
set( MODULE_DATA_DESTINATION share/calamares/modules )
@ -9,6 +8,16 @@ macro( calamares_skip_module )
set( SKIPPED_MODULES ${SKIPPED_MODULES} ${ARGV} PARENT_SCOPE )
endmacro()
function( calamares_explain_skipped_modules )
if ( ARGN )
message( "${ColorReset}-- Skipped modules:" )
foreach( SUBDIRECTORY ${ARGN} )
message( "${ColorReset}-- Skipped ${BoldRed}${SUBDIRECTORY}${ColorReset}." )
endforeach()
message( "" )
endif()
endfunction()
function( calamares_add_module_subdirectory )
set( SUBDIRECTORY ${ARGV0} )

View File

@ -37,7 +37,7 @@ class CalamaresWindow : public QWidget
Q_OBJECT
public:
CalamaresWindow( QWidget* parent = nullptr );
virtual ~CalamaresWindow() {}
virtual ~CalamaresWindow() override {}
public slots:
/**

View File

@ -1,5 +1,3 @@
include( CMakeColors )
# The variable SKIP_MODULES can be set to skip particular modules;
# individual modules can also decide they must be skipped (e.g. OS-specific
# modules, or ones with unmet dependencies). Collect the skipped modules
@ -31,13 +29,9 @@ foreach( SUBDIRECTORY ${SUBDIRECTORIES} )
endif()
endforeach()
if ( LIST_SKIPPED_MODULES )
message( "${ColorReset}-- Skipped modules:" )
foreach( SUBDIRECTORY ${LIST_SKIPPED_MODULES} )
message( "${ColorReset}-- Skipped ${BoldRed}${SUBDIRECTORY}${ColorReset}." )
endforeach()
message( "" )
endif()
# This is *also* done in top-level, so list is displayed
# both before and after the feature summary.
calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} )
include( CalamaresAddTranslations )
add_calamares_python_translations( ${CALAMARES_TRANSLATION_LANGUAGES} )

View File

@ -20,8 +20,16 @@ fallbackKernelLine: ", with _manjaro_kernel_ (fallback initramfs)"
grubInstall: "grub-install"
grubMkconfig: "grub-mkconfig"
grubCfg: "/boot/grub/grub.cfg"
# Optionally set the --bootloader-id to use for EFI. If not set, this defaults
# to the bootloaderEntryName from branding.desc with problematic characters
# replaced. If an efiBootloaderId is specified here, it is taken to already be a
# valid directory name, so no such postprocessing is done in this case.
# Optionally set the bootloader ID to use for EFI. This is passed to
# grub-install --bootloader-id.
#
# If not set here, the value from bootloaderEntryName from branding.desc
# is used, with problematic characters (space and slash) replaced.
#
# The ID is also used as a directory name within the EFI environment,
# and the bootloader is copied from /boot/efi/EFI/<dirname>/ . When
# setting the option here, take care to use only valid directory
# names since no sanitizing is done.
#
# efiBootloaderId: "dirname"

View File

@ -292,10 +292,49 @@ KeyboardPage::guessLayout( const QStringList& langParts )
void
KeyboardPage::onActivate()
{
static auto specialCaseMap = QMap<std::string, std::string>( {
{ "ar_EG", "ara" },
{ "ca_ES", "cat_ES" },
{ "as_ES", "ast_ES" },
/* Guessing a keyboard layout based on the locale means
* mapping between language identifiers in <lang>_<country>
* format to keyboard mappings, which are <country>_<layout>
* format; in addition, some countries have multiple languages,
* so fr_BE and nl_BE want different layouts (both Belgian)
* and sometimes the language-country name doesn't match the
* keyboard-country name at all (e.g. Ellas vs. Greek).
*
* This is a table of language-to-keyboard mappings. The
* language identifier is the key, while the value is
* a string that is used instead of the real language
* identifier in guessing -- so it should be something
* like <layout>_<country>.
*/
static constexpr char arabic[] = "ara";
static const auto specialCaseMap = QMap<std::string, std::string>( {
/* Most Arab countries map to Arabic keyboard (Default) */
{ "ar_AE", arabic },
{ "ar_BH", arabic },
{ "ar_DZ", arabic },
{ "ar_EG", arabic },
{ "ar_IN", arabic },
{ "ar_IQ", arabic },
{ "ar_JO", arabic },
{ "ar_KW", arabic },
{ "ar_LB", arabic },
{ "ar_LY", arabic },
/* Not Morocco: use layout ma */
{ "ar_OM", arabic },
{ "ar_QA", arabic },
{ "ar_SA", arabic },
{ "ar_SD", arabic },
{ "ar_SS", arabic },
/* Not Syria: use layout sy */
{ "ar_TN", arabic },
{ "ar_YE", arabic },
{ "ca_ES", "cat_ES" }, /* Catalan */
{ "as_ES", "ast_ES" }, /* Asturian */
{ "en_CA", "eng_CA" }, /* Canadian English */
{ "el_CY", "gr" }, /* Greek in Cyprus */
{ "el_GR", "gr" }, /* Greek in Greeze */
{ "ig_NG", "igbo_NG" }, /* Igbo in Nigeria */
{ "ha_NG", "hausa_NG" } /* Hausa */
} );
ui->listLayout->setFocus();

View File

@ -66,7 +66,6 @@ protected slots:
private:
/// Guess a layout based on the split-apart locale
void guessLayout( const QStringList& langParts );
void updateVariants( const QPersistentModelIndex& currentItem,
QString currentVariant = QString() );

View File

@ -144,7 +144,7 @@ Qt::ItemFlags
PackageModel::flags( const QModelIndex& index ) const
{
if ( !index.isValid() )
return 0;
return Qt::ItemFlags();
if ( index.column() == 0 )
return Qt::ItemIsUserCheckable | QAbstractItemModel::flags( index );
return QAbstractItemModel::flags( index );

View File

@ -5,64 +5,72 @@ include(GenerateExportHeader)
find_package( Qt5 REQUIRED DBus )
find_package( KF5 REQUIRED Config CoreAddons I18n WidgetsAddons )
find_package( KPMcore 3.3 REQUIRED )
include_directories( ${KPMCORE_INCLUDE_DIR} )
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
add_subdirectory( tests )
calamares_add_plugin( partition
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
core/BootLoaderModel.cpp
core/ColorUtils.cpp
core/DeviceList.cpp
core/DeviceModel.cpp
core/KPMHelpers.cpp
core/PartitionActions.cpp
core/PartitionCoreModule.cpp
core/PartitionInfo.cpp
core/PartitionIterator.cpp
core/PartitionModel.cpp
core/PartUtils.cpp
gui/BootInfoWidget.cpp
gui/ChoicePage.cpp
gui/CreatePartitionDialog.cpp
gui/DeviceInfoWidget.cpp
gui/EditExistingPartitionDialog.cpp
gui/EncryptWidget.cpp
gui/PartitionPage.cpp
gui/PartitionBarsView.cpp
gui/PartitionLabelsView.cpp
gui/PartitionSizeController.cpp
gui/PartitionSplitterWidget.cpp
gui/PartitionViewStep.cpp
gui/PrettyRadioButton.cpp
gui/ScanningDialog.cpp
gui/ReplaceWidget.cpp
jobs/ClearMountsJob.cpp
jobs/ClearTempMountsJob.cpp
jobs/CreatePartitionJob.cpp
jobs/CreatePartitionTableJob.cpp
jobs/DeletePartitionJob.cpp
jobs/FillGlobalStorageJob.cpp
jobs/FormatPartitionJob.cpp
jobs/PartitionJob.cpp
jobs/ResizePartitionJob.cpp
jobs/SetPartitionFlagsJob.cpp
UI
gui/ChoicePage.ui
gui/CreatePartitionDialog.ui
gui/CreatePartitionTableDialog.ui
gui/EditExistingPartitionDialog.ui
gui/EncryptWidget.ui
gui/PartitionPage.ui
gui/ReplaceWidget.ui
LINK_PRIVATE_LIBRARIES
kpmcore
calamaresui
KF5::CoreAddons
SHARED_LIB
find_package( KPMcore 3.3 )
set_package_properties(
KPMcore PROPERTIES
PURPOSE "For partitioning module"
)
if ( KPMcore_FOUND )
include_directories( ${KPMCORE_INCLUDE_DIR} )
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
add_subdirectory( tests )
calamares_add_plugin( partition
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
core/BootLoaderModel.cpp
core/ColorUtils.cpp
core/DeviceList.cpp
core/DeviceModel.cpp
core/KPMHelpers.cpp
core/PartitionActions.cpp
core/PartitionCoreModule.cpp
core/PartitionInfo.cpp
core/PartitionIterator.cpp
core/PartitionModel.cpp
core/PartUtils.cpp
gui/BootInfoWidget.cpp
gui/ChoicePage.cpp
gui/CreatePartitionDialog.cpp
gui/DeviceInfoWidget.cpp
gui/EditExistingPartitionDialog.cpp
gui/EncryptWidget.cpp
gui/PartitionPage.cpp
gui/PartitionBarsView.cpp
gui/PartitionLabelsView.cpp
gui/PartitionSizeController.cpp
gui/PartitionSplitterWidget.cpp
gui/PartitionViewStep.cpp
gui/PrettyRadioButton.cpp
gui/ScanningDialog.cpp
gui/ReplaceWidget.cpp
jobs/ClearMountsJob.cpp
jobs/ClearTempMountsJob.cpp
jobs/CreatePartitionJob.cpp
jobs/CreatePartitionTableJob.cpp
jobs/DeletePartitionJob.cpp
jobs/FillGlobalStorageJob.cpp
jobs/FormatPartitionJob.cpp
jobs/PartitionJob.cpp
jobs/ResizePartitionJob.cpp
jobs/SetPartitionFlagsJob.cpp
UI
gui/ChoicePage.ui
gui/CreatePartitionDialog.ui
gui/CreatePartitionTableDialog.ui
gui/EditExistingPartitionDialog.ui
gui/EncryptWidget.ui
gui/PartitionPage.ui
gui/ReplaceWidget.ui
LINK_PRIVATE_LIBRARIES
kpmcore
calamaresui
KF5::CoreAddons
SHARED_LIB
)
else()
calamares_skip_module( "partition (missing suitable KPMcore)" )
endif()

View File

@ -340,4 +340,26 @@ isEfiSystem()
return QDir( "/sys/firmware/efi/efivars" ).exists();
}
bool
isEfiBootable( const Partition* candidate )
{
/* If bit 17 is set, old-style Esp flag, it's OK */
if ( candidate->activeFlags().testFlag( PartitionTable::FlagEsp ) )
return true;
/* Otherwise, if it's a GPT table, Boot (bit 0) is the same as Esp */
const PartitionNode* root = candidate;
while ( root && !root->isRoot() )
root = root->parent();
// Strange case: no root found, no partition table node?
if ( !root )
return false;
const PartitionTable* table = dynamic_cast<const PartitionTable*>( root );
return table && ( table->type() == PartitionTable::TableType::gpt ) &&
candidate->activeFlags().testFlag( PartitionTable::FlagBoot );
}
} // nmamespace PartUtils

View File

@ -67,6 +67,11 @@ OsproberEntryList runOsprober( PartitionCoreModule* core );
*/
bool isEfiSystem();
/**
* @brief Is the given @p partition bootable in EFI? Depending on
* the partition table layout, this may mean different flags.
*/
bool isEfiBootable( const Partition* candidate );
}
#endif // PARTUTILS_H

View File

@ -505,16 +505,7 @@ PartitionCoreModule::scanForEfiSystemPartitions()
}
QList< Partition* > efiSystemPartitions =
KPMHelpers::findPartitions( devices,
[]( Partition* partition ) -> bool
{
if ( partition->activeFlags().testFlag( PartitionTable::FlagEsp ) )
{
cDebug() << "Found EFI system partition at" << partition->partitionPath();
return true;
}
return false;
} );
KPMHelpers::findPartitions( devices, PartUtils::isEfiBootable );
if ( efiSystemPartitions.isEmpty() )
cDebug() << "WARNING: system is EFI but no EFI system partitions found.";

View File

@ -300,6 +300,16 @@ ChoicePage::selectedDevice()
}
void
ChoicePage::hideButtons()
{
m_eraseButton->hide();
m_replaceButton->hide();
m_alongsideButton->hide();
m_somethingElseButton->hide();
}
/**
* @brief ChoicePage::applyDeviceChoice handler for the selected event of the device
* picker. Calls ChoicePage::selectedDevice() to get the current Device*, then
@ -311,7 +321,10 @@ void
ChoicePage::applyDeviceChoice()
{
if ( !selectedDevice() )
{
hideButtons();
return;
}
if ( m_core->isDirty() )
{
@ -342,11 +355,14 @@ ChoicePage::continueApplyDeviceChoice()
// applyDeviceChoice() will be called again momentarily as soon as we handle the
// PartitionCoreModule::reverted signal.
if ( !currd )
{
hideButtons();
return;
}
updateDeviceStatePreview();
// Preview setup done. Now we show/hide choices as needed.
// Preview setup done. Now we show/hide choices as needed.
setupActions();
m_lastSelectedDeviceIndex = m_drivesCombo->currentIndex();
@ -562,7 +578,11 @@ ChoicePage::onLeave()
{
if ( m_bootloaderComboBox.isNull() )
{
m_core->setBootLoaderInstallPath( selectedDevice()->deviceNode() );
auto d_p = selectedDevice();
if ( d_p )
m_core->setBootLoaderInstallPath( d_p->deviceNode() );
else
cDebug() << "WARNING: No device selected for bootloader.";
}
else
{
@ -1156,6 +1176,9 @@ ChoicePage::setupActions()
else
m_deviceInfoWidget->setPartitionTableType( PartitionTable::unknownTableType );
// Manual partitioning is always a possibility
m_somethingElseButton->show();
bool atLeastOneCanBeResized = false;
bool atLeastOneCanBeReplaced = false;
bool atLeastOneIsMounted = false; // Suppress 'erase' if so
@ -1332,18 +1355,16 @@ ChoicePage::updateNextEnabled()
{
bool enabled = false;
auto sm_p = m_beforePartitionBarsView ? m_beforePartitionBarsView->selectionModel() : nullptr;
switch ( m_choice )
{
case NoChoice:
enabled = false;
break;
case Replace:
enabled = m_beforePartitionBarsView->selectionModel()->
currentIndex().isValid();
break;
case Alongside:
enabled = m_beforePartitionBarsView->selectionModel()->
currentIndex().isValid();
enabled = sm_p && sm_p->currentIndex().isValid();
break;
case Erase:
case Manual:

View File

@ -113,8 +113,12 @@ private:
void setupChoices();
QComboBox* createBootloaderComboBox( QWidget* parentButton );
Device* selectedDevice();
void applyDeviceChoice();
void continueApplyDeviceChoice();
/* Change the UI depending on the device selected. */
void hideButtons(); // Hide everything when no device
void applyDeviceChoice(); // Start scanning new device
void continueApplyDeviceChoice(); // .. called after scan
void updateDeviceStatePreview();
void updateActionChoicePreview( ChoicePage::Choice choice );
void setupActions();

View File

@ -408,7 +408,7 @@ PartitionViewStep::onLeave()
.arg( *Calamares::Branding::ShortProductName )
.arg( espMountPoint );
}
else if ( esp && !esp->activeFlags().testFlag( PartitionTable::FlagEsp ) )
else if ( esp && !PartUtils::isEfiBootable( esp ) )
{
message = tr( "EFI system partition flag not set" );
description = tr( "An EFI system partition is necessary to start %1."

View File

@ -30,7 +30,7 @@ class TrackingInstallJob : public Calamares::Job
Q_OBJECT
public:
TrackingInstallJob( const QString& url );
~TrackingInstallJob();
~TrackingInstallJob() override;
QString prettyName() const override;
QString prettyDescription() const override;

View File

@ -1,18 +0,0 @@
### Umount Module
---------
This module represents the last part of the installation, the unmounting of partitions used for the install. It is also the last place where it is possible to copy files to the target system, thus the best place to copy an installation log.
You can either use the default ```/root/.cache/Calamares/Calamares/Calamares.log```
to copy or if you want to use the full output of ```sudo calamares -d``` to create a log you will need to include a log creation to your launcher script or add it to the used calamares.desktop, example of a launcher script:
```
#!/bin/sh
sudo /usr/bin/calamares -d > installation.log
```
Example desktop line:
```
Exec=sudo /usr/bin/calamares -d > installation.log
```
Set the source and destination path of your install log in umount.conf.
If you do not wish to use the copy of an install log feature, no action needed, the default settings do not execute the copy of an install log in this module.

View File

@ -55,11 +55,18 @@ def run():
"destLog" in libcalamares.job.configuration):
log_source = libcalamares.job.configuration["srcLog"]
log_destination = libcalamares.job.configuration["destLog"]
# Relocate log_destination into target system
log_destination = '{!s}/{!s}'.format(root_mount_point, log_destination)
# Make sure source is a string
log_source = '{!s}'.format(log_source)
# copy installation log before umount
if os.path.exists('{!s}'.format(log_source)):
shutil.copy2('{!s}'.format(log_source), '{!s}/{!s}'.format(
root_mount_point, log_destination))
if os.path.exists(log_source):
try:
shutil.copy2(log_source, log_destination)
except Exception as e:
libcalamares.utils.debug("WARNING Could not preserve file {!s}, "
"error {!s}".format(log_source, e))
if not root_mount_point:
return ("No mount point for root partition in globalstorage",

View File

@ -1,9 +1,42 @@
### Umount Module
#
# This module represents the last part of the installation, the unmounting
# of partitions used for the install. It is also the last place where it
# is possible to copy files to the target system, thus the best place to
# copy an installation log.
#
# This module has two configuration keys:
# srcLog location in the live system where the log is
# destLog location in the target system to copy the log
#
# You can either use the default source path (which is
# `/root/.cache/Calamares/Calamares/Calamares.log` ) to copy the regular log,
# or if you want to use the full output of `sudo calamares -d` you will need
# to redirect standard output, for instance in a launcher script or
# in the desktop file.
#
# Example launcher script:
#
# ```
# #!/bin/sh
# sudo /usr/bin/calamares -d > installation.log
# ```
#
# Example desktop line:
#
# ```
# Exec=sudo /usr/bin/calamares -d > installation.log
# ```
#
# If no source and destination are set, no copy is attempted. If the
# copy fails for some reason, a warning is printed but the installation
# does not fail.
---
#srcLog: "/path/to/installation.log"
#destLog: "/var/log/installation.log"
# example when using the Calamares created log:
#srcLog: "/root/.cache/Calamares/Calamares/Calamares.log"
#destLog: "/var/log/Calamares.log"
# example when creating with a sudo calamares -d log:
# example when using the normal Calamares log:
srcLog: "/root/.cache/Calamares/Calamares/Calamares.log"
destLog: "/var/log/Calamares.log"
# example when using a log created by `sudo calamares -d`:
#srcLog: "/home/live/installation.log"
#destLog: "/var/log/installation.log"

View File

@ -218,7 +218,7 @@ class UnpackOperation:
return None
finally:
shutil.rmtree(source_mount_path)
shutil.rmtree(source_mount_path, ignore_errors=True, onerror=None)
def mount_image(self, entry, imgmountdir):
"""

View File

@ -1,20 +1,24 @@
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
find_package( LIBPARTED REQUIRED )
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED DBus Network )
find_package( LIBPARTED )
if ( LIBPARTED_FOUND )
set( PARTMAN_SRC checker/partman_devices.c )
set( CHECKER_LINK_LIBRARIES ${LIBPARTED_LIBRARY} )
else()
set( PARTMAN_SRC )
set( CHECKER_LINK_LIBRARIES )
add_definitions( -DWITHOUT_LIBPARTED )
endif()
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
set( CHECKER_SOURCES
checker/CheckItemWidget.cpp
checker/CheckerWidget.cpp
checker/RequirementsChecker.cpp
checker/partman_devices.c
)
set( CHECKER_LINK_LIBRARIES
${LIBPARTED_LIBRARY}
Qt5::DBus
Qt5::Network
${PARTMAN_SRC}
)
calamares_add_plugin( welcome
@ -29,5 +33,7 @@ calamares_add_plugin( welcome
LINK_PRIVATE_LIBRARIES
calamaresui
${CHECKER_LINK_LIBRARIES}
Qt5::DBus
Qt5::Network
SHARED_LIB
)

View File

@ -2,7 +2,7 @@
*
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
* Copyright 2015, Anke Boersma <demm@kaosx.us>
* Copyright 2017, Adriaan de Groot <groot@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -82,7 +82,7 @@ WelcomePage::WelcomePage( RequirementsChecker* requirementsChecker, QWidget* par
" Philip Müller, Pier Luigi Fiorini, Rohan Garg and the <a "
"href=\"https://www.transifex.com/calamares/calamares/\">Calamares "
"translators team</a>.<br/><br/>"
"<a href=\"http://calamares.io/\">Calamares</a> "
"<a href=\"https://calamares.io/\">Calamares</a> "
"development is sponsored by <br/>"
"<a href=\"http://www.blue-systems.com/\">Blue Systems</a> - "
"Liberating Software."

View File

@ -313,7 +313,12 @@ RequirementsChecker::verdict() const
bool
RequirementsChecker::checkEnoughStorage( qint64 requiredSpace )
{
#ifdef WITHOUT_LIBPARTED
cDebug() << "WARNING: RequirementsChecker is configured without libparted.";
return false;
#else
return check_big_enough( requiredSpace );
#endif
}