From b5d900c1c6da2b25c185ad16f98d56861c4921d5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 23 May 2018 09:25:57 -0400 Subject: [PATCH] [libcalamares] Allow a @@USER@@ replacement in commands - Following example in preservefiles module, allow @@USER@@ in commands (e.g. to do something specific in the home-dir of the new user). --- src/libcalamares/utils/CommandList.cpp | 31 +++++++++++++++------- src/libcalamares/utils/CommandList.h | 3 +++ src/modules/shellprocess/shellprocess.conf | 8 +++--- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/libcalamares/utils/CommandList.cpp b/src/libcalamares/utils/CommandList.cpp index 3b2935c55..8e332a066 100644 --- a/src/libcalamares/utils/CommandList.cpp +++ b/src/libcalamares/utils/CommandList.cpp @@ -98,9 +98,19 @@ CommandList::~CommandList() { } +static inline bool +findInCommands( const CommandList& l, const QString& needle ) +{ + for ( CommandList::const_iterator i = l.cbegin(); i != l.cend(); ++i ) + if ( i->command().contains( needle ) ) + return true; + return false; +} + Calamares::JobResult CommandList::run() { QLatin1Literal rootMagic( "@@ROOT@@" ); + QLatin1Literal userMagic( "@@USER@@" ); System::RunLocation location = m_doChroot ? System::RunLocation::RunInTarget : System::RunLocation::RunInHost; @@ -108,14 +118,7 @@ Calamares::JobResult CommandList::run() QString root = QStringLiteral( "/" ); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - bool needsRootSubstitution = false; - for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i ) - if ( i->command().contains( rootMagic ) ) - { - needsRootSubstitution = true; - break; - } - + bool needsRootSubstitution = findInCommands( *this, rootMagic ); if ( needsRootSubstitution && ( location == System::RunLocation::RunInHost ) ) { if ( !gs || !gs->contains( "rootMountPoint" ) ) @@ -127,10 +130,20 @@ Calamares::JobResult CommandList::run() root = gs->value( "rootMountPoint" ).toString(); } + bool needsUserSubstitution = findInCommands( *this, userMagic ); + if ( needsUserSubstitution && ( !gs || !gs->contains( "username" ) ) ) + { + cError() << "No username defined."; + return Calamares::JobResult::error( + QCoreApplication::translate( "CommandList", "Could not run command." ), + QCoreApplication::translate( "CommandList", "The command needs to know the user's name, but no username is defined." ) ); + } + QString user = gs->value( "username" ).toString(); // may be blank if unset + for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i ) { QString processed_cmd = i->command(); - processed_cmd.replace( rootMagic, root ); + processed_cmd.replace( rootMagic, root ).replace( userMagic, user ); bool suppress_result = false; if ( processed_cmd.startsWith( '-' ) ) { diff --git a/src/libcalamares/utils/CommandList.h b/src/libcalamares/utils/CommandList.h index b766259c0..9faf705f2 100644 --- a/src/libcalamares/utils/CommandList.h +++ b/src/libcalamares/utils/CommandList.h @@ -74,6 +74,9 @@ 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). + * + * Documentation for the format of commands can be found in + * `shellprocess.conf`. */ class CommandList : protected CommandList_t { diff --git a/src/modules/shellprocess/shellprocess.conf b/src/modules/shellprocess/shellprocess.conf index ff53dc228..4734aaadd 100644 --- a/src/modules/shellprocess/shellprocess.conf +++ b/src/modules/shellprocess/shellprocess.conf @@ -4,9 +4,11 @@ # If the top-level key *dontChroot* is true, then the commands # are executed in the context of the live system, otherwise # in the context of the target system. In all of the commands, -# `@@ROOT@@` is replaced by the root mount point of the **target** -# system from the point of view of the command (for chrooted -# commands, that will be */*). +# the following substitutions will take place: +# - `@@ROOT@@` is replaced by the root mount point of the **target** +# system from the point of view of the command (for chrooted +# commands, that will be */*). +# - `@@USER@@` is replaced by the username, set on the user page. # # The (global) timeout for the command list can be set with # the *timeout* key. The value is a time in seconds, default