From 778feb50e86091f93b0a1ed00d813675deaa1517 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 14:45:42 +0100 Subject: [PATCH 1/8] [libcalamares] Additional convenience for doubles --- src/libcalamares/utils/CalamaresUtils.cpp | 16 ++++++++++++++++ src/libcalamares/utils/CalamaresUtils.h | 7 ++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/utils/CalamaresUtils.cpp b/src/libcalamares/utils/CalamaresUtils.cpp index 9e678737b..c0175f771 100644 --- a/src/libcalamares/utils/CalamaresUtils.cpp +++ b/src/libcalamares/utils/CalamaresUtils.cpp @@ -366,6 +366,22 @@ getInteger( const QVariantMap& map, const QString& key, int d ) return result; } +double +getDouble( const QVariantMap& map, const QString& key, double d ) +{ + double result = d; + if ( map.contains( key ) ) + { + auto v = map.value( key ); + if ( v.type() == QVariant::Int ) + result = v.toInt(); + else if ( v.type() == QVariant::Double ) + result = v.toDouble(); + } + + return result; +} + QVariantMap getSubMap( const QVariantMap& map, const QString& key, bool& success ) { diff --git a/src/libcalamares/utils/CalamaresUtils.h b/src/libcalamares/utils/CalamaresUtils.h index 9b279ef43..13caf1cad 100644 --- a/src/libcalamares/utils/CalamaresUtils.h +++ b/src/libcalamares/utils/CalamaresUtils.h @@ -110,10 +110,15 @@ namespace CalamaresUtils DLLEXPORT QString getString( const QVariantMap& map, const QString& key ); /** - * Get an integer value from a mapping; returns @p default if no value. + * Get an integer value from a mapping; returns @p d if no value. */ DLLEXPORT int getInteger( const QVariantMap& map, const QString& key, int d ); + /** + * Get a double value from a mapping (integers are converted); returns @p d if no value. + */ + DLLEXPORT double getDouble( const QVariantMap& map, const QString& key, double d ); + /** * Returns a sub-map (i.e. a nested map) from the given mapping with the * given key. @p success is set to true if the @p key exists From ea179eaef43060dc37657662210a1dfcfd070474 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 15:49:21 +0100 Subject: [PATCH 2/8] [contextualprocess] Document command lists - Show that a command list is also allowed, not just a single command. Refer to shellprocess for more documentation. --- .../contextualprocess/contextualprocess.conf | 18 ++++++++++-------- src/modules/shellprocess/shellprocess.conf | 5 +++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/modules/contextualprocess/contextualprocess.conf b/src/modules/contextualprocess/contextualprocess.conf index 4e9ddea7f..03bfc4e36 100644 --- a/src/modules/contextualprocess/contextualprocess.conf +++ b/src/modules/contextualprocess/contextualprocess.conf @@ -4,18 +4,18 @@ # When a given global value (string) equals a given value, then # the associated command is executed. # -# Configuration consists of keys for global variable names, -# and the sub-keys are strings to compare to the variable's value. -# If the variable has that particular value, the corresponding -# value is executed as a shell command in the target environment. -# -# You can check for an empty value with "". -# # The special configuration key *dontChroot* specifies whether # the commands are run in the target system (default, value *false*), # or in the host system. This key is not used for comparisons # with global configuration values. # +# Configuration consists of keys for global variable names (except +# *dontChroot*), 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. +# +# You can check for an empty value with "". +# # If a command starts with "-" (a single minus sign), then the # return value of the command following the - is ignored; otherwise, # a failing command will abort the installation. This is much like @@ -31,6 +31,8 @@ --- dontChroot: false firmwareType: - efi: "-pkg remove efi-firmware" + efi: + - "-pkg remove efi-firmware" + - "-mkinitramfsrd -abgn" bios: "-pkg remove bios-firmware" "": "/bin/false no-firmware-type-set" diff --git a/src/modules/shellprocess/shellprocess.conf b/src/modules/shellprocess/shellprocess.conf index 0825538e1..3735db987 100644 --- a/src/modules/shellprocess/shellprocess.conf +++ b/src/modules/shellprocess/shellprocess.conf @@ -12,6 +12,11 @@ # return value of the command following the - is ignored; otherwise, # a failing command will abort the installation. This is much like # make's use of - in a command. +# +# The value of *script* may be: +# - a single string; this is one command that is executed. +# - a list of strings; these are executed one at a time, by +# separate shells (/bin/sh -c is invoked for each command). --- dontChroot: false script: From fe2be46d3f66647097ac187a714bcf02e581e0b3 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 17:01:28 +0100 Subject: [PATCH 3/8] [libcalamares] Extend command-list with timeouts - Replace plain StringList with a list of pairs, and run that instead. All code paths still use the default 10sec timeout and there's no way to change that. --- src/libcalamares/utils/CommandList.cpp | 31 ++++++++------ src/libcalamares/utils/CommandList.h | 57 ++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/libcalamares/utils/CommandList.cpp b/src/libcalamares/utils/CommandList.cpp index ae42a13bd..543c6a5ad 100644 --- a/src/libcalamares/utils/CommandList.cpp +++ b/src/libcalamares/utils/CommandList.cpp @@ -26,14 +26,17 @@ #include -static QStringList get_variant_stringlist( const QVariantList& l ) +namespace CalamaresUtils { - QStringList retl; + +static CommandList_t get_variant_stringlist( const QVariantList& l, int timeout ) +{ + CommandList_t retl; unsigned int c = 0; for ( const auto& v : l ) { if ( v.type() == QVariant::String ) - retl.append( v.toString() ); + retl.append( CommandLine( v.toString(), timeout ) ); else cDebug() << "WARNING Bad CommandList element" << c << v.type() << v; ++c; @@ -41,22 +44,20 @@ static QStringList get_variant_stringlist( const QVariantList& l ) return retl; } -namespace CalamaresUtils -{ - -CommandList::CommandList( bool doChroot ) +CommandList::CommandList( bool doChroot, int timeout ) : m_doChroot( doChroot ) + , m_timeout( timeout ) { } -CommandList::CommandList::CommandList( const QVariant& v, bool doChroot ) - : CommandList( doChroot ) +CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, int timeout ) + : CommandList( doChroot, timeout ) { if ( v.type() == QVariant::List ) { const auto v_list = v.toList(); if ( v_list.count() ) - append( get_variant_stringlist( v_list ) ); + append( get_variant_stringlist( v_list, m_timeout ) ); else cDebug() << "WARNING: Empty CommandList"; } @@ -90,7 +91,7 @@ Calamares::JobResult CommandList::run( const QObject* parent ) for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i ) { - QString processed_cmd = *i; + QString processed_cmd = i->command(); processed_cmd.replace( "@@ROOT@@", root ); // FIXME? bool suppress_result = false; if ( processed_cmd.startsWith( '-' ) ) @@ -103,7 +104,7 @@ Calamares::JobResult CommandList::run( const QObject* parent ) shell_cmd << processed_cmd; ProcessResult r = System::runCommand( - location, shell_cmd, QString(), QString(), 10 ); + location, shell_cmd, QString(), QString(), i->timeout() ); if ( r.getExitCode() != 0 ) { @@ -117,4 +118,10 @@ Calamares::JobResult CommandList::run( const QObject* parent ) return Calamares::JobResult::ok(); } +void +CommandList::append( const QString& s ) +{ + append( CommandLine( s, m_timeout ) ); +} + } // namespace diff --git a/src/libcalamares/utils/CommandList.h b/src/libcalamares/utils/CommandList.h index 0137fe41e..e80a1b742 100644 --- a/src/libcalamares/utils/CommandList.h +++ b/src/libcalamares/utils/CommandList.h @@ -27,11 +27,47 @@ namespace CalamaresUtils { -class CommandList : protected QStringList +/** + * Each command can have an associated timeout in seconds. The timeout + * defaults to 10 seconds. Provide some convenience naming and construction. + */ +struct CommandLine : public QPair< QString, int > +{ + CommandLine( const QString& s ) + : QPair< QString, int >( s, 10 ) + { + } + + CommandLine( const QString& s, int t ) + : QPair< QString, int >( s, t) + { + } + + QString command() const + { + return first; + } + + int timeout() const + { + return second; + } +} ; + +/** @brief Abbreviation, used internally. */ +using CommandList_t = QList< CommandLine >; + +/** + * A list of commands; the list may have its own default timeout + * for commands (which is then applied to each individual command + * that doesn't have one of its own). + */ +class CommandList : protected CommandList_t { public: - CommandList( bool doChroot = true ); - CommandList( const QVariant& v, bool doChroot = true ); + /** @brief empty command-list with timeout to apply to entries. */ + CommandList( bool doChroot = true, int timeout = 10 ); + CommandList( const QVariant& v, bool doChroot = true, int timeout = 10 ); ~CommandList(); bool doChroot() const @@ -41,14 +77,19 @@ public: Calamares::JobResult run( const QObject* parent ); - using QStringList::isEmpty; - using QStringList::count; - using QStringList::cbegin; - using QStringList::cend; - using QStringList::const_iterator; + using CommandList_t::isEmpty; + using CommandList_t::count; + using CommandList_t::cbegin; + using CommandList_t::cend; + using CommandList_t::const_iterator; + +protected: + using CommandList_t::append; + void append( const QString& ); private: bool m_doChroot; + int m_timeout; } ; } // namespace From 4917b5c778e56853f85cba5b08ae194eefab22b2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 17:38:16 +0100 Subject: [PATCH 4/8] [shellprocess] Add test for future feature - proposed syntax for command+timeout configuration, both for single- entry and for lists. - test it already --- src/modules/shellprocess/Tests.cpp | 27 +++++++++++++++++++++++++++ src/modules/shellprocess/Tests.h | 4 ++++ 2 files changed, 31 insertions(+) diff --git a/src/modules/shellprocess/Tests.cpp b/src/modules/shellprocess/Tests.cpp index abf988124..a1198a190 100644 --- a/src/modules/shellprocess/Tests.cpp +++ b/src/modules/shellprocess/Tests.cpp @@ -113,3 +113,30 @@ script: false QCOMPARE( cl1.count(), 0 ); } + +void ShellProcessTests::testProcessFromObject() +{ + YAML::Node doc = YAML::Load( R"(--- +script: + command: "ls /tmp" + timeout: 20 +)" ); + CommandList cl( + CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); + QVERIFY( !cl.isEmpty() ); + QCOMPARE( cl.count(), 1 ); +} + +void ShellProcessTests::testProcessListFromObject() +{ + YAML::Node doc = YAML::Load( R"(--- +script: + - command: "ls /tmp" + timeout: 20 + - "-/bin/false" +)" ); + CommandList cl( + CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); + QVERIFY( !cl.isEmpty() ); + QCOMPARE( cl.count(), 2 ); +} diff --git a/src/modules/shellprocess/Tests.h b/src/modules/shellprocess/Tests.h index fa29efeb2..af1f78487 100644 --- a/src/modules/shellprocess/Tests.h +++ b/src/modules/shellprocess/Tests.h @@ -36,6 +36,10 @@ private Q_SLOTS: void testProcessListFromList(); // Create from a simple YAML string void testProcessListFromString(); + // Create from a single complex YAML + void testProcessFromObject(); + // Create from a complex YAML list + void testProcessListFromObject(); }; #endif From 72bac332be7bd1cc3886f6e4e42a5a4afcd5d7b2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 20:59:58 +0100 Subject: [PATCH 5/8] FIXUP document --- src/modules/contextualprocess/contextualprocess.conf | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/modules/contextualprocess/contextualprocess.conf b/src/modules/contextualprocess/contextualprocess.conf index 03bfc4e36..4252d1043 100644 --- a/src/modules/contextualprocess/contextualprocess.conf +++ b/src/modules/contextualprocess/contextualprocess.conf @@ -16,11 +16,6 @@ # # You can check for an empty value with "". # -# If a command starts with "-" (a single minus sign), then the -# return value of the command following the - is ignored; otherwise, -# a failing command will abort the installation. This is much like -# make's use of - in a command. -# # Global configuration variables are not checked in a deterministic # order, so do not rely on commands from one variable-check to # always happen before (or after) checks on another @@ -28,6 +23,9 @@ # done in a deterministic order, but all of the value-checks # for a given variable happen together. # +# The values after a value sub-keys are the same kinds of values +# as can be given to the *script* key in the shellprocess module. +# See shellprocess.conf for documentation on valid values. --- dontChroot: false firmwareType: From c641f5dec68df2db2cc1fdafd99eb0cd4c057f15 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 21:08:42 +0100 Subject: [PATCH 6/8] [libcalamares] Implement object-style command line - handle command: and timeout: entries - test for setting the values --- src/libcalamares/utils/CommandList.cpp | 26 ++++++++++++++++++++++++++ src/libcalamares/utils/CommandList.h | 12 ++++++++++++ src/modules/shellprocess/Tests.cpp | 9 ++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/utils/CommandList.cpp b/src/libcalamares/utils/CommandList.cpp index 543c6a5ad..64b88a387 100644 --- a/src/libcalamares/utils/CommandList.cpp +++ b/src/libcalamares/utils/CommandList.cpp @@ -21,6 +21,7 @@ #include "GlobalStorage.h" #include "JobQueue.h" +#include "utils/CalamaresUtils.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" @@ -29,6 +30,17 @@ namespace CalamaresUtils { +static CommandLine get_variant_object( const QVariantMap& m ) +{ + QString command = CalamaresUtils::getString( m, "command" ); + int timeout = CalamaresUtils::getInteger( m, "timeout", -1 ); + + if ( !command.isEmpty() ) + return CommandLine( command, timeout ); + cDebug() << "WARNING Bad CommandLine element" << m; + return CommandLine(); +} + static CommandList_t get_variant_stringlist( const QVariantList& l, int timeout ) { CommandList_t retl; @@ -37,6 +49,13 @@ static CommandList_t get_variant_stringlist( const QVariantList& l, int timeout { if ( v.type() == QVariant::String ) retl.append( CommandLine( v.toString(), timeout ) ); + else if ( v.type() == QVariant::Map ) + { + auto c( get_variant_object( v.toMap() ) ); + if ( c.isValid() ) + retl.append( c ); + // Otherwise warning is already given + } else cDebug() << "WARNING Bad CommandList element" << c << v.type() << v; ++c; @@ -63,6 +82,13 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, int tim } else if ( v.type() == QVariant::String ) append( v.toString() ); + else if ( v.type() == QVariant::Map ) + { + auto c( get_variant_object( v.toMap() ) ); + if ( c.isValid() ) + append( c ); + // Otherwise warning is already given + } else cDebug() << "WARNING: CommandList does not understand variant" << v.type(); } diff --git a/src/libcalamares/utils/CommandList.h b/src/libcalamares/utils/CommandList.h index e80a1b742..58d2e2721 100644 --- a/src/libcalamares/utils/CommandList.h +++ b/src/libcalamares/utils/CommandList.h @@ -33,6 +33,12 @@ namespace CalamaresUtils */ struct CommandLine : public QPair< QString, int > { + /// An invalid command line + CommandLine() + : QPair< QString, int >( QString(), -1 ) + { + } + CommandLine( const QString& s ) : QPair< QString, int >( s, 10 ) { @@ -52,6 +58,11 @@ struct CommandLine : public QPair< QString, int > { return second; } + + bool isValid() const + { + return !first.isEmpty(); + } } ; /** @brief Abbreviation, used internally. */ @@ -82,6 +93,7 @@ public: using CommandList_t::cbegin; using CommandList_t::cend; using CommandList_t::const_iterator; + using CommandList_t::at; protected: using CommandList_t::append; diff --git a/src/modules/shellprocess/Tests.cpp b/src/modules/shellprocess/Tests.cpp index a1198a190..9792f4e7c 100644 --- a/src/modules/shellprocess/Tests.cpp +++ b/src/modules/shellprocess/Tests.cpp @@ -102,6 +102,8 @@ script: "ls /tmp" CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); QVERIFY( !cl.isEmpty() ); QCOMPARE( cl.count(), 1 ); + QCOMPARE( cl.at(0).timeout(), 10 ); + QCOMPARE( cl.at(0).command(), QStringLiteral( "ls /tmp" ) ); // Not a string doc = YAML::Load( R"(--- @@ -125,6 +127,8 @@ script: CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); QVERIFY( !cl.isEmpty() ); QCOMPARE( cl.count(), 1 ); + QCOMPARE( cl.at(0).timeout(), 20 ); + QCOMPARE( cl.at(0).command(), QStringLiteral( "ls /tmp" ) ); } void ShellProcessTests::testProcessListFromObject() @@ -132,11 +136,14 @@ void ShellProcessTests::testProcessListFromObject() YAML::Node doc = YAML::Load( R"(--- script: - command: "ls /tmp" - timeout: 20 + timeout: 12 - "-/bin/false" )" ); CommandList cl( CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); QVERIFY( !cl.isEmpty() ); QCOMPARE( cl.count(), 2 ); + QCOMPARE( cl.at(0).timeout(), 12 ); + QCOMPARE( cl.at(0).command(), QStringLiteral( "ls /tmp" ) ); + QCOMPARE( cl.at(1).timeout(), 10 ); // default } From 2da430fa366c7a57d058504013d4405aad0a86c6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 21:25:18 +0100 Subject: [PATCH 7/8] [libcalamares] Allow CommandLine to have unset timeout - Introduce enum for the appropriate constant - If the timeout isn't set, then defer to the timeout set on the commandlist when running the commands. --- src/libcalamares/utils/CommandList.cpp | 17 +++++++++-------- src/libcalamares/utils/CommandList.h | 6 ++++-- src/modules/shellprocess/Tests.cpp | 2 +- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/libcalamares/utils/CommandList.cpp b/src/libcalamares/utils/CommandList.cpp index 64b88a387..eb73c798e 100644 --- a/src/libcalamares/utils/CommandList.cpp +++ b/src/libcalamares/utils/CommandList.cpp @@ -33,7 +33,7 @@ namespace CalamaresUtils static CommandLine get_variant_object( const QVariantMap& m ) { QString command = CalamaresUtils::getString( m, "command" ); - int timeout = CalamaresUtils::getInteger( m, "timeout", -1 ); + int timeout = CalamaresUtils::getInteger( m, "timeout", CommandLine::TimeoutNotSet ); if ( !command.isEmpty() ) return CommandLine( command, timeout ); @@ -41,14 +41,14 @@ static CommandLine get_variant_object( const QVariantMap& m ) return CommandLine(); } -static CommandList_t get_variant_stringlist( const QVariantList& l, int timeout ) +static CommandList_t get_variant_stringlist( const QVariantList& l ) { CommandList_t retl; unsigned int c = 0; for ( const auto& v : l ) { if ( v.type() == QVariant::String ) - retl.append( CommandLine( v.toString(), timeout ) ); + retl.append( CommandLine( v.toString(), CommandLine::TimeoutNotSet ) ); else if ( v.type() == QVariant::Map ) { auto c( get_variant_object( v.toMap() ) ); @@ -76,7 +76,7 @@ CommandList::CommandList::CommandList( const QVariant& v, bool doChroot, int tim { const auto v_list = v.toList(); if ( v_list.count() ) - append( get_variant_stringlist( v_list, m_timeout ) ); + append( get_variant_stringlist( v_list ) ); else cDebug() << "WARNING: Empty CommandList"; } @@ -118,26 +118,27 @@ Calamares::JobResult CommandList::run( const QObject* parent ) for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i ) { QString processed_cmd = i->command(); - processed_cmd.replace( "@@ROOT@@", root ); // FIXME? + processed_cmd.replace( "@@ROOT@@", root ); bool suppress_result = false; if ( processed_cmd.startsWith( '-' ) ) { suppress_result = true; - processed_cmd.remove( 0, 1 ); // Drop the - // FIXME? + processed_cmd.remove( 0, 1 ); // Drop the - } QStringList shell_cmd { "/bin/sh", "-c" }; shell_cmd << processed_cmd; + int timeout = i->timeout() >= 0 ? i->timeout() : m_timeout; ProcessResult r = System::runCommand( - location, shell_cmd, QString(), QString(), i->timeout() ); + location, shell_cmd, QString(), QString(), timeout ); if ( r.getExitCode() != 0 ) { if ( suppress_result ) cDebug() << "Error code" << r.getExitCode() << "ignored by CommandList configuration."; else - return r.explainProcess( parent, processed_cmd, 10 ); + return r.explainProcess( parent, processed_cmd, timeout ); } } diff --git a/src/libcalamares/utils/CommandList.h b/src/libcalamares/utils/CommandList.h index 58d2e2721..4ed7616eb 100644 --- a/src/libcalamares/utils/CommandList.h +++ b/src/libcalamares/utils/CommandList.h @@ -33,14 +33,16 @@ namespace CalamaresUtils */ struct CommandLine : public QPair< QString, int > { + enum { TimeoutNotSet = -1 }; + /// An invalid command line CommandLine() - : QPair< QString, int >( QString(), -1 ) + : QPair< QString, int >( QString(), TimeoutNotSet ) { } CommandLine( const QString& s ) - : QPair< QString, int >( s, 10 ) + : QPair< QString, int >( s, TimeoutNotSet ) { } diff --git a/src/modules/shellprocess/Tests.cpp b/src/modules/shellprocess/Tests.cpp index 9792f4e7c..c406fde17 100644 --- a/src/modules/shellprocess/Tests.cpp +++ b/src/modules/shellprocess/Tests.cpp @@ -145,5 +145,5 @@ script: QCOMPARE( cl.count(), 2 ); QCOMPARE( cl.at(0).timeout(), 12 ); QCOMPARE( cl.at(0).command(), QStringLiteral( "ls /tmp" ) ); - QCOMPARE( cl.at(1).timeout(), 10 ); // default + QCOMPARE( cl.at(1).timeout(), -1 ); // not set } From c2aca1f5c65e9a6ddddef6a60ae2aa1e4b5088b8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 29 Jan 2018 22:08:12 +0100 Subject: [PATCH 8/8] [shellprocess] Implement timeout setting - For both shellprocess and contextualprocess, add a top-level key "timeout" that defaults to 10 seconds (which it already did). - Allows setting "global" timeout for command-lists, while still allowing individual timeouts per-command. - Setting timeout per global variable in contextualprocess is not supported; that would restrict the possible space of comparisions, while not supporting a global setting timeout seems reasonable enough. Use instances if you need wildly variable timeouts and don't want to set them individually. --- .../contextualprocess/ContextualProcessJob.cpp | 9 ++++++--- .../contextualprocess/ContextualProcessJob.h | 1 - .../contextualprocess/contextualprocess.conf | 14 +++++++------- src/modules/shellprocess/ShellProcessJob.cpp | 8 +++++--- src/modules/shellprocess/ShellProcessJob.h | 1 - src/modules/shellprocess/Tests.cpp | 4 +++- src/modules/shellprocess/shellprocess.conf | 10 ++++++++++ 7 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/modules/contextualprocess/ContextualProcessJob.cpp b/src/modules/contextualprocess/ContextualProcessJob.cpp index 50a28f417..6744db054 100644 --- a/src/modules/contextualprocess/ContextualProcessJob.cpp +++ b/src/modules/contextualprocess/ContextualProcessJob.cpp @@ -97,12 +97,15 @@ ContextualProcessJob::exec() void ContextualProcessJob::setConfigurationMap( const QVariantMap& configurationMap ) { - m_dontChroot = CalamaresUtils::getBool( configurationMap, "dontChroot", false ); + bool dontChroot = CalamaresUtils::getBool( configurationMap, "dontChroot", false ); + int timeout = CalamaresUtils::getInteger( configurationMap, "timeout", 10 ); + if ( timeout < 1 ) + timeout = 10; for ( QVariantMap::const_iterator iter = configurationMap.cbegin(); iter != configurationMap.cend(); ++iter ) { QString variableName = iter.key(); - if ( variableName.isEmpty() || ( variableName == "dontChroot" ) ) + if ( variableName.isEmpty() || ( variableName == "dontChroot" ) || ( variableName == "timeout" ) ) continue; if ( iter.value().type() != QVariant::Map ) @@ -121,7 +124,7 @@ ContextualProcessJob::setConfigurationMap( const QVariantMap& configurationMap ) continue; } - CalamaresUtils::CommandList* commands = new CalamaresUtils::CommandList( valueiter.value(), !m_dontChroot ); + CalamaresUtils::CommandList* commands = new CalamaresUtils::CommandList( valueiter.value(), !dontChroot, timeout ); if ( commands->count() > 0 ) { diff --git a/src/modules/contextualprocess/ContextualProcessJob.h b/src/modules/contextualprocess/ContextualProcessJob.h index aea09aa9b..e8a39c3f4 100644 --- a/src/modules/contextualprocess/ContextualProcessJob.h +++ b/src/modules/contextualprocess/ContextualProcessJob.h @@ -45,7 +45,6 @@ public: private: QList m_commands; - bool m_dontChroot; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( ContextualProcessJobFactory ) diff --git a/src/modules/contextualprocess/contextualprocess.conf b/src/modules/contextualprocess/contextualprocess.conf index 4252d1043..20668e1ce 100644 --- a/src/modules/contextualprocess/contextualprocess.conf +++ b/src/modules/contextualprocess/contextualprocess.conf @@ -4,14 +4,13 @@ # When a given global value (string) equals a given value, then # the associated command is executed. # -# The special configuration key *dontChroot* specifies whether -# the commands are run in the target system (default, value *false*), -# or in the host system. This key is not used for comparisons -# with global configuration values. +# 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 the sub-keys are strings to compare to the -# variable's value. If the variable has that particular value, the +# *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. # # You can check for an empty value with "". @@ -31,6 +30,7 @@ dontChroot: false firmwareType: efi: - "-pkg remove efi-firmware" - - "-mkinitramfsrd -abgn" + - command: "-mkinitramfsrd -abgn" + timeout: 120 # This is slow bios: "-pkg remove bios-firmware" "": "/bin/false no-firmware-type-set" diff --git a/src/modules/shellprocess/ShellProcessJob.cpp b/src/modules/shellprocess/ShellProcessJob.cpp index 45b8b2537..5c14284ec 100644 --- a/src/modules/shellprocess/ShellProcessJob.cpp +++ b/src/modules/shellprocess/ShellProcessJob.cpp @@ -34,7 +34,6 @@ ShellProcessJob::ShellProcessJob( QObject* parent ) : Calamares::CppJob( parent ) , m_commands( nullptr ) - , m_dontChroot( false ) { } @@ -70,11 +69,14 @@ ShellProcessJob::exec() void ShellProcessJob::setConfigurationMap( const QVariantMap& configurationMap ) { - m_dontChroot = CalamaresUtils::getBool( configurationMap, "dontChroot", false ); + bool dontChroot = CalamaresUtils::getBool( configurationMap, "dontChroot", false ); + int timeout = CalamaresUtils::getInteger( configurationMap, "timeout", 10 ); + if ( timeout < 1 ) + timeout = 10; if ( configurationMap.contains( "script" ) ) { - m_commands = new CalamaresUtils::CommandList( configurationMap.value( "script" ), !m_dontChroot ); + m_commands = new CalamaresUtils::CommandList( configurationMap.value( "script" ), !dontChroot, timeout ); if ( m_commands->isEmpty() ) cDebug() << "ShellProcessJob: \"script\" contains no commands for" << moduleInstanceKey(); } diff --git a/src/modules/shellprocess/ShellProcessJob.h b/src/modules/shellprocess/ShellProcessJob.h index afc58fdc7..3111fc26e 100644 --- a/src/modules/shellprocess/ShellProcessJob.h +++ b/src/modules/shellprocess/ShellProcessJob.h @@ -46,7 +46,6 @@ public: private: CalamaresUtils::CommandList* m_commands; - bool m_dontChroot; }; CALAMARES_PLUGIN_FACTORY_DECLARATION( ShellProcessJobFactory ) diff --git a/src/modules/shellprocess/Tests.cpp b/src/modules/shellprocess/Tests.cpp index c406fde17..c6643325f 100644 --- a/src/modules/shellprocess/Tests.cpp +++ b/src/modules/shellprocess/Tests.cpp @@ -64,7 +64,9 @@ ShellProcessTests::testProcessListSampleConfig() CommandList cl( CalamaresUtils::yamlMapToVariant( doc ).toMap().value( "script" ) ); QVERIFY( !cl.isEmpty() ); - QCOMPARE( cl.count(), 2 ); + QCOMPARE( cl.count(), 3 ); + QCOMPARE( cl.at(0).timeout(), -1 ); + QCOMPARE( cl.at(2).timeout(), 3600 ); // slowloris } void ShellProcessTests::testProcessListFromList() diff --git a/src/modules/shellprocess/shellprocess.conf b/src/modules/shellprocess/shellprocess.conf index 3735db987..ff53dc228 100644 --- a/src/modules/shellprocess/shellprocess.conf +++ b/src/modules/shellprocess/shellprocess.conf @@ -8,6 +8,10 @@ # system from the point of view of the command (for chrooted # commands, that will be */*). # +# The (global) timeout for the command list can be set with +# the *timeout* key. The value is a time in seconds, default +# is 10 seconds if not set. +# # If a command starts with "-" (a single minus sign), then the # return value of the command following the - is ignored; otherwise, # a failing command will abort the installation. This is much like @@ -17,8 +21,14 @@ # - a single string; this is one command that is executed. # - a list of strings; these are executed one at a time, by # separate shells (/bin/sh -c is invoked for each command). +# - an object, specifying a key *command* and (optionally) +# a key *timeout* to set the timeout for this specific +# command differently from the global setting. --- dontChroot: false +timeout: 10 script: - "-touch @@ROOT@@/tmp/thingy" - "/usr/bin/false" + - command: "/usr/local/bin/slowloris" + timeout: 3600