mirror of
https://github.com/parchlinux/calamares.git
synced 2025-02-28 21:05:45 -05:00
Back targetEnvCommand() with a more general runCommand() that takes an argument selecting the location to run the command in. This allows us also to use the same API for running processes in the host during install, as we do for running them in the target system. One reason for this change is wanting to run (user-specified) commands and independently from the global dontChroot setting, run those commands in the live system or the target. This changes the ABI of the DLL, since targetEnvCommand() is no longer exported. Plugins will need to be recompiled. - refactor targetEnvCommand() into more general runCommand(). - While here, allow host system commands to run even if there is no global storage. - provide convenience accessors for ProcessResult members - Move explanation of process errors out of ProcessJob - Move from ProcessJob to ProcessResult, so it can be reused outside of ProcessJob (e.g. from ShellProcessJob). - Add some convenience functions, too.
147 lines
3.9 KiB
C++
147 lines
3.9 KiB
C++
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
|
*
|
|
* Copyright 2014-2015, Teo Mrnjavac <teo@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 "ProcessJob.h"
|
|
|
|
#include "utils/CalamaresUtilsSystem.h"
|
|
#include "utils/Logger.h"
|
|
|
|
#include <QDir>
|
|
#include <QProcess>
|
|
|
|
namespace Calamares {
|
|
|
|
|
|
ProcessJob::ProcessJob( const QString& command,
|
|
const QString& workingPath,
|
|
bool runInChroot,
|
|
int secondsTimeout,
|
|
QObject* parent )
|
|
: Job( parent )
|
|
, m_command( command )
|
|
, m_workingPath( workingPath )
|
|
, m_runInChroot( runInChroot )
|
|
, m_timeoutSec( secondsTimeout )
|
|
{}
|
|
|
|
|
|
ProcessJob::~ProcessJob()
|
|
{}
|
|
|
|
|
|
QString
|
|
ProcessJob::prettyName() const
|
|
{
|
|
//TODO: show something more meaningful
|
|
return tr( "Run command %1 %2" )
|
|
.arg( m_command )
|
|
.arg( m_runInChroot ? "in chroot." : " ." );
|
|
}
|
|
|
|
|
|
QString
|
|
ProcessJob::prettyStatusMessage() const
|
|
{
|
|
return tr( "Running command %1 %2" )
|
|
.arg( m_command )
|
|
.arg( m_runInChroot ? "in chroot." : " ." );
|
|
}
|
|
|
|
|
|
JobResult
|
|
ProcessJob::exec()
|
|
{
|
|
int ec = 0;
|
|
QString output;
|
|
if ( m_runInChroot )
|
|
ec = CalamaresUtils::System::instance()->
|
|
targetEnvOutput( m_command,
|
|
output,
|
|
m_workingPath,
|
|
QString(),
|
|
m_timeoutSec );
|
|
else
|
|
ec = callOutput( m_command,
|
|
output,
|
|
m_workingPath,
|
|
QString(),
|
|
m_timeoutSec );
|
|
|
|
return CalamaresUtils::ProcessResult::explainProcess( this, ec, m_command, output, m_timeoutSec );
|
|
}
|
|
|
|
|
|
int
|
|
ProcessJob::callOutput( const QString& command,
|
|
QString& output,
|
|
const QString& workingPath,
|
|
const QString& stdInput,
|
|
int timeoutSec )
|
|
{
|
|
output.clear();
|
|
|
|
QProcess process;
|
|
process.setProgram( "/bin/sh" );
|
|
process.setArguments( { "-c", command } );
|
|
process.setProcessChannelMode( QProcess::MergedChannels );
|
|
|
|
if ( !workingPath.isEmpty() )
|
|
{
|
|
if ( QDir( workingPath ).exists() )
|
|
process.setWorkingDirectory( QDir( workingPath ).absolutePath() );
|
|
else
|
|
{
|
|
cLog() << "Invalid working directory:" << workingPath;
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
cLog() << "Running" << command;
|
|
process.start();
|
|
if ( !process.waitForStarted() )
|
|
{
|
|
cLog() << "Process failed to start" << process.error();
|
|
return -2;
|
|
}
|
|
|
|
if ( !stdInput.isEmpty() )
|
|
{
|
|
process.write( stdInput.toLocal8Bit() );
|
|
process.closeWriteChannel();
|
|
}
|
|
|
|
if ( !process.waitForFinished( timeoutSec ? ( timeoutSec * 1000 ) : -1 ) )
|
|
{
|
|
cLog() << "Timed out. output so far:";
|
|
cLog() << process.readAllStandardOutput();
|
|
return -4;
|
|
}
|
|
|
|
output.append( QString::fromLocal8Bit( process.readAllStandardOutput() ).trimmed() );
|
|
|
|
if ( process.exitStatus() == QProcess::CrashExit )
|
|
{
|
|
cLog() << "Process crashed";
|
|
return -1;
|
|
}
|
|
|
|
cLog() << "Finished. Exit code:" << process.exitCode();
|
|
return process.exitCode();
|
|
}
|
|
|
|
} // namespace Calamares
|