[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).
This commit is contained in:
Adriaan de Groot 2018-05-23 09:25:57 -04:00
parent b7890d865f
commit b5d900c1c6
3 changed files with 30 additions and 12 deletions

View File

@ -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() Calamares::JobResult CommandList::run()
{ {
QLatin1Literal rootMagic( "@@ROOT@@" ); QLatin1Literal rootMagic( "@@ROOT@@" );
QLatin1Literal userMagic( "@@USER@@" );
System::RunLocation location = m_doChroot ? System::RunLocation::RunInTarget : System::RunLocation::RunInHost; System::RunLocation location = m_doChroot ? System::RunLocation::RunInTarget : System::RunLocation::RunInHost;
@ -108,14 +118,7 @@ Calamares::JobResult CommandList::run()
QString root = QStringLiteral( "/" ); QString root = QStringLiteral( "/" );
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
bool needsRootSubstitution = false; bool needsRootSubstitution = findInCommands( *this, rootMagic );
for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i )
if ( i->command().contains( rootMagic ) )
{
needsRootSubstitution = true;
break;
}
if ( needsRootSubstitution && ( location == System::RunLocation::RunInHost ) ) if ( needsRootSubstitution && ( location == System::RunLocation::RunInHost ) )
{ {
if ( !gs || !gs->contains( "rootMountPoint" ) ) if ( !gs || !gs->contains( "rootMountPoint" ) )
@ -127,10 +130,20 @@ Calamares::JobResult CommandList::run()
root = gs->value( "rootMountPoint" ).toString(); 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 ) for ( CommandList::const_iterator i = cbegin(); i != cend(); ++i )
{ {
QString processed_cmd = i->command(); QString processed_cmd = i->command();
processed_cmd.replace( rootMagic, root ); processed_cmd.replace( rootMagic, root ).replace( userMagic, user );
bool suppress_result = false; bool suppress_result = false;
if ( processed_cmd.startsWith( '-' ) ) if ( processed_cmd.startsWith( '-' ) )
{ {

View File

@ -74,6 +74,9 @@ using CommandList_t = QList< CommandLine >;
* A list of commands; the list may have its own default timeout * A list of commands; the list may have its own default timeout
* for commands (which is then applied to each individual command * for commands (which is then applied to each individual command
* that doesn't have one of its own). * 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 class CommandList : protected CommandList_t
{ {

View File

@ -4,9 +4,11 @@
# If the top-level key *dontChroot* is true, then the commands # If the top-level key *dontChroot* is true, then the commands
# are executed in the context of the live system, otherwise # are executed in the context of the live system, otherwise
# in the context of the target system. In all of the commands, # in the context of the target system. In all of the commands,
# `@@ROOT@@` is replaced by the root mount point of the **target** # the following substitutions will take place:
# system from the point of view of the command (for chrooted # - `@@ROOT@@` is replaced by the root mount point of the **target**
# commands, that will be */*). # 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 (global) timeout for the command list can be set with
# the *timeout* key. The value is a time in seconds, default # the *timeout* key. The value is a time in seconds, default