Merge branch 'development' into 3.2.x-stable
This commit is contained in:
commit
693ea79704
31
CHANGES
31
CHANGES
@ -3,6 +3,36 @@ contributors are listed. Note that Calamares does not have a historical
|
|||||||
changelog -- this log starts with version 3.2.0. The release notes on the
|
changelog -- this log starts with version 3.2.0. The release notes on the
|
||||||
website will have to do for older versions.
|
website will have to do for older versions.
|
||||||
|
|
||||||
|
# 3.2.5 (unreleased) #
|
||||||
|
|
||||||
|
This release contains contributions from (alphabetically by first name):
|
||||||
|
- Arnaud Ferraris
|
||||||
|
- Dan Simmons
|
||||||
|
- Gabriel Craciunescu
|
||||||
|
|
||||||
|
## Core ##
|
||||||
|
|
||||||
|
* View modules (in C++) can now perform their own requirements-checking
|
||||||
|
to see if installation makes sense. This expands upon the existing
|
||||||
|
requirements checks in the welcome module (RAM, disk space, ..).
|
||||||
|
The checks have been made asynchronous, so that responsiveness during
|
||||||
|
requirements-checking is improved and the user has better feedback.
|
||||||
|
|
||||||
|
## Modules ##
|
||||||
|
|
||||||
|
* *Bootloader* module: a serious bug introduced in 3.2.4 which prevents
|
||||||
|
succesful boot after installation on EFI machines, has been repaired.
|
||||||
|
(Thanks to Gabriel)
|
||||||
|
* *Partition* module: it is now possible to build without libparted. Since
|
||||||
|
KPMCore may not need this library anymore, it is a dependency that will
|
||||||
|
be dropped as soon as it is feasible. Add `-DCMAKE_DISABLE_FIND_PACKAGE_LIBPARTED=ON`
|
||||||
|
to the CMake flags to do so.
|
||||||
|
* Python modules: several modules have had translations added. This is
|
||||||
|
usually only visible when the module runs as part of the *exec* step,
|
||||||
|
when the module's *pretty name* is displayed. In addition, error
|
||||||
|
messages are now translated.
|
||||||
|
|
||||||
|
|
||||||
# 3.2.4 (2019-02-12) #
|
# 3.2.4 (2019-02-12) #
|
||||||
|
|
||||||
This release contains contributions from (alphabetically by first name):
|
This release contains contributions from (alphabetically by first name):
|
||||||
@ -66,6 +96,7 @@ This release contains contributions from (alphabetically by first name):
|
|||||||
the installation media to the target stystem. This can be used, for instance,
|
the installation media to the target stystem. This can be used, for instance,
|
||||||
for block-level-identical installations.
|
for block-level-identical installations.
|
||||||
|
|
||||||
|
|
||||||
# 3.2.3 (2019-01-09) #
|
# 3.2.3 (2019-01-09) #
|
||||||
|
|
||||||
This release contains contributions from (alphabetically by first name):
|
This release contains contributions from (alphabetically by first name):
|
||||||
|
@ -75,8 +75,8 @@ set( CALAMARES_DESCRIPTION_SUMMARY
|
|||||||
|
|
||||||
set( CALAMARES_VERSION_MAJOR 3 )
|
set( CALAMARES_VERSION_MAJOR 3 )
|
||||||
set( CALAMARES_VERSION_MINOR 2 )
|
set( CALAMARES_VERSION_MINOR 2 )
|
||||||
set( CALAMARES_VERSION_PATCH 4 )
|
set( CALAMARES_VERSION_PATCH 5 )
|
||||||
set( CALAMARES_VERSION_RC 0 )
|
set( CALAMARES_VERSION_RC 1 )
|
||||||
|
|
||||||
|
|
||||||
### Transifex (languages) info
|
### Transifex (languages) info
|
||||||
@ -240,7 +240,7 @@ include( CMakeColors )
|
|||||||
|
|
||||||
### DEPENDENCIES
|
### DEPENDENCIES
|
||||||
#
|
#
|
||||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Core Gui Widgets LinguistTools Svg Quick QuickWidgets )
|
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui Widgets LinguistTools Svg Quick QuickWidgets )
|
||||||
find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED )
|
find_package( YAMLCPP ${YAMLCPP_VERSION} REQUIRED )
|
||||||
if( INSTALL_POLKIT )
|
if( INSTALL_POLKIT )
|
||||||
find_package( PolkitQt5-1 REQUIRED )
|
find_package( PolkitQt5-1 REQUIRED )
|
||||||
|
@ -348,6 +348,7 @@ void
|
|||||||
CalamaresApplication::initViewSteps()
|
CalamaresApplication::initViewSteps()
|
||||||
{
|
{
|
||||||
cDebug() << "STARTUP: loadModules for all modules done";
|
cDebug() << "STARTUP: loadModules for all modules done";
|
||||||
|
m_moduleManager->checkRequirements();
|
||||||
if ( Calamares::Branding::instance()->windowMaximize() )
|
if ( Calamares::Branding::instance()->windowMaximize() )
|
||||||
{
|
{
|
||||||
m_mainwindow->setWindowFlag( Qt::FramelessWindowHint );
|
m_mainwindow->setWindowFlag( Qt::FramelessWindowHint );
|
||||||
@ -355,6 +356,7 @@ CalamaresApplication::initViewSteps()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_mainwindow->show();
|
m_mainwindow->show();
|
||||||
|
|
||||||
ProgressTreeModel* m = new ProgressTreeModel( nullptr );
|
ProgressTreeModel* m = new ProgressTreeModel( nullptr );
|
||||||
ProgressTreeView::instance()->setModel( m );
|
ProgressTreeView::instance()->setModel( m );
|
||||||
cDebug() << "STARTUP: Window now visible and ProgressTreeView populated";
|
cDebug() << "STARTUP: Window now visible and ProgressTreeView populated";
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -68,9 +68,9 @@ logLevel()
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
log( const char* msg, unsigned int debugLevel, bool toDisk = true )
|
log( const char* msg, unsigned int debugLevel )
|
||||||
{
|
{
|
||||||
if ( toDisk || debugLevel < s_threshold )
|
if ( true )
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &s_mutex );
|
QMutexLocker lock( &s_mutex );
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ struct NamedEnumTable
|
|||||||
*
|
*
|
||||||
* static const NamedEnumTable<Colors> c{ {"red", Colors::Red } };
|
* static const NamedEnumTable<Colors> c{ {"red", Colors::Red } };
|
||||||
*/
|
*/
|
||||||
NamedEnumTable( const std::initializer_list< pair_t >& v ) : table( v ) { /* static_assert( v.size() > 0 ); */ };
|
NamedEnumTable( const std::initializer_list< pair_t >& v ) : table( v ) { /* static_assert( v.size() > 0 ); */ }
|
||||||
|
|
||||||
/** @brief Find a name @p s in the table.
|
/** @brief Find a name @p s in the table.
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,10 +25,16 @@
|
|||||||
namespace CalamaresUtils
|
namespace CalamaresUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/** User defined literals, 1_KiB is 1 KibiByte (= 2^10 bytes) */
|
||||||
|
constexpr qint64 operator ""_KiB( unsigned long long m )
|
||||||
|
{
|
||||||
|
return qint64(m) * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
/** User defined literals, 1_MiB is 1 MibiByte (= 2^20 bytes) */
|
/** User defined literals, 1_MiB is 1 MibiByte (= 2^20 bytes) */
|
||||||
constexpr qint64 operator ""_MiB( unsigned long long m )
|
constexpr qint64 operator ""_MiB( unsigned long long m )
|
||||||
{
|
{
|
||||||
return qint64(m) * 1024 * 1024;
|
return operator ""_KiB(m) * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** User defined literals, 1_GiB is 1 GibiByte (= 2^30 bytes) */
|
/** User defined literals, 1_GiB is 1 GibiByte (= 2^30 bytes) */
|
||||||
@ -36,6 +43,11 @@ constexpr qint64 operator ""_GiB( unsigned long long m )
|
|||||||
return operator ""_MiB(m) * 1024;
|
return operator ""_MiB(m) * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr qint64 KiBtoBytes( unsigned long long m )
|
||||||
|
{
|
||||||
|
return operator ""_KiB( m );
|
||||||
|
}
|
||||||
|
|
||||||
constexpr qint64 MiBtoBytes( unsigned long long m )
|
constexpr qint64 MiBtoBytes( unsigned long long m )
|
||||||
{
|
{
|
||||||
return operator ""_MiB( m );
|
return operator ""_MiB( m );
|
||||||
@ -46,7 +58,12 @@ constexpr qint64 GiBtoBytes( unsigned long long m )
|
|||||||
return operator ""_GiB( m );
|
return operator ""_GiB( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr qint64 MiBToBytes( double m )
|
constexpr qint64 KiBtoBytes( double m )
|
||||||
|
{
|
||||||
|
return qint64(m * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr qint64 MiBtoBytes( double m )
|
||||||
{
|
{
|
||||||
return qint64(m * 1024 * 1024);
|
return qint64(m * 1024 * 1024);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ set( calamaresui_SOURCES
|
|||||||
modulesystem/Module.cpp
|
modulesystem/Module.cpp
|
||||||
modulesystem/ModuleManager.cpp
|
modulesystem/ModuleManager.cpp
|
||||||
modulesystem/ProcessJobModule.cpp
|
modulesystem/ProcessJobModule.cpp
|
||||||
|
modulesystem/Requirement.cpp
|
||||||
|
modulesystem/RequirementsChecker.cpp
|
||||||
modulesystem/ViewModule.cpp
|
modulesystem/ViewModule.cpp
|
||||||
|
|
||||||
utils/CalamaresUtilsGui.cpp
|
utils/CalamaresUtilsGui.cpp
|
||||||
|
@ -281,4 +281,10 @@ Module::initFrom( const QVariantMap& moduleDescriptor )
|
|||||||
m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool();
|
m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequirementsList
|
||||||
|
Module::checkRequirements()
|
||||||
|
{
|
||||||
|
return RequirementsList();
|
||||||
|
}
|
||||||
|
|
||||||
} //ns
|
} //ns
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#ifndef CALAMARES_MODULE_H
|
#ifndef CALAMARES_MODULE_H
|
||||||
#define CALAMARES_MODULE_H
|
#define CALAMARES_MODULE_H
|
||||||
|
|
||||||
|
#include "Requirement.h"
|
||||||
#include "UiDllMacro.h"
|
#include "UiDllMacro.h"
|
||||||
|
|
||||||
#include <Typedefs.h>
|
#include <Typedefs.h>
|
||||||
@ -178,6 +180,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
QVariantMap configurationMap();
|
QVariantMap configurationMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check the requirements of this module.
|
||||||
|
*/
|
||||||
|
virtual RequirementsList checkRequirements();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit Module();
|
explicit Module();
|
||||||
virtual void initFrom( const QVariantMap& moduleDescriptor );
|
virtual void initFrom( const QVariantMap& moduleDescriptor );
|
||||||
|
@ -21,26 +21,23 @@
|
|||||||
|
|
||||||
#include "ExecutionViewStep.h"
|
#include "ExecutionViewStep.h"
|
||||||
#include "Module.h"
|
#include "Module.h"
|
||||||
#include "utils/Logger.h"
|
#include "RequirementsChecker.h"
|
||||||
#include "utils/YamlUtils.h"
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
|
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/YamlUtils.h"
|
||||||
|
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
#define MODULE_CONFIG_FILENAME "module.desc"
|
|
||||||
|
|
||||||
namespace Calamares
|
namespace Calamares
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
ModuleManager* ModuleManager::s_instance = nullptr;
|
ModuleManager* ModuleManager::s_instance = nullptr;
|
||||||
|
|
||||||
|
|
||||||
ModuleManager*
|
ModuleManager*
|
||||||
ModuleManager::instance()
|
ModuleManager::instance()
|
||||||
{
|
{
|
||||||
@ -94,7 +91,7 @@ ModuleManager::doInit()
|
|||||||
bool success = currentDir.cd( subdir );
|
bool success = currentDir.cd( subdir );
|
||||||
if ( success )
|
if ( success )
|
||||||
{
|
{
|
||||||
QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( MODULE_CONFIG_FILENAME ) );
|
QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( QLatin1Literal( "module.desc") ) );
|
||||||
if ( ! ( descriptorFileInfo.exists() && descriptorFileInfo.isReadable() ) )
|
if ( ! ( descriptorFileInfo.exists() && descriptorFileInfo.isReadable() ) )
|
||||||
{
|
{
|
||||||
cDebug() << Q_FUNC_INFO << "unreadable file: "
|
cDebug() << Q_FUNC_INFO << "unreadable file: "
|
||||||
@ -307,6 +304,26 @@ ModuleManager::loadModules()
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ModuleManager::checkRequirements()
|
||||||
|
{
|
||||||
|
cDebug() << "Checking module requirements ..";
|
||||||
|
|
||||||
|
QVector< Module* > modules( m_loadedModulesByInstanceKey.count() );
|
||||||
|
int count = 0;
|
||||||
|
for (const auto& module : m_loadedModulesByInstanceKey )
|
||||||
|
{
|
||||||
|
modules[count++] = module;
|
||||||
|
}
|
||||||
|
|
||||||
|
RequirementsChecker *rq = new RequirementsChecker( modules, this );
|
||||||
|
connect( rq, &RequirementsChecker::requirementsResult, this, &ModuleManager::requirementsResult );
|
||||||
|
connect( rq, &RequirementsChecker::requirementsComplete, this, &ModuleManager::requirementsComplete );
|
||||||
|
connect( rq, &RequirementsChecker::requirementsProgress, this, &ModuleManager::requirementsProgress );
|
||||||
|
connect( rq, &RequirementsChecker::done, rq, &RequirementsChecker::deleteLater );
|
||||||
|
|
||||||
|
QTimer::singleShot( 0, rq, &RequirementsChecker::run );
|
||||||
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList
|
||||||
ModuleManager::checkDependencies()
|
ModuleManager::checkDependencies()
|
||||||
@ -334,8 +351,6 @@ ModuleManager::checkDependencies()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( somethingWasRemovedBecauseOfUnmetDependencies )
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if ( !somethingWasRemovedBecauseOfUnmetDependencies )
|
if ( !somethingWasRemovedBecauseOfUnmetDependencies )
|
||||||
break;
|
break;
|
||||||
@ -369,4 +384,4 @@ ModuleManager::checkDependencies( const Module& m )
|
|||||||
return allRequirementsFound;
|
return allRequirementsFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#ifndef MODULELOADER_H
|
#ifndef MODULELOADER_H
|
||||||
#define MODULELOADER_H
|
#define MODULELOADER_H
|
||||||
|
|
||||||
|
#include "Requirement.h"
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
@ -30,6 +31,7 @@ namespace Calamares
|
|||||||
{
|
{
|
||||||
|
|
||||||
class Module;
|
class Module;
|
||||||
|
struct RequirementEntry; // from Requirement.h
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The ModuleManager class is a singleton which manages Calamares modules.
|
* @brief The ModuleManager class is a singleton which manages Calamares modules.
|
||||||
@ -81,10 +83,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
void loadModules();
|
void loadModules();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Starts asynchronous requirements checking for each module.
|
||||||
|
* When this is done, the signal modulesChecked is emitted.
|
||||||
|
*/
|
||||||
|
void checkRequirements();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void initDone();
|
void initDone();
|
||||||
void modulesLoaded(); /// All of the modules were loaded successfully
|
void modulesLoaded(); /// All of the modules were loaded successfully
|
||||||
void modulesFailed( QStringList ); /// .. or not
|
void modulesFailed( QStringList ); /// .. or not
|
||||||
|
// Below, see RequirementsChecker documentation
|
||||||
|
void requirementsComplete( bool );
|
||||||
|
void requirementsResult( RequirementsList );
|
||||||
|
void requirementsProgress( const QString& );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void doInit();
|
void doInit();
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
|
||||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
@ -16,23 +15,5 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include "Requirement.h"
|
||||||
|
|
||||||
#ifndef CHECKITEMWIDGET_H
|
|
||||||
#define CHECKITEMWIDGET_H
|
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
|
|
||||||
class CheckItemWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit CheckItemWidget( bool checked, bool required,
|
|
||||||
QWidget* parent = nullptr );
|
|
||||||
|
|
||||||
void setText( const QString& text );
|
|
||||||
private:
|
|
||||||
QLabel* m_textLabel;
|
|
||||||
QLabel* m_iconLabel;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CHECKITEMWIDGET_H
|
|
67
src/libcalamaresui/modulesystem/Requirement.h
Normal file
67
src/libcalamaresui/modulesystem/Requirement.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef CALAMARES_REQUIREMENT_H
|
||||||
|
#define CALAMARES_REQUIREMENT_H
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QMetaType>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Calamares
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An indication of a requirement, which is checked in preparation
|
||||||
|
* for system installation. An entry has a name and some explanation functions
|
||||||
|
* (functions, because they need to respond to translations).
|
||||||
|
*
|
||||||
|
* A requirement can be *satisfied* or not.
|
||||||
|
* A requirement can be optional (i.e. a "good to have") or mandatory.
|
||||||
|
*
|
||||||
|
* Requirements which are not satisfied, and also mandatory, will prevent the
|
||||||
|
* installation from proceeding.
|
||||||
|
*/
|
||||||
|
struct RequirementEntry
|
||||||
|
{
|
||||||
|
using TextFunction = std::function< QString() >;
|
||||||
|
|
||||||
|
/// @brief name of this requirement; not shown to user and used as ID
|
||||||
|
QString name;
|
||||||
|
|
||||||
|
/// @brief Detailed description of this requirement, for use in user-visible lists
|
||||||
|
TextFunction enumerationText;
|
||||||
|
|
||||||
|
/// @brief User-visible string to show that the requirement is not met, short form
|
||||||
|
TextFunction negatedText;
|
||||||
|
|
||||||
|
bool satisfied;
|
||||||
|
bool mandatory;
|
||||||
|
|
||||||
|
/// @brief Convenience to check if this entry should be shown in details dialog
|
||||||
|
bool hasDetails() const { return !enumerationText().isEmpty(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
using RequirementsList = QList< RequirementEntry >;
|
||||||
|
|
||||||
|
} // namespace Calamares
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Calamares::RequirementEntry)
|
||||||
|
|
||||||
|
#endif
|
154
src/libcalamaresui/modulesystem/RequirementsChecker.cpp
Normal file
154
src/libcalamaresui/modulesystem/RequirementsChecker.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RequirementsChecker.h"
|
||||||
|
|
||||||
|
#include "Module.h"
|
||||||
|
#include "Requirement.h"
|
||||||
|
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Calamares
|
||||||
|
{
|
||||||
|
|
||||||
|
static void
|
||||||
|
registerMetatypes()
|
||||||
|
{
|
||||||
|
static bool done = false;
|
||||||
|
|
||||||
|
if ( !done )
|
||||||
|
{
|
||||||
|
qRegisterMetaType< RequirementEntry >( "RequirementEntry" );
|
||||||
|
// It's sensitive to the names of types in parameters; in particular
|
||||||
|
// althrough QList<RequirementEntry> is the same as RequirementsList,
|
||||||
|
// because we *name* the type as RequirementsList in the parameters,
|
||||||
|
// we need to register that (as well). Here, be safe and register
|
||||||
|
// both names.
|
||||||
|
qRegisterMetaType< QList< RequirementEntry > >( "QList<RequirementEntry>" );
|
||||||
|
qRegisterMetaType< RequirementsList >( "RequirementsList" );
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check( Module * const &m, RequirementsChecker *c )
|
||||||
|
{
|
||||||
|
RequirementsList l = m->checkRequirements();
|
||||||
|
if ( l.count() > 0 )
|
||||||
|
c->addCheckedRequirements( l );
|
||||||
|
c->requirementsProgress( QObject::tr( "Requirements checking for module <i>%1</i> is complete." ).arg( m->name() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
RequirementsChecker::RequirementsChecker( QVector< Module* > modules, QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, m_modules( std::move( modules ) )
|
||||||
|
, m_progressTimer( nullptr )
|
||||||
|
, m_progressTimeouts( 0 )
|
||||||
|
{
|
||||||
|
m_watchers.reserve( m_modules.count() );
|
||||||
|
m_collectedRequirements.reserve( m_modules.count() );
|
||||||
|
|
||||||
|
registerMetatypes();
|
||||||
|
}
|
||||||
|
|
||||||
|
RequirementsChecker::~RequirementsChecker()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RequirementsChecker::run()
|
||||||
|
{
|
||||||
|
m_progressTimer = new QTimer( this );
|
||||||
|
connect( m_progressTimer, &QTimer::timeout, this, &RequirementsChecker::reportProgress );
|
||||||
|
m_progressTimer->start( 1200 ); // msec
|
||||||
|
|
||||||
|
for (const auto& module : m_modules )
|
||||||
|
{
|
||||||
|
Watcher *watcher = new Watcher( this );
|
||||||
|
watcher->setFuture( QtConcurrent::run( check, module, this ) );
|
||||||
|
m_watchers.append( watcher );
|
||||||
|
connect( watcher, &Watcher::finished, this, &RequirementsChecker::finished );
|
||||||
|
}
|
||||||
|
|
||||||
|
QTimer::singleShot( 0, this, &RequirementsChecker::finished );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RequirementsChecker::finished()
|
||||||
|
{
|
||||||
|
if ( std::all_of( m_watchers.cbegin(), m_watchers.cend(), []( const Watcher *w ) { return w && w->isFinished(); } ) )
|
||||||
|
{
|
||||||
|
cDebug() << "All requirements have been checked.";
|
||||||
|
|
||||||
|
if ( m_progressTimer )
|
||||||
|
m_progressTimer->stop();
|
||||||
|
|
||||||
|
bool acceptable = true;
|
||||||
|
int count = 0;
|
||||||
|
for ( const auto& r : m_collectedRequirements )
|
||||||
|
{
|
||||||
|
if ( r.mandatory && !r.satisfied )
|
||||||
|
{
|
||||||
|
cDebug() << " .. requirement" << count << r.name << "is not satisfied.";
|
||||||
|
acceptable = false;
|
||||||
|
}
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit requirementsComplete( acceptable );
|
||||||
|
QTimer::singleShot(0, this, &RequirementsChecker::done );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RequirementsChecker::addCheckedRequirements( RequirementsList l )
|
||||||
|
{
|
||||||
|
static QMutex addMutex;
|
||||||
|
{
|
||||||
|
QMutexLocker lock( &addMutex );
|
||||||
|
m_collectedRequirements.append( l );
|
||||||
|
}
|
||||||
|
cDebug() << "Added" << l.count() << "requirement results";
|
||||||
|
emit requirementsResult( l );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RequirementsChecker::reportProgress()
|
||||||
|
{
|
||||||
|
m_progressTimeouts++;
|
||||||
|
|
||||||
|
auto remaining = std::count_if( m_watchers.cbegin(), m_watchers.cend(), []( const Watcher *w ) { return w && !w->isFinished(); } );
|
||||||
|
if ( remaining > 0 )
|
||||||
|
{
|
||||||
|
QString waiting = tr( "Waiting for %n module(s).", "", remaining );
|
||||||
|
QString elapsed = tr( "(%n second(s))", "", m_progressTimeouts * m_progressTimer->interval() / 1000 );
|
||||||
|
emit requirementsProgress( waiting + QString( " " ) + elapsed );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
emit requirementsProgress( tr( "System-requirements checking is complete." ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
87
src/libcalamaresui/modulesystem/RequirementsChecker.h
Normal file
87
src/libcalamaresui/modulesystem/RequirementsChecker.h
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef CALAMARES_REQUIREMENTSCHECKER_H
|
||||||
|
#define CALAMARES_REQUIREMENTSCHECKER_H
|
||||||
|
|
||||||
|
#include "Requirement.h"
|
||||||
|
|
||||||
|
#include <QFutureWatcher>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Calamares
|
||||||
|
{
|
||||||
|
|
||||||
|
class Module;
|
||||||
|
|
||||||
|
/** @brief A manager-class that checks all the module requirements
|
||||||
|
*
|
||||||
|
* Asynchronously checks the requirements for each module, and
|
||||||
|
* emits progress signals as appropriate.
|
||||||
|
*/
|
||||||
|
class RequirementsChecker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
RequirementsChecker( QVector< Module* > modules, QObject* parent = nullptr );
|
||||||
|
virtual ~RequirementsChecker() override;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
/// @brief Start checking all the requirements
|
||||||
|
void run();
|
||||||
|
|
||||||
|
/// @brief Called when requirements are reported by a module
|
||||||
|
void addCheckedRequirements( RequirementsList );
|
||||||
|
|
||||||
|
/// @brief Called when all requirements have been checked
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
/// @brief Called periodically while requirements are being checked
|
||||||
|
void reportProgress();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
/// @brief Human-readable progress message
|
||||||
|
void requirementsProgress( const QString& );
|
||||||
|
/// @brief Requirements from a single module
|
||||||
|
void requirementsResult( RequirementsList );
|
||||||
|
/** @brief When all requirements are collected
|
||||||
|
*
|
||||||
|
* The argument indicates if all mandatory requirements are satisfied.
|
||||||
|
*/
|
||||||
|
void requirementsComplete( bool );
|
||||||
|
/// @brief Emitted after requirementsComplete
|
||||||
|
void done();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector< Module* > m_modules;
|
||||||
|
|
||||||
|
using Watcher = QFutureWatcher< void >;
|
||||||
|
QVector< Watcher* > m_watchers;
|
||||||
|
|
||||||
|
RequirementsList m_collectedRequirements;
|
||||||
|
|
||||||
|
QTimer *m_progressTimer;
|
||||||
|
unsigned m_progressTimeouts;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -132,4 +132,10 @@ ViewModule::~ViewModule()
|
|||||||
delete m_loader;
|
delete m_loader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequirementsList
|
||||||
|
ViewModule::checkRequirements()
|
||||||
|
{
|
||||||
|
return m_viewStep->checkRequirements();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
void loadSelf() override;
|
void loadSelf() override;
|
||||||
JobList jobs() const override;
|
JobList jobs() const override;
|
||||||
|
|
||||||
|
RequirementsList checkRequirements() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void initFrom( const QVariantMap& moduleDescriptor ) override;
|
void initFrom( const QVariantMap& moduleDescriptor ) override;
|
||||||
|
|
||||||
|
@ -52,6 +52,14 @@ void
|
|||||||
ViewStep::onLeave()
|
ViewStep::onLeave()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewStep::next()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
ViewStep::back()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ViewStep::setModuleInstanceKey( const QString& instanceKey )
|
ViewStep::setModuleInstanceKey( const QString& instanceKey )
|
||||||
@ -66,4 +74,10 @@ ViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
Q_UNUSED( configurationMap );
|
Q_UNUSED( configurationMap );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RequirementsList ViewStep::checkRequirements()
|
||||||
|
{
|
||||||
|
return RequirementsList();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "modulesystem/Requirement.h"
|
||||||
#include "../UiDllMacro.h"
|
#include "../UiDllMacro.h"
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
|
|
||||||
@ -68,13 +69,39 @@ public:
|
|||||||
//TODO: we might want to make this a QSharedPointer
|
//TODO: we might want to make this a QSharedPointer
|
||||||
virtual QWidget* widget() = 0;
|
virtual QWidget* widget() = 0;
|
||||||
|
|
||||||
virtual void next() = 0;
|
/**
|
||||||
virtual void back() = 0;
|
* @brief Multi-page support, go next
|
||||||
|
*
|
||||||
|
* Multi-page view steps need to manage the content visible in the widget
|
||||||
|
* themselves. This method is called when the user clicks the *next*
|
||||||
|
* button, and should switch to the next of the multiple-pages. It needs
|
||||||
|
* to be consistent with both isNextEnabled() and isAtEnd().
|
||||||
|
*
|
||||||
|
* In particular: when isAtEnd() returns false, next() is called when
|
||||||
|
* the user clicks the button and a new page should be shown by this
|
||||||
|
* view step. When isAtEnd() returns true, clicking the button will
|
||||||
|
* switch to the next view step in sequence, rather than a next page
|
||||||
|
* in the current view step.
|
||||||
|
*/
|
||||||
|
virtual void next();
|
||||||
|
/// @brief Multi-page support, go back
|
||||||
|
virtual void back();
|
||||||
|
|
||||||
|
/// @brief Can the user click *next* with currently-filled-in data?
|
||||||
virtual bool isNextEnabled() const = 0;
|
virtual bool isNextEnabled() const = 0;
|
||||||
|
/// @brief Can the user click *previous* with currently-filled-in data?
|
||||||
virtual bool isBackEnabled() const = 0;
|
virtual bool isBackEnabled() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Multi-page support, switch to previous view step?
|
||||||
|
*
|
||||||
|
* For a multi-page view step, this indicates that the first (beginning)
|
||||||
|
* page is showing. Clicking *previous* when at the beginning of a view
|
||||||
|
* step, switches to the previous step, not the previous page of the
|
||||||
|
* current view step.
|
||||||
|
*/
|
||||||
virtual bool isAtBeginning() const = 0;
|
virtual bool isAtBeginning() const = 0;
|
||||||
|
/// @brief Multi-page support, switch to next view step?
|
||||||
virtual bool isAtEnd() const = 0;
|
virtual bool isAtEnd() const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -91,6 +118,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void onLeave();
|
virtual void onLeave();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Jobs needed to run this viewstep
|
||||||
|
*
|
||||||
|
* When a ViewStep is listed in the exec section, its jobs are executed instead.
|
||||||
|
* This function returns that list of jobs; an empty list is ok.
|
||||||
|
*/
|
||||||
virtual JobList jobs() const = 0;
|
virtual JobList jobs() const = 0;
|
||||||
|
|
||||||
void setModuleInstanceKey( const QString& instanceKey );
|
void setModuleInstanceKey( const QString& instanceKey );
|
||||||
@ -101,9 +134,18 @@ public:
|
|||||||
|
|
||||||
virtual void setConfigurationMap( const QVariantMap& configurationMap );
|
virtual void setConfigurationMap( const QVariantMap& configurationMap );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Can this module proceed, on this machine?
|
||||||
|
*
|
||||||
|
* This is called asynchronously at startup, and returns a list of
|
||||||
|
* the requirements that the module has checked, and their status.
|
||||||
|
* See Calamares::RequirementEntry for details.
|
||||||
|
*/
|
||||||
|
virtual RequirementsList checkRequirements();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
/// @brief Tells the viewmanager to enable the *next* button according to @p status
|
||||||
void nextStatusChanged( bool status );
|
void nextStatusChanged( bool status );
|
||||||
void done();
|
|
||||||
|
|
||||||
/* Emitted when the viewstep thinks it needs more space than is currently
|
/* Emitted when the viewstep thinks it needs more space than is currently
|
||||||
* available for display. @p enlarge is the requested additional space,
|
* available for display. @p enlarge is the requested additional space,
|
||||||
|
@ -8,27 +8,28 @@ Each Calamares module lives in its own directory.
|
|||||||
|
|
||||||
All modules are installed in `$DESTDIR/lib/calamares/modules`.
|
All modules are installed in `$DESTDIR/lib/calamares/modules`.
|
||||||
|
|
||||||
# Module types
|
There are two **types** of Calamares module:
|
||||||
|
|
||||||
There are two types of Calamares module:
|
|
||||||
* viewmodule, for user-visible modules. These may be in C++, or PythonQt.
|
* viewmodule, for user-visible modules. These may be in C++, or PythonQt.
|
||||||
* jobmodule, for not-user-visible modules. These may be done in C++,
|
* jobmodule, for not-user-visible modules. These may be done in C++,
|
||||||
Python, or as external processes.
|
Python, or as external processes.
|
||||||
|
|
||||||
# Module interfaces
|
A viewmodule exposes a UI to the user. The PythonQt-based modules
|
||||||
|
are considered experimental (and as of march 2019 may be on the
|
||||||
|
way out again as never-used-much and PythonQt is not packaged
|
||||||
|
on Debian anymore).
|
||||||
|
|
||||||
There are three (four) interfaces for Calamares modules:
|
There are three (four) **interfaces** for Calamares modules:
|
||||||
* qtplugin,
|
* qtplugin (viewmodules, jobmodules),
|
||||||
* python (jobmodules only),
|
* python (jobmodules only),
|
||||||
* pythonqt (optional),
|
* pythonqt (viewmodules, jobmodules, optional),
|
||||||
* process (jobmodules only).
|
* process (jobmodules only).
|
||||||
|
|
||||||
# Module directory
|
## Module directory
|
||||||
|
|
||||||
Each Calamares module lives in its own directory. The contents
|
Each Calamares module lives in its own directory. The contents
|
||||||
of the directory depend on the interface and type of the module.
|
of the directory depend on the interface and type of the module.
|
||||||
|
|
||||||
## Module descriptor
|
### Module descriptor
|
||||||
|
|
||||||
A Calamares module must have a *module descriptor file*, named
|
A Calamares module must have a *module descriptor file*, named
|
||||||
`module.desc`. For C++ (qtplugin) modules using CMake as a build-
|
`module.desc`. For C++ (qtplugin) modules using CMake as a build-
|
||||||
@ -49,25 +50,66 @@ Module descriptors **must** have the following keys:
|
|||||||
- *interface* (see below for the different interfaces; generally we
|
- *interface* (see below for the different interfaces; generally we
|
||||||
refer to the kinds of modules by their interface)
|
refer to the kinds of modules by their interface)
|
||||||
|
|
||||||
|
Module descriptors for Python and PythonQt modules **must** have the following key:
|
||||||
|
- *script* (the name of the Python script to load, nearly always `main.py`)
|
||||||
|
|
||||||
Module descriptors **may** have the following keys:
|
Module descriptors **may** have the following keys:
|
||||||
- *required* **unimplemented** (a list of modules which are required for this module
|
- *requiredModules* (a list of modules which are required for this module
|
||||||
to operate properly)
|
to operate properly)
|
||||||
- *emergency* (a boolean value, set to true to mark the module
|
- *emergency* (a boolean value, set to true to mark the module
|
||||||
as an emergency module)
|
as an emergency module)
|
||||||
|
|
||||||
## Module-specific configuration
|
### Required Modules
|
||||||
|
|
||||||
|
A module may list zero (if it has no requirements) or more modules
|
||||||
|
by name. As modules are loaded from the global sequence in `settings.conf`,
|
||||||
|
each module is checked that all of the modules it requires are
|
||||||
|
already loaded before it. This ensures that if a module needs
|
||||||
|
another one to fill in globalstorage keys, that happens before
|
||||||
|
it needs those keys.
|
||||||
|
|
||||||
|
### Emergency Modules
|
||||||
|
|
||||||
|
Only C++ modules and job modules may be emergency modules. If, during an
|
||||||
|
*exec* step in the sequence, a module fails, installation as a whole fails
|
||||||
|
and the install is aborted. If there are emergency modules in the **same**
|
||||||
|
exec block, those will be executed before the installation is aborted.
|
||||||
|
Non-emergency modules are not executed.
|
||||||
|
|
||||||
|
If an emergency-module fails while processing emergency-modules for
|
||||||
|
another failed module, that failure is ignored and emergency-module
|
||||||
|
processing continues.
|
||||||
|
|
||||||
|
Use the EMERGENCY keyword in the CMake description of a C++ module
|
||||||
|
to generate a suitable `module.desc`.
|
||||||
|
|
||||||
|
A module that is marked as an emergency module in its module.desc
|
||||||
|
must **also** set the *emergency* key to *true* in its configuration file
|
||||||
|
(see below). If it does not, the module is not considered to be an emergency
|
||||||
|
module after all (this is so that you can have modules that have several
|
||||||
|
instances, only some of which are actually needed for emergencies).
|
||||||
|
|
||||||
|
### Module-specific configuration
|
||||||
|
|
||||||
A Calamares module **may** read a module configuration file,
|
A Calamares module **may** read a module configuration file,
|
||||||
named `<modulename>.conf`. If such a file is present in the
|
named `<modulename>.conf`. If such a file is present in the
|
||||||
module's directory, it is shipped as a *default* configuration file.
|
module's directory, it can be shipped as a *default* configuration file.
|
||||||
|
This only happens if the CMake-time option `INSTALL_CONFIG` is on.
|
||||||
|
|
||||||
|
The sample configuration files may work and may be suitable for
|
||||||
|
your distribution, but no guarantee is given about their stability
|
||||||
|
beyond syntactic correctness.
|
||||||
|
|
||||||
The module configuration file, if it exists, is a YAML 1.2 document
|
The module configuration file, if it exists, is a YAML 1.2 document
|
||||||
which contains a YAML map of anything.
|
which contains a YAML map of anything.
|
||||||
|
|
||||||
All default module configuration files are installed in
|
All sample module configuration files are installed in
|
||||||
`$DESTDIR/share/calamares/modules` but can be overridden by
|
`$DESTDIR/share/calamares/modules` but can be overridden by
|
||||||
files with the same name placed manually (or by the packager)
|
files with the same name placed manually (or by the packager)
|
||||||
in `/etc/calamares/modules`.
|
in `/etc/calamares/modules`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## C++ modules
|
## C++ modules
|
||||||
|
|
||||||
Currently the recommended way to write a module which exposes one or more
|
Currently the recommended way to write a module which exposes one or more
|
||||||
@ -79,6 +121,8 @@ To add a Qt plugin module, put it in a subdirectory and make sure it has
|
|||||||
a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked
|
a `CMakeLists.txt` with a `calamares_add_plugin` call. It will be picked
|
||||||
up automatically by our CMake magic. The `module.desc` file is optional.
|
up automatically by our CMake magic. The `module.desc` file is optional.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Python modules
|
## Python modules
|
||||||
|
|
||||||
Modules may use one of the python interfaces, which may be present
|
Modules may use one of the python interfaces, which may be present
|
||||||
@ -90,7 +134,7 @@ or the experimental pythonqt job- and viewmodule interfaces.
|
|||||||
To add a Python or process jobmodule, put it in a subdirectory and make sure
|
To add a Python or process jobmodule, put it in a subdirectory and make sure
|
||||||
it has a `module.desc`. It will be picked up automatically by our CMake magic.
|
it has a `module.desc`. It will be picked up automatically by our CMake magic.
|
||||||
For all kinds of Python jobs, the key *script* must be set to the name of
|
For all kinds of Python jobs, the key *script* must be set to the name of
|
||||||
the main python file for the job. This is almost universally "main.py".
|
the main python file for the job. This is almost universally `main.py`.
|
||||||
|
|
||||||
`CMakeLists.txt` is *not* used for Python and process jobmodules.
|
`CMakeLists.txt` is *not* used for Python and process jobmodules.
|
||||||
|
|
||||||
@ -113,6 +157,17 @@ function `run()` as entry point. The function `run()` must return `None` if
|
|||||||
everything went well, or a tuple `(str,str)` with an error message and
|
everything went well, or a tuple `(str,str)` with an error message and
|
||||||
description if something went wrong.
|
description if something went wrong.
|
||||||
|
|
||||||
|
### Python API
|
||||||
|
|
||||||
|
**TODO:** this needs documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## PythonQt modules
|
||||||
|
|
||||||
|
The PythonQt modules are considered experimental and may be removed again
|
||||||
|
due to low uptake. Their documentation is also almost completely lacking.
|
||||||
|
|
||||||
### PythonQt Jobmodule
|
### PythonQt Jobmodule
|
||||||
|
|
||||||
A PythonQt jobmodule implements the experimental Job interface by defining
|
A PythonQt jobmodule implements the experimental Job interface by defining
|
||||||
@ -123,31 +178,18 @@ a subclass of something.
|
|||||||
A PythonQt viewmodule implements the experimental View interface by defining
|
A PythonQt viewmodule implements the experimental View interface by defining
|
||||||
a subclass of something.
|
a subclass of something.
|
||||||
|
|
||||||
|
### Python API
|
||||||
|
|
||||||
|
**TODO:** this needs documentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Process jobmodules
|
## Process jobmodules
|
||||||
|
|
||||||
A process jobmodule runs a (single) command. The interface is "process",
|
A process jobmodule runs a (single) command. The interface is *process*,
|
||||||
while the module type must be "job" or "jobmodule".
|
while the module type must be *job* or *jobmodule*.
|
||||||
|
|
||||||
The key *command* should have a string as value, which is passed to the
|
The module-descriptor key *command* should have a string as value, which is
|
||||||
shell -- remember to quote it properly.
|
passed to the shell -- remember to quote it properly. It is generally
|
||||||
|
recommended to use a *shellprocess* job module instead (less configuration,
|
||||||
## Emergency Modules
|
easier to have multiple instances).
|
||||||
|
|
||||||
Only C++ modules and job modules may be emergency modules. If, during an
|
|
||||||
*exec* step in the sequence, a module fails, installation as a whole fails
|
|
||||||
and the install is aborted. If there are emergency modules in the **same**
|
|
||||||
exec block, those will be executed before the installation is aborted.
|
|
||||||
Non-emergency modules are not executed.
|
|
||||||
|
|
||||||
If an emergency-module fails while processing emergency-modules for
|
|
||||||
another failed module, that failure is ignored and emergency-module
|
|
||||||
processing continues.
|
|
||||||
|
|
||||||
Use the EMERGENCY keyword in the CMake description of a C++ module
|
|
||||||
to generate a suitable `module.desc`.
|
|
||||||
|
|
||||||
A module that is marked as an emergency module in its module.desc
|
|
||||||
must **also** set the *emergency* key to *true* in its configuration file.
|
|
||||||
If it does not, the module is not considered to be an emergency module
|
|
||||||
after all (this is so that you can have modules that have several
|
|
||||||
instances, only some of which are actually needed for emergencies.
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
---
|
---
|
||||||
type: "job"
|
type: "job"
|
||||||
name: "bootloader"
|
|
||||||
interface: "python"
|
interface: "python"
|
||||||
|
name: "bootloader"
|
||||||
script: "main.py"
|
script: "main.py"
|
||||||
|
# The partition module sets up the EFI firmware type
|
||||||
|
# global key, which is used to decide how to install.
|
||||||
|
requiredModules: [ "partition" ]
|
||||||
|
@ -768,11 +768,11 @@ def run():
|
|||||||
displaymanagers.remove(dm)
|
displaymanagers.remove(dm)
|
||||||
|
|
||||||
if not dm_impl:
|
if not dm_impl:
|
||||||
return (
|
libcalamares.utils.warning(
|
||||||
_("No display managers selected for the displaymanager module."),
|
"No display managers selected for the displaymanager module. "
|
||||||
_("The list is empty after checking for installed display managers.")
|
"The list is empty after checking for installed display managers."
|
||||||
)
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
# Pick up remaining settings
|
# Pick up remaining settings
|
||||||
if "defaultDesktopEnvironment" in libcalamares.job.configuration:
|
if "defaultDesktopEnvironment" in libcalamares.job.configuration:
|
||||||
|
@ -67,18 +67,6 @@ FinishedViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
FinishedViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
FinishedViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FinishedViewStep::isNextEnabled() const
|
FinishedViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -40,9 +40,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ ResizeFSJob::RelativeSize::apply( qint64 totalSectors, qint64 sectorSize )
|
|||||||
case unit_t::None:
|
case unit_t::None:
|
||||||
return -1;
|
return -1;
|
||||||
case unit_t::Absolute:
|
case unit_t::Absolute:
|
||||||
return CalamaresUtils::MiBtoBytes( value() ) / sectorSize;
|
return CalamaresUtils::MiBtoBytes( static_cast<unsigned long long>( value() ) ) / sectorSize;
|
||||||
case unit_t::Percent:
|
case unit_t::Percent:
|
||||||
if ( value() == 100 )
|
if ( value() == 100 )
|
||||||
return totalSectors; // Common-case, avoid futzing around
|
return totalSectors; // Common-case, avoid futzing around
|
||||||
|
@ -62,12 +62,6 @@ def modify_grub_default(partitions, root_mount_point, distributor):
|
|||||||
|
|
||||||
cryptdevice_params = []
|
cryptdevice_params = []
|
||||||
|
|
||||||
# GRUB needs to decrypt the partition that /boot is on, which may be / or /boot
|
|
||||||
boot_mountpoint = "/"
|
|
||||||
for partition in partitions:
|
|
||||||
if partition["mountPoint"] == "/boot":
|
|
||||||
boot_mountpoint = "/boot"
|
|
||||||
|
|
||||||
if have_dracut:
|
if have_dracut:
|
||||||
for partition in partitions:
|
for partition in partitions:
|
||||||
has_luks = "luksMapperName" in partition
|
has_luks = "luksMapperName" in partition
|
||||||
@ -78,7 +72,7 @@ def modify_grub_default(partitions, root_mount_point, distributor):
|
|||||||
swap_outer_uuid = partition["luksUuid"]
|
swap_outer_uuid = partition["luksUuid"]
|
||||||
swap_outer_mappername = partition["luksMapperName"]
|
swap_outer_mappername = partition["luksMapperName"]
|
||||||
|
|
||||||
if (partition["mountPoint"] == boot_mountpoint and has_luks):
|
if (partition["mountPoint"] == "/" and has_luks):
|
||||||
cryptdevice_params = [
|
cryptdevice_params = [
|
||||||
"rd.luks.uuid={!s}".format(partition["luksUuid"])
|
"rd.luks.uuid={!s}".format(partition["luksUuid"])
|
||||||
]
|
]
|
||||||
@ -88,7 +82,7 @@ def modify_grub_default(partitions, root_mount_point, distributor):
|
|||||||
if partition["fs"] == "linuxswap" and not has_luks:
|
if partition["fs"] == "linuxswap" and not has_luks:
|
||||||
swap_uuid = partition["uuid"]
|
swap_uuid = partition["uuid"]
|
||||||
|
|
||||||
if (partition["mountPoint"] == boot_mountpoint and has_luks):
|
if (partition["mountPoint"] == "/" and has_luks):
|
||||||
cryptdevice_params = [
|
cryptdevice_params = [
|
||||||
"cryptdevice=UUID={!s}:{!s}".format(
|
"cryptdevice=UUID={!s}:{!s}".format(
|
||||||
partition["luksUuid"], partition["luksMapperName"]
|
partition["luksUuid"], partition["luksMapperName"]
|
||||||
|
@ -53,18 +53,6 @@ InteractiveTerminalViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
InteractiveTerminalViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
InteractiveTerminalViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
InteractiveTerminalViewStep::isNextEnabled() const
|
InteractiveTerminalViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -41,9 +41,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -65,19 +65,6 @@ KeyboardViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
KeyboardViewStep::next()
|
|
||||||
{
|
|
||||||
//TODO: actually save those settings somewhere
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
KeyboardViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
KeyboardViewStep::isNextEnabled() const
|
KeyboardViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -42,9 +42,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -59,18 +59,6 @@ LicenseViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LicenseViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LicenseViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LicenseViewStep::isNextEnabled() const
|
LicenseViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -42,9 +42,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
explicit LocaleConfiguration();
|
explicit LocaleConfiguration();
|
||||||
/// @brief Create a locale with everything set to the given @p localeName
|
/// @brief Create a locale with everything set to the given @p localeName
|
||||||
explicit LocaleConfiguration( const QString& localeName /* "en_US.UTF-8" */ )
|
explicit LocaleConfiguration( const QString& localeName /* "en_US.UTF-8" */ )
|
||||||
: LocaleConfiguration( localeName, localeName ) { };
|
: LocaleConfiguration( localeName, localeName ) { }
|
||||||
/// @brief Create a locale with language and formats separate
|
/// @brief Create a locale with language and formats separate
|
||||||
explicit LocaleConfiguration( const QString& localeName, const QString& formatsName );
|
explicit LocaleConfiguration( const QString& localeName, const QString& formatsName );
|
||||||
|
|
||||||
|
@ -190,18 +190,6 @@ LocaleViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LocaleViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
LocaleViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
LocaleViewStep::isNextEnabled() const
|
LocaleViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -45,9 +45,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
# Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
|
# Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
|
||||||
# Copyright 2016, Philip Müller <philm@manjaro.org>
|
# Copyright 2016, Philip Müller <philm@manjaro.org>
|
||||||
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
||||||
|
# Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
#
|
#
|
||||||
# Calamares is free software: you can redistribute it and/or modify
|
# Calamares is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -69,18 +69,6 @@ NetInstallViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
NetInstallViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
NetInstallViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
NetInstallViewStep::isNextEnabled() const
|
NetInstallViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -42,9 +42,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -42,6 +43,25 @@
|
|||||||
namespace PartUtils
|
namespace PartUtils
|
||||||
{
|
{
|
||||||
|
|
||||||
|
static QString
|
||||||
|
convenienceName( const Partition* const candidate )
|
||||||
|
{
|
||||||
|
if ( !candidate->mountPoint().isEmpty() )
|
||||||
|
return candidate->mountPoint();
|
||||||
|
if ( !candidate->partitionPath().isEmpty() )
|
||||||
|
return candidate->partitionPath();
|
||||||
|
if ( !candidate->devicePath().isEmpty() )
|
||||||
|
return candidate->devicePath();
|
||||||
|
if ( !candidate->deviceNode().isEmpty() )
|
||||||
|
return candidate->devicePath();
|
||||||
|
|
||||||
|
QString p;
|
||||||
|
QTextStream s( &p );
|
||||||
|
s << (void *)candidate;
|
||||||
|
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
canBeReplaced( Partition* candidate )
|
canBeReplaced( Partition* candidate )
|
||||||
{
|
{
|
||||||
@ -63,12 +83,12 @@ canBeReplaced( Partition* candidate )
|
|||||||
<< QString( "(%1GB)" ).arg( requiredStorageB / 1024 / 1024 / 1024 );
|
<< QString( "(%1GB)" ).arg( requiredStorageB / 1024 / 1024 / 1024 );
|
||||||
cDebug() << "Storage capacity B:" << availableStorageB
|
cDebug() << "Storage capacity B:" << availableStorageB
|
||||||
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
|
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
|
||||||
<< "for" << candidate->partitionPath() << " length:" << candidate->length();
|
<< "for" << convenienceName( candidate ) << " length:" << candidate->length();
|
||||||
|
|
||||||
if ( ok &&
|
if ( ok &&
|
||||||
availableStorageB > requiredStorageB )
|
availableStorageB > requiredStorageB )
|
||||||
{
|
{
|
||||||
cDebug() << "Partition" << candidate->partitionPath() << "authorized for replace install.";
|
cDebug() << "Partition" << convenienceName( candidate ) << "authorized for replace install.";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -85,7 +105,7 @@ canBeResized( Partition* candidate )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cDebug() << "Checking if" << candidate->partitionPath() << "can be resized.";
|
cDebug() << "Checking if" << convenienceName( candidate ) << "can be resized.";
|
||||||
if ( !candidate->fileSystem().supportGrow() ||
|
if ( !candidate->fileSystem().supportGrow() ||
|
||||||
!candidate->fileSystem().supportShrink() )
|
!candidate->fileSystem().supportShrink() )
|
||||||
{
|
{
|
||||||
@ -139,13 +159,13 @@ canBeResized( Partition* candidate )
|
|||||||
<< QString( "(%1GB)" ).arg( advisedStorageGB );
|
<< QString( "(%1GB)" ).arg( advisedStorageGB );
|
||||||
cDebug() << "Available storage B:" << availableStorageB
|
cDebug() << "Available storage B:" << availableStorageB
|
||||||
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
|
<< QString( "(%1GB)" ).arg( availableStorageB / 1024 / 1024 / 1024 )
|
||||||
<< "for" << candidate->partitionPath() << " length:" << candidate->length()
|
<< "for" << convenienceName( candidate ) << " length:" << candidate->length()
|
||||||
<< " sectorsUsed:" << candidate->sectorsUsed() << " fsType:" << candidate->fileSystem().name();
|
<< " sectorsUsed:" << candidate->sectorsUsed() << " fsType:" << candidate->fileSystem().name();
|
||||||
|
|
||||||
if ( ok &&
|
if ( ok &&
|
||||||
availableStorageB > advisedStorageB )
|
availableStorageB > advisedStorageB )
|
||||||
{
|
{
|
||||||
cDebug() << "Partition" << candidate->partitionPath() << "authorized for resize + autopartition install.";
|
cDebug() << "Partition" << convenienceName( candidate ) << "authorized for resize + autopartition install.";
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -381,7 +401,7 @@ isEfiSystem()
|
|||||||
bool
|
bool
|
||||||
isEfiBootable( const Partition* candidate )
|
isEfiBootable( const Partition* candidate )
|
||||||
{
|
{
|
||||||
cDebug() << "Check EFI bootable" << candidate->partitionPath() << candidate->devicePath();
|
cDebug() << "Check EFI bootable" << convenienceName( candidate ) << candidate->devicePath();
|
||||||
cDebug() << " .. flags" << candidate->activeFlags();
|
cDebug() << " .. flags" << candidate->activeFlags();
|
||||||
|
|
||||||
auto flags = PartitionInfo::flags( candidate );
|
auto flags = PartitionInfo::flags( candidate );
|
||||||
@ -408,6 +428,149 @@ isEfiBootable( const Partition* candidate )
|
|||||||
flags.testFlag( PartitionTable::FlagBoot );
|
flags.testFlag( PartitionTable::FlagBoot );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
findFS( QString fsName, FileSystem::Type* fsType )
|
||||||
|
{
|
||||||
|
QStringList fsLanguage { QLatin1Literal( "C" ) }; // Required language list to turn off localization
|
||||||
|
if ( fsName.isEmpty() )
|
||||||
|
fsName = QStringLiteral( "ext4" );
|
||||||
|
|
||||||
|
FileSystem::Type tmpType = FileSystem::typeForName( fsName, fsLanguage );
|
||||||
|
if ( tmpType != FileSystem::Unknown )
|
||||||
|
{
|
||||||
|
cDebug() << "Found filesystem" << fsName;
|
||||||
|
if ( fsType )
|
||||||
|
*fsType = tmpType;
|
||||||
|
return fsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second pass: try case-insensitive
|
||||||
|
const auto fstypes = FileSystem::types();
|
||||||
|
for ( FileSystem::Type t : fstypes )
|
||||||
|
{
|
||||||
|
if ( 0 == QString::compare( fsName, FileSystem::nameForType( t, fsLanguage ), Qt::CaseInsensitive ) )
|
||||||
|
{
|
||||||
|
QString fsRealName = FileSystem::nameForType( t, fsLanguage );
|
||||||
|
cDebug() << "Filesystem name" << fsName << "translated to" << fsRealName;
|
||||||
|
if ( fsType )
|
||||||
|
*fsType = t;
|
||||||
|
return fsRealName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cDebug() << "Filesystem" << fsName << "not found, using ext4";
|
||||||
|
fsName = QStringLiteral( "ext4" );
|
||||||
|
// fsType can be used to check whether fsName was a valid filesystem.
|
||||||
|
if (fsType)
|
||||||
|
*fsType = FileSystem::Unknown;
|
||||||
|
#ifdef DEBUG_FILESYSTEMS
|
||||||
|
// This bit is for distro's debugging their settings, and shows
|
||||||
|
// all the strings that KPMCore is matching against for FS type.
|
||||||
|
{
|
||||||
|
Logger::CDebug d;
|
||||||
|
using TR = Logger::DebugRow< int, QString >;
|
||||||
|
const auto fstypes = FileSystem::types();
|
||||||
|
d << "Available types (" << fstypes.count() << ')';
|
||||||
|
for ( FileSystem::Type t : fstypes )
|
||||||
|
d << TR( static_cast<int>( t ), FileSystem::nameForType( t, fsLanguage ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return fsName;
|
||||||
|
}
|
||||||
|
|
||||||
|
static qint64
|
||||||
|
sizeToBytes( double size, SizeUnit unit, qint64 totalSize )
|
||||||
|
{
|
||||||
|
qint64 bytes;
|
||||||
|
|
||||||
|
switch ( unit )
|
||||||
|
{
|
||||||
|
case SizeUnit::Percent:
|
||||||
|
bytes = qint64( static_cast<double>( totalSize ) * size / 100.0L );
|
||||||
|
break;
|
||||||
|
case SizeUnit::KiB:
|
||||||
|
bytes = CalamaresUtils::KiBtoBytes(size);
|
||||||
|
break;
|
||||||
|
case SizeUnit::MiB:
|
||||||
|
bytes = CalamaresUtils::MiBtoBytes(size);
|
||||||
|
break;
|
||||||
|
case SizeUnit::GiB:
|
||||||
|
bytes = CalamaresUtils::GiBtoBytes(size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bytes = size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
parseSizeString( const QString& sizeString, SizeUnit* unit )
|
||||||
|
{
|
||||||
|
double value;
|
||||||
|
bool ok;
|
||||||
|
QString valueString;
|
||||||
|
QString unitString;
|
||||||
|
|
||||||
|
QRegExp rx( "[KkMmGg%]" );
|
||||||
|
int pos = rx.indexIn( sizeString );
|
||||||
|
if (pos > 0)
|
||||||
|
{
|
||||||
|
valueString = sizeString.mid( 0, pos );
|
||||||
|
unitString = sizeString.mid( pos );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
valueString = sizeString;
|
||||||
|
|
||||||
|
value = valueString.toDouble( &ok );
|
||||||
|
if ( !ok )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* In case the conversion fails, a size of 100% allows a few cases to pass
|
||||||
|
* anyway (e.g. when it is the last partition of the layout)
|
||||||
|
*/
|
||||||
|
*unit = SizeUnit::Percent;
|
||||||
|
return 100.0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( unitString.length() > 0 )
|
||||||
|
{
|
||||||
|
if ( unitString.at(0) == '%' )
|
||||||
|
*unit = SizeUnit::Percent;
|
||||||
|
else if ( unitString.at(0).toUpper() == 'K' )
|
||||||
|
*unit = SizeUnit::KiB;
|
||||||
|
else if ( unitString.at(0).toUpper() == 'M' )
|
||||||
|
*unit = SizeUnit::MiB;
|
||||||
|
else if ( unitString.at(0).toUpper() == 'G' )
|
||||||
|
*unit = SizeUnit::GiB;
|
||||||
|
else
|
||||||
|
*unit = SizeUnit::Byte;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*unit = SizeUnit::Byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64
|
||||||
|
parseSizeString( const QString& sizeString, qint64 totalSize )
|
||||||
|
{
|
||||||
|
SizeUnit unit;
|
||||||
|
double value = parseSizeString( sizeString, &unit );
|
||||||
|
|
||||||
|
return sizeToBytes( value, unit, totalSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64
|
||||||
|
sizeToSectors( double size, SizeUnit unit, qint64 totalSectors, qint64 logicalSize )
|
||||||
|
{
|
||||||
|
qint64 bytes = sizeToBytes( size, unit, totalSectors * logicalSize );
|
||||||
|
return bytesToSectors( static_cast<unsigned long long>( bytes ), logicalSize );
|
||||||
|
}
|
||||||
|
|
||||||
} // nmamespace PartUtils
|
} // nmamespace PartUtils
|
||||||
|
|
||||||
/* Implementation of methods for FstabEntry, from OsproberEntry.h */
|
/* Implementation of methods for FstabEntry, from OsproberEntry.h */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2015-2016, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -21,7 +22,12 @@
|
|||||||
#define PARTUTILS_H
|
#define PARTUTILS_H
|
||||||
|
|
||||||
#include "OsproberEntry.h"
|
#include "OsproberEntry.h"
|
||||||
|
#include "utils/Units.h"
|
||||||
|
|
||||||
|
// KPMcore
|
||||||
|
#include <kpmcore/fs/filesystem.h>
|
||||||
|
|
||||||
|
// Qt
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
class PartitionCoreModule;
|
class PartitionCoreModule;
|
||||||
@ -29,6 +35,16 @@ class Partition;
|
|||||||
|
|
||||||
namespace PartUtils
|
namespace PartUtils
|
||||||
{
|
{
|
||||||
|
using CalamaresUtils::MiBtoBytes;
|
||||||
|
|
||||||
|
enum SizeUnit
|
||||||
|
{
|
||||||
|
Percent = 0,
|
||||||
|
Byte,
|
||||||
|
KiB,
|
||||||
|
MiB,
|
||||||
|
GiB
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief canBeReplaced checks whether the given Partition satisfies the criteria
|
* @brief canBeReplaced checks whether the given Partition satisfies the criteria
|
||||||
@ -73,6 +89,56 @@ bool isEfiSystem();
|
|||||||
* the partition table layout, this may mean different flags.
|
* the partition table layout, this may mean different flags.
|
||||||
*/
|
*/
|
||||||
bool isEfiBootable( const Partition* candidate );
|
bool isEfiBootable( const Partition* candidate );
|
||||||
|
|
||||||
|
/** @brief translate @p fsName into a recognized name and type
|
||||||
|
*
|
||||||
|
* Makes several attempts to translate the string into a
|
||||||
|
* name that KPMCore will recognize.
|
||||||
|
* The corresponding filesystem type is stored in @p fsType, and
|
||||||
|
* its value is FileSystem::Unknown if @p fsName is not recognized.
|
||||||
|
*/
|
||||||
|
QString findFS( QString fsName, FileSystem::Type* fsType );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse a partition size string and return its value and unit used.
|
||||||
|
* @param sizeString the string to parse.
|
||||||
|
* @param unit pointer to a SizeUnit variable for storing the parsed unit.
|
||||||
|
* @return the size value, as parsed from the input string.
|
||||||
|
*/
|
||||||
|
double parseSizeString( const QString& sizeString, SizeUnit* unit );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse a partition size string and return its value in bytes.
|
||||||
|
* @param sizeString the string to parse.
|
||||||
|
* @param totalSize the size of the selected drive (used when the size is expressed in %)
|
||||||
|
* @return the size value in bytes.
|
||||||
|
*/
|
||||||
|
qint64 parseSizeString( const QString& sizeString, qint64 totalSize );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert a partition size to a sectors count.
|
||||||
|
* @param size the partition size.
|
||||||
|
* @param unit the partition size unit.
|
||||||
|
* @param totalSectors the total number of sectors of the selected drive.
|
||||||
|
* @param logicalSize the sector size, in bytes.
|
||||||
|
* @return the number of sectors to be used for the given partition size.
|
||||||
|
*/
|
||||||
|
qint64 sizeToSectors( double size, SizeUnit unit, qint64 totalSectors, qint64 logicalSize );
|
||||||
|
|
||||||
|
constexpr qint64 alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
|
||||||
|
{
|
||||||
|
qint64 blocks = bytes / blocksize;
|
||||||
|
|
||||||
|
if ( blocks * blocksize != bytes )
|
||||||
|
++blocks;
|
||||||
|
return blocks * blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr qint64 bytesToSectors( qint64 bytes, qint64 blocksize )
|
||||||
|
{
|
||||||
|
return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1ULL) ) / blocksize;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // PARTUTILS_H
|
#endif // PARTUTILS_H
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -28,6 +29,7 @@
|
|||||||
#include "utils/Units.h"
|
#include "utils/Units.h"
|
||||||
#include "utils/NamedEnum.h"
|
#include "utils/NamedEnum.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
@ -38,8 +40,6 @@
|
|||||||
|
|
||||||
namespace PartitionActions
|
namespace PartitionActions
|
||||||
{
|
{
|
||||||
using CalamaresUtils::GiBtoBytes;
|
|
||||||
using CalamaresUtils::MiBtoBytes;
|
|
||||||
using CalamaresUtils::operator""_GiB;
|
using CalamaresUtils::operator""_GiB;
|
||||||
using CalamaresUtils::operator""_MiB;
|
using CalamaresUtils::operator""_MiB;
|
||||||
|
|
||||||
@ -82,25 +82,10 @@ swapSuggestion( const qint64 availableSpaceB, Choices::SwapChoice swap )
|
|||||||
return suggestedSwapSizeB;
|
return suggestedSwapSizeB;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr qint64
|
|
||||||
alignBytesToBlockSize( qint64 bytes, qint64 blocksize )
|
|
||||||
{
|
|
||||||
qint64 blocks = bytes / blocksize;
|
|
||||||
|
|
||||||
if ( blocks * blocksize != bytes )
|
|
||||||
++blocks;
|
|
||||||
return blocks * blocksize;
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64
|
|
||||||
bytesToSectors( qint64 bytes, qint64 blocksize )
|
|
||||||
{
|
|
||||||
return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1) ) / blocksize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionOptions o )
|
doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionOptions o )
|
||||||
{
|
{
|
||||||
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
QString defaultFsType = o.defaultFsType;
|
QString defaultFsType = o.defaultFsType;
|
||||||
if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown )
|
if ( FileSystem::typeForName( defaultFsType ) == FileSystem::Unknown )
|
||||||
defaultFsType = "ext4";
|
defaultFsType = "ext4";
|
||||||
@ -109,19 +94,27 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO
|
|||||||
|
|
||||||
// Partition sizes are expressed in MiB, should be multiples of
|
// Partition sizes are expressed in MiB, should be multiples of
|
||||||
// the logical sector size (usually 512B). EFI starts with 2MiB
|
// the logical sector size (usually 512B). EFI starts with 2MiB
|
||||||
// empty and a 300MiB EFI boot partition, while BIOS starts at
|
// empty and a EFI boot partition, while BIOS starts at
|
||||||
// the 1MiB boundary (usually sector 2048).
|
// the 1MiB boundary (usually sector 2048).
|
||||||
int uefisys_part_sizeB = isEfi ? 300_MiB : 0_MiB;
|
|
||||||
int empty_space_sizeB = isEfi ? 2_MiB : 1_MiB;
|
int empty_space_sizeB = isEfi ? 2_MiB : 1_MiB;
|
||||||
|
int uefisys_part_sizeB = 0_MiB;
|
||||||
|
|
||||||
|
if ( isEfi )
|
||||||
|
{
|
||||||
|
if ( gs->contains( "efiSystemPartitionSize" ) )
|
||||||
|
uefisys_part_sizeB = PartUtils::parseSizeString( gs->value( "efiSystemPartitionSize" ).toString(), dev->capacity() );
|
||||||
|
else
|
||||||
|
uefisys_part_sizeB = 300_MiB;
|
||||||
|
}
|
||||||
|
|
||||||
// Since sectors count from 0, if the space is 2048 sectors in size,
|
// Since sectors count from 0, if the space is 2048 sectors in size,
|
||||||
// the first free sector has number 2048 (and there are 2048 sectors
|
// the first free sector has number 2048 (and there are 2048 sectors
|
||||||
// before that one, numbered 0..2047).
|
// before that one, numbered 0..2047).
|
||||||
qint64 firstFreeSector = bytesToSectors( empty_space_sizeB, dev->logicalSize() );
|
qint64 firstFreeSector = PartUtils::bytesToSectors( empty_space_sizeB, dev->logicalSize() );
|
||||||
|
|
||||||
if ( isEfi )
|
if ( isEfi )
|
||||||
{
|
{
|
||||||
qint64 efiSectorCount = bytesToSectors( uefisys_part_sizeB, dev->logicalSize() );
|
qint64 efiSectorCount = PartUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() );
|
||||||
Q_ASSERT( efiSectorCount > 0 );
|
Q_ASSERT( efiSectorCount > 0 );
|
||||||
|
|
||||||
// Since sectors count from 0, and this partition is created starting
|
// Since sectors count from 0, and this partition is created starting
|
||||||
|
@ -75,8 +75,6 @@ namespace Choices
|
|||||||
|
|
||||||
} // namespace Choices
|
} // namespace Choices
|
||||||
|
|
||||||
qint64 bytesToSectors( qint64 bytes, qint64 blocksize );
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief doAutopartition sets up an autopartitioning operation on the given Device.
|
* @brief doAutopartition sets up an autopartitioning operation on the given Device.
|
||||||
* @param core a pointer to the PartitionCoreModule instance.
|
* @param core a pointer to the PartitionCoreModule instance.
|
||||||
|
@ -154,6 +154,9 @@ public:
|
|||||||
|
|
||||||
void setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags );
|
void setPartitionFlags( Device* device, Partition* partition, PartitionTable::Flags flags );
|
||||||
|
|
||||||
|
/// @brief Retrieve the path where the bootloader will be installed
|
||||||
|
QString bootLoaderInstallPath() const { return m_bootLoaderInstallPath; }
|
||||||
|
/// @brief Set the path where the bootloader will be installed
|
||||||
void setBootLoaderInstallPath( const QString& path );
|
void setBootLoaderInstallPath( const QString& path );
|
||||||
|
|
||||||
void initLayout();
|
void initLayout();
|
||||||
|
@ -18,27 +18,50 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
|
|
||||||
#include "core/PartitionLayout.h"
|
#include "core/PartitionLayout.h"
|
||||||
|
|
||||||
#include "core/KPMHelpers.h"
|
#include "core/KPMHelpers.h"
|
||||||
#include "core/PartitionActions.h"
|
#include "core/PartitionActions.h"
|
||||||
#include "core/PartitionInfo.h"
|
#include "core/PartitionInfo.h"
|
||||||
|
#include "core/PartUtils.h"
|
||||||
|
|
||||||
#include <kpmcore/core/device.h>
|
#include <kpmcore/core/device.h>
|
||||||
#include <kpmcore/core/partition.h>
|
#include <kpmcore/core/partition.h>
|
||||||
#include <kpmcore/fs/filesystem.h>
|
#include <kpmcore/fs/filesystem.h>
|
||||||
|
|
||||||
|
static FileSystem::Type
|
||||||
|
getDefaultFileSystemType()
|
||||||
|
{
|
||||||
|
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
FileSystem::Type defaultFS = FileSystem::Ext4;
|
||||||
|
|
||||||
|
if ( gs->contains( "defaultFileSystemType" ) )
|
||||||
|
{
|
||||||
|
PartUtils::findFS( gs->value( "defaultFileSystemType" ).toString(), &defaultFS);
|
||||||
|
if ( defaultFS == FileSystem::Unknown )
|
||||||
|
defaultFS = FileSystem::Ext4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultFS;
|
||||||
|
}
|
||||||
|
|
||||||
PartitionLayout::PartitionLayout()
|
PartitionLayout::PartitionLayout()
|
||||||
{
|
{
|
||||||
|
m_defaultFsType = getDefaultFileSystemType();
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionLayout::PartitionLayout( PartitionLayout::PartitionEntry entry )
|
PartitionLayout::PartitionLayout( PartitionLayout::PartitionEntry entry )
|
||||||
{
|
{
|
||||||
partLayout.append( entry );
|
m_defaultFsType = getDefaultFileSystemType();
|
||||||
|
m_partLayout.append( entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionLayout::PartitionLayout( const PartitionLayout& layout )
|
PartitionLayout::PartitionLayout( const PartitionLayout& layout )
|
||||||
: partLayout( layout.partLayout )
|
: m_partLayout( layout.m_partLayout )
|
||||||
|
, m_defaultFsType( layout.m_defaultFsType )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,64 +72,14 @@ PartitionLayout::~PartitionLayout()
|
|||||||
void
|
void
|
||||||
PartitionLayout::addEntry( PartitionLayout::PartitionEntry entry )
|
PartitionLayout::addEntry( PartitionLayout::PartitionEntry entry )
|
||||||
{
|
{
|
||||||
partLayout.append( entry );
|
m_partLayout.append( entry );
|
||||||
}
|
|
||||||
|
|
||||||
static double
|
|
||||||
parseSizeString( const QString& sizeString, PartitionLayout::SizeUnit* unit )
|
|
||||||
{
|
|
||||||
double value;
|
|
||||||
bool ok;
|
|
||||||
QString valueString;
|
|
||||||
QString unitString;
|
|
||||||
|
|
||||||
QRegExp rx( "[KkMmGg%]" );
|
|
||||||
int pos = rx.indexIn( sizeString );
|
|
||||||
if (pos > 0)
|
|
||||||
{
|
|
||||||
valueString = sizeString.mid( 0, pos );
|
|
||||||
unitString = sizeString.mid( pos );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
valueString = sizeString;
|
|
||||||
|
|
||||||
value = valueString.toDouble( &ok );
|
|
||||||
if ( !ok )
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* In case the conversion fails, a size of 100% allows a few cases to pass
|
|
||||||
* anyway (e.g. when it is the last partition of the layout)
|
|
||||||
*/
|
|
||||||
*unit = PartitionLayout::SizeUnit::Percent;
|
|
||||||
return 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( unitString.length() > 0 )
|
|
||||||
{
|
|
||||||
if ( unitString.at(0) == '%' )
|
|
||||||
*unit = PartitionLayout::SizeUnit::Percent;
|
|
||||||
else if ( unitString.at(0).toUpper() == 'K' )
|
|
||||||
*unit = PartitionLayout::SizeUnit::KiB;
|
|
||||||
else if ( unitString.at(0).toUpper() == 'M' )
|
|
||||||
*unit = PartitionLayout::SizeUnit::MiB;
|
|
||||||
else if ( unitString.at(0).toUpper() == 'G' )
|
|
||||||
*unit = PartitionLayout::SizeUnit::GiB;
|
|
||||||
else
|
|
||||||
*unit = PartitionLayout::SizeUnit::Byte;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*unit = PartitionLayout::SizeUnit::Byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionLayout::PartitionEntry::PartitionEntry(const QString& size, const QString& min)
|
PartitionLayout::PartitionEntry::PartitionEntry(const QString& size, const QString& min)
|
||||||
{
|
{
|
||||||
partSize = parseSizeString( size , &partSizeUnit );
|
partSize = PartUtils::parseSizeString( size , &partSizeUnit );
|
||||||
if ( !min.isEmpty() )
|
if ( !min.isEmpty() )
|
||||||
partMinSize = parseSizeString( min , &partMinSizeUnit );
|
partMinSize = PartUtils::parseSizeString( min , &partMinSizeUnit );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -115,9 +88,9 @@ PartitionLayout::addEntry( const QString& mountPoint, const QString& size, const
|
|||||||
PartitionLayout::PartitionEntry entry( size, min );
|
PartitionLayout::PartitionEntry entry( size, min );
|
||||||
|
|
||||||
entry.partMountPoint = mountPoint;
|
entry.partMountPoint = mountPoint;
|
||||||
entry.partFileSystem = FileSystem::Ext4;
|
entry.partFileSystem = m_defaultFsType;
|
||||||
|
|
||||||
partLayout.append( entry );
|
m_partLayout.append( entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -127,38 +100,11 @@ PartitionLayout::addEntry( const QString& label, const QString& mountPoint, cons
|
|||||||
|
|
||||||
entry.partLabel = label;
|
entry.partLabel = label;
|
||||||
entry.partMountPoint = mountPoint;
|
entry.partMountPoint = mountPoint;
|
||||||
entry.partFileSystem = FileSystem::typeForName( fs );
|
PartUtils::findFS( fs, &entry.partFileSystem );
|
||||||
|
if ( entry.partFileSystem == FileSystem::Unknown )
|
||||||
|
entry.partFileSystem = m_defaultFsType;
|
||||||
|
|
||||||
partLayout.append( entry );
|
m_partLayout.append( entry );
|
||||||
}
|
|
||||||
|
|
||||||
static qint64
|
|
||||||
sizeToSectors( double size, PartitionLayout::SizeUnit unit, qint64 totalSize, qint64 logicalSize )
|
|
||||||
{
|
|
||||||
qint64 sectors;
|
|
||||||
double tmp;
|
|
||||||
|
|
||||||
if ( unit == PartitionLayout::SizeUnit::Percent )
|
|
||||||
{
|
|
||||||
tmp = static_cast<double>( totalSize ) * size / 100;
|
|
||||||
sectors = static_cast<qint64>( tmp );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmp = size;
|
|
||||||
if ( unit >= PartitionLayout::SizeUnit::KiB )
|
|
||||||
tmp *= 1024;
|
|
||||||
if ( unit >= PartitionLayout::SizeUnit::MiB )
|
|
||||||
tmp *= 1024;
|
|
||||||
if ( unit >= PartitionLayout::SizeUnit::GiB )
|
|
||||||
tmp *= 1024;
|
|
||||||
|
|
||||||
sectors = PartitionActions::bytesToSectors( static_cast<unsigned long long>( tmp ),
|
|
||||||
logicalSize
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sectors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList< Partition* >
|
QList< Partition* >
|
||||||
@ -175,13 +121,13 @@ PartitionLayout::execute( Device *dev, qint64 firstSector,
|
|||||||
// TODO: Refine partition sizes to make sure there is room for every partition
|
// TODO: Refine partition sizes to make sure there is room for every partition
|
||||||
// Use a default (200-500M ?) minimum size for partition without minSize
|
// Use a default (200-500M ?) minimum size for partition without minSize
|
||||||
|
|
||||||
foreach( const PartitionLayout::PartitionEntry& part, partLayout )
|
foreach( const PartitionLayout::PartitionEntry& part, m_partLayout )
|
||||||
{
|
{
|
||||||
Partition *currentPartition = nullptr;
|
Partition *currentPartition = nullptr;
|
||||||
|
|
||||||
// Calculate partition size
|
// Calculate partition size
|
||||||
size = sizeToSectors( part.partSize, part.partSizeUnit, totalSize, dev->logicalSize() );
|
size = PartUtils::sizeToSectors( part.partSize, part.partSizeUnit, totalSize, dev->logicalSize() );
|
||||||
minSize = sizeToSectors( part.partMinSize, part.partMinSizeUnit, totalSize, dev->logicalSize() );
|
minSize = PartUtils::sizeToSectors( part.partMinSize, part.partMinSizeUnit, totalSize, dev->logicalSize() );
|
||||||
if ( size < minSize )
|
if ( size < minSize )
|
||||||
size = minSize;
|
size = minSize;
|
||||||
if ( size > availableSize )
|
if ( size > availableSize )
|
||||||
@ -194,7 +140,7 @@ PartitionLayout::execute( Device *dev, qint64 firstSector,
|
|||||||
parent,
|
parent,
|
||||||
*dev,
|
*dev,
|
||||||
role,
|
role,
|
||||||
static_cast<FileSystem::Type>(part.partFileSystem),
|
part.partFileSystem,
|
||||||
firstSector,
|
firstSector,
|
||||||
end,
|
end,
|
||||||
PartitionTable::FlagNone
|
PartitionTable::FlagNone
|
||||||
@ -206,7 +152,7 @@ PartitionLayout::execute( Device *dev, qint64 firstSector,
|
|||||||
parent,
|
parent,
|
||||||
*dev,
|
*dev,
|
||||||
role,
|
role,
|
||||||
static_cast<FileSystem::Type>(part.partFileSystem),
|
part.partFileSystem,
|
||||||
firstSector,
|
firstSector,
|
||||||
end,
|
end,
|
||||||
luksPassphrase,
|
luksPassphrase,
|
||||||
|
@ -20,10 +20,13 @@
|
|||||||
#ifndef PARTITIONLAYOUT_H
|
#ifndef PARTITIONLAYOUT_H
|
||||||
#define PARTITIONLAYOUT_H
|
#define PARTITIONLAYOUT_H
|
||||||
|
|
||||||
|
#include "core/PartUtils.h"
|
||||||
|
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
|
|
||||||
// KPMcore
|
// KPMcore
|
||||||
#include <kpmcore/core/partitiontable.h>
|
#include <kpmcore/core/partitiontable.h>
|
||||||
|
#include <kpmcore/fs/filesystem.h>
|
||||||
|
|
||||||
// Qt
|
// Qt
|
||||||
#include <QList>
|
#include <QList>
|
||||||
@ -35,24 +38,15 @@ class PartitionLayout
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum SizeUnit
|
|
||||||
{
|
|
||||||
Percent = 0,
|
|
||||||
Byte,
|
|
||||||
KiB,
|
|
||||||
MiB,
|
|
||||||
GiB
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PartitionEntry
|
struct PartitionEntry
|
||||||
{
|
{
|
||||||
QString partLabel;
|
QString partLabel;
|
||||||
QString partMountPoint;
|
QString partMountPoint;
|
||||||
int partFileSystem = 0;
|
FileSystem::Type partFileSystem = FileSystem::Unknown;
|
||||||
double partSize = 0.0L;
|
double partSize = 0.0L;
|
||||||
SizeUnit partSizeUnit = Percent;
|
PartUtils::SizeUnit partSizeUnit = PartUtils::SizeUnit::Percent;
|
||||||
double partMinSize = 0.0L;
|
double partMinSize = 0.0L;
|
||||||
SizeUnit partMinSizeUnit = Percent;
|
PartUtils::SizeUnit partMinSizeUnit = PartUtils::SizeUnit::Percent;
|
||||||
|
|
||||||
/// @brief All-zeroes PartitionEntry
|
/// @brief All-zeroes PartitionEntry
|
||||||
PartitionEntry() {};
|
PartitionEntry() {};
|
||||||
@ -76,7 +70,8 @@ public:
|
|||||||
QList< Partition* > execute( Device *dev, qint64 firstSector, qint64 lastSector, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role );
|
QList< Partition* > execute( Device *dev, qint64 firstSector, qint64 lastSector, QString luksPassphrase, PartitionNode* parent, const PartitionRole& role );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList< PartitionEntry > partLayout;
|
FileSystem::Type m_defaultFsType;
|
||||||
|
QList< PartitionEntry > m_partLayout;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* PARTITIONLAYOUT_H */
|
#endif /* PARTITIONLAYOUT_H */
|
||||||
|
@ -882,11 +882,6 @@ ChoicePage::updateDeviceStatePreview()
|
|||||||
PartitionModel* model = new PartitionModel( m_beforePartitionBarsView );
|
PartitionModel* model = new PartitionModel( m_beforePartitionBarsView );
|
||||||
model->init( deviceBefore, m_core->osproberEntries() );
|
model->init( deviceBefore, m_core->osproberEntries() );
|
||||||
|
|
||||||
// The QObject parents tree is meaningful for memory management here,
|
|
||||||
// see qDeleteAll above.
|
|
||||||
deviceBefore->setParent( model ); // Can't reparent across threads
|
|
||||||
model->setParent( m_beforePartitionBarsView );
|
|
||||||
|
|
||||||
m_beforePartitionBarsView->setModel( model );
|
m_beforePartitionBarsView->setModel( model );
|
||||||
m_beforePartitionLabelsView->setModel( model );
|
m_beforePartitionLabelsView->setModel( model );
|
||||||
|
|
||||||
@ -1248,7 +1243,7 @@ ChoicePage::setupActions()
|
|||||||
}
|
}
|
||||||
if ( PartUtils::canBeReplaced( *it ) )
|
if ( PartUtils::canBeReplaced( *it ) )
|
||||||
{
|
{
|
||||||
cDebug() << ".. contains replacable" << it;
|
cDebug() << ".. contains replaceable" << it;
|
||||||
atLeastOneCanBeReplaced = true;
|
atLeastOneCanBeReplaced = true;
|
||||||
}
|
}
|
||||||
if ( (*it)->isMounted() )
|
if ( (*it)->isMounted() )
|
||||||
|
@ -34,7 +34,7 @@ CreateVolumeGroupDialog::CreateVolumeGroupDialog( QString& vgName,
|
|||||||
, m_selectedPVs( selectedPVs )
|
, m_selectedPVs( selectedPVs )
|
||||||
, m_peSize( pSize )
|
, m_peSize( pSize )
|
||||||
{
|
{
|
||||||
setWindowTitle( "Create Volume Group" );
|
setWindowTitle( tr( "Create Volume Group" ) );
|
||||||
|
|
||||||
peSize()->setValue( pSize );
|
peSize()->setValue( pSize );
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ void
|
|||||||
standardMountPoints(QComboBox& combo)
|
standardMountPoints(QComboBox& combo)
|
||||||
{
|
{
|
||||||
combo.clear();
|
combo.clear();
|
||||||
combo.addItem( combo.tr( "(no mount point)" ) );
|
combo.addItem( QObject::tr( "(no mount point)" ) );
|
||||||
combo.addItems( standardMountPoints() );
|
combo.addItems( standardMountPoints() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +56,6 @@
|
|||||||
#include <kpmcore/ops/removevolumegroupoperation.h>
|
#include <kpmcore/ops/removevolumegroupoperation.h>
|
||||||
|
|
||||||
// Qt
|
// Qt
|
||||||
#include <QDebug>
|
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QItemSelectionModel>
|
#include <QItemSelectionModel>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
@ -90,22 +89,9 @@ PartitionPage::PartitionPage( PartitionCoreModule* core, QWidget* parent )
|
|||||||
|
|
||||||
updateFromCurrentDevice();
|
updateFromCurrentDevice();
|
||||||
|
|
||||||
connect( m_ui->deviceComboBox, &QComboBox::currentTextChanged,
|
connect( m_ui->deviceComboBox, &QComboBox::currentTextChanged, this, &PartitionPage::updateFromCurrentDevice );
|
||||||
[ this ]( const QString& /* text */ )
|
connect( m_ui->bootLoaderComboBox, QOverload<int>::of(&QComboBox::activated), this, &PartitionPage::updateSelectedBootLoaderIndex );
|
||||||
{
|
connect( m_ui->bootLoaderComboBox, &QComboBox::currentTextChanged, this, &PartitionPage::updateBootLoaderInstallPath );
|
||||||
updateFromCurrentDevice();
|
|
||||||
} );
|
|
||||||
connect( m_ui->bootLoaderComboBox, static_cast<void(QComboBox::*)(const QString &)>(&QComboBox::activated),
|
|
||||||
[ this ]( const QString& /* text */ )
|
|
||||||
{
|
|
||||||
m_lastSelectedBootLoaderIndex = m_ui->bootLoaderComboBox->currentIndex();
|
|
||||||
} );
|
|
||||||
|
|
||||||
connect( m_ui->bootLoaderComboBox, &QComboBox::currentTextChanged,
|
|
||||||
[ this ]( const QString& /* text */ )
|
|
||||||
{
|
|
||||||
updateBootLoaderInstallPath();
|
|
||||||
} );
|
|
||||||
|
|
||||||
connect( m_core, &PartitionCoreModule::isDirtyChanged, m_ui->revertButton, &QWidget::setEnabled );
|
connect( m_core, &PartitionCoreModule::isDirtyChanged, m_ui->revertButton, &QWidget::setEnabled );
|
||||||
|
|
||||||
@ -376,18 +362,18 @@ PartitionPage::onCreateClicked()
|
|||||||
if ( !checkCanCreate( model->device() ) )
|
if ( !checkCanCreate( model->device() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QPointer< CreatePartitionDialog > dlg = new CreatePartitionDialog( model->device(),
|
CreatePartitionDialog dlg(
|
||||||
|
model->device(),
|
||||||
partition->parent(),
|
partition->parent(),
|
||||||
nullptr,
|
nullptr,
|
||||||
getCurrentUsedMountpoints(),
|
getCurrentUsedMountpoints(),
|
||||||
this );
|
this );
|
||||||
dlg->initFromFreeSpace( partition );
|
dlg.initFromFreeSpace( partition );
|
||||||
if ( dlg->exec() == QDialog::Accepted )
|
if ( dlg.exec() == QDialog::Accepted )
|
||||||
{
|
{
|
||||||
Partition* newPart = dlg->createPartition();
|
Partition* newPart = dlg.createPartition();
|
||||||
m_core->createPartition( model->device(), newPart, dlg->newFlags() );
|
m_core->createPartition( model->device(), newPart, dlg.newFlags() );
|
||||||
}
|
}
|
||||||
delete dlg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -508,10 +494,17 @@ PartitionPage::updateBootLoaderInstallPath()
|
|||||||
QVariant var = m_ui->bootLoaderComboBox->currentData( BootLoaderModel::BootLoaderPathRole );
|
QVariant var = m_ui->bootLoaderComboBox->currentData( BootLoaderModel::BootLoaderPathRole );
|
||||||
if ( !var.isValid() )
|
if ( !var.isValid() )
|
||||||
return;
|
return;
|
||||||
qDebug() << "PartitionPage::updateBootLoaderInstallPath" << var.toString();
|
cDebug() << "PartitionPage::updateBootLoaderInstallPath" << var.toString();
|
||||||
m_core->setBootLoaderInstallPath( var.toString() );
|
m_core->setBootLoaderInstallPath( var.toString() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PartitionPage::updateSelectedBootLoaderIndex()
|
||||||
|
{
|
||||||
|
m_lastSelectedBootLoaderIndex = m_ui->bootLoaderComboBox->currentIndex();
|
||||||
|
cDebug() << "Selected bootloader index" << m_lastSelectedBootLoaderIndex;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PartitionPage::updateFromCurrentDevice()
|
PartitionPage::updateFromCurrentDevice()
|
||||||
{
|
{
|
||||||
@ -581,7 +574,7 @@ void
|
|||||||
PartitionPage::onPartitionModelReset()
|
PartitionPage::onPartitionModelReset()
|
||||||
{
|
{
|
||||||
m_ui->partitionTreeView->expandAll();
|
m_ui->partitionTreeView->expandAll();
|
||||||
// updateButtons();
|
updateButtons();
|
||||||
updateBootLoaderIndex();
|
updateBootLoaderIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,14 @@ public:
|
|||||||
int selectedDeviceIndex();
|
int selectedDeviceIndex();
|
||||||
void selectDeviceByIndex( int index );
|
void selectDeviceByIndex( int index );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
/// @brief Update everything when the base device changes
|
||||||
|
void updateFromCurrentDevice();
|
||||||
|
/// @brief Update when the selected device for boot loader changes
|
||||||
|
void updateBootLoaderInstallPath();
|
||||||
|
/// @brief Explicitly selected boot loader path
|
||||||
|
void updateSelectedBootLoaderIndex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer< Ui_PartitionPage > m_ui;
|
QScopedPointer< Ui_PartitionPage > m_ui;
|
||||||
PartitionCoreModule* m_core;
|
PartitionCoreModule* m_core;
|
||||||
@ -67,8 +75,6 @@ private:
|
|||||||
|
|
||||||
void updatePartitionToCreate( Device*, Partition* );
|
void updatePartitionToCreate( Device*, Partition* );
|
||||||
void editExistingPartition( Device*, Partition* );
|
void editExistingPartition( Device*, Partition* );
|
||||||
void updateBootLoaderInstallPath();
|
|
||||||
void updateFromCurrentDevice();
|
|
||||||
void updateBootLoaderIndex();
|
void updateBootLoaderIndex();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
|
* Copyright 2014, Aurélien Gâteau <agateau@kde.org>
|
||||||
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||||
* Copyright 2019, Collabora Ltd
|
* Copyright 2019, Collabora Ltd <arnaud.ferraris@collabora.com>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -60,6 +60,8 @@
|
|||||||
#include <QtConcurrent/QtConcurrent>
|
#include <QtConcurrent/QtConcurrent>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
|
|
||||||
|
#include <unistd.h> // For sleep(3)
|
||||||
|
|
||||||
PartitionViewStep::PartitionViewStep( QObject* parent )
|
PartitionViewStep::PartitionViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
, m_core( nullptr )
|
, m_core( nullptr )
|
||||||
@ -292,25 +294,8 @@ PartitionViewStep::next()
|
|||||||
if ( m_core->isDirty() )
|
if ( m_core->isDirty() )
|
||||||
m_manualPartitionPage->onRevertClicked();
|
m_manualPartitionPage->onRevertClicked();
|
||||||
}
|
}
|
||||||
else if ( m_choicePage->currentChoice() == ChoicePage::Erase )
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( m_choicePage->currentChoice() == ChoicePage::Alongside )
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if ( m_choicePage->currentChoice() == ChoicePage::Replace )
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
cDebug() << "Choice applied: " << m_choicePage->currentChoice();
|
cDebug() << "Choice applied: " << m_choicePage->currentChoice();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
emit done();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -397,7 +382,7 @@ PartitionViewStep::onLeave()
|
|||||||
if ( PartUtils::isEfiSystem() )
|
if ( PartUtils::isEfiSystem() )
|
||||||
{
|
{
|
||||||
QString espMountPoint = Calamares::JobQueue::instance()->globalStorage()->
|
QString espMountPoint = Calamares::JobQueue::instance()->globalStorage()->
|
||||||
value( "efiSystemPartition").toString();
|
value( "efiSystemPartition" ).toString();
|
||||||
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
|
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
|
||||||
|
|
||||||
QString message;
|
QString message;
|
||||||
@ -493,55 +478,6 @@ nameToChoice( QString name, bool& ok )
|
|||||||
return names.find( name, ok );
|
return names.find( name, ok );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief translate @p defaultFS into a recognized name
|
|
||||||
*
|
|
||||||
* Makes several attempts to translate the string into a
|
|
||||||
* name that KPMCore will recognize.
|
|
||||||
*/
|
|
||||||
static QString
|
|
||||||
findFS( QString defaultFS )
|
|
||||||
{
|
|
||||||
QStringList fsLanguage { QLatin1Literal( "C" ) }; // Required language list to turn off localization
|
|
||||||
if ( defaultFS.isEmpty() )
|
|
||||||
{
|
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* is missing, using ext4";
|
|
||||||
defaultFS = QStringLiteral( "ext4" );
|
|
||||||
}
|
|
||||||
if ( FileSystem::typeForName( defaultFS, fsLanguage ) != FileSystem::Unknown )
|
|
||||||
{
|
|
||||||
cDebug() << "Partition-module setting *defaultFileSystemType*" << defaultFS;
|
|
||||||
return defaultFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Second pass: try case-insensitive
|
|
||||||
const auto fstypes = FileSystem::types();
|
|
||||||
for ( FileSystem::Type t : fstypes )
|
|
||||||
{
|
|
||||||
if ( 0 == QString::compare( defaultFS, FileSystem::nameForType( t, fsLanguage ), Qt::CaseInsensitive ) )
|
|
||||||
{
|
|
||||||
defaultFS = FileSystem::nameForType( t, fsLanguage );
|
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* changed" << defaultFS;
|
|
||||||
return defaultFS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cWarning() << "Partition-module setting *defaultFileSystemType* is bad (" << defaultFS << ") using ext4.";
|
|
||||||
defaultFS = QStringLiteral( "ext4" );
|
|
||||||
#ifdef DEBUG_FILESYSTEMS
|
|
||||||
// This bit is for distro's debugging their settings, and shows
|
|
||||||
// all the strings that KPMCore is matching against for FS type.
|
|
||||||
{
|
|
||||||
Logger::CDebug d;
|
|
||||||
using TR = Logger::DebugRow< int, QString >;
|
|
||||||
const auto fstypes = FileSystem::types();
|
|
||||||
d << "Available types (" << fstypes.count() << ')';
|
|
||||||
for ( FileSystem::Type t : fstypes )
|
|
||||||
d << TR( static_cast<int>( t ), FileSystem::nameForType( t, fsLanguage ) );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return defaultFS;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
@ -553,6 +489,17 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
efiSP = QStringLiteral( "/boot/efi" );
|
efiSP = QStringLiteral( "/boot/efi" );
|
||||||
gs->insert( "efiSystemPartition", efiSP );
|
gs->insert( "efiSystemPartition", efiSP );
|
||||||
|
|
||||||
|
// Set up firmwareType global storage entry. This is used, e.g. by the bootloader module.
|
||||||
|
QString firmwareType( PartUtils::isEfiSystem() ? QStringLiteral( "efi" ) : QStringLiteral( "bios" ) );
|
||||||
|
cDebug() << "Setting firmwareType to" << firmwareType;
|
||||||
|
gs->insert( "firmwareType", firmwareType );
|
||||||
|
|
||||||
|
// Read and parse key efiSystemPartitionSize
|
||||||
|
if ( configurationMap.contains( "efiSystemPartitionSize" ) )
|
||||||
|
{
|
||||||
|
gs->insert( "efiSystemPartitionSize", CalamaresUtils::getString( configurationMap, "efiSystemPartitionSize" ) );
|
||||||
|
}
|
||||||
|
|
||||||
// SWAP SETTINGS
|
// SWAP SETTINGS
|
||||||
//
|
//
|
||||||
// This is a bit convoluted because there's legacy settings to handle as well
|
// This is a bit convoluted because there's legacy settings to handle as well
|
||||||
@ -630,23 +577,38 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
gs->insert( "alwaysShowPartitionLabels", CalamaresUtils::getBool( configurationMap, "alwaysShowPartitionLabels", true ) );
|
gs->insert( "alwaysShowPartitionLabels", CalamaresUtils::getBool( configurationMap, "alwaysShowPartitionLabels", true ) );
|
||||||
gs->insert( "enableLuksAutomatedPartitioning", CalamaresUtils::getBool( configurationMap, "enableLuksAutomatedPartitioning", true ) );
|
gs->insert( "enableLuksAutomatedPartitioning", CalamaresUtils::getBool( configurationMap, "enableLuksAutomatedPartitioning", true ) );
|
||||||
gs->insert( "allowManualPartitioning", CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ) );
|
gs->insert( "allowManualPartitioning", CalamaresUtils::getBool( configurationMap, "allowManualPartitioning", true ) );
|
||||||
gs->insert( "defaultFileSystemType", findFS( CalamaresUtils::getString( configurationMap, "defaultFileSystemType" ) ) );
|
|
||||||
|
// The defaultFileSystemType setting needs a bit more processing,
|
||||||
|
// as we want to cover various cases (such as different cases)
|
||||||
|
QString fsName = CalamaresUtils::getString( configurationMap, "defaultFileSystemType" );
|
||||||
|
FileSystem::Type fsType;
|
||||||
|
if ( fsName.isEmpty() )
|
||||||
|
cWarning() << "Partition-module setting *defaultFileSystemType* is missing, will use ext4";
|
||||||
|
QString fsRealName = PartUtils::findFS( fsName, &fsType );
|
||||||
|
if ( fsRealName == fsName )
|
||||||
|
cDebug() << "Partition-module setting *defaultFileSystemType*" << fsRealName;
|
||||||
|
else if ( fsType != FileSystem::Unknown )
|
||||||
|
cWarning() << "Partition-module setting *defaultFileSystemType* changed" << fsRealName;
|
||||||
|
else
|
||||||
|
cWarning() << "Partition-module setting *defaultFileSystemType* is bad (" << fsRealName << ") using ext4.";
|
||||||
|
gs->insert( "defaultFileSystemType", fsRealName );
|
||||||
|
|
||||||
|
|
||||||
// Now that we have the config, we load the PartitionCoreModule in the background
|
// Now that we have the config, we load the PartitionCoreModule in the background
|
||||||
// because it could take a while. Then when it's done, we can set up the widgets
|
// because it could take a while. Then when it's done, we can set up the widgets
|
||||||
// and remove the spinner.
|
// and remove the spinner.
|
||||||
QFutureWatcher< void >* watcher = new QFutureWatcher< void >();
|
m_future = new QFutureWatcher< void >();
|
||||||
connect( watcher, &QFutureWatcher< void >::finished,
|
connect( m_future, &QFutureWatcher< void >::finished,
|
||||||
this, [ this, watcher, choices ]
|
this, [ this ]
|
||||||
{
|
{
|
||||||
continueLoading();
|
continueLoading();
|
||||||
watcher->deleteLater();
|
this->m_future->deleteLater();
|
||||||
|
this->m_future = nullptr;
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QFuture< void > future =
|
QFuture< void > future =
|
||||||
QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
||||||
watcher->setFuture( future );
|
m_future->setFuture( future );
|
||||||
|
|
||||||
if ( configurationMap.contains( "partitionLayout" ) )
|
if ( configurationMap.contains( "partitionLayout" ) )
|
||||||
{
|
{
|
||||||
@ -665,5 +627,24 @@ PartitionViewStep::jobs() const
|
|||||||
return m_core->jobs();
|
return m_core->jobs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Calamares::RequirementsList
|
||||||
|
PartitionViewStep::checkRequirements()
|
||||||
|
{
|
||||||
|
if ( m_future )
|
||||||
|
m_future->waitForFinished();
|
||||||
|
|
||||||
|
Calamares::RequirementsList l;
|
||||||
|
l.append(
|
||||||
|
{
|
||||||
|
QLatin1Literal( "partitions" ),
|
||||||
|
[]{ return tr( "has at least one disk device available." ); },
|
||||||
|
[]{ return tr( "There are no partitons to install on." ); },
|
||||||
|
m_core->deviceModel()->rowCount() > 0, // satisfied
|
||||||
|
true // required
|
||||||
|
} );
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( PartitionViewStepFactory, registerPlugin<PartitionViewStep>(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( PartitionViewStepFactory, registerPlugin<PartitionViewStep>(); )
|
||||||
|
@ -36,6 +36,8 @@ class PartitionPage;
|
|||||||
class PartitionCoreModule;
|
class PartitionCoreModule;
|
||||||
class QStackedWidget;
|
class QStackedWidget;
|
||||||
|
|
||||||
|
template<typename T> class QFutureWatcher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The starting point of the module. Instantiates PartitionCoreModule,
|
* The starting point of the module. Instantiates PartitionCoreModule,
|
||||||
* ChoicePage and PartitionPage, then connects them.
|
* ChoicePage and PartitionPage, then connects them.
|
||||||
@ -69,6 +71,8 @@ public:
|
|||||||
|
|
||||||
QList< Calamares::job_ptr > jobs() const override;
|
QList< Calamares::job_ptr > jobs() const override;
|
||||||
|
|
||||||
|
Calamares::RequirementsList checkRequirements() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initPartitionCoreModule();
|
void initPartitionCoreModule();
|
||||||
void continueLoading();
|
void continueLoading();
|
||||||
@ -79,6 +83,7 @@ private:
|
|||||||
PartitionPage* m_manualPartitionPage;
|
PartitionPage* m_manualPartitionPage;
|
||||||
|
|
||||||
QWidget* m_waitingWidget;
|
QWidget* m_waitingWidget;
|
||||||
|
QFutureWatcher<void>* m_future;
|
||||||
|
|
||||||
QSet< PartitionActions::Choices::SwapChoice > m_swapChoices;
|
QSet< PartitionActions::Choices::SwapChoice > m_swapChoices;
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,7 @@ ResizeVolumeGroupDialog::ResizeVolumeGroupDialog( LvmDevice *device,
|
|||||||
: VolumeGroupBaseDialog( device->name(), device->physicalVolumes(), parent )
|
: VolumeGroupBaseDialog( device->name(), device->physicalVolumes(), parent )
|
||||||
, m_selectedPVs( selectedPVs )
|
, m_selectedPVs( selectedPVs )
|
||||||
{
|
{
|
||||||
setWindowTitle( "Resize Volume Group" );
|
setWindowTitle( tr( "Resize Volume Group" ) );
|
||||||
|
|
||||||
for ( int i = 0; i < pvList()->count(); i++ )
|
for ( int i = 0; i < pvList()->count(); i++ )
|
||||||
pvList()->item(i)->setCheckState( Qt::Checked );
|
pvList()->item(i)->setCheckState( Qt::Checked );
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>VolumeGroupDialog</string>
|
<string>Create Volume Group</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
class CreateVolumeGroupJob : public Calamares::Job
|
class CreateVolumeGroupJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize );
|
CreateVolumeGroupJob( QString& vgName, QVector< const Partition* > pvList, const qint32 peSize );
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ class LvmDevice;
|
|||||||
|
|
||||||
class DeactivateVolumeGroupJob : public Calamares::Job
|
class DeactivateVolumeGroupJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
DeactivateVolumeGroupJob( LvmDevice* device );
|
DeactivateVolumeGroupJob( LvmDevice* device );
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ class LvmDevice;
|
|||||||
|
|
||||||
class RemoveVolumeGroupJob : public Calamares::Job
|
class RemoveVolumeGroupJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
RemoveVolumeGroupJob( LvmDevice* device );
|
RemoveVolumeGroupJob( LvmDevice* device );
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ class Partition;
|
|||||||
|
|
||||||
class ResizeVolumeGroupJob : public Calamares::Job
|
class ResizeVolumeGroupJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList );
|
ResizeVolumeGroupJob( LvmDevice* device, QVector< const Partition* >& partitionList );
|
||||||
|
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
# etc.) use just /boot.
|
# etc.) use just /boot.
|
||||||
efiSystemPartition: "/boot/efi"
|
efiSystemPartition: "/boot/efi"
|
||||||
|
|
||||||
|
# This optional setting specifies the size of the EFI system partition.
|
||||||
|
# If nothing is specified, the default size of 300MiB will be used.
|
||||||
|
# efiSystemPartitionSize: 300M
|
||||||
|
|
||||||
# In autogenerated partitioning, allow the user to select a swap size?
|
# In autogenerated partitioning, allow the user to select a swap size?
|
||||||
# If there is exactly one choice, no UI is presented, and the user
|
# If there is exactly one choice, no UI is presented, and the user
|
||||||
# cannot make a choice -- this setting is used. If there is more than
|
# cannot make a choice -- this setting is used. If there is more than
|
||||||
|
@ -350,7 +350,8 @@ PartitionJobTests::testResizePartition()
|
|||||||
|
|
||||||
// Make the test data file smaller than the full size of the partition to
|
// Make the test data file smaller than the full size of the partition to
|
||||||
// accomodate for the file system overhead
|
// accomodate for the file system overhead
|
||||||
const QByteArray testData = generateTestData( CalamaresUtils::MiBtoBytes( qMin( oldSizeMB, newSizeMB ) ) * 3 / 4 );
|
const unsigned long long minSizeMB = qMin( oldSizeMB, newSizeMB );
|
||||||
|
const QByteArray testData = generateTestData( CalamaresUtils::MiBtoBytes( minSizeMB ) * 3 / 4 );
|
||||||
const QString testName = "test.data";
|
const QString testName = "test.data";
|
||||||
|
|
||||||
// Setup: create the test partition
|
// Setup: create the test partition
|
||||||
|
@ -76,18 +76,6 @@ PlasmaLnfViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlasmaLnfViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlasmaLnfViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PlasmaLnfViewStep::isNextEnabled() const
|
PlasmaLnfViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -41,9 +41,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
# Copyright 2016, Artoo <artoo@manjaro.org>
|
# Copyright 2016, Artoo <artoo@manjaro.org>
|
||||||
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
||||||
# Copyright 2018, Gabriel Craciunescu <crazy@frugalware.org>
|
# Copyright 2018, Gabriel Craciunescu <crazy@frugalware.org>
|
||||||
|
# Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
#
|
#
|
||||||
# Calamares is free software: you can redistribute it and/or modify
|
# Calamares is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -24,6 +25,16 @@ import libcalamares
|
|||||||
|
|
||||||
from libcalamares.utils import debug, target_env_call
|
from libcalamares.utils import debug, target_env_call
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
_ = gettext.translation("calamares-python",
|
||||||
|
localedir=libcalamares.utils.gettext_path(),
|
||||||
|
languages=libcalamares.utils.gettext_languages(),
|
||||||
|
fallback=True).gettext
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_name():
|
||||||
|
return _("Configure Plymouth theme")
|
||||||
|
|
||||||
|
|
||||||
class PlymouthController:
|
class PlymouthController:
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Copyright 2015, Teo Mrnjavac <teo@kde.org>
|
# Copyright 2015, Teo Mrnjavac <teo@kde.org>
|
||||||
# Copyright 2017. Alf Gaida <agaida@siduction.org>
|
# Copyright 2017. Alf Gaida <agaida@siduction.org>
|
||||||
|
# Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
#
|
#
|
||||||
# Calamares is free software: you can redistribute it and/or modify
|
# Calamares is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -22,6 +23,16 @@
|
|||||||
import subprocess
|
import subprocess
|
||||||
import libcalamares
|
import libcalamares
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
_ = gettext.translation("calamares-python",
|
||||||
|
localedir=libcalamares.utils.gettext_path(),
|
||||||
|
languages=libcalamares.utils.gettext_languages(),
|
||||||
|
fallback=True).gettext
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_name():
|
||||||
|
return _("Remove live user from target system")
|
||||||
|
|
||||||
|
|
||||||
def run():
|
def run():
|
||||||
"""
|
"""
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# Copyright 2016, Artoo <artoo@manjaro.org>
|
# Copyright 2016, Artoo <artoo@manjaro.org>
|
||||||
# Copyright 2017, Philip Müller <philm@manjaro.org>
|
# Copyright 2017, Philip Müller <philm@manjaro.org>
|
||||||
# Copyright 2018, Artoo <artoo@artixlinux.org>
|
# Copyright 2018, Artoo <artoo@artixlinux.org>
|
||||||
# Copyright 2018, Adriaan de Groot <groot@kde.org>
|
# Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
|
||||||
#
|
#
|
||||||
# Calamares is free software: you can redistribute it and/or modify
|
# Calamares is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -27,6 +27,17 @@ from libcalamares.utils import target_env_call, warning
|
|||||||
from os.path import exists, join
|
from os.path import exists, join
|
||||||
|
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
_ = gettext.translation("calamares-python",
|
||||||
|
localedir=libcalamares.utils.gettext_path(),
|
||||||
|
languages=libcalamares.utils.gettext_languages(),
|
||||||
|
fallback=True).gettext
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_name():
|
||||||
|
return _("Configure OpenRC services")
|
||||||
|
|
||||||
|
|
||||||
class OpenrcController:
|
class OpenrcController:
|
||||||
"""
|
"""
|
||||||
This is the openrc service controller.
|
This is the openrc service controller.
|
||||||
@ -45,6 +56,22 @@ class OpenrcController:
|
|||||||
self.initdDir = libcalamares.job.configuration['initdDir']
|
self.initdDir = libcalamares.job.configuration['initdDir']
|
||||||
self.runlevelsDir = libcalamares.job.configuration['runlevelsDir']
|
self.runlevelsDir = libcalamares.job.configuration['runlevelsDir']
|
||||||
|
|
||||||
|
|
||||||
|
def make_failure_description(self, state, name, runlevel):
|
||||||
|
"""
|
||||||
|
Returns a generic "could not <foo>" failure message, specialized
|
||||||
|
for the action @p state and the specific service @p name in @p runlevel.
|
||||||
|
"""
|
||||||
|
if state == "add":
|
||||||
|
description = _("Cannot add service {name!s} to run-level {level!s}.")
|
||||||
|
elif state == "del":
|
||||||
|
description = _("Cannot remove service {name!s} from run-level {level!s}.")
|
||||||
|
else:
|
||||||
|
description = _("Unknown service-action <code>{arg!s}</code> for service {name!s} in run-level {level!s}.")
|
||||||
|
|
||||||
|
return description.format(arg=state, name=name, level=runlevel)
|
||||||
|
|
||||||
|
|
||||||
def update(self, state):
|
def update(self, state):
|
||||||
"""
|
"""
|
||||||
Call rc-update for each service listed
|
Call rc-update for each service listed
|
||||||
@ -69,24 +96,31 @@ class OpenrcController:
|
|||||||
if exists(runlevel_path):
|
if exists(runlevel_path):
|
||||||
ec = target_env_call(["rc-update", state, name, runlevel])
|
ec = target_env_call(["rc-update", state, name, runlevel])
|
||||||
if ec != 0:
|
if ec != 0:
|
||||||
|
warning("Cannot {} service {} to {}".format(state, name, runlevel))
|
||||||
|
warning("rc-update returned error code {!s}".format(ec))
|
||||||
if mandatory:
|
if mandatory:
|
||||||
return ("Cannot {} service {} to {}".format(state, name, runlevel),
|
title = _("Cannot modify service")
|
||||||
"rc-update {} call in chroot returned error code {}".format(state, ec)
|
diagnostic = _("<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=state, num=ec)
|
||||||
|
return (title,
|
||||||
|
self.make_failure_description(state, name, runlevel) + " " + diagnostic
|
||||||
)
|
)
|
||||||
else:
|
|
||||||
warning("Could not {} service {} in {}, error {!s}".format(state, name, runlevel, ec))
|
|
||||||
else:
|
|
||||||
if mandatory:
|
|
||||||
return ("Target runlevel {} does not exist for {}.".format(runlevel, name),
|
|
||||||
"No {} found.".format(runlevel_path))
|
|
||||||
else:
|
else:
|
||||||
warning("Target runlevel {} does not exist for {}.".format(runlevel, name))
|
warning("Target runlevel {} does not exist for {}.".format(runlevel, name))
|
||||||
else:
|
|
||||||
if mandatory:
|
if mandatory:
|
||||||
return ("Target service {} does not exist.".format(name),
|
title = _("Target runlevel does not exist")
|
||||||
"No {} found.".format(service_path))
|
diagnostic = _("The path for runlevel {level!s} is <code>{path!s}</code>, which does not exist.").format(level=runlevel, path=runlevel_path)
|
||||||
|
|
||||||
|
return (title,
|
||||||
|
self.make_failure_description(state, name, runlevel) + " " + diagnostic
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
warning("Target service {} does not exist in {}.".format(name, self.initdDir))
|
warning("Target service {} does not exist in {}.".format(name, self.initdDir))
|
||||||
|
if mandatory:
|
||||||
|
title = _("Target service does not exist")
|
||||||
|
diagnostic = _("The path for service {name!s} is <code>{path!s}</code>, which does not exist.").format(name=name, path=service_path)
|
||||||
|
return (title,
|
||||||
|
self.make_failure_description(state, name, runlevel) + " " + diagnostic
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
# Copyright 2014, Philip Müller <philm@manjaro.org>
|
# Copyright 2014, Philip Müller <philm@manjaro.org>
|
||||||
# Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
# Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
||||||
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
||||||
# Copyright 2018, Adriaan de Groot <groot@kde.org>
|
# Copyright 2018-2019, Adriaan de Groot <groot@kde.org>
|
||||||
#
|
#
|
||||||
# Calamares is free software: you can redistribute it and/or modify
|
# Calamares is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
@ -24,6 +24,17 @@
|
|||||||
import libcalamares
|
import libcalamares
|
||||||
|
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
_ = gettext.translation("calamares-python",
|
||||||
|
localedir=libcalamares.utils.gettext_path(),
|
||||||
|
languages=libcalamares.utils.gettext_languages(),
|
||||||
|
fallback=True).gettext
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_name():
|
||||||
|
return _("Configure systemd services")
|
||||||
|
|
||||||
|
|
||||||
def systemctl(targets, command, suffix):
|
def systemctl(targets, command, suffix):
|
||||||
"""
|
"""
|
||||||
For each entry in @p targets, run "systemctl <command> <thing>",
|
For each entry in @p targets, run "systemctl <command> <thing>",
|
||||||
@ -47,17 +58,32 @@ def systemctl(targets, command, suffix):
|
|||||||
)
|
)
|
||||||
|
|
||||||
if ec != 0:
|
if ec != 0:
|
||||||
if mandatory:
|
|
||||||
return ("Cannot {} systemd {} {}".format(command, suffix, name),
|
|
||||||
"systemctl {} call in chroot returned error code {}".format(command, ec)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
libcalamares.utils.warning(
|
libcalamares.utils.warning(
|
||||||
"Cannot {} systemd {} {}".format(command, suffix, name)
|
"Cannot {} systemd {} {}".format(command, suffix, name)
|
||||||
)
|
)
|
||||||
libcalamares.utils.warning(
|
libcalamares.utils.warning(
|
||||||
"systemctl {} call in chroot returned error code {}".format(command, ec)
|
"systemctl {} call in chroot returned error code {}".format(command, ec)
|
||||||
)
|
)
|
||||||
|
if mandatory:
|
||||||
|
title = _("Cannot modify service")
|
||||||
|
diagnostic = _("<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=command, num=ec)
|
||||||
|
|
||||||
|
if command == "enable" and suffix == ".service":
|
||||||
|
description = _("Cannot enable systemd service <code>{name!s}</code>.")
|
||||||
|
elif command == "enable" and suffix == ".target":
|
||||||
|
description = _("Cannot enable systemd target <code>{name!s}</code>.")
|
||||||
|
elif command == "disable" and suffix == ".service":
|
||||||
|
description = _("Cannot enable systemd service <code>{name!s}</code>.")
|
||||||
|
elif command == "disable" and suffix == ".target":
|
||||||
|
description = _("Cannot disable systemd target <code>{name!s}</code>.")
|
||||||
|
elif command == "mask":
|
||||||
|
description = _("Cannot mask systemd unit <code>{name!s}</code>.")
|
||||||
|
else:
|
||||||
|
description = _("Unknown systemd commands <code>{command!s}</code> and <code>{suffix!s}</code> for unit {name!s}.")
|
||||||
|
|
||||||
|
return (title,
|
||||||
|
description.format(name=name, command=command, suffix=suffix) + " " + diagnostic
|
||||||
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@ -92,6 +118,4 @@ def run():
|
|||||||
if r is not None:
|
if r is not None:
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
# This could have just been return r
|
|
||||||
return None
|
return None
|
||||||
|
@ -51,18 +51,6 @@ SummaryViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SummaryViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
SummaryViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SummaryViewStep::isNextEnabled() const
|
SummaryViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -40,9 +40,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -67,18 +67,6 @@ TrackingViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TrackingViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TrackingViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TrackingViewStep::isNextEnabled() const
|
TrackingViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -43,9 +43,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -154,29 +154,29 @@ CreateUserJob::exec()
|
|||||||
useradd << "-c" << m_fullName;
|
useradd << "-c" << m_fullName;
|
||||||
useradd << m_userName;
|
useradd << m_userName;
|
||||||
|
|
||||||
auto pres = CalamaresUtils::System::instance()->targetEnvCommand( useradd );
|
auto commandResult = CalamaresUtils::System::instance()->targetEnvCommand( useradd );
|
||||||
if ( pres.getExitCode() )
|
if ( commandResult.getExitCode() )
|
||||||
{
|
{
|
||||||
cError() << "useradd failed" << pres.getExitCode();
|
cError() << "useradd failed" << commandResult.getExitCode();
|
||||||
return pres.explainProcess( useradd, 10 /* bogus timeout */ );
|
return commandResult.explainProcess( useradd, 10 /* bogus timeout */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
pres = CalamaresUtils::System::instance()->targetEnvCommand(
|
commandResult = CalamaresUtils::System::instance()->targetEnvCommand(
|
||||||
{ "usermod", "-aG", defaultGroups, m_userName } );
|
{ "usermod", "-aG", defaultGroups, m_userName } );
|
||||||
if ( pres.getExitCode() )
|
if ( commandResult.getExitCode() )
|
||||||
{
|
{
|
||||||
cError() << "usermod failed" << pres.getExitCode();
|
cError() << "usermod failed" << commandResult.getExitCode();
|
||||||
return pres.explainProcess( "usermod", 10 );
|
return commandResult.explainProcess( "usermod", 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString userGroup = QString( "%1:%2" ).arg( m_userName ).arg( m_userName );
|
QString userGroup = QString( "%1:%2" ).arg( m_userName ).arg( m_userName );
|
||||||
QString homeDir = QString( "/home/%1" ).arg( m_userName );
|
QString homeDir = QString( "/home/%1" ).arg( m_userName );
|
||||||
pres = CalamaresUtils::System::instance()->targetEnvCommand(
|
commandResult = CalamaresUtils::System::instance()->targetEnvCommand(
|
||||||
{ "chown", "-R", userGroup, homeDir } );
|
{ "chown", "-R", userGroup, homeDir } );
|
||||||
if ( pres.getExitCode() )
|
if ( commandResult.getExitCode() )
|
||||||
{
|
{
|
||||||
cError() << "chown failed" << pres.getExitCode();
|
cError() << "chown failed" << commandResult.getExitCode();
|
||||||
return pres.explainProcess( "chown", 10 );
|
return commandResult.explainProcess( "chown", 10 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return Calamares::JobResult::ok();
|
return Calamares::JobResult::ok();
|
||||||
|
@ -61,18 +61,6 @@ UsersViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
UsersViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
UsersViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
UsersViewStep::isNextEnabled() const
|
UsersViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -43,9 +43,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
|
@ -72,18 +72,6 @@ WebViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WebViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WebViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WebViewStep::isNextEnabled() const
|
WebViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
|
@ -50,8 +50,6 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
void onActivate() override;
|
void onActivate() override;
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
|
@ -15,9 +15,10 @@ endif()
|
|||||||
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
|
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
|
||||||
|
|
||||||
set( CHECKER_SOURCES
|
set( CHECKER_SOURCES
|
||||||
checker/CheckItemWidget.cpp
|
checker/CheckerContainer.cpp
|
||||||
checker/CheckerWidget.cpp
|
checker/ResultWidget.cpp
|
||||||
checker/RequirementsChecker.cpp
|
checker/ResultsListWidget.cpp
|
||||||
|
checker/GeneralRequirements.cpp
|
||||||
${PARTMAN_SRC}
|
${PARTMAN_SRC}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,10 +22,12 @@
|
|||||||
|
|
||||||
#include "ui_WelcomePage.h"
|
#include "ui_WelcomePage.h"
|
||||||
#include "CalamaresVersion.h"
|
#include "CalamaresVersion.h"
|
||||||
#include "checker/RequirementsChecker.h"
|
#include "checker/CheckerContainer.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
#include "utils/Retranslator.h"
|
#include "utils/Retranslator.h"
|
||||||
|
|
||||||
|
#include "modulesystem/ModuleManager.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
@ -39,11 +41,14 @@
|
|||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
|
|
||||||
|
|
||||||
WelcomePage::WelcomePage( RequirementsChecker* requirementsChecker, QWidget* parent )
|
WelcomePage::WelcomePage( QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
, ui( new Ui::WelcomePage )
|
, ui( new Ui::WelcomePage )
|
||||||
, m_requirementsChecker( requirementsChecker )
|
, m_checkingWidget( new CheckerContainer( this ) )
|
||||||
{
|
{
|
||||||
|
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsResult, m_checkingWidget, &CheckerContainer::requirementsChecked );
|
||||||
|
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsComplete, m_checkingWidget, &CheckerContainer::requirementsComplete );
|
||||||
|
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsProgress, m_checkingWidget, &CheckerContainer::requirementsProgress );
|
||||||
ui->setupUi( this );
|
ui->setupUi( this );
|
||||||
|
|
||||||
ui->verticalLayout->insertSpacing( 1, CalamaresUtils::defaultFontHeight() * 2 );
|
ui->verticalLayout->insertSpacing( 1, CalamaresUtils::defaultFontHeight() * 2 );
|
||||||
@ -102,7 +107,7 @@ WelcomePage::WelcomePage( RequirementsChecker* requirementsChecker, QWidget* par
|
|||||||
mb.exec();
|
mb.exec();
|
||||||
} );
|
} );
|
||||||
|
|
||||||
ui->verticalLayout->insertWidget( 3, m_requirementsChecker->widget() );
|
ui->verticalLayout->insertWidget( 3, m_checkingWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -277,3 +282,8 @@ WelcomePage::focusInEvent( QFocusEvent* e )
|
|||||||
ui->languageWidget->setFocus();
|
ui->languageWidget->setFocus();
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WelcomePage::verdict() const
|
||||||
|
{
|
||||||
|
return m_checkingWidget->verdict();
|
||||||
|
}
|
||||||
|
@ -26,26 +26,27 @@ namespace Ui
|
|||||||
class WelcomePage;
|
class WelcomePage;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RequirementsChecker;
|
class CheckerContainer;
|
||||||
|
|
||||||
class WelcomePage : public QWidget
|
class WelcomePage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit WelcomePage( RequirementsChecker* requirementsChecker,
|
explicit WelcomePage( QWidget* parent = nullptr );
|
||||||
QWidget* parent = nullptr );
|
|
||||||
|
|
||||||
void setUpLinks( bool showSupportUrl,
|
void setUpLinks( bool showSupportUrl,
|
||||||
bool showKnownIssuesUrl,
|
bool showKnownIssuesUrl,
|
||||||
bool showReleaseNotesUrl );
|
bool showReleaseNotesUrl );
|
||||||
|
|
||||||
|
bool verdict() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void focusInEvent( QFocusEvent* e ) override; //choose the child widget to focus
|
void focusInEvent( QFocusEvent* e ) override; //choose the child widget to focus
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initLanguages();
|
void initLanguages();
|
||||||
Ui::WelcomePage* ui;
|
Ui::WelcomePage* ui;
|
||||||
RequirementsChecker* m_requirementsChecker;
|
CheckerContainer* m_checkingWidget;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WELCOMEPAGE_H
|
#endif // WELCOMEPAGE_H
|
||||||
|
@ -20,9 +20,10 @@
|
|||||||
#include "WelcomeViewStep.h"
|
#include "WelcomeViewStep.h"
|
||||||
|
|
||||||
#include "WelcomePage.h"
|
#include "WelcomePage.h"
|
||||||
#include "checker/RequirementsChecker.h"
|
#include "checker/GeneralRequirements.h"
|
||||||
#include "utils/Logger.h"
|
|
||||||
|
|
||||||
|
#include "modulesystem/ModuleManager.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
@ -30,12 +31,10 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeViewStepFactory, registerPlugin<Welc
|
|||||||
|
|
||||||
WelcomeViewStep::WelcomeViewStep( QObject* parent )
|
WelcomeViewStep::WelcomeViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
, m_requirementsChecker( new RequirementsChecker( this ) )
|
, m_requirementsChecker( new GeneralRequirements( this ) )
|
||||||
{
|
{
|
||||||
emit nextStatusChanged( true );
|
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsComplete, this, &WelcomeViewStep::nextStatusChanged );
|
||||||
m_widget = new WelcomePage( m_requirementsChecker );
|
m_widget = new WelcomePage();
|
||||||
connect( m_requirementsChecker, &RequirementsChecker::verdictChanged,
|
|
||||||
this, &WelcomeViewStep::nextStatusChanged );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -60,22 +59,10 @@ WelcomeViewStep::widget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WelcomeViewStep::next()
|
|
||||||
{
|
|
||||||
emit done();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WelcomeViewStep::back()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WelcomeViewStep::isNextEnabled() const
|
WelcomeViewStep::isNextEnabled() const
|
||||||
{
|
{
|
||||||
return m_requirementsChecker->verdict();
|
return m_widget->verdict();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,10 +87,10 @@ WelcomeViewStep::isAtEnd() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QList< Calamares::job_ptr >
|
Calamares::JobList
|
||||||
WelcomeViewStep::jobs() const
|
WelcomeViewStep::jobs() const
|
||||||
{
|
{
|
||||||
return QList< Calamares::job_ptr >();
|
return Calamares::JobList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -135,3 +122,7 @@ WelcomeViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
"module configuration.";
|
"module configuration.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Calamares::RequirementsList WelcomeViewStep::checkRequirements()
|
||||||
|
{
|
||||||
|
return m_requirementsChecker->checkRequirements();
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <modulesystem/Requirement.h>
|
||||||
#include <utils/PluginFactory.h>
|
#include <utils/PluginFactory.h>
|
||||||
#include <viewpages/ViewStep.h>
|
#include <viewpages/ViewStep.h>
|
||||||
|
|
||||||
@ -29,7 +30,7 @@
|
|||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
class WelcomePage;
|
class WelcomePage;
|
||||||
class RequirementsChecker;
|
class GeneralRequirements;
|
||||||
|
|
||||||
class PLUGINDLLEXPORT WelcomeViewStep : public Calamares::ViewStep
|
class PLUGINDLLEXPORT WelcomeViewStep : public Calamares::ViewStep
|
||||||
{
|
{
|
||||||
@ -43,23 +44,21 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() override;
|
QWidget* widget() override;
|
||||||
|
|
||||||
void next() override;
|
|
||||||
void back() override;
|
|
||||||
|
|
||||||
bool isNextEnabled() const override;
|
bool isNextEnabled() const override;
|
||||||
bool isBackEnabled() const override;
|
bool isBackEnabled() const override;
|
||||||
|
|
||||||
bool isAtBeginning() const override;
|
bool isAtBeginning() const override;
|
||||||
bool isAtEnd() const override;
|
bool isAtEnd() const override;
|
||||||
|
|
||||||
QList< Calamares::job_ptr > jobs() const override;
|
Calamares::JobList jobs() const override;
|
||||||
|
|
||||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||||
|
|
||||||
|
Calamares::RequirementsList checkRequirements() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WelcomePage* m_widget;
|
WelcomePage* m_widget;
|
||||||
|
GeneralRequirements* m_requirementsChecker;
|
||||||
RequirementsChecker* m_requirementsChecker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeViewStepFactory )
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeViewStepFactory )
|
||||||
|
83
src/modules/welcome/checker/CheckerContainer.cpp
Normal file
83
src/modules/welcome/checker/CheckerContainer.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2017, 2019, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2017, Gabriel Craciunescu <crazy@frugalware.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Based on code extracted from RequirementsChecker.cpp */
|
||||||
|
|
||||||
|
#include "CheckerContainer.h"
|
||||||
|
|
||||||
|
#include "ResultsListWidget.h"
|
||||||
|
|
||||||
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Retranslator.h"
|
||||||
|
#include "widgets/WaitingWidget.h"
|
||||||
|
|
||||||
|
CheckerContainer::CheckerContainer( QWidget* parent )
|
||||||
|
: QWidget( parent )
|
||||||
|
, m_waitingWidget( new WaitingWidget( QString(), this ) )
|
||||||
|
, m_checkerWidget( nullptr )
|
||||||
|
, m_verdict( false )
|
||||||
|
{
|
||||||
|
QBoxLayout* mainLayout = new QHBoxLayout;
|
||||||
|
setLayout( mainLayout );
|
||||||
|
CalamaresUtils::unmarginLayout( mainLayout );
|
||||||
|
|
||||||
|
mainLayout->addWidget( m_waitingWidget );
|
||||||
|
CALAMARES_RETRANSLATE(
|
||||||
|
if ( m_waitingWidget )
|
||||||
|
m_waitingWidget->setText( tr( "Gathering system information..." ) );
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckerContainer::~CheckerContainer()
|
||||||
|
{
|
||||||
|
delete m_waitingWidget;
|
||||||
|
delete m_checkerWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckerContainer::requirementsComplete( bool ok )
|
||||||
|
{
|
||||||
|
|
||||||
|
layout()->removeWidget( m_waitingWidget );
|
||||||
|
m_waitingWidget->deleteLater();
|
||||||
|
m_waitingWidget = nullptr; // Don't delete in destructor
|
||||||
|
|
||||||
|
m_checkerWidget = new ResultsListWidget( this );
|
||||||
|
m_checkerWidget->init( m_requirements );
|
||||||
|
layout()->addWidget( m_checkerWidget );
|
||||||
|
|
||||||
|
m_verdict = ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckerContainer::requirementsChecked(const Calamares::RequirementsList& l)
|
||||||
|
{
|
||||||
|
m_requirements.append( l );
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckerContainer::requirementsProgress(const QString& message)
|
||||||
|
{
|
||||||
|
if ( m_waitingWidget )
|
||||||
|
m_waitingWidget->setText( message );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckerContainer::verdict() const
|
||||||
|
{
|
||||||
|
return m_verdict;
|
||||||
|
}
|
64
src/modules/welcome/checker/CheckerContainer.h
Normal file
64
src/modules/welcome/checker/CheckerContainer.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||||
|
* Copyright 2017, Gabriel Craciunescu <crazy@frugalware.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Based on code extracted from RequirementsChecker.cpp */
|
||||||
|
|
||||||
|
#ifndef CHECKERCONTAINER_H
|
||||||
|
#define CHECKERCONTAINER_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
#include "modulesystem/Requirement.h"
|
||||||
|
|
||||||
|
class ResultsListWidget;
|
||||||
|
class WaitingWidget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A widget that collects requirements results; until the results are
|
||||||
|
* all in, displays a spinner / waiting widget. Then it switches to
|
||||||
|
* a (list) diplay of the results, plus some explanation of the
|
||||||
|
* overall state of the entire list of results.
|
||||||
|
*/
|
||||||
|
class CheckerContainer : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit CheckerContainer( QWidget* parent = nullptr );
|
||||||
|
virtual ~CheckerContainer();
|
||||||
|
|
||||||
|
bool verdict() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void requirementsChecked( const Calamares::RequirementsList& );
|
||||||
|
|
||||||
|
/** @brief All the requirements are complete, switch to list view */
|
||||||
|
void requirementsComplete( bool );
|
||||||
|
|
||||||
|
void requirementsProgress( const QString& message );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
WaitingWidget *m_waitingWidget;
|
||||||
|
ResultsListWidget *m_checkerWidget;
|
||||||
|
|
||||||
|
Calamares::RequirementsList m_requirements;
|
||||||
|
bool m_verdict;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
#endif
|
@ -18,11 +18,12 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "RequirementsChecker.h"
|
#include "GeneralRequirements.h"
|
||||||
|
|
||||||
#include "CheckerWidget.h"
|
#include "CheckerContainer.h"
|
||||||
#include "partman_devices.h"
|
#include "partman_devices.h"
|
||||||
|
|
||||||
|
#include "modulesystem/Requirement.h"
|
||||||
#include "widgets/WaitingWidget.h"
|
#include "widgets/WaitingWidget.h"
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
@ -30,6 +31,7 @@
|
|||||||
#include "utils/CalamaresUtilsSystem.h"
|
#include "utils/CalamaresUtilsSystem.h"
|
||||||
#include "utils/Units.h"
|
#include "utils/Units.h"
|
||||||
|
|
||||||
|
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
#include "GlobalStorage.h"
|
#include "GlobalStorage.h"
|
||||||
|
|
||||||
@ -51,29 +53,17 @@
|
|||||||
|
|
||||||
#include <unistd.h> //geteuid
|
#include <unistd.h> //geteuid
|
||||||
|
|
||||||
RequirementsChecker::RequirementsChecker( QObject* parent )
|
GeneralRequirements::GeneralRequirements( QObject* parent )
|
||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_widget( new QWidget() )
|
|
||||||
, m_requiredStorageGB( -1 )
|
, m_requiredStorageGB( -1 )
|
||||||
, m_requiredRamGB( -1 )
|
, m_requiredRamGB( -1 )
|
||||||
, m_actualWidget( new CheckerWidget() )
|
|
||||||
, m_verdict( false )
|
|
||||||
{
|
{
|
||||||
QBoxLayout* mainLayout = new QHBoxLayout;
|
}
|
||||||
m_widget->setLayout( mainLayout );
|
|
||||||
CalamaresUtils::unmarginLayout( mainLayout );
|
|
||||||
|
|
||||||
WaitingWidget* waitingWidget = new WaitingWidget( QString() );
|
Calamares::RequirementsList GeneralRequirements::checkRequirements()
|
||||||
mainLayout->addWidget( waitingWidget );
|
{
|
||||||
CALAMARES_RETRANSLATE( waitingWidget->setText( tr( "Gathering system information..." ) ); )
|
QSize availableSize = qApp->desktop()->availableGeometry().size();
|
||||||
|
|
||||||
QSize availableSize = qApp->desktop()->availableGeometry( m_widget ).size();
|
|
||||||
|
|
||||||
QTimer* timer = new QTimer;
|
|
||||||
timer->setSingleShot( true );
|
|
||||||
connect( timer, &QTimer::timeout,
|
|
||||||
[=]()
|
|
||||||
{
|
|
||||||
bool enoughStorage = false;
|
bool enoughStorage = false;
|
||||||
bool enoughRam = false;
|
bool enoughRam = false;
|
||||||
bool hasPower = false;
|
bool hasPower = false;
|
||||||
@ -101,15 +91,14 @@ RequirementsChecker::RequirementsChecker( QObject* parent )
|
|||||||
isRoot = checkIsRoot();
|
isRoot = checkIsRoot();
|
||||||
|
|
||||||
using TR = Logger::DebugRow<const char *, bool>;
|
using TR = Logger::DebugRow<const char *, bool>;
|
||||||
|
cDebug() << "GeneralRequirements output:"
|
||||||
cDebug() << "RequirementsChecker output:"
|
|
||||||
<< TR("enoughStorage", enoughStorage)
|
<< TR("enoughStorage", enoughStorage)
|
||||||
<< TR("enoughRam", enoughRam)
|
<< TR("enoughRam", enoughRam)
|
||||||
<< TR("hasPower", hasPower)
|
<< TR("hasPower", hasPower)
|
||||||
<< TR("hasInternet", hasInternet)
|
<< TR("hasInternet", hasInternet)
|
||||||
<< TR("isRoot", isRoot);
|
<< TR("isRoot", isRoot);
|
||||||
|
|
||||||
QList< PrepareEntry > checkEntries;
|
Calamares::RequirementsList checkEntries;
|
||||||
foreach ( const QString& entry, m_entriesToCheck )
|
foreach ( const QString& entry, m_entriesToCheck )
|
||||||
{
|
{
|
||||||
if ( entry == "storage" )
|
if ( entry == "storage" )
|
||||||
@ -165,52 +154,12 @@ RequirementsChecker::RequirementsChecker( QObject* parent )
|
|||||||
false
|
false
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
return checkEntries;
|
||||||
m_actualWidget->init( checkEntries );
|
|
||||||
m_widget->layout()->removeWidget( waitingWidget );
|
|
||||||
waitingWidget->deleteLater();
|
|
||||||
m_actualWidget->setParent( m_widget );
|
|
||||||
m_widget->layout()->addWidget( m_actualWidget );
|
|
||||||
|
|
||||||
bool canGoNext = true;
|
|
||||||
foreach ( const PrepareEntry& entry, checkEntries )
|
|
||||||
{
|
|
||||||
if ( !entry.checked && entry.required )
|
|
||||||
{
|
|
||||||
canGoNext = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_verdict = canGoNext;
|
|
||||||
emit verdictChanged( m_verdict );
|
|
||||||
|
|
||||||
if ( canGoNext )
|
|
||||||
detectFirmwareType();
|
|
||||||
|
|
||||||
timer->deleteLater();
|
|
||||||
} );
|
|
||||||
timer->start( 0 );
|
|
||||||
|
|
||||||
emit verdictChanged( true );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RequirementsChecker::~RequirementsChecker()
|
|
||||||
{
|
|
||||||
if ( m_widget && m_widget->parent() == nullptr )
|
|
||||||
m_widget->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QWidget*
|
|
||||||
RequirementsChecker::widget() const
|
|
||||||
{
|
|
||||||
return m_widget;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
bool incompleteConfiguration = false;
|
bool incompleteConfiguration = false;
|
||||||
|
|
||||||
@ -222,7 +171,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'check' is incomplete.";
|
cWarning() << "GeneralRequirements entry 'check' is incomplete.";
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,14 +183,25 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'required' is incomplete.";
|
cWarning() << "GeneralRequirements entry 'required' is incomplete.";
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WITHOUT_LIBPARTED
|
||||||
|
if ( m_entriesToCheck.contains( "storage" ) || m_entriesToRequire.contains( "storage" ) )
|
||||||
|
{
|
||||||
|
// Warn, but also drop the required bit because otherwise installation
|
||||||
|
// will be impossible (because the check always returns false).
|
||||||
|
cWarning() << "GeneralRequirements checks 'storage' but libparted is disabled.";
|
||||||
|
m_entriesToCheck.removeAll( "storage" );
|
||||||
|
m_entriesToRequire.removeAll( "storage" );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Help out with consistency, but don't fix
|
// Help out with consistency, but don't fix
|
||||||
for ( const auto& r : m_entriesToRequire )
|
for ( const auto& r : m_entriesToRequire )
|
||||||
if ( !m_entriesToCheck.contains( r ) )
|
if ( !m_entriesToCheck.contains( r ) )
|
||||||
cWarning() << "RequirementsChecker requires" << r << "but does not check it.";
|
cWarning() << "GeneralRequirements requires" << r << "but does not check it.";
|
||||||
|
|
||||||
if ( configurationMap.contains( "requiredStorage" ) &&
|
if ( configurationMap.contains( "requiredStorage" ) &&
|
||||||
( configurationMap.value( "requiredStorage" ).type() == QVariant::Double ||
|
( configurationMap.value( "requiredStorage" ).type() == QVariant::Double ||
|
||||||
@ -251,7 +211,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_requiredStorageGB = configurationMap.value( "requiredStorage" ).toDouble( &ok );
|
m_requiredStorageGB = configurationMap.value( "requiredStorage" ).toDouble( &ok );
|
||||||
if ( !ok )
|
if ( !ok )
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'requiredStorage' is invalid.";
|
cWarning() << "GeneralRequirements entry 'requiredStorage' is invalid.";
|
||||||
m_requiredStorageGB = 3.;
|
m_requiredStorageGB = 3.;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +219,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'requiredStorage' is missing.";
|
cWarning() << "GeneralRequirements entry 'requiredStorage' is missing.";
|
||||||
m_requiredStorageGB = 3.;
|
m_requiredStorageGB = 3.;
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
@ -272,14 +232,14 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok );
|
m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok );
|
||||||
if ( !ok )
|
if ( !ok )
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'requiredRam' is invalid.";
|
cWarning() << "GeneralRequirements entry 'requiredRam' is invalid.";
|
||||||
m_requiredRamGB = 1.;
|
m_requiredRamGB = 1.;
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'requiredRam' is missing.";
|
cWarning() << "GeneralRequirements entry 'requiredRam' is missing.";
|
||||||
m_requiredRamGB = 1.;
|
m_requiredRamGB = 1.;
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
@ -291,7 +251,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
if ( m_checkHasInternetUrl.isEmpty() ||
|
if ( m_checkHasInternetUrl.isEmpty() ||
|
||||||
!QUrl( m_checkHasInternetUrl ).isValid() )
|
!QUrl( m_checkHasInternetUrl ).isValid() )
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl
|
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl
|
||||||
<< "reverting to default (http://example.com).";
|
<< "reverting to default (http://example.com).";
|
||||||
m_checkHasInternetUrl = "http://example.com";
|
m_checkHasInternetUrl = "http://example.com";
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
@ -299,7 +259,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker entry 'internetCheckUrl' is undefined in welcome.conf,"
|
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is undefined in welcome.conf,"
|
||||||
"reverting to default (http://example.com).";
|
"reverting to default (http://example.com).";
|
||||||
|
|
||||||
m_checkHasInternetUrl = "http://example.com";
|
m_checkHasInternetUrl = "http://example.com";
|
||||||
@ -308,24 +268,17 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
|
|
||||||
if ( incompleteConfiguration )
|
if ( incompleteConfiguration )
|
||||||
{
|
{
|
||||||
cWarning() << "RequirementsChecker configuration map:" << Logger::DebugMap( configurationMap );
|
cWarning() << "GeneralRequirements configuration map:" << Logger::DebugMap( configurationMap );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::verdict() const
|
GeneralRequirements::checkEnoughStorage( qint64 requiredSpace )
|
||||||
{
|
|
||||||
return m_verdict;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
RequirementsChecker::checkEnoughStorage( qint64 requiredSpace )
|
|
||||||
{
|
{
|
||||||
#ifdef WITHOUT_LIBPARTED
|
#ifdef WITHOUT_LIBPARTED
|
||||||
Q_UNUSED( requiredSpace );
|
Q_UNUSED( requiredSpace );
|
||||||
cWarning() << "RequirementsChecker is configured without libparted.";
|
cWarning() << "GeneralRequirements is configured without libparted.";
|
||||||
return false;
|
return false;
|
||||||
#else
|
#else
|
||||||
return check_big_enough( requiredSpace );
|
return check_big_enough( requiredSpace );
|
||||||
@ -334,7 +287,7 @@ RequirementsChecker::checkEnoughStorage( qint64 requiredSpace )
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::checkEnoughRam( qint64 requiredRam )
|
GeneralRequirements::checkEnoughRam( qint64 requiredRam )
|
||||||
{
|
{
|
||||||
// Ignore the guesstimate-factor; we get an under-estimate
|
// Ignore the guesstimate-factor; we get an under-estimate
|
||||||
// which is probably the usable RAM for programs.
|
// which is probably the usable RAM for programs.
|
||||||
@ -344,7 +297,7 @@ RequirementsChecker::checkEnoughRam( qint64 requiredRam )
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::checkBatteryExists()
|
GeneralRequirements::checkBatteryExists()
|
||||||
{
|
{
|
||||||
const QFileInfo basePath( "/sys/class/power_supply" );
|
const QFileInfo basePath( "/sys/class/power_supply" );
|
||||||
|
|
||||||
@ -370,7 +323,7 @@ RequirementsChecker::checkBatteryExists()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::checkHasPower()
|
GeneralRequirements::checkHasPower()
|
||||||
{
|
{
|
||||||
const QString UPOWER_SVC_NAME( "org.freedesktop.UPower" );
|
const QString UPOWER_SVC_NAME( "org.freedesktop.UPower" );
|
||||||
const QString UPOWER_INTF_NAME( "org.freedesktop.UPower" );
|
const QString UPOWER_INTF_NAME( "org.freedesktop.UPower" );
|
||||||
@ -401,10 +354,10 @@ RequirementsChecker::checkHasPower()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::checkHasInternet()
|
GeneralRequirements::checkHasInternet()
|
||||||
{
|
{
|
||||||
// default to true in the QNetworkAccessManager::UnknownAccessibility case
|
// default to true in the QNetworkAccessManager::UnknownAccessibility case
|
||||||
QNetworkAccessManager qnam( this );
|
QNetworkAccessManager qnam;
|
||||||
bool hasInternet = qnam.networkAccessible() == QNetworkAccessManager::Accessible;
|
bool hasInternet = qnam.networkAccessible() == QNetworkAccessManager::Accessible;
|
||||||
|
|
||||||
if ( !hasInternet && qnam.networkAccessible() == QNetworkAccessManager::UnknownAccessibility )
|
if ( !hasInternet && qnam.networkAccessible() == QNetworkAccessManager::UnknownAccessibility )
|
||||||
@ -425,15 +378,7 @@ RequirementsChecker::checkHasInternet()
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
RequirementsChecker::checkIsRoot()
|
GeneralRequirements::checkIsRoot()
|
||||||
{
|
{
|
||||||
return !geteuid();
|
return !geteuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
RequirementsChecker::detectFirmwareType()
|
|
||||||
{
|
|
||||||
QString fwType = QFile::exists( "/sys/firmware/efi/efivars" ) ? "efi" : "bios";
|
|
||||||
Calamares::JobQueue::instance()->globalStorage()->insert( "firmwareType", fwType );
|
|
||||||
}
|
|
@ -17,52 +17,23 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef REQUIREMENTSCHECKER_H
|
#ifndef GENERALREQUIREMENTS_H
|
||||||
#define REQUIREMENTSCHECKER_H
|
#define GENERALREQUIREMENTS_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
|
||||||
#include <functional>
|
#include "modulesystem/Requirement.h"
|
||||||
|
|
||||||
class CheckerWidget;
|
class GeneralRequirements : public QObject
|
||||||
class QWidget;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An indication of a requirement, which is checked in preparation
|
|
||||||
* for system installation. An entry has a name and some explanation,
|
|
||||||
* as well as three meaningful states:
|
|
||||||
* - checked = true, the requirement is met (green)
|
|
||||||
* - checked = false, the requirement is not met
|
|
||||||
* - required = false, warn about it (yellow), no failure
|
|
||||||
* - required = true, prohibit installation (red)
|
|
||||||
*/
|
|
||||||
struct PrepareEntry
|
|
||||||
{
|
|
||||||
QString name;
|
|
||||||
std::function< QString() > enumerationText; //Partial string, inserted in a
|
|
||||||
//list of requirements to satisfy.
|
|
||||||
std::function< QString() > negatedText; //Complete sentence about this requirement
|
|
||||||
//not having been met.
|
|
||||||
bool checked;
|
|
||||||
bool required;
|
|
||||||
};
|
|
||||||
|
|
||||||
class RequirementsChecker : public QObject
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit RequirementsChecker( QObject* parent = nullptr );
|
explicit GeneralRequirements( QObject* parent = nullptr );
|
||||||
virtual ~RequirementsChecker();
|
|
||||||
|
|
||||||
QWidget* widget() const;
|
|
||||||
|
|
||||||
void setConfigurationMap( const QVariantMap& configurationMap );
|
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||||
|
|
||||||
bool verdict() const;
|
Calamares::RequirementsList checkRequirements();
|
||||||
|
|
||||||
signals:
|
|
||||||
void verdictChanged( bool );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QStringList m_entriesToCheck;
|
QStringList m_entriesToCheck;
|
||||||
@ -74,15 +45,10 @@ private:
|
|||||||
bool checkHasPower();
|
bool checkHasPower();
|
||||||
bool checkHasInternet();
|
bool checkHasInternet();
|
||||||
bool checkIsRoot();
|
bool checkIsRoot();
|
||||||
void detectFirmwareType();
|
|
||||||
|
|
||||||
QWidget* m_widget;
|
|
||||||
qreal m_requiredStorageGB;
|
qreal m_requiredStorageGB;
|
||||||
qreal m_requiredRamGB;
|
qreal m_requiredRamGB;
|
||||||
QString m_checkHasInternetUrl;
|
QString m_checkHasInternetUrl;
|
||||||
|
|
||||||
CheckerWidget* m_actualWidget;
|
|
||||||
bool m_verdict;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // REQUIREMENTSCHECKER_H
|
#endif // REQUIREMENTSCHECKER_H
|
@ -1,7 +1,7 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017, 2019, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -17,7 +17,7 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CheckItemWidget.h"
|
#include "ResultWidget.h"
|
||||||
|
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
@ -26,12 +26,13 @@
|
|||||||
|
|
||||||
static inline void setCondition( QLabel* label, CalamaresUtils::ImageType t )
|
static inline void setCondition( QLabel* label, CalamaresUtils::ImageType t )
|
||||||
{
|
{
|
||||||
label->setPixmap( CalamaresUtils::defaultPixmap( t,
|
label->setPixmap(
|
||||||
|
CalamaresUtils::defaultPixmap( t,
|
||||||
CalamaresUtils::Original,
|
CalamaresUtils::Original,
|
||||||
QSize( label->height(), label->height() ) ) );
|
QSize( label->height(), label->height() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckItemWidget::CheckItemWidget( bool checked,
|
ResultWidget::ResultWidget( bool satisfied,
|
||||||
bool required,
|
bool required,
|
||||||
QWidget* parent )
|
QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
@ -46,11 +47,9 @@ CheckItemWidget::CheckItemWidget( bool checked,
|
|||||||
mainLayout->addWidget( m_textLabel );
|
mainLayout->addWidget( m_textLabel );
|
||||||
m_textLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
m_textLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
||||||
|
|
||||||
if ( checked )
|
if ( satisfied )
|
||||||
// Condition is satisfied
|
|
||||||
setCondition( m_iconLabel, CalamaresUtils::StatusOk );
|
setCondition( m_iconLabel, CalamaresUtils::StatusOk );
|
||||||
else
|
else if ( required )
|
||||||
if ( required )
|
|
||||||
setCondition( m_iconLabel, CalamaresUtils::StatusError );
|
setCondition( m_iconLabel, CalamaresUtils::StatusError );
|
||||||
else
|
else
|
||||||
setCondition( m_iconLabel, CalamaresUtils::StatusWarning );
|
setCondition( m_iconLabel, CalamaresUtils::StatusWarning );
|
||||||
@ -58,7 +57,7 @@ CheckItemWidget::CheckItemWidget( bool checked,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CheckItemWidget::setText( const QString& text )
|
ResultWidget::setText( const QString& text )
|
||||||
{
|
{
|
||||||
m_textLabel->setText( text );
|
m_textLabel->setText( text );
|
||||||
}
|
}
|
51
src/modules/welcome/checker/ResultWidget.h
Normal file
51
src/modules/welcome/checker/ResultWidget.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2017, 2019, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CHECKER_RESULTWIDGET_H
|
||||||
|
#define CHECKER_RESULTWIDGET_H
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Displays the results of a single check.
|
||||||
|
*
|
||||||
|
* Widget to insert into a ResultListWidget to display an iconic status
|
||||||
|
* (warning or failure when the check is not satisfied) along with
|
||||||
|
* descriptive test.
|
||||||
|
*/
|
||||||
|
class ResultWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Create widget with results of a check.
|
||||||
|
*
|
||||||
|
* Use setText() to set up the text of the widget.
|
||||||
|
*/
|
||||||
|
explicit ResultWidget( bool satisfied, bool required,
|
||||||
|
QWidget* parent = nullptr );
|
||||||
|
|
||||||
|
/// @brief Set the displayed description of the check.
|
||||||
|
void setText( const QString& text );
|
||||||
|
private:
|
||||||
|
QLabel* m_textLabel;
|
||||||
|
QLabel* m_iconLabel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CHECKER_RESULTWIDGET_H
|
@ -1,7 +1,7 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
* Copyright 2017, 2019, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -17,9 +17,9 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "CheckerWidget.h"
|
#include "ResultsListWidget.h"
|
||||||
|
|
||||||
#include "CheckItemWidget.h"
|
#include "ResultWidget.h"
|
||||||
|
|
||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
@ -33,7 +33,7 @@
|
|||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
|
|
||||||
CheckerWidget::CheckerWidget( QWidget* parent )
|
ResultsListWidget::ResultsListWidget( QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
{
|
{
|
||||||
setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||||
@ -53,25 +53,23 @@ CheckerWidget::CheckerWidget( QWidget* parent )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CheckerWidget::init( const QList< PrepareEntry >& checkEntries )
|
ResultsListWidget::init( const Calamares::RequirementsList& checkEntries )
|
||||||
{
|
{
|
||||||
bool allChecked = true;
|
bool allChecked = true;
|
||||||
bool requirementsSatisfied = true;
|
bool requirementsSatisfied = true;
|
||||||
|
|
||||||
for ( const PrepareEntry& entry : checkEntries )
|
for ( const auto& entry : checkEntries )
|
||||||
{
|
{
|
||||||
if ( !entry.checked )
|
if ( !entry.satisfied )
|
||||||
{
|
{
|
||||||
CheckItemWidget* ciw = new CheckItemWidget( entry.checked, entry.required );
|
ResultWidget* ciw = new ResultWidget( entry.satisfied, entry.mandatory );
|
||||||
CALAMARES_RETRANSLATE( ciw->setText( entry.negatedText() ); )
|
CALAMARES_RETRANSLATE( ciw->setText( entry.negatedText() ); )
|
||||||
m_entriesLayout->addWidget( ciw );
|
m_entriesLayout->addWidget( ciw );
|
||||||
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
||||||
|
|
||||||
allChecked = false;
|
allChecked = false;
|
||||||
if ( entry.required )
|
if ( entry.mandatory )
|
||||||
{
|
|
||||||
requirementsSatisfied = false;
|
requirementsSatisfied = false;
|
||||||
}
|
|
||||||
ciw->setAutoFillBackground( true );
|
ciw->setAutoFillBackground( true );
|
||||||
QPalette pal( ciw->palette() );
|
QPalette pal( ciw->palette() );
|
||||||
pal.setColor( QPalette::Background, Qt::white );
|
pal.setColor( QPalette::Background, Qt::white );
|
||||||
@ -131,7 +129,7 @@ CheckerWidget::init( const QList< PrepareEntry >& checkEntries )
|
|||||||
QLabel* imageLabel;
|
QLabel* imageLabel;
|
||||||
if ( Calamares::Branding::instance()->welcomeExpandingLogo() )
|
if ( Calamares::Branding::instance()->welcomeExpandingLogo() )
|
||||||
{
|
{
|
||||||
FixedAspectRatioLabel *p = new FixedAspectRatioLabel;
|
FixedAspectRatioLabel* p = new FixedAspectRatioLabel;
|
||||||
p->setPixmap( theImage );
|
p->setPixmap( theImage );
|
||||||
imageLabel = p;
|
imageLabel = p;
|
||||||
}
|
}
|
||||||
@ -155,14 +153,12 @@ CheckerWidget::init( const QList< PrepareEntry >& checkEntries )
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
m_mainLayout->addStretch();
|
m_mainLayout->addStretch();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
CheckerWidget::showDetailsDialog( const QList< PrepareEntry >& checkEntries )
|
ResultsListWidget::showDetailsDialog( const Calamares::RequirementsList& checkEntries )
|
||||||
{
|
{
|
||||||
QDialog* detailsDialog = new QDialog( this );
|
QDialog* detailsDialog = new QDialog( this );
|
||||||
QBoxLayout* mainLayout = new QVBoxLayout;
|
QBoxLayout* mainLayout = new QVBoxLayout;
|
||||||
@ -177,12 +173,12 @@ CheckerWidget::showDetailsDialog( const QList< PrepareEntry >& checkEntries )
|
|||||||
CalamaresUtils::unmarginLayout( entriesLayout );
|
CalamaresUtils::unmarginLayout( entriesLayout );
|
||||||
mainLayout->addLayout( entriesLayout );
|
mainLayout->addLayout( entriesLayout );
|
||||||
|
|
||||||
for ( const PrepareEntry& entry : checkEntries )
|
for ( const auto& entry : checkEntries )
|
||||||
{
|
{
|
||||||
if ( entry.enumerationText().isEmpty() )
|
if ( !entry.hasDetails() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CheckItemWidget* ciw = new CheckItemWidget( entry.checked, entry.required );
|
ResultWidget* ciw = new ResultWidget( entry.satisfied, entry.mandatory );
|
||||||
CALAMARES_RETRANSLATE( ciw->setText( entry.enumerationText() ); )
|
CALAMARES_RETRANSLATE( ciw->setText( entry.enumerationText() ); )
|
||||||
entriesLayout->addWidget( ciw );
|
entriesLayout->addWidget( ciw );
|
||||||
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
@ -1,6 +1,7 @@
|
|||||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
*
|
*
|
||||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||||
*
|
*
|
||||||
* Calamares is free software: you can redistribute it and/or modify
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -16,28 +17,28 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef CHECKERWIDGET_H
|
#ifndef CHECKER_RESULTSLISTWIDGET_H
|
||||||
#define CHECKERWIDGET_H
|
#define CHECKER_RESULTSLISTWIDGET_H
|
||||||
|
|
||||||
#include "RequirementsChecker.h"
|
#include "modulesystem/Requirement.h"
|
||||||
|
|
||||||
#include <QBoxLayout>
|
#include <QBoxLayout>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
class CheckerWidget : public QWidget
|
class ResultsListWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit CheckerWidget( QWidget* parent = nullptr );
|
explicit ResultsListWidget( QWidget* parent = nullptr );
|
||||||
|
|
||||||
void init( const QList< PrepareEntry >& checkEntries );
|
void init( const Calamares::RequirementsList& checkEntries );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void showDetailsDialog( const QList< PrepareEntry >& checkEntries );
|
void showDetailsDialog( const Calamares::RequirementsList& checkEntries );
|
||||||
|
|
||||||
QBoxLayout* m_mainLayout;
|
QBoxLayout* m_mainLayout;
|
||||||
QBoxLayout* m_entriesLayout;
|
QBoxLayout* m_entriesLayout;
|
||||||
int m_paddingSize;
|
int m_paddingSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHECKERWIDGET_H
|
#endif // CHECKER_RESULTSLISTWIDGET_H
|
@ -1,18 +1,37 @@
|
|||||||
|
# Configuration for the welcome module. The welcome page
|
||||||
|
# displays some information from the branding file.
|
||||||
|
# Which parts it displays can be configured through
|
||||||
|
# the show* variables.
|
||||||
|
#
|
||||||
|
# In addition to displaying the welcome page, this module
|
||||||
|
# can check requirements for installation.
|
||||||
---
|
---
|
||||||
|
# Display settings for various buttons on the welcome page.
|
||||||
showSupportUrl: true
|
showSupportUrl: true
|
||||||
showKnownIssuesUrl: true
|
showKnownIssuesUrl: true
|
||||||
showReleaseNotesUrl: true
|
showReleaseNotesUrl: true
|
||||||
|
|
||||||
|
# Requirements checking. These are general, generic, things
|
||||||
|
# that are checked. They may not match with the actual requirements
|
||||||
|
# imposed by other modules in the system.
|
||||||
requirements:
|
requirements:
|
||||||
|
# Amount of available disk, in GB. Floating-point is allowed here.
|
||||||
|
# Note that this does not account for *usable* disk, so it is possible
|
||||||
|
# to pass this requirement, yet have no space to install to.
|
||||||
requiredStorage: 5.5
|
requiredStorage: 5.5
|
||||||
|
|
||||||
|
# Amount of available RAM, in GB. Floating-point is allowed here.
|
||||||
requiredRam: 1.0
|
requiredRam: 1.0
|
||||||
|
|
||||||
|
# To check for internet connectivity, Calamares does a HTTP GET
|
||||||
|
# on this URL; on success (e.g. HTTP code 200) internet is OK.
|
||||||
internetCheckUrl: http://google.com
|
internetCheckUrl: http://google.com
|
||||||
|
|
||||||
# List conditions to check. Each listed condition will be
|
# List conditions to check. Each listed condition will be
|
||||||
# probed in some way, and yields true or false according to
|
# probed in some way, and yields true or false according to
|
||||||
# the host system satisfying the condition.
|
# the host system satisfying the condition.
|
||||||
#
|
#
|
||||||
# This sample file lists all the conditions that are know.
|
# This sample file lists all the conditions that are known.
|
||||||
check:
|
check:
|
||||||
- storage
|
- storage
|
||||||
- ram
|
- ram
|
||||||
@ -20,7 +39,7 @@ requirements:
|
|||||||
- internet
|
- internet
|
||||||
- root
|
- root
|
||||||
- screen
|
- screen
|
||||||
# List conditions that must be satisfied (from the list
|
# List conditions that **must** be satisfied (from the list
|
||||||
# of conditions, above) for installation to proceed.
|
# of conditions, above) for installation to proceed.
|
||||||
# If any of these conditions are not met, the user cannot
|
# If any of these conditions are not met, the user cannot
|
||||||
# continue past the welcome page.
|
# continue past the welcome page.
|
||||||
|
Loading…
Reference in New Issue
Block a user