Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
91454a71d0 | ||
![]() |
6658708576 | ||
![]() |
c4e0456acc | ||
![]() |
9925d6666f | ||
![]() |
2555b5baf4 | ||
![]() |
f57ee158b7 | ||
![]() |
028e9e68f9 | ||
![]() |
0f2bceb72f | ||
![]() |
5eac7a021c | ||
![]() |
ab3612d18d | ||
![]() |
2fce6a3c44 | ||
![]() |
01cbe07641 | ||
![]() |
2697c35fc7 | ||
![]() |
4329b824d4 | ||
![]() |
0ced01ddc3 | ||
![]() |
d5555eba32 | ||
![]() |
6770f781e3 | ||
![]() |
ae3e609024 | ||
![]() |
4aa2c4988c | ||
![]() |
0d9d2ac59a | ||
![]() |
15c514326c | ||
![]() |
b795fd82bb | ||
![]() |
dc91255ff5 | ||
![]() |
7379e7f28d | ||
![]() |
633d6bda0d | ||
![]() |
dbddeaba68 | ||
![]() |
809d6cdda0 | ||
![]() |
b37cf66acb | ||
![]() |
be5ce2e60f | ||
![]() |
34888edae1 | ||
![]() |
7a3bff5117 | ||
![]() |
b7e34abeaa | ||
![]() |
8a5876410e |
36
.github/workflows/nightly-fedora-qt6-boost.yml
vendored
Normal file
36
.github/workflows/nightly-fedora-qt6-boost.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: nightly-fedora-qt6
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "52 2 * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BUILDDIR: /build
|
||||
SRCDIR: ${{ github.workspace }}
|
||||
CMAKE_ARGS: |
|
||||
-DKDE_INSTALL_USE_QT_SYS_PATHS=ON
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
-DWITH_QT6=ON
|
||||
-DBUILD_APPSTREAM=ON
|
||||
-DBUILD_APPDATA=ON
|
||||
-DWITH_PYBIND11=OFF
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: docker://registry.fedoraproject.org/fedora:40
|
||||
options: --tmpfs /build:rw --user 0:0
|
||||
steps:
|
||||
- name: "prepare git"
|
||||
shell: bash
|
||||
run: yum install -y git-core jq curl
|
||||
- name: "prepare source"
|
||||
uses: calamares/actions/generic-checkout@v5
|
||||
- name: "install dependencies"
|
||||
shell: bash
|
||||
run: ./ci/deps-fedora-qt6-boost.sh
|
||||
- name: "build"
|
||||
shell: bash
|
||||
run: ./ci/build.sh
|
31
CHANGES-3.3
31
CHANGES-3.3
@@ -7,6 +7,37 @@ contributors are listed. Note that Calamares does not have a historical
|
||||
changelog -- this log starts with version 3.3.0. See CHANGES-3.2 for
|
||||
the history of the 3.2 series (2018-05 - 2022-08).
|
||||
|
||||
# 3.3.4 (2024-02-27)
|
||||
|
||||
In this release, process jobmodules -- a particular kind of module
|
||||
recognizable by `type: job` and `interface: process` in the descriptor
|
||||
file -- undergo a large change to resemble *shellprocess* more.
|
||||
|
||||
Users of process jobmodules are encouraged to double-check the Functionality
|
||||
of those modules in this release.
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Adriaan de Groot
|
||||
- Victor Fuentes
|
||||
|
||||
## Core ##
|
||||
- Process jobs (a job type provided by Calamares core) now share more
|
||||
code with *contextualprocess* and *shellprocess* jobs. The execution
|
||||
mechanism is the same, and always invokes the shell, whether the command
|
||||
runs in the host or in the target system. It is no longer necessary to
|
||||
add `/bin/sh` in the *command* key -- this is always present.
|
||||
|
||||
## Modules ##
|
||||
- *contextualprocess* and *shellprocess* can now set environment variables
|
||||
as part of the configuration. See *shellprocess* documentation for details.
|
||||
This is optional, and does not do anything that could not already be done
|
||||
by putting `export VAR=value ;` in front of the command before.
|
||||
- *partition* fixed a bug with an uninitialized variable. (thanks Victor)
|
||||
- *shellprocess* (and therefore also *contextualprocess* and process
|
||||
jobmodules) now substitutes `${LANG}` in commands with the language
|
||||
selected in the user-interface of Calamares.
|
||||
|
||||
|
||||
# 3.3.3 (2024-02-24)
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
|
@@ -47,7 +47,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
set(CALAMARES_VERSION 3.3.3)
|
||||
set(CALAMARES_VERSION 3.3.4)
|
||||
set(CALAMARES_RELEASE_MODE ON) # Set to ON during a release
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
@@ -455,9 +455,11 @@ if(NOT Python_Development_FOUND)
|
||||
message(STATUS "Disabling Python modules")
|
||||
set(WITH_PYTHON OFF)
|
||||
set(WITH_PYBIND11 OFF)
|
||||
set(WITH_BOOST_PYTHON OFF)
|
||||
endif()
|
||||
|
||||
if(WITH_PYTHON AND NOT WITH_PYBIND11)
|
||||
set(WITH_BOOST_PYTHON ON)
|
||||
find_package(boost_python)
|
||||
if(NOT TARGET Boost::python)
|
||||
find_package(Boost ${BOOSTPYTHON_VERSION} COMPONENTS python)
|
||||
@@ -470,12 +472,16 @@ if(WITH_PYTHON AND NOT WITH_PYBIND11)
|
||||
set(Boost_FOUND ON)
|
||||
endif()
|
||||
endif()
|
||||
add_feature_info(python WITH_PYTHON "Enable Python-modules")
|
||||
add_feature_info(python-pybind11 WITH_PYBIND11 "Python-modules through pybind11")
|
||||
add_feature_info(python-boost WITH_BOOST_PYTHON "Python-modules through Boost::Python")
|
||||
|
||||
# Now we know the state of the ABI-options, copy them into "Calamares_"
|
||||
# prefixed variables, to match how the variables would-be-named
|
||||
# when building out-of-tree.
|
||||
set(Calamares_WITH_PYBIND11 ${WITH_PYBIND11})
|
||||
set(Calamares_WITH_PYTHON ${WITH_PYTHON})
|
||||
set(Calamares_WITH_PYBIND11 ${WITH_PYBIND11})
|
||||
set(Calamares_WITH_BOOST_PYTHON ${WITH_BOOST_PYTHON})
|
||||
set(Calamares_WITH_QML ${WITH_QML})
|
||||
set(Calamares_WITH_QT6 ${WITH_QT6})
|
||||
|
||||
@@ -715,6 +721,7 @@ endif()
|
||||
get_directory_property(SKIPPED_MODULES DIRECTORY src/modules DEFINITION LIST_SKIPPED_MODULES)
|
||||
calamares_explain_skipped_modules( ${SKIPPED_MODULES} )
|
||||
|
||||
feature_summary(WHAT ENABLED_FEATURES DESCRIPTION "The following features are enabled" QUIET_ON_EMPTY)
|
||||
feature_summary(WHAT DISABLED_FEATURES DESCRIPTION "The following features have been disabled:" QUIET_ON_EMPTY)
|
||||
feature_summary(
|
||||
WHAT OPTIONAL_PACKAGES_NOT_FOUND
|
||||
|
@@ -94,4 +94,7 @@ include(CalamaresAddPlugin)
|
||||
# This list should match the one in libcalamares/CalamaresConfig.h,
|
||||
# which is the C++-language side of the same configuration.
|
||||
set(Calamares_WITH_PYTHON @WITH_PYTHON@)
|
||||
set(Calamares_WITH_PYBIND11 @WITH_PYBIND11@)
|
||||
set(Calamares_WITH_BOOST_PYTHON @WITH_BOOST_PYTHON@)
|
||||
set(Calamares_WITH_QML @WITH_QML@)
|
||||
set(Calamares_WITH_QT6 @WITH_QT6@)
|
||||
|
18
ci/deps-fedora-qt6-boost.sh
Executable file
18
ci/deps-fedora-qt6-boost.sh
Executable file
@@ -0,0 +1,18 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Install dependencies for the nightly-fedora-qt6-boost build
|
||||
#
|
||||
|
||||
yum install -y bison flex git make cmake gcc-c++ ninja-build
|
||||
yum install -y yaml-cpp-devel libpwquality-devel parted-devel python-devel gettext gettext-devel
|
||||
yum install -y libicu-devel libatasmart-devel
|
||||
yum install -y boost-devel
|
||||
# Qt6/KF6 dependencies
|
||||
yum install -y qt6-qtbase-devel qt6-linguist qt6-qtbase-private-devel qt6-qtdeclarative-devel qt6-qtsvg-devel qt6-qttools-devel
|
||||
yum install -y extra-cmake-modules kf6-kcoreaddons-devel kf6-kdbusaddons-devel kf6-kcrash-devel
|
||||
yum install -y kf6-kconfig-devel kf6-ki18n-devel kf6-kwidgetsaddons-devel kf6-kservice-devel
|
||||
yum install -y polkit-qt6-1-devel appstream-qt-devel
|
||||
# Runtime dependencies for QML modules
|
||||
yum install -y kf6-kirigami2-devel || true
|
||||
yum install -y qt6-qt5compat-devel || true
|
||||
true
|
@@ -64,9 +64,4 @@ if(BUILD_TESTING)
|
||||
|
||||
add_executable(test_conf test_conf.cpp)
|
||||
target_link_libraries(test_conf PUBLIC yamlcpp::yamlcpp ${qtname}::Core)
|
||||
|
||||
if(WITH_PYBIND11)
|
||||
target_compile_definitions(loadmodule PRIVATE WITH_PYBIND11=1)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
@@ -537,7 +537,11 @@ CalamaresWindow::closeEvent( QCloseEvent* event )
|
||||
if ( ( !m_viewManager ) || m_viewManager->confirmCancelInstallation() )
|
||||
{
|
||||
event->accept();
|
||||
qApp->quit();
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QApplication::quit();
|
||||
#else
|
||||
QApplication::exit( EXIT_SUCCESS );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -33,14 +33,16 @@
|
||||
#include <QTreeView>
|
||||
#include <QWidget>
|
||||
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/**
|
||||
* @brief crash makes Calamares crash immediately.
|
||||
*/
|
||||
static void
|
||||
crash()
|
||||
{
|
||||
volatile int* a = nullptr;
|
||||
*a = 1;
|
||||
kill(getpid(), SIGTRAP);
|
||||
}
|
||||
|
||||
/// @brief Print out the widget tree (names) in indented form.
|
||||
|
@@ -34,7 +34,7 @@
|
||||
// - Python support with older Boost implementation
|
||||
// - QML support
|
||||
#ifdef WITH_PYTHON
|
||||
#if WITH_PYBIND11
|
||||
#ifdef WITH_PYBIND11
|
||||
#include "python/PythonJob.h"
|
||||
#else
|
||||
#include "PythonJob.h"
|
||||
@@ -486,7 +486,7 @@ main( int argc, char* argv[] )
|
||||
#ifdef WITH_PYTHON
|
||||
if ( module.m_pythonInjection )
|
||||
{
|
||||
#if WITH_PYBIND11
|
||||
#ifdef WITH_PYBIND11
|
||||
Calamares::Python::Job::setInjectedPreScript( pythonPreScript );
|
||||
#else
|
||||
// Old Boost approach
|
||||
|
@@ -25,6 +25,9 @@
|
||||
* which is the CMake-time side of the same configuration.
|
||||
*/
|
||||
#cmakedefine WITH_PYTHON
|
||||
#cmakedefine WITH_PYBIND11
|
||||
#cmakedefine WITH_BOOST_PYTHON
|
||||
#cmakedefine WITH_QML
|
||||
#cmakedefine WITH_QT6
|
||||
|
||||
#endif // CALAMARESCONFIG_H
|
||||
|
@@ -10,8 +10,8 @@
|
||||
|
||||
#include "ProcessJob.h"
|
||||
|
||||
#include "utils/CommandList.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/System.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
@@ -57,23 +57,9 @@ ProcessJob::prettyStatusMessage() const
|
||||
JobResult
|
||||
ProcessJob::exec()
|
||||
{
|
||||
using Calamares::System;
|
||||
|
||||
if ( m_runInChroot )
|
||||
{
|
||||
return Calamares::System::instance()
|
||||
->targetEnvCommand( { m_command }, m_workingPath, QString(), m_timeoutSec )
|
||||
.explainProcess( m_command, m_timeoutSec );
|
||||
}
|
||||
else
|
||||
{
|
||||
return System::runCommand( System::RunLocation::RunInHost,
|
||||
{ "/bin/sh", "-c", m_command },
|
||||
m_workingPath,
|
||||
QString(),
|
||||
m_timeoutSec )
|
||||
.explainProcess( m_command, m_timeoutSec );
|
||||
}
|
||||
Calamares::CommandList l( m_runInChroot, m_timeoutSec );
|
||||
l.push_back( Calamares::CommandLine { m_command } );
|
||||
return l.run();
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#ifndef CALAMARES_PYTHONJOBHELPER_H
|
||||
#define CALAMARES_PYTHONJOBHELPER_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "PythonJob.h"
|
||||
#include "utils/BoostPython.h"
|
||||
|
||||
@@ -24,20 +25,20 @@ class GlobalStorage;
|
||||
namespace CalamaresPython
|
||||
{
|
||||
|
||||
boost::python::object variantToPyObject( const QVariant& variant );
|
||||
QVariant variantFromPyObject( const boost::python::object& pyObject );
|
||||
DLLEXPORT boost::python::object variantToPyObject( const QVariant& variant );
|
||||
DLLEXPORT QVariant variantFromPyObject( const boost::python::object& pyObject );
|
||||
|
||||
boost::python::list variantListToPyList( const QVariantList& variantList );
|
||||
QVariantList variantListFromPyList( const boost::python::list& pyList );
|
||||
DLLEXPORT boost::python::list variantListToPyList( const QVariantList& variantList );
|
||||
DLLEXPORT QVariantList variantListFromPyList( const boost::python::list& pyList );
|
||||
|
||||
boost::python::dict variantMapToPyDict( const QVariantMap& variantMap );
|
||||
QVariantMap variantMapFromPyDict( const boost::python::dict& pyDict );
|
||||
DLLEXPORT boost::python::dict variantMapToPyDict( const QVariantMap& variantMap );
|
||||
DLLEXPORT QVariantMap variantMapFromPyDict( const boost::python::dict& pyDict );
|
||||
|
||||
boost::python::dict variantHashToPyDict( const QVariantHash& variantHash );
|
||||
QVariantHash variantHashFromPyDict( const boost::python::dict& pyDict );
|
||||
DLLEXPORT boost::python::dict variantHashToPyDict( const QVariantHash& variantHash );
|
||||
DLLEXPORT QVariantHash variantHashFromPyDict( const boost::python::dict& pyDict );
|
||||
|
||||
|
||||
class Helper : public QObject
|
||||
class DLLEXPORT Helper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@@ -19,6 +19,11 @@
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#ifdef WITH_PYBIND11
|
||||
#error Source only for Boost::Python
|
||||
#else
|
||||
#endif
|
||||
|
||||
static const char* s_preScript = nullptr;
|
||||
|
||||
namespace bp = boost::python;
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#ifndef CALAMARES_PYTHONJOB_H
|
||||
#define CALAMARES_PYTHONJOB_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "Job.h"
|
||||
#include "modulesystem/InstanceKey.h"
|
||||
|
||||
@@ -18,6 +19,11 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef WITH_PYBIND11
|
||||
#error Source only for Boost::Python
|
||||
#else
|
||||
#endif
|
||||
|
||||
namespace CalamaresPython
|
||||
{
|
||||
class PythonJobInterface;
|
||||
@@ -27,7 +33,7 @@ class Helper;
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class PythonJob : public Job
|
||||
class DLLEXPORT PythonJob : public Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
@@ -20,6 +20,11 @@
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
|
||||
#ifdef WITH_PYBIND11
|
||||
#else
|
||||
#error Source only for pybind11
|
||||
#endif
|
||||
|
||||
namespace py = pybind11;
|
||||
|
||||
// Forward-declare function generated by PYBIND11_MODULE
|
||||
|
@@ -11,7 +11,9 @@
|
||||
#define CALAMARES_PYTHON_PYTHONJOB_H
|
||||
|
||||
// This file is called PythonJob.h because it would otherwise
|
||||
// clashwith the Job.h in libcalamares proper.
|
||||
// clash with the Job.h in libcalamares proper.
|
||||
|
||||
#include "CalamaresConfig.h"
|
||||
#include "DllMacro.h"
|
||||
#include "Job.h"
|
||||
|
||||
@@ -19,6 +21,11 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#ifdef WITH_PYBIND11
|
||||
#else
|
||||
#error Source only for pybind11
|
||||
#endif
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Python
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include "compat/Variant.h"
|
||||
#include "locale/Global.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/StringExpander.h"
|
||||
#include "utils/System.h"
|
||||
@@ -25,20 +26,6 @@
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
static CommandLine
|
||||
get_variant_object( const QVariantMap& m )
|
||||
{
|
||||
QString command = Calamares::getString( m, "command" );
|
||||
qint64 timeout = Calamares::getInteger( m, "timeout", -1 );
|
||||
|
||||
if ( !command.isEmpty() )
|
||||
{
|
||||
return CommandLine( command, timeout >= 0 ? std::chrono::seconds( timeout ) : CommandLine::TimeoutNotSet() );
|
||||
}
|
||||
cWarning() << "Bad CommandLine element" << m;
|
||||
return CommandLine();
|
||||
}
|
||||
|
||||
static CommandList_t
|
||||
get_variant_stringlist( const QVariantList& l )
|
||||
{
|
||||
@@ -52,7 +39,7 @@ get_variant_stringlist( const QVariantList& l )
|
||||
}
|
||||
else if ( Calamares::typeOf( v ) == Calamares::MapVariantType )
|
||||
{
|
||||
auto command( get_variant_object( v.toMap() ) );
|
||||
CommandLine command( v.toMap() );
|
||||
if ( command.isValid() )
|
||||
{
|
||||
retl.append( command );
|
||||
@@ -91,15 +78,48 @@ get_gs_expander( System::RunLocation location )
|
||||
expander.insert( QStringLiteral( "USER" ), gs->value( "username" ).toString() );
|
||||
}
|
||||
|
||||
if ( gs )
|
||||
{
|
||||
const auto key = QStringLiteral( "LANG" );
|
||||
const QString lang = Calamares::Locale::readGS( *gs, key );
|
||||
if ( !lang.isEmpty() )
|
||||
{
|
||||
expander.insert( key, lang );
|
||||
}
|
||||
}
|
||||
|
||||
return expander;
|
||||
}
|
||||
|
||||
CommandLine::CommandLine( const QVariantMap& m )
|
||||
{
|
||||
const QString command = Calamares::getString( m, "command" );
|
||||
const qint64 timeout = Calamares::getInteger( m, "timeout", -1 );
|
||||
if ( !command.isEmpty() )
|
||||
{
|
||||
m_command = command;
|
||||
m_timeout = timeout >= 0 ? std::chrono::seconds( timeout ) : CommandLine::TimeoutNotSet();
|
||||
m_environment = Calamares::getStringList( m, "environment" );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Bad CommandLine element" << m;
|
||||
// this CommandLine is invalid
|
||||
}
|
||||
}
|
||||
|
||||
CommandLine
|
||||
CommandLine::expand( KMacroExpanderBase& expander ) const
|
||||
{
|
||||
QString c = first;
|
||||
// Calamares variable expansion in the command
|
||||
QString c = m_command;
|
||||
expander.expandMacrosShellQuote( c );
|
||||
return { c, second };
|
||||
|
||||
// .. and expand in each environment key=value string.
|
||||
QStringList e = m_environment;
|
||||
std::for_each( e.begin(), e.end(), [ &expander ]( QString& s ) { expander.expandMacrosShellQuote( s ); } );
|
||||
|
||||
return { c, m_environment, m_timeout };
|
||||
}
|
||||
|
||||
Calamares::CommandLine
|
||||
@@ -136,7 +156,7 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, std::ch
|
||||
}
|
||||
else if ( Calamares::typeOf( v ) == Calamares::MapVariantType )
|
||||
{
|
||||
auto c( get_variant_object( v.toMap() ) );
|
||||
CommandLine c( v.toMap() );
|
||||
if ( c.isValid() )
|
||||
{
|
||||
append( c );
|
||||
@@ -178,8 +198,18 @@ CommandList::run()
|
||||
processed_cmd.remove( 0, 1 ); // Drop the -
|
||||
}
|
||||
|
||||
const QString environmentSetting = []( const QStringList& l ) -> QString
|
||||
{
|
||||
if ( l.isEmpty() )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return QStringLiteral( "export " ) + l.join( " " ) + QStringLiteral( " ; " );
|
||||
}( i->environment() );
|
||||
|
||||
QStringList shell_cmd { "/bin/sh", "-c" };
|
||||
shell_cmd << processed_cmd;
|
||||
shell_cmd << ( environmentSetting + processed_cmd );
|
||||
|
||||
std::chrono::seconds timeout = i->timeout() >= std::chrono::seconds::zero() ? i->timeout() : m_timeout;
|
||||
ProcessResult r = System::runCommand( location, shell_cmd, QString(), QString(), timeout );
|
||||
|
@@ -28,30 +28,43 @@ namespace Calamares
|
||||
* Each command can have an associated timeout in seconds. The timeout
|
||||
* defaults to 10 seconds. Provide some convenience naming and construction.
|
||||
*/
|
||||
struct CommandLine
|
||||
class CommandLine
|
||||
{
|
||||
public:
|
||||
static inline constexpr std::chrono::seconds TimeoutNotSet() { return std::chrono::seconds( -1 ); }
|
||||
|
||||
/// An invalid command line
|
||||
CommandLine() = default;
|
||||
|
||||
CommandLine( const QString& s )
|
||||
: first( s )
|
||||
, second( TimeoutNotSet() )
|
||||
: m_command( s )
|
||||
{
|
||||
}
|
||||
|
||||
CommandLine( const QString& s, std::chrono::seconds t )
|
||||
: first( s )
|
||||
, second( t )
|
||||
: m_command( s )
|
||||
, m_timeout( t )
|
||||
{
|
||||
}
|
||||
|
||||
QString command() const { return first; }
|
||||
CommandLine( const QString& s, const QStringList& env, std::chrono::seconds t )
|
||||
: m_command( s )
|
||||
, m_environment( env )
|
||||
, m_timeout( t )
|
||||
{
|
||||
}
|
||||
|
||||
std::chrono::seconds timeout() const { return second; }
|
||||
/** @brief Constructs a CommandLine from a map with keys
|
||||
*
|
||||
* Relevant keys are *command*, *environment* and *timeout*.
|
||||
*/
|
||||
CommandLine( const QVariantMap& m );
|
||||
|
||||
bool isValid() const { return !first.isEmpty(); }
|
||||
QString command() const { return m_command; }
|
||||
[[nodiscard]] QStringList environment() const { return m_environment; }
|
||||
std::chrono::seconds timeout() const { return m_timeout; }
|
||||
|
||||
bool isValid() const { return !m_command.isEmpty(); }
|
||||
|
||||
/** @brief Returns a copy of this one command, with variables expanded
|
||||
*
|
||||
@@ -60,6 +73,7 @@ struct CommandLine
|
||||
* instance, which handles the ROOT and USER variables.
|
||||
*/
|
||||
DLLEXPORT CommandLine expand( KMacroExpanderBase& expander ) const;
|
||||
|
||||
/** @brief As above, with a default macro-expander.
|
||||
*
|
||||
* The default macro-expander assumes RunInHost (e.g. ROOT will
|
||||
@@ -68,8 +82,9 @@ struct CommandLine
|
||||
DLLEXPORT CommandLine expand() const;
|
||||
|
||||
private:
|
||||
QString first;
|
||||
std::chrono::seconds second = std::chrono::seconds( -1 );
|
||||
QString m_command;
|
||||
QStringList m_environment;
|
||||
std::chrono::seconds m_timeout = TimeoutNotSet();
|
||||
};
|
||||
|
||||
/** @brief Abbreviation, used internally. */
|
||||
@@ -91,6 +106,7 @@ public:
|
||||
CommandList( const QVariant& v, bool doChroot = true, std::chrono::seconds timeout = std::chrono::seconds( 10 ) );
|
||||
|
||||
bool doChroot() const { return m_doChroot; }
|
||||
std::chrono::seconds defaultTimeout() const { return m_timeout; }
|
||||
|
||||
Calamares::JobResult run();
|
||||
|
||||
@@ -109,6 +125,7 @@ public:
|
||||
* @see CommandLine::expand() for details.
|
||||
*/
|
||||
CommandList expand( KMacroExpanderBase& expander ) const;
|
||||
|
||||
/** @brief As above, with a default macro-expander.
|
||||
*
|
||||
* Each command-line in the list is expanded with that default macro-expander.
|
||||
|
@@ -12,6 +12,7 @@
|
||||
#include "CommandList.h"
|
||||
#include "Entropy.h"
|
||||
#include "Logger.h"
|
||||
#include "Permissions.h"
|
||||
#include "RAII.h"
|
||||
#include "Runner.h"
|
||||
#include "String.h"
|
||||
@@ -52,6 +53,9 @@ private Q_SLOTS:
|
||||
void testCommands();
|
||||
void testCommandExpansion_data();
|
||||
void testCommandExpansion(); // See also shellprocess tests
|
||||
void testCommandConstructors();
|
||||
void testCommandConstructorsYAML();
|
||||
void testCommandRunning();
|
||||
|
||||
/** @section Test that all the UMask objects work correctly. */
|
||||
void testUmask();
|
||||
@@ -300,6 +304,136 @@ LibCalamaresTests::testCommandExpansion()
|
||||
QCOMPARE( e.command(), expected );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testCommandConstructors()
|
||||
{
|
||||
const QString command( "do this" );
|
||||
Calamares::CommandLine c0( command );
|
||||
|
||||
QCOMPARE( c0.command(), command );
|
||||
QCOMPARE( c0.timeout(), Calamares::CommandLine::TimeoutNotSet() );
|
||||
QVERIFY( c0.environment().isEmpty() );
|
||||
|
||||
const QStringList env { "-la", "/tmp" };
|
||||
Calamares::CommandLine c1( command, env, Calamares::CommandLine::TimeoutNotSet() );
|
||||
|
||||
QCOMPARE( c1.command(), command );
|
||||
QCOMPARE( c1.timeout(), Calamares::CommandLine::TimeoutNotSet() );
|
||||
QVERIFY( !c1.environment().isEmpty() );
|
||||
QCOMPARE( c1.environment().count(), 2 );
|
||||
QCOMPARE( c1.environment(), env );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testCommandConstructorsYAML()
|
||||
{
|
||||
QTemporaryFile f;
|
||||
QVERIFY( f.open() );
|
||||
f.write( R"(---
|
||||
commands:
|
||||
- one-string-command
|
||||
- command: only-command
|
||||
- command: with-timeout
|
||||
timeout: 12
|
||||
- command: all-three
|
||||
timeout: 20
|
||||
environment:
|
||||
- PATH=/USER
|
||||
- DISPLAY=:0
|
||||
)" );
|
||||
f.close();
|
||||
bool ok = false;
|
||||
QVariantMap m = Calamares::YAML::load( f.fileName(), &ok );
|
||||
|
||||
QVERIFY( ok );
|
||||
QCOMPARE( m.count(), 1 );
|
||||
QCOMPARE( m[ "commands" ].toList().count(), 4 );
|
||||
|
||||
{
|
||||
// Take care! The second parameter is a bool, so "3" here means "true"
|
||||
Calamares::CommandList cmds( m[ "commands" ], 3 );
|
||||
QCOMPARE( cmds.defaultTimeout(), std::chrono::seconds( 10 ) );
|
||||
// But the 4 commands are there anyway
|
||||
QCOMPARE( cmds.count(), 4 );
|
||||
QCOMPARE( cmds.at( 0 ).command(), QString( "one-string-command" ) );
|
||||
QCOMPARE( cmds.at( 0 ).environment(), QStringList() );
|
||||
QCOMPARE( cmds.at( 0 ).timeout(), Calamares::CommandLine::TimeoutNotSet() );
|
||||
QCOMPARE( cmds.at( 1 ).command(), QString( "only-command" ) );
|
||||
QCOMPARE( cmds.at( 2 ).command(), QString( "with-timeout" ) );
|
||||
QCOMPARE( cmds.at( 2 ).environment(), QStringList() );
|
||||
QCOMPARE( cmds.at( 2 ).timeout(), std::chrono::seconds( 12 ) );
|
||||
|
||||
QStringList expectedEnvironment = { "PATH=/USER", "DISPLAY=:0" };
|
||||
QCOMPARE( cmds.at( 3 ).command(), QString( "all-three" ) );
|
||||
QCOMPARE( cmds.at( 3 ).environment(), expectedEnvironment );
|
||||
QCOMPARE( cmds.at( 3 ).timeout(), std::chrono::seconds( 20 ) );
|
||||
}
|
||||
|
||||
{
|
||||
Calamares::CommandList cmds( m[ "commands" ], true, std::chrono::seconds( 3 ) );
|
||||
QCOMPARE( cmds.defaultTimeout(), std::chrono::seconds( 3 ) );
|
||||
QCOMPARE( cmds.at( 0 ).timeout(), Calamares::CommandLine::TimeoutNotSet() );
|
||||
QCOMPARE( cmds.at( 2 ).timeout(), std::chrono::seconds( 12 ) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testCommandRunning()
|
||||
{
|
||||
|
||||
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
|
||||
tempRoot.setAutoRemove( false );
|
||||
|
||||
const QString testExecutable = tempRoot.filePath( "example.sh" );
|
||||
const QString testFile = tempRoot.filePath( "example.txt" );
|
||||
|
||||
{
|
||||
QFile f( testExecutable );
|
||||
QVERIFY( f.open( QIODevice::WriteOnly ) );
|
||||
f.write( "#! /bin/sh\necho \"$calamares_test_variable\"\n" );
|
||||
f.close();
|
||||
Calamares::Permissions::apply( testExecutable, 0755 );
|
||||
}
|
||||
|
||||
const QString echoCommand = testExecutable + QStringLiteral( " > " ) + testFile;
|
||||
|
||||
// Without an environment, the variable echoed in the example
|
||||
// executable is empty, and we write a single newline to stdout,
|
||||
// which is redirected to testFile.
|
||||
{
|
||||
Calamares::CommandList l( false ); // no chroot
|
||||
Calamares::CommandLine c( echoCommand, {}, std::chrono::seconds( 2 ) );
|
||||
l.push_back( c );
|
||||
|
||||
const auto r = l.run();
|
||||
QVERIFY( bool( r ) );
|
||||
|
||||
QCOMPARE( QFileInfo( testFile ).size(), 1 ); // single newline
|
||||
}
|
||||
|
||||
// With an environment, echoes the value of the variable and a newline
|
||||
{
|
||||
const QString world = QStringLiteral( "Hello world" );
|
||||
Calamares::CommandList l( false ); // no chroot
|
||||
Calamares::CommandLine c(
|
||||
echoCommand,
|
||||
{ QStringLiteral( "calamares_test_variable=" ) + QChar( '"' ) + world + QChar( '"' ) },
|
||||
std::chrono::seconds( 2 ) );
|
||||
l.push_back( c );
|
||||
|
||||
const auto r = l.run();
|
||||
QVERIFY( bool( r ) );
|
||||
|
||||
QCOMPARE( QFileInfo( testFile ).size(), world.length() + 1 ); // plus newline
|
||||
QFile f( testFile );
|
||||
QVERIFY( f.open( QIODevice::ReadOnly ) );
|
||||
QCOMPARE( f.readAll(), world + QChar( '\n' ) );
|
||||
}
|
||||
|
||||
|
||||
tempRoot.setAutoRemove( true );
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testUmask()
|
||||
{
|
||||
|
@@ -63,9 +63,6 @@ if(WITH_QML)
|
||||
target_link_libraries(calamaresui PUBLIC ${qtname}::QuickWidgets)
|
||||
endif()
|
||||
|
||||
if(WITH_PYBIND11)
|
||||
target_compile_definitions(calamaresui PRIVATE WITH_PYBIND11=1)
|
||||
endif()
|
||||
set_target_properties(
|
||||
calamaresui
|
||||
PROPERTIES
|
||||
|
@@ -172,7 +172,11 @@ ViewManager::onInstallationFailed( const QString& message, const QString& detail
|
||||
{
|
||||
Calamares::Paste::doLogUploadUI( errorDialog );
|
||||
}
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QApplication::quit();
|
||||
#else
|
||||
QApplication::exit( EXIT_SUCCESS );
|
||||
#endif
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -487,7 +491,11 @@ ViewManager::quit()
|
||||
{
|
||||
if ( confirmCancelInstallation() )
|
||||
{
|
||||
qApp->quit();
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||
QApplication::quit();
|
||||
#else
|
||||
QApplication::exit( EXIT_SUCCESS );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,13 +10,16 @@
|
||||
|
||||
#include "PythonJobModule.h"
|
||||
|
||||
#if WITH_PYBIND11
|
||||
#include "CalamaresConfig.h"
|
||||
#ifdef WITH_PYBIND11
|
||||
#include "python/PythonJob.h"
|
||||
using JobType = Calamares::Python::Job;
|
||||
#else
|
||||
#elif defined(WITH_BOOST_PYTHON)
|
||||
// Old Boost::Python version
|
||||
#include "PythonJob.h"
|
||||
using JobType = Calamares::PythonJob;
|
||||
#else
|
||||
#error Python without bindings
|
||||
#endif
|
||||
|
||||
#include <QDir>
|
||||
|
@@ -497,7 +497,8 @@ LC_ALL and LANG to "C" for the called command.
|
||||
|
||||
## Process modules
|
||||
|
||||
Use of this kind of module is **not** recommended.
|
||||
Use of this kind of module is **not** recommended. Use *shellprocess*
|
||||
instead, which is more configurable.
|
||||
|
||||
> Type: jobmodule
|
||||
> Interface: process
|
||||
@@ -506,9 +507,14 @@ A process jobmodule runs a (single) command. The interface is *process*,
|
||||
while the module type must be *job* or *jobmodule*.
|
||||
|
||||
The module-descriptor key *command* should have a string as value, which is
|
||||
passed to the shell -- remember to quote it properly. It is generally
|
||||
passed to the shell -- remember to quote it properly in YAML. It is generally
|
||||
recommended to use a *shellprocess* job module instead (less configuration,
|
||||
easier to have multiple instances).
|
||||
easier to have multiple instances). There is no configuration outside
|
||||
of the module-descriptor. The *command* undergoes Calamares variable-
|
||||
expansion (e.g. replacing `${ROOT}` by the target of the installation).
|
||||
See *shellprocess* documentation for details.
|
||||
|
||||
Optional keys are *timeout* and *chroot*.
|
||||
|
||||
`CMakeLists.txt` is *not* used for process jobmodules.
|
||||
|
||||
|
@@ -7,14 +7,13 @@
|
||||
# When a given global value (string) equals a given value, then
|
||||
# the associated command is executed.
|
||||
#
|
||||
# The special top-level keys *dontChroot* and *timeout* have
|
||||
# meaning just like in shellprocess.conf. They are excluded from
|
||||
# the comparison with global variables.
|
||||
#
|
||||
# Configuration consists of keys for global variable names (except
|
||||
# *dontChroot* and *timeout*), and the sub-keys are strings to compare
|
||||
# to the variable's value. If the variable has that particular value, the
|
||||
# corresponding value (script) is executed.
|
||||
# corresponding value (script) is executed. The top-level keys *dontChroot*
|
||||
# and *timeout* are not global variable names. They have
|
||||
# meaning just like in shellprocess.conf, that is they
|
||||
# determine **where** the command runs and how long it has.
|
||||
#
|
||||
# The variable **may** contain dots, in which case the dot is used
|
||||
# to select into maps inside global storage, e.g.
|
||||
|
@@ -84,5 +84,6 @@ LCLocaleDialog::LCLocaleDialog( const QString& guessedLCLocale, const QStringLis
|
||||
QString
|
||||
LCLocaleDialog::selectedLCLocale()
|
||||
{
|
||||
return m_localesWidget->selectedItems().first()->text();
|
||||
const auto items = m_localesWidget->selectedItems();
|
||||
return items.isEmpty() ? QString{} : items.first()->text();
|
||||
}
|
||||
|
@@ -279,6 +279,11 @@ class PMApt(PackageManager):
|
||||
|
||||
|
||||
class PMDnf(PackageManager):
|
||||
"""
|
||||
This is "legacy" DNF, called DNF-4 even though the
|
||||
executable is dnf-3 in modern Fedora. Executable dnf
|
||||
is a symlink to dnf-3 in systems that use it.
|
||||
"""
|
||||
backend = "dnf"
|
||||
|
||||
def install(self, pkgs, from_local=False):
|
||||
@@ -298,6 +303,30 @@ class PMDnf(PackageManager):
|
||||
check_target_env_call(["dnf-3", "-y", "upgrade"])
|
||||
|
||||
|
||||
class PMDnf5(PackageManager):
|
||||
"""
|
||||
This is "modern" DNF, DNF-5 which is for Fedora 41 (presumably)
|
||||
and later. Executable dnf is a symlink to dnf5 in systems that use it.
|
||||
"""
|
||||
backend = "dnf5"
|
||||
|
||||
def install(self, pkgs, from_local=False):
|
||||
check_target_env_call(["dnf5", "-y", "install"] + pkgs)
|
||||
|
||||
def remove(self, pkgs):
|
||||
# ignore the error code for now because dnf thinks removing a
|
||||
# nonexistent package is an error
|
||||
target_env_call(["dnf5", "--disablerepo=*", "-C", "-y",
|
||||
"remove"] + pkgs)
|
||||
|
||||
def update_db(self):
|
||||
# Doesn't need updates
|
||||
pass
|
||||
|
||||
def update_system(self):
|
||||
check_target_env_call(["dnf5", "-y", "upgrade"])
|
||||
|
||||
|
||||
class PMDummy(PackageManager):
|
||||
backend = "dummy"
|
||||
|
||||
|
@@ -23,6 +23,7 @@
|
||||
# - apk - Alpine Linux package manager
|
||||
# - apt - APT frontend for DEB and RPM
|
||||
# - dnf - DNF, the new RPM frontend
|
||||
# - dnf5 - DNF5, the newer new RPM frontend
|
||||
# - entropy - Sabayon package manager (is being deprecated)
|
||||
# - luet - Sabayon package manager (next-gen)
|
||||
# - packagekit - PackageKit CLI tool
|
||||
|
@@ -12,6 +12,7 @@ properties:
|
||||
- apk
|
||||
- apt
|
||||
- dnf
|
||||
- dnf5
|
||||
- entropy
|
||||
- luet
|
||||
- packagekit
|
||||
|
@@ -71,13 +71,13 @@ PartitionLayout::PartitionEntry::PartitionEntry( const QString& label,
|
||||
, partType( type )
|
||||
, partAttributes( attributes )
|
||||
, partMountPoint( mountPoint )
|
||||
, partNoEncrypt( noEncrypt )
|
||||
, partFeatures( features )
|
||||
, partSize( size )
|
||||
, partMinSize( minSize )
|
||||
, partMaxSize( maxSize )
|
||||
{
|
||||
PartUtils::canonicalFilesystemName( fs, &partFileSystem );
|
||||
partNoEncrypt = noEncrypt;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@@ -37,7 +37,7 @@ public:
|
||||
quint64 partAttributes = 0;
|
||||
QString partMountPoint;
|
||||
FileSystem::Type partFileSystem = FileSystem::Unknown;
|
||||
bool partNoEncrypt;
|
||||
bool partNoEncrypt = false;
|
||||
QVariantMap partFeatures;
|
||||
Calamares::Partition::PartitionSize partSize;
|
||||
Calamares::Partition::PartitionSize partMinSize;
|
||||
|
@@ -12,8 +12,15 @@
|
||||
# system from the point of view of the command (when run in the target
|
||||
# system, e.g. when *dontChroot* is false, that will be `/`).
|
||||
# - `USER` is replaced by the username, set on the user page.
|
||||
# - `LANG` is replaced by the language chosen for the user-interface
|
||||
# of Calamares, set on the welcome page. This may not reflect the
|
||||
# chosen system language from the locale page.
|
||||
#
|
||||
# Variables are written as `${var}`, e.g. `${ROOT}`.
|
||||
# Write `$$` to get a shell-escaped `\$` in the shell command.
|
||||
# It is not possible to get an un-escaped `$` in the shell command
|
||||
# (either the command will fail because of undefined variables, or
|
||||
# you get a shell-escaped `\$`).
|
||||
#
|
||||
# The (global) timeout for the command list can be set with
|
||||
# the *timeout* key. The value is a time in seconds, default
|
||||
@@ -35,20 +42,33 @@
|
||||
#
|
||||
# The value of *script* may be:
|
||||
# - a single string; this is one command that is executed.
|
||||
# - a single object (this is not useful).
|
||||
# - a single object (see below).
|
||||
# - a list of items; these are executed one at a time, by
|
||||
# separate shells (/bin/sh -c is invoked for each command).
|
||||
# Each list item may be:
|
||||
# - a single string; this is one command that is executed.
|
||||
# - a single object, specifying a key *command* and (optionally)
|
||||
# a key *timeout* to set the timeout for this specific
|
||||
# command differently from the global setting.
|
||||
# command differently from the global setting. An optional
|
||||
# key *environment* is a list of strings to put into the
|
||||
# environment of the command.
|
||||
#
|
||||
# Using a single object is not useful because the same effect can
|
||||
# be obtained with a single string and a global timeout, but when
|
||||
# there are multiple commands to execute, one of them might have
|
||||
# Using a single object is not generally useful because the same effect
|
||||
# can be obtained with a single string and a global timeout, except
|
||||
# when the command needs environment-settings. When there are
|
||||
# multiple commands to execute, one of them might have
|
||||
# a different timeout than the others.
|
||||
#
|
||||
# The environment strings should all be "KEY='some value'" strings,
|
||||
# as if they can be typed into the shell. Quoting the environment
|
||||
# strings with "" in YAML is recommended. Adding the '' quotes ensures
|
||||
# that the value will not be interpreted by the shell. Writing
|
||||
# environment strings is the same as placing `export KEY='some value' ;`
|
||||
# in front of the *command*.
|
||||
#
|
||||
# Calamares variable expansion is **also** done on the environment strings.
|
||||
# Write `$$` to get a literal `$` in the shell command.
|
||||
#
|
||||
# To change the description of the job, set the *name* entries in *i18n*.
|
||||
---
|
||||
# Set to true to run in host, rather than target system
|
||||
|
Reference in New Issue
Block a user