We have a Python API for jobmodules!
Created a Boost.Python module interface in libcalamares. Added a PythonJob wrapper and exposed it in the Python module. Rename target calamareslib ==> calamares so in Python it's libcalamares. Python-related classes in libcalamares that aren't exported as C++ symbols are now in a CalamaresPrivate namespace. Import the libcalamares python module into every Python script before running it. Added Python error handling to PythonJobHelper. Added some more testing code to dummypython module.
This commit is contained in:
parent
c13179fdf0
commit
a61a36d99d
@ -53,7 +53,7 @@ endif()
|
|||||||
###
|
###
|
||||||
### Calamares application info
|
### Calamares application info
|
||||||
###
|
###
|
||||||
set( CALAMARES_ORGANIZATION_NAME "The Calamares Team" )
|
set( CALAMARES_ORGANIZATION_NAME "Calamares" )
|
||||||
set( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
|
set( CALAMARES_ORGANIZATION_DOMAIN "github.com/calamares" )
|
||||||
set( CALAMARES_APPLICATION_NAME "Calamares" )
|
set( CALAMARES_APPLICATION_NAME "Calamares" )
|
||||||
set( CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework" )
|
set( CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framework" )
|
||||||
@ -108,7 +108,7 @@ file( COPY CalamaresAddLibrary.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
|
|||||||
file( COPY CalamaresAddModuleSubdirectory.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
|
file( COPY CalamaresAddModuleSubdirectory.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
|
||||||
file( COPY CalamaresAddPlugin.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
|
file( COPY CalamaresAddPlugin.cmake DESTINATION "${PROJECT_BINARY_DIR}" )
|
||||||
|
|
||||||
set( CALAMARES_LIBRARIES calamareslib )
|
set( CALAMARES_LIBRARIES calamares )
|
||||||
|
|
||||||
add_subdirectory( src )
|
add_subdirectory( src )
|
||||||
add_subdirectory( tests )
|
add_subdirectory( tests )
|
||||||
@ -118,8 +118,8 @@ macro_display_feature_log()
|
|||||||
# Add all targets to the build-tree export set
|
# Add all targets to the build-tree export set
|
||||||
set( CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files" )
|
set( CMAKE_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Calamares" CACHE PATH "Installation directory for CMake files" )
|
||||||
set( CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}" )
|
set( CMAKE_INSTALL_FULL_CMAKEDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}" )
|
||||||
export(TARGETS calamareslib
|
export( TARGETS calamares
|
||||||
FILE "${PROJECT_BINARY_DIR}/CalamaresLibraryDepends.cmake")
|
FILE "${PROJECT_BINARY_DIR}/CalamaresLibraryDepends.cmake" )
|
||||||
|
|
||||||
# Export the package for use from the build-tree
|
# Export the package for use from the build-tree
|
||||||
# (this registers the build-tree with a global CMake-registry)
|
# (this registers the build-tree with a global CMake-registry)
|
||||||
|
@ -17,5 +17,5 @@ endif()
|
|||||||
include("${CALAMARES_CMAKE_DIR}/CalamaresLibraryDepends.cmake")
|
include("${CALAMARES_CMAKE_DIR}/CalamaresLibraryDepends.cmake")
|
||||||
|
|
||||||
# These are IMPORTED targets created by CalamaresLibraryDepends.cmake
|
# These are IMPORTED targets created by CalamaresLibraryDepends.cmake
|
||||||
set(CALAMARES_LIBRARIES calamareslib)
|
set(CALAMARES_LIBRARIES calamares)
|
||||||
set(CALAMARES_USE_FILE "${CALAMARES_CMAKE_DIR}/CalamaresUse.cmake")
|
set(CALAMARES_USE_FILE "${CALAMARES_CMAKE_DIR}/CalamaresUse.cmake")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
project( calamareslib )
|
project( libcalamares )
|
||||||
|
|
||||||
add_definitions( ${QT_DEFINITIONS} )
|
add_definitions( ${QT_DEFINITIONS} )
|
||||||
add_definitions( -DQT_SHARED )
|
add_definitions( -DQT_SHARED )
|
||||||
@ -36,6 +36,7 @@ if( WITH_PYTHON )
|
|||||||
set( libSources
|
set( libSources
|
||||||
${libSources}
|
${libSources}
|
||||||
PythonJob.cpp
|
PythonJob.cpp
|
||||||
|
PythonJobApi.cpp
|
||||||
PythonJobHelper.cpp
|
PythonJobHelper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -53,19 +54,18 @@ if( WITH_PYTHON )
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
add_library( calamareslib SHARED ${libSources} )
|
add_library( calamares SHARED ${libSources} )
|
||||||
set_target_properties( calamareslib
|
set_target_properties( calamares
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
AUTOMOC TRUE
|
AUTOMOC TRUE
|
||||||
VERSION ${CALAMARES_VERSION_SHORT}
|
VERSION ${CALAMARES_VERSION_SHORT}
|
||||||
SOVERSION ${CALAMARES_VERSION_SHORT}
|
SOVERSION ${CALAMARES_VERSION_SHORT}
|
||||||
OUTPUT_NAME "calamares"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
qt5_use_modules( calamareslib Core )
|
qt5_use_modules( calamares Core )
|
||||||
|
|
||||||
|
|
||||||
target_link_libraries( calamareslib
|
target_link_libraries( calamares
|
||||||
LINK_PRIVATE
|
LINK_PRIVATE
|
||||||
# internal deps, if any
|
# internal deps, if any
|
||||||
${OPTIONAL_PRIVATE_LIBRARIES}
|
${OPTIONAL_PRIVATE_LIBRARIES}
|
||||||
@ -75,7 +75,7 @@ target_link_libraries( calamareslib
|
|||||||
Qt5::Core
|
Qt5::Core
|
||||||
)
|
)
|
||||||
|
|
||||||
install( TARGETS calamareslib
|
install( TARGETS calamares
|
||||||
EXPORT CalamaresLibraryDepends
|
EXPORT CalamaresLibraryDepends
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
, m_queue( queue )
|
, m_queue( queue )
|
||||||
{
|
{
|
||||||
#ifdef WITH_PYTHON
|
#ifdef WITH_PYTHON
|
||||||
new PythonJobHelper( this );
|
new CalamaresPrivate::PythonJobHelper( this );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,26 @@
|
|||||||
#undef slots
|
#undef slots
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
|
#include "PythonJobApi.h"
|
||||||
|
|
||||||
|
|
||||||
namespace bp = boost::python;
|
namespace bp = boost::python;
|
||||||
|
|
||||||
|
|
||||||
|
BOOST_PYTHON_MODULE( libcalamares )
|
||||||
|
{
|
||||||
|
bp::scope().attr( "ORGANIZATION_NAME" ) = CALAMARES_ORGANIZATION_NAME;
|
||||||
|
bp::scope().attr( "ORGANIZATION_DOMAIN" ) = CALAMARES_ORGANIZATION_DOMAIN;
|
||||||
|
bp::scope().attr( "APPLICATION_NAME" ) = CALAMARES_APPLICATION_NAME;
|
||||||
|
bp::scope().attr( "VERSION" ) = CALAMARES_VERSION;
|
||||||
|
bp::scope().attr( "VERSION_SHORT" ) = CALAMARES_VERSION_SHORT;
|
||||||
|
|
||||||
|
bp::class_< CalamaresPrivate::PythonJobInterface >( "job", bp::init< const Calamares::PythonJob* >() )
|
||||||
|
.def( "prettyName", &CalamaresPrivate::PythonJobInterface::prettyName )
|
||||||
|
.def( "workingPath", &CalamaresPrivate::PythonJobInterface::workingPath );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace Calamares {
|
namespace Calamares {
|
||||||
|
|
||||||
|
|
||||||
@ -84,6 +102,11 @@ PythonJob::exec()
|
|||||||
{
|
{
|
||||||
bp::object scriptNamespace = helper()->createCleanNamespace();
|
bp::object scriptNamespace = helper()->createCleanNamespace();
|
||||||
|
|
||||||
|
bp::object calamaresModule = bp::import( "libcalamares" );
|
||||||
|
bp::dict calamaresNamespace = bp::extract< bp::dict >( calamaresModule.attr( "__dict__" ) );
|
||||||
|
|
||||||
|
calamaresNamespace[ "job" ] = CalamaresPrivate::PythonJobInterface( this );
|
||||||
|
|
||||||
bp::object result = bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(),
|
bp::object result = bp::exec_file( scriptFI.absoluteFilePath().toLocal8Bit().data(),
|
||||||
scriptNamespace,
|
scriptNamespace,
|
||||||
scriptNamespace );
|
scriptNamespace );
|
||||||
@ -94,19 +117,28 @@ PythonJob::exec()
|
|||||||
|
|
||||||
cDebug() << "Python job" << prettyName() << "finished with message" << message;
|
cDebug() << "Python job" << prettyName() << "finished with message" << message;
|
||||||
}
|
}
|
||||||
catch ( bp::error_already_set e )
|
catch ( bp::error_already_set )
|
||||||
{
|
{
|
||||||
return JobResult::error( tr( "Boost.Python error" ) );
|
QString msg;
|
||||||
|
if ( PyErr_Occurred() )
|
||||||
|
{
|
||||||
|
msg = helper()->handleLastError();
|
||||||
|
}
|
||||||
|
bp::handle_exception();
|
||||||
|
PyErr_Clear();
|
||||||
|
return JobResult::error( tr( "Boost.Python error" ),
|
||||||
|
msg );
|
||||||
}
|
}
|
||||||
|
|
||||||
return JobResult::ok();
|
return JobResult::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PythonJobHelper*
|
CalamaresPrivate::PythonJobHelper*
|
||||||
PythonJob::helper()
|
PythonJob::helper()
|
||||||
{
|
{
|
||||||
return PythonJobHelper::s_instance;
|
return CalamaresPrivate::PythonJobHelper::s_instance;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,9 +21,13 @@
|
|||||||
|
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
|
|
||||||
namespace Calamares {
|
namespace CalamaresPrivate
|
||||||
|
{
|
||||||
|
class PythonJobInterface;
|
||||||
class PythonJobHelper;
|
class PythonJobHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Calamares {
|
||||||
|
|
||||||
class PythonJob : public Job
|
class PythonJob : public Job
|
||||||
{
|
{
|
||||||
@ -38,8 +42,9 @@ public:
|
|||||||
JobResult exec() override;
|
JobResult exec() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class PythonJobHelper;
|
friend class CalamaresPrivate::PythonJobHelper;
|
||||||
PythonJobHelper* helper();
|
friend class CalamaresPrivate::PythonJobInterface;
|
||||||
|
CalamaresPrivate::PythonJobHelper* helper();
|
||||||
QString m_scriptFile;
|
QString m_scriptFile;
|
||||||
QString m_workingPath;
|
QString m_workingPath;
|
||||||
};
|
};
|
||||||
|
42
src/libcalamares/PythonJobApi.cpp
Normal file
42
src/libcalamares/PythonJobApi.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014, 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 "PythonJobApi.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace CalamaresPrivate
|
||||||
|
{
|
||||||
|
|
||||||
|
PythonJobInterface::PythonJobInterface( const Calamares::PythonJob* parent )
|
||||||
|
: m_parent( parent )
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
PythonJobInterface::prettyName() const
|
||||||
|
{
|
||||||
|
return m_parent->prettyName().toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
PythonJobInterface::workingPath() const
|
||||||
|
{
|
||||||
|
return m_parent->m_workingPath.toStdString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
44
src/libcalamares/PythonJobApi.h
Normal file
44
src/libcalamares/PythonJobApi.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2014, 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PYTHONJOBAPI_H
|
||||||
|
#define PYTHONJOBAPI_H
|
||||||
|
|
||||||
|
#include "CalamaresVersion.h"
|
||||||
|
|
||||||
|
#include "PythonJob.h"
|
||||||
|
|
||||||
|
namespace CalamaresPrivate
|
||||||
|
{
|
||||||
|
|
||||||
|
class PythonJobInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PythonJobInterface( const Calamares::PythonJob* parent );
|
||||||
|
|
||||||
|
std::string prettyName() const;
|
||||||
|
|
||||||
|
std::string workingPath() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Calamares::PythonJob* m_parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PYTHONJOBAPI_H
|
@ -18,13 +18,18 @@
|
|||||||
|
|
||||||
#include "PythonJobHelper.h"
|
#include "PythonJobHelper.h"
|
||||||
|
|
||||||
|
#include "utils/CalamaresUtils.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
#undef slots
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
|
||||||
namespace bp = boost::python;
|
namespace bp = boost::python;
|
||||||
|
|
||||||
namespace Calamares {
|
namespace CalamaresPrivate {
|
||||||
|
|
||||||
PythonJobHelper* PythonJobHelper::s_instance = nullptr;
|
PythonJobHelper* PythonJobHelper::s_instance = nullptr;
|
||||||
|
|
||||||
@ -38,6 +43,34 @@ PythonJobHelper::PythonJobHelper( QObject* parent )
|
|||||||
|
|
||||||
m_mainModule = bp::import( "__main__" );
|
m_mainModule = bp::import( "__main__" );
|
||||||
m_mainNamespace = m_mainModule.attr( "__dict__" );
|
m_mainNamespace = m_mainModule.attr( "__dict__" );
|
||||||
|
|
||||||
|
// If we're running from the build dir
|
||||||
|
QFileInfo fi( QDir::current().absoluteFilePath( "libcalamares.so" ) );
|
||||||
|
if ( fi.exists() && fi.isReadable() )
|
||||||
|
{
|
||||||
|
m_pythonPaths.append( fi.dir().absolutePath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir calaPythonPath( CalamaresUtils::systemLibDir().absolutePath() +
|
||||||
|
QDir::separator() + "calamares" );
|
||||||
|
if ( calaPythonPath.exists() &&
|
||||||
|
calaPythonPath.isReadable() )
|
||||||
|
{
|
||||||
|
QFileInfo fi( calaPythonPath.absoluteFilePath( "libcalamares.so" ) );
|
||||||
|
if ( fi.exists() && fi.isReadable() )
|
||||||
|
{
|
||||||
|
m_pythonPaths.append( fi.dir().absolutePath() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bp::object sys = bp::import( "sys" );
|
||||||
|
|
||||||
|
foreach ( QString path, m_pythonPaths )
|
||||||
|
{
|
||||||
|
bp::str dir = path.toLocal8Bit().data();
|
||||||
|
sys.attr( "path" ).attr( "append" )( dir );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -64,4 +97,27 @@ PythonJobHelper::createCleanNamespace()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QString
|
||||||
|
PythonJobHelper::handleLastError()
|
||||||
|
{
|
||||||
|
using namespace boost::python;
|
||||||
|
using namespace boost;
|
||||||
|
|
||||||
|
PyObject *exc,*val,*tb;
|
||||||
|
object formatted_list, formatted;
|
||||||
|
PyErr_Fetch(&exc,&val,&tb);
|
||||||
|
handle<> hexc(exc),hval(allow_null(val)),htb(allow_null(tb));
|
||||||
|
object traceback(import("traceback"));
|
||||||
|
if (!tb) {
|
||||||
|
object format_exception_only(traceback.attr("format_exception_only"));
|
||||||
|
formatted_list = format_exception_only(hexc,hval);
|
||||||
|
} else {
|
||||||
|
object format_exception(traceback.attr("format_exception"));
|
||||||
|
formatted_list = format_exception(hexc,hval,htb);
|
||||||
|
}
|
||||||
|
formatted = str("\n").join(formatted_list);
|
||||||
|
return QString::fromStdString( extract<std::string>(formatted) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
|
|
||||||
#include "PythonJob.h"
|
#include "PythonJob.h"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
#undef slots
|
#undef slots
|
||||||
#include <boost/python/object.hpp>
|
#include <boost/python/object.hpp>
|
||||||
|
|
||||||
namespace Calamares {
|
namespace CalamaresPrivate {
|
||||||
|
|
||||||
class PythonJobHelper : public QObject
|
class PythonJobHelper : public QObject
|
||||||
{
|
{
|
||||||
@ -35,12 +37,16 @@ public:
|
|||||||
|
|
||||||
boost::python::object createCleanNamespace();
|
boost::python::object createCleanNamespace();
|
||||||
|
|
||||||
|
QString handleLastError();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend PythonJobHelper* PythonJob::helper();
|
friend PythonJobHelper* Calamares::PythonJob::helper();
|
||||||
static PythonJobHelper* s_instance;
|
static PythonJobHelper* s_instance;
|
||||||
|
|
||||||
boost::python::object m_mainModule;
|
boost::python::object m_mainModule;
|
||||||
boost::python::object m_mainNamespace;
|
boost::python::object m_mainNamespace;
|
||||||
|
|
||||||
|
QStringList m_pythonPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Calamares
|
} // namespace Calamares
|
||||||
|
@ -16,9 +16,16 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import libcalamares
|
||||||
import os
|
import os
|
||||||
from time import gmtime, strftime
|
from time import gmtime, strftime
|
||||||
|
|
||||||
def calamares_main():
|
def calamares_main():
|
||||||
os.system( "/bin/sh -c \"touch ~/calamares-dummypython\"" )
|
os.system( "/bin/sh -c \"touch ~/calamares-dummypython\"" )
|
||||||
return strftime( "%Y-%m-%d %H:%M:%S", gmtime() )
|
accumulator = strftime( "%Y-%m-%d %H:%M:%S", gmtime() ) + "\n"
|
||||||
|
accumulator += "Calamares version: " + libcalamares.VERSION_SHORT + "\n"
|
||||||
|
accumulator += "This job's name: " + libcalamares.job.prettyName() + "\n"
|
||||||
|
accumulator += "This job's path: " + libcalamares.job.workingPath() + "\n"
|
||||||
|
return accumulator
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user