From 63534f71546e4e5b5e409d25cdae9efe0bbc4960 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Tue, 29 Jul 2014 20:18:02 +0200 Subject: [PATCH] Add mount and chrootCall utilities to libcalamares + Python wrappers. --- src/libcalamares/CMakeLists.txt | 1 + src/libcalamares/PythonJob.cpp | 58 ++++++++++- src/libcalamares/PythonJobApi.cpp | 46 +++++++++ src/libcalamares/PythonJobApi.h | 13 +++ .../utils/CalamaresUtilsSystem.cpp | 95 +++++++++++++++++++ src/libcalamares/utils/CalamaresUtilsSystem.h | 52 ++++++++++ 6 files changed, 262 insertions(+), 3 deletions(-) create mode 100644 src/libcalamares/utils/CalamaresUtilsSystem.cpp create mode 100644 src/libcalamares/utils/CalamaresUtilsSystem.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 98be31795..c92dabfd1 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -22,6 +22,7 @@ set( libSources kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp utils/CalamaresUtils.cpp + utils/CalamaresUtilsSystem.cpp utils/Logger.cpp ) diff --git a/src/libcalamares/PythonJob.cpp b/src/libcalamares/PythonJob.cpp index b314bbf52..455891336 100644 --- a/src/libcalamares/PythonJob.cpp +++ b/src/libcalamares/PythonJob.cpp @@ -27,13 +27,22 @@ #undef slots #include +#include #include "PythonJobApi.h" namespace bp = boost::python; - +BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, + CalamaresPython::mount, + 2, 4 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( chroot_call_str_overloads, + CalamaresPython::chroot_call, + 1, 3 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( chroot_call_list_overloads, + CalamaresPython::chroot_call, + 1, 3 ); BOOST_PYTHON_MODULE( libcalamares ) { bp::scope().attr( "ORGANIZATION_NAME" ) = CALAMARES_ORGANIZATION_NAME; @@ -42,8 +51,6 @@ BOOST_PYTHON_MODULE( libcalamares ) bp::scope().attr( "VERSION" ) = CALAMARES_VERSION; bp::scope().attr( "VERSION_SHORT" ) = CALAMARES_VERSION_SHORT; - bp::def( "debug", &CalamaresPython::debug ); - bp::class_< CalamaresPython::PythonJobInterface >( "Job", bp::init< Calamares::PythonJob* >() ) .def_readonly( "module_name", &CalamaresPython::PythonJobInterface::moduleName ) .def_readonly( "pretty_name", &CalamaresPython::PythonJobInterface::prettyName ) @@ -58,6 +65,51 @@ BOOST_PYTHON_MODULE( libcalamares ) .def( "keys", &Calamares::GlobalStorage::python_keys ) .def( "remove", &Calamares::GlobalStorage::python_remove ) .def( "value", &Calamares::GlobalStorage::python_value ); + + // libcalamares.utils submodule starts here + bp::object submodule( bp::borrowed( PyImport_AddModule( "utils" ) ) ); + bp::scope().attr( "utils" ) = submodule; + bp::scope utilsScope = submodule; + 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" ) ); } diff --git a/src/libcalamares/PythonJobApi.cpp b/src/libcalamares/PythonJobApi.cpp index feb05b1c8..af972082a 100644 --- a/src/libcalamares/PythonJobApi.cpp +++ b/src/libcalamares/PythonJobApi.cpp @@ -20,12 +20,57 @@ #include "PythonHelper.h" #include "utils/Logger.h" +#include "utils/CalamaresUtilsSystem.h" #include +#undef slots +#include + + namespace CalamaresPython { +int +mount( const std::string& device_path, + const std::string& mount_point, + const std::string& filesystem_name, + const std::string& options ) +{ + return CalamaresUtils::mount( QString::fromStdString( device_path ), + QString::fromStdString( mount_point ), + QString::fromStdString( filesystem_name ), + QString::fromStdString( options ) ); +} + + +int +chroot_call( const std::string& command, + const std::string& stdin, + int timeout ) +{ + return CalamaresUtils::chrootCall( QString::fromStdString( command ), + QString::fromStdString( stdin ), + timeout ); +} + + +int +chroot_call( const boost::python::list& args, + const std::string& stdin, + int timeout ) +{ + QStringList list; + for ( int i = 0; i < boost::python::len( args ); ++i ) + { + list.append( QString::fromStdString( + boost::python::extract< std::string >( args[ i ] ) ) ); + } + return CalamaresUtils::chrootCall( list.join( ' ' ), + QString::fromStdString( stdin ), + timeout ); +} + void debug( const std::string& s ) @@ -51,4 +96,5 @@ PythonJobInterface::setprogress( qreal progress ) m_parent->emitProgress( progress ); } + } diff --git a/src/libcalamares/PythonJobApi.h b/src/libcalamares/PythonJobApi.h index a0fadb239..43c0657a0 100644 --- a/src/libcalamares/PythonJobApi.h +++ b/src/libcalamares/PythonJobApi.h @@ -29,6 +29,19 @@ namespace CalamaresPython { +int mount( const std::string& device_path, + const std::string& mount_point, + const std::string& filesystem_name = std::string(), + const std::string& options = std::string() ); + +int chroot_call( const std::string& command, + const std::string& stdin = std::string(), + int timeout = 0 ); + +int chroot_call( const boost::python::list& args, + const std::string& stdin = std::string(), + int timeout = 0 ); + void debug( const std::string& s ); class PythonJobInterface diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp new file mode 100644 index 000000000..86115293f --- /dev/null +++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp @@ -0,0 +1,95 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Teo Mrnjavac + * + * 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 . + */ + +#include "CalamaresUtilsSystem.h" + +#include "JobQueue.h" +#include "GlobalStorage.h" + +#include +#include + +namespace CalamaresUtils +{ + +int mount( const QString& devicePath, + const QString& mountPoint, + const QString& filesystemName, + const QString& options ) +{ + if ( devicePath.isEmpty() || mountPoint.isEmpty() ) + return -3; + + QDir mountPointDir( mountPoint ); + if ( !mountPointDir.exists() ) + { + bool ok = mountPointDir.mkpath( mountPoint ); + if ( !ok ) + return -3; + } + + QString program( "mount" ); + QStringList args = { devicePath, mountPoint }; + + if ( !filesystemName.isEmpty() ) + args << "-t" << filesystemName; + + if ( !options.isEmpty() ) + args << "-o" << options; + + return QProcess::execute( program, args ); +} + +int chrootCall( const QString& command, + const QString& stdInput, + int timeoutSec ) +{ + Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage(); + if ( !gs->contains( "rootMountPoint" ) ) + return -3; + + QString destDir = gs->value( "rootMountPoint" ).toString(); + if ( !QDir( destDir ).exists() ) + return -3; + + QString program( "chroot" ); + QStringList args = { destDir, command }; + + QProcess process; + process.setProgram( program ); + process.setArguments( args ); + + if ( !process.waitForStarted() ) + return -2; + + if ( !stdInput.isEmpty() ) + { + process.write( stdInput.toLocal8Bit() ); + process.closeWriteChannel(); + } + + if ( !process.waitForFinished( timeoutSec ? ( timeoutSec * 1000 ) : 30000 ) ) + return -4; + + if ( process.exitStatus() == QProcess::CrashExit ) + return -1; + + return process.exitCode(); +} + +} diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.h b/src/libcalamares/utils/CalamaresUtilsSystem.h new file mode 100644 index 000000000..d268892b0 --- /dev/null +++ b/src/libcalamares/utils/CalamaresUtilsSystem.h @@ -0,0 +1,52 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014, Teo Mrnjavac + * + * 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 . + */ +#ifndef CALAMARESUTILSSYSTEM_H +#define CALAMARESUTILSSYSTEM_H + +#include "DllMacro.h" + +#include + +namespace CalamaresUtils +{ +/** + * Runs the mount utility with the specified parameters. + * @returns the program's exit code, or: + * -1 = QProcess crash + * -2 = QProcess cannot start + * -3 = bad arguments + */ +DLLEXPORT int mount( const QString& devicePath, + const QString& mountPoint, + const QString& filesystemName = QString(), + const QString& options = QString() ); + +/** + * Runs the specified command in the chroot of the target system. + * @returns the program's exit code, or: + * -1 = QProcess crash + * -2 = QProcess cannot start + * -3 = bad arguments + * -4 = QProcess timeout + */ +DLLEXPORT int chrootCall( const QString& command, + const QString& stdInput = QString(), + int timeoutSec = 0 ); +} + +#endif // CALAMARESUTILSSYSTEM_H