diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index df3a11016120c00571970d16b289a285b3e669df..0d4d1ac5b8b3b2cec7e233cc5e80bf04b62853e3 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -43,6 +43,12 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( chroot_call_str_overloads, BOOST_PYTHON_FUNCTION_OVERLOADS( chroot_call_list_overloads, CalamaresPython::chroot_call, 1, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( check_chroot_call_str_overloads, + CalamaresPython::check_chroot_call, + 1, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( check_chroot_call_list_overloads, + CalamaresPython::check_chroot_call, + 1, 3 ); BOOST_PYTHON_MODULE( libcalamares ) { bp::scope().attr( "ORGANIZATION_NAME" ) = CALAMARES_ORGANIZATION_NAME; @@ -73,43 +79,84 @@ BOOST_PYTHON_MODULE( libcalamares ) Q_UNUSED( utilsScope ); bp::def( "debug", &CalamaresPython::debug ); - bp::def( "mount", - &CalamaresPython::mount, - mount_overloads( bp::args( "device_path", - "mount_point", - "filesystem_name", - "options" ), - "Runs the mount utility with the specified parameters.\n" - "Returns the program's exit code, or:\n" - "-1 = QProcess crash\n" - "-2 = QProcess cannot start\n" - "-3 = bad arguments" ) ); - bp::def( "chroot_call", - static_cast< int (*)( const std::string&, - const std::string&, - int ) >( &CalamaresPython::chroot_call ), - chroot_call_str_overloads( bp::args( "command", - "stdin", - "timeout" ), - "Runs the specified command in the chroot of the target system.\n" - "Returns the program's exit code, or:\n" - "-1 = QProcess crash\n" - "-2 = QProcess cannot start\n" - "-3 = bad arguments\n" - "-4 = QProcess timeout" ) ); - bp::def( "chroot_call", - static_cast< int (*)( const bp::list&, - const std::string&, - int ) >( &CalamaresPython::chroot_call ), - chroot_call_list_overloads( bp::args( "args", - "stdin", - "timeout" ), - "Runs the specified command in the chroot of the target system.\n" - "Returns the program's exit code, or:\n" - "-1 = QProcess crash\n" - "-2 = QProcess cannot start\n" - "-3 = bad arguments\n" - "-4 = QProcess timeout" ) ); + bp::def( + "mount", + &CalamaresPython::mount, + mount_overloads( + bp::args( "device_path", + "mount_point", + "filesystem_name", + "options" ), + "Runs the mount utility with the specified parameters.\n" + "Returns the program's exit code, or:\n" + "-1 = QProcess crash\n" + "-2 = QProcess cannot start\n" + "-3 = bad arguments" + ) + ); + bp::def( + "chroot_call", + static_cast< int (*)( const std::string&, + const std::string&, + int ) >( &CalamaresPython::chroot_call ), + chroot_call_str_overloads( + bp::args( "command", + "stdin", + "timeout" ), + "Runs the specified command in the chroot of the target system.\n" + "Returns the program's exit code, or:\n" + "-1 = QProcess crash\n" + "-2 = QProcess cannot start\n" + "-3 = bad arguments\n" + "-4 = QProcess timeout" + ) + ); + bp::def( + "chroot_call", + static_cast< int (*)( const bp::list&, + const std::string&, + int ) >( &CalamaresPython::chroot_call ), + chroot_call_list_overloads( + bp::args( "args", + "stdin", + "timeout" ), + "Runs the specified command in the chroot of the target system.\n" + "Returns the program's exit code, or:\n" + "-1 = QProcess crash\n" + "-2 = QProcess cannot start\n" + "-3 = bad arguments\n" + "-4 = QProcess timeout" + ) + ); + + bp::def( + "check_chroot_call", + static_cast< int (*)( const std::string&, + const std::string&, + int ) >( &CalamaresPython::check_chroot_call ), + check_chroot_call_str_overloads( + bp::args( "command", + "stdin", + "timeout" ), + "Runs the specified command in the chroot of the target system.\n" + "Returns 0, which is program's exit code if the program exited " + "successfully, or raises a subprocess.CalledProcessError." + ) + ); + bp::def( + "check_chroot_call", + static_cast< int (*)( const bp::list&, + const std::string&, + int ) >( &CalamaresPython::check_chroot_call ), + check_chroot_call_list_overloads( + bp::args( "args", + "stdin", + "timeout" ), + "Runs the specified command in the chroot of the target system.\n" + "Returns 0, which is program's exit code if the program exited " + "successfully, or raises a subprocess.CalledProcessError." + ) + ); } @@ -185,7 +232,6 @@ PythonJob::exec() bp::object runResult = entryPoint(); - //QString message = QString::fromStdString( bp::extract< std::string >( entryPoint() ) ); if ( runResult.is_none() ) { return JobResult::ok(); diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index 4e302e1b487340ca3b7f845cc03cfd65ae7a8bf1..d2532b6af8dd23e73c22b7d556b2b99d8aad480f 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -25,8 +25,9 @@ #include <QDir> #undef slots -#include <boost/python/extract.hpp> +#include <boost/python.hpp> +namespace bp = boost::python; namespace CalamaresPython { @@ -56,15 +57,15 @@ chroot_call( const std::string& command, int -chroot_call( const boost::python::list& args, +chroot_call( const bp::list& args, const std::string& stdin, int timeout ) { QStringList list; - for ( int i = 0; i < boost::python::len( args ); ++i ) + for ( int i = 0; i < bp::len( args ); ++i ) { list.append( QString::fromStdString( - boost::python::extract< std::string >( args[ i ] ) ) ); + bp::extract< std::string >( args[ i ] ) ) ); } return CalamaresUtils::chrootCall( list, @@ -73,6 +74,52 @@ chroot_call( const boost::python::list& args, } +int +check_chroot_call( const std::string& command, + const std::string& stdin, + int timeout ) +{ + int ec = chroot_call( command, stdin, timeout ); + return _handle_check_chroot_call_error( ec, QString::fromStdString( command ) ); +} + + +int +check_chroot_call( const bp::list& args, + const std::string& stdin, + int timeout ) +{ + int ec = chroot_call( args, stdin, timeout ); + if ( !ec ) + return ec; + + QStringList failedCmdList; + for ( int i = 0; i < bp::len( args ); ++i ) + { + failedCmdList.append( QString::fromStdString( + bp::extract< std::string >( args[ i ] ) ) ); + } + + return _handle_check_chroot_call_error( ec, failedCmdList.join( ' ' ) ); +} + + +int +_handle_check_chroot_call_error( int ec, const QString& cmd ) +{ + if ( !ec ) + return ec; + + QString raise = QString( "import subprocess\n" + "raise subprocess.CalledProcessError(%1,\"%2\")" ) + .arg( ec ) + .arg( cmd ); + bp::exec( raise.toStdString().c_str() ); + bp::throw_error_already_set(); + return ec; +} + + void debug( const std::string& s ) { @@ -97,5 +144,4 @@ PythonJobInterface::setprogress( qreal progress ) m_parent->emitProgress( progress ); } - } diff --git a/src/libcalamares/PythonJobApi.h b/src/libcalamares/PythonJobApi.h index 43c0657a0ab2a0aef1e66f73cc5ac1582b11e62e..96e0d5efaac17cc36f6e2f8972b2f8b2392778d0 100644 --- a/src/libcalamares/PythonJobApi.h +++ b/src/libcalamares/PythonJobApi.h @@ -42,6 +42,16 @@ int chroot_call( const boost::python::list& args, const std::string& stdin = std::string(), int timeout = 0 ); +int check_chroot_call( const std::string& command, + const std::string& stdin = std::string(), + int timeout = 0 ); + +int check_chroot_call( const boost::python::list& args, + const std::string& stdin = std::string(), + int timeout = 0 ); + +inline int _handle_check_chroot_call_error( int ec, const QString& cmd ); + void debug( const std::string& s ); class PythonJobInterface diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp index dc414c974ccbc99bc9733ff46b40a8f31c3318ad..1cfae4a46d66615f1bc793ce54c084aa52796b20 100644 --- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -60,8 +60,11 @@ int chrootCall( const QStringList& args, const QString& stdInput, int timeoutSec ) { + if ( !Calamares::JobQueue::instance() ) + return -3; + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); - if ( !gs->contains( "rootMountPoint" ) ) + if ( !gs || !gs->contains( "rootMountPoint" ) ) { cLog() << "No rootMountPoint in global storage"; return -3;