commit solid for openSUSE:Factory
Hello community, here is the log from the commit of package solid for openSUSE:Factory checked in at 2014-04-02 17:22:33 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/solid (Old) and /work/SRC/openSUSE:Factory/.solid.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "solid" Changes: -------- --- /work/SRC/openSUSE:Factory/solid/solid.changes 2014-03-10 12:17:37.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.solid.new/solid.changes 2014-04-02 17:22:47.000000000 +0200 @@ -1,0 +2,9 @@ +Sat Mar 29 19:47:55 UTC 2014 - hrvoje.senjan@gmail.com + +- Update to 4.98.0 + * API improvements and cleanups + * Buildsystem fixes + * For more details please see: + http://www.kde.org/announcements/announce-frameworks5-beta1.php + +------------------------------------------------------------------- Old: ---- solid-4.97.0.tar.xz New: ---- solid-4.98.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ solid.spec ++++++ --- /var/tmp/diff_new_pack.LukpS3/_old 2014-04-02 17:22:48.000000000 +0200 +++ /var/tmp/diff_new_pack.LukpS3/_new 2014-04-02 17:22:48.000000000 +0200 @@ -18,11 +18,11 @@ %define lname libKF5Solid5 Name: solid -Version: 4.97.0 +Version: 4.98.0 Release: 0 BuildRequires: bison BuildRequires: cmake >= 2.8.12 -BuildRequires: extra-cmake-modules >= 0.0.11 +BuildRequires: extra-cmake-modules >= 0.0.12 BuildRequires: fdupes BuildRequires: flex BuildRequires: kf5-filesystem @@ -74,6 +74,9 @@ %install %kf5_makeinstall -C build + pushd %{buildroot}%{_kf5_bindir} + mv solid-hardware solid-hardware2 + popd %fdupes -s %{buildroot} %post -n %lname -p /sbin/ldconfig @@ -83,6 +86,7 @@ %files -n %lname %defattr(-,root,root) %doc COPYING* +%{_kf5_bindir}/solid-hardware2 %{_kf5_libdir}/libKF5Solid.so.* %{_kf5_qmldir}/ ++++++ solid-4.97.0.tar.xz -> solid-4.98.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/CMakeLists.txt new/solid-4.98.0/CMakeLists.txt --- old/solid-4.97.0/CMakeLists.txt 2014-03-01 12:51:52.000000000 +0100 +++ new/solid-4.98.0/CMakeLists.txt 2014-03-28 19:17:47.000000000 +0100 @@ -3,7 +3,7 @@ project(Solid) -find_package(ECM 0.0.11 REQUIRED NO_MODULE) +find_package(ECM 0.0.12 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake) @@ -23,6 +23,7 @@ include(ECMPackageConfigHelpers) include(ECMSetupVersion) include(ECMGenerateHeaders) +include(ECMMarkNonGuiExecutable) if(NOT APPLE) find_package(HUpnp 0.9) @@ -67,7 +68,7 @@ ############### Give the user the option to build the deprecated WMI solid backend instead of the new win backend ############### option(WITH_SOLID_WMI "Enables the deprecated WMI backend on Windows") -set(KF5_VERSION "4.97.0") +set(KF5_VERSION "4.98.0") ecm_setup_version(${KF5_VERSION} VARIABLE_PREFIX SOLID VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/solid_version.h" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/CMakeLists.txt new/solid-4.98.0/src/CMakeLists.txt --- old/solid-4.97.0/src/CMakeLists.txt 2014-03-01 12:51:52.000000000 +0100 +++ new/solid-4.98.0/src/CMakeLists.txt 2014-03-28 19:17:47.000000000 +0100 @@ -1,2 +1,3 @@ add_subdirectory(solid) +add_subdirectory(tools) add_subdirectory(imports) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/tools/CMakeLists.txt new/solid-4.98.0/src/tools/CMakeLists.txt --- old/solid-4.97.0/src/tools/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/solid-4.98.0/src/tools/CMakeLists.txt 2014-03-28 19:17:47.000000000 +0100 @@ -0,0 +1 @@ +add_subdirectory(solid-hardware) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/tools/solid-hardware/CMakeLists.txt new/solid-4.98.0/src/tools/solid-hardware/CMakeLists.txt --- old/solid-4.97.0/src/tools/solid-hardware/CMakeLists.txt 1970-01-01 01:00:00.000000000 +0100 +++ new/solid-4.98.0/src/tools/solid-hardware/CMakeLists.txt 2014-03-28 19:17:47.000000000 +0100 @@ -0,0 +1,7 @@ +add_executable(solid-hardware solid-hardware.cpp) +ecm_mark_nongui_executable(solid-hardware) +target_link_libraries(solid-hardware KF5::Solid) +install(TARGETS solid-hardware ${INSTALL_TARGETS_DEFAULT_ARGS}) + + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/tools/solid-hardware/Messages.sh new/solid-4.98.0/src/tools/solid-hardware/Messages.sh --- old/solid-4.97.0/src/tools/solid-hardware/Messages.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/solid-4.98.0/src/tools/solid-hardware/Messages.sh 2014-03-28 19:17:47.000000000 +0100 @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT solid-hardware.cpp -o $podir/solid-hardware.pot diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/tools/solid-hardware/solid-hardware.cpp new/solid-4.98.0/src/tools/solid-hardware/solid-hardware.cpp --- old/solid-4.97.0/src/tools/solid-hardware/solid-hardware.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/solid-4.98.0/src/tools/solid-hardware/solid-hardware.cpp 2014-03-28 19:17:47.000000000 +0100 @@ -0,0 +1,440 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens <ervin@kde.org> + Copyright (C) 2014 Alejandro Fiestas Olivares <afiestas@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "solid-hardware.h" + + +#include <QString> +#include <QStringList> +#include <QMetaProperty> +#include <QMetaEnum> +#include <QTimer> + +#include <QCoreApplication> +#include <QCommandLineParser> + +#include <solid/device.h> +#include <solid/genericinterface.h> +#include <solid/storageaccess.h> +#include <solid/opticaldrive.h> + +#include <iostream> +#include <solid/devicenotifier.h> +using namespace std; + +static const char appName[] = "solid-hardware"; + +static const char version[] = "0.1a"; + +std::ostream &operator<<(std::ostream &out, const QString &msg) +{ + return (out << msg.toLocal8Bit().constData()); +} + +std::ostream &operator<<(std::ostream &out, const QVariant &value) +{ + switch (value.type()) + { + case QVariant::StringList: + { + out << "{"; + + const QStringList list = value.toStringList(); + + QStringList::ConstIterator it = list.constBegin(); + QStringList::ConstIterator end = list.constEnd(); + + for (; it!=end; ++it) + { + out << "'" << *it << "'"; + + if (it+1!=end) + { + out << ", "; + } + } + + out << "} (string list)"; + break; + } + case QVariant::Bool: + out << (value.toBool()?"true":"false") << " (bool)"; + break; + case QVariant::Int: + case QVariant::LongLong: + out << value.toString() + << " (0x" << QString::number(value.toLongLong(), 16) << ") (" << QVariant::typeToName(value.type()) << ")"; + break; + case QVariant::UInt: + case QVariant::ULongLong: + out << value.toString() + << " (0x" << QString::number(value.toULongLong(), 16) << ") (" << QVariant::typeToName(value.type()) << ")"; + break; + case QVariant::UserType: + { + //qDebug() << "got variant type:" << value.typeName(); + if (value.canConvert<QList<int> >()) + { + QList<int> intlist = value.value<QList<int> >(); + QStringList tmp; + foreach (int val, intlist) + tmp.append(QString::number(val)); + out << "{" << tmp.join(",") << "} (int list)"; + } + break; + } + default: + out << "'" << value.toString() << "' (string)"; + break; + } + + return out; +} + +std::ostream &operator<<(std::ostream &out, const Solid::Device &device) +{ + out << " parent = " << QVariant(device.parentUdi()) << endl; + out << " vendor = " << QVariant(device.vendor()) << endl; + out << " product = " << QVariant(device.product()) << endl; + out << " description = " << QVariant(device.description()) << endl; + + int index = Solid::DeviceInterface::staticMetaObject.indexOfEnumerator("Type"); + QMetaEnum typeEnum = Solid::DeviceInterface::staticMetaObject.enumerator(index); + + for (int i=0; i<typeEnum.keyCount(); i++) + { + Solid::DeviceInterface::Type type = (Solid::DeviceInterface::Type)typeEnum.value(i); + const Solid::DeviceInterface *interface = device.asDeviceInterface(type); + + if (interface) + { + const QMetaObject *meta = interface->metaObject(); + + for (int i=meta->propertyOffset(); i<meta->propertyCount(); i++) + { + QMetaProperty property = meta->property(i); + out << " " << QString(meta->className()).mid(7) << "." << property.name() + << " = "; + + QVariant value = property.read(interface); + + if (property.isEnumType()) { + QMetaEnum metaEnum = property.enumerator(); + if (metaEnum.isFlag()) { + out << "'" << metaEnum.valueToKeys(value.toInt()).constData() << "'" + << " (0x" << QString::number(value.toInt(), 16) << ") (flag)"; + } else { + out << "'" << metaEnum.valueToKey(value.toInt()) << "'" + << " (0x" << QString::number(value.toInt(), 16) << ") (enum)"; + } + out << endl; + } else { + out << value << endl; + } + } + } + } + + return out; +} + +std::ostream &operator<<(std::ostream &out, const QMap<QString,QVariant> &properties) +{ + Q_FOREACH (const QString &key, properties.keys()) + { + out << " " << key << " = " << properties[key] << endl; + } + + return out; +} + +QString getUdiFromArguments(QCoreApplication &app, QCommandLineParser &parser) +{ + parser.addPositionalArgument("udi", app.tr("Device udi")); + parser.process(app); + if (parser.positionalArguments().count() < 2) { + parser.showHelp(1); + } + return parser.positionalArguments().at(1); +} + +int main(int argc, char **argv) +{ + SolidHardware app(argc, argv); + app.setApplicationName(appName); + app.setApplicationVersion(version); + + QCommandLineParser parser; + parser.setApplicationDescription(app.tr("KDE tool for querying your hardware from the command line")); + parser.addHelpOption(); + parser.addVersionOption(); + parser.addPositionalArgument("command", app.tr("Command to execute")); + + QCommandLineOption commands("commands", app.tr("Show available commands")); + parser.addOption(commands); + + parser.process(app); + if (parser.isSet(commands)) + { + cout << endl << app.tr("Syntax:") << endl << endl; + + cout << " solid-hardware list [details|nonportableinfo]" << endl; + cout << app.tr(" # List the hardware available in the system.\n" + " # - If the 'nonportableinfo' option is specified, the device\n" + " # properties are listed (be careful, in this case property names\n" + " # are backend dependent),\n" + " # - If the 'details' option is specified, the device interfaces\n" + " # and the corresponding properties are listed in a platform\n" + " # neutral fashion,\n" + " # - Otherwise only device UDIs are listed.\n") << endl; + + cout << " solid-hardware details 'udi'" << endl; + cout << app.tr(" # Display all the interfaces and properties of the device\n" + " # corresponding to 'udi' in a platform neutral fashion.\n") << endl; + + cout << " solid-hardware nonportableinfo 'udi'" << endl; + cout << app.tr(" # Display all the properties of the device corresponding to 'udi'\n" + " # (be careful, in this case property names are backend dependent).\n") << endl; + + cout << " solid-hardware query 'predicate' ['parentUdi']" << endl; + cout << app.tr(" # List the UDI of devices corresponding to 'predicate'.\n" + " # - If 'parentUdi' is specified, the search is restricted to the\n" + " # branch of the corresponding device,\n" + " # - Otherwise the search is done on all the devices.\n") << endl; + + cout << " solid-hardware mount 'udi'" << endl; + cout << app.tr(" # If applicable, mount the device corresponding to 'udi'.\n") << endl; + + cout << " solid-hardware unmount 'udi'" << endl; + cout << app.tr(" # If applicable, unmount the device corresponding to 'udi'.\n") << endl; + + cout << " solid-hardware eject 'udi'" << endl; + cout << app.tr(" # If applicable, eject the device corresponding to 'udi'.\n") << endl; + + cout << " solid-hardware listen" << endl; + cout << app.tr(" # Listen to all add/remove events on supported hardware.") << endl; + + return 0; + } + + QStringList args = parser.positionalArguments(); + if (args.count() < 1) { + parser.showHelp(1); + } + + parser.clearPositionalArguments(); + + QString command(args.at(0)); + + if (command == "list") + { + parser.addPositionalArgument("details", app.tr("Show device details")); + parser.addPositionalArgument("nonportableinfo", app.tr("Show non portable information")); + parser.process(app); + args = parser.positionalArguments(); + QByteArray extra(args.count() == 2 ? args.at(1).toLocal8Bit() : ""); + return app.hwList(extra == "details", extra == "nonportableinfo"); + } else if (command == "details") { + const QString udi = getUdiFromArguments(app, parser); + return app.hwCapabilities(udi); + } else if (command == "nonportableinfo") { + const QString udi = getUdiFromArguments(app, parser); + return app.hwProperties(udi); + } else if (command == "query") { + parser.addPositionalArgument("udi", app.tr("Device udi")); + parser.addPositionalArgument("parent", app.tr("Parent device udi")); + parser.process(app); + if (parser.positionalArguments().count() < 2 || parser.positionalArguments().count() > 3) { + parser.showHelp(1); + } + + QString query = args.at(1); + QString parent; + + if (args.count() == 3) + { + parent = args.at(2); + } + + return app.hwQuery(parent, query); + } else if (command == "mount") { + const QString udi = getUdiFromArguments(app, parser); + return app.hwVolumeCall(SolidHardware::Mount, udi); + } else if (command == "unmount") { + const QString udi = getUdiFromArguments(app, parser); + return app.hwVolumeCall(SolidHardware::Unmount, udi); + } else if (command == "eject") { + const QString udi = getUdiFromArguments(app, parser); + return app.hwVolumeCall(SolidHardware::Eject, udi); + } else if (command == "listen") { + return app.listen(); + } + + cerr << app.tr("Syntax Error: Unknown command '%1'").arg(command) << endl; + + return 1; +} + +bool SolidHardware::hwList(bool interfaces, bool system) +{ + const QList<Solid::Device> all = Solid::Device::allDevices(); + + Q_FOREACH (const Solid::Device &device, all) + { + cout << "udi = '" << device.udi() << "'" << endl; + + if (interfaces) + { + cout << device << endl; + } + else if (system && device.is<Solid::GenericInterface>()) + { + QMap<QString,QVariant> properties = device.as<Solid::GenericInterface>()->allProperties(); + cout << properties << endl; + } + } + + return true; +} + +bool SolidHardware::hwCapabilities(const QString &udi) +{ + const Solid::Device device(udi); + + cout << "udi = '" << device.udi() << "'" << endl; + cout << device << endl; + + return true; +} + +bool SolidHardware::hwProperties(const QString &udi) +{ + const Solid::Device device(udi); + + cout << "udi = '" << device.udi() << "'" << endl; + if (device.is<Solid::GenericInterface>()) { + QMap<QString,QVariant> properties = device.as<Solid::GenericInterface>()->allProperties(); + cout << properties << endl; + } + + return true; +} + +bool SolidHardware::hwQuery(const QString &parentUdi, const QString &query) +{ + const QList<Solid::Device> devices + = Solid::Device::listFromQuery(query, parentUdi); + + Q_FOREACH (const Solid::Device &device, devices) + { + cout << "udi = '" << device.udi() << "'" << endl; + } + + return true; +} + +bool SolidHardware::hwVolumeCall(SolidHardware::VolumeCallType type, const QString &udi) +{ + Solid::Device device(udi); + + if (!device.is<Solid::StorageAccess>() && type!=Eject) + { + cerr << tr("Error: %1 does not have the interface StorageAccess.").arg(udi) << endl; + return false; + } + else if (!device.is<Solid::OpticalDrive>() && type==Eject) + { + cerr << tr("Error: %1 does not have the interface OpticalDrive.").arg(udi) << endl; + return false; + } + + switch(type) + { + case Mount: + connect(device.as<Solid::StorageAccess>(), + SIGNAL(setupDone(Solid::ErrorType, QVariant, const QString &)), + this, + SLOT(slotStorageResult(Solid::ErrorType, QVariant))); + device.as<Solid::StorageAccess>()->setup(); + break; + case Unmount: + connect(device.as<Solid::StorageAccess>(), + SIGNAL(teardownDone(Solid::ErrorType, QVariant, const QString &)), + this, + SLOT(slotStorageResult(Solid::ErrorType, QVariant))); + device.as<Solid::StorageAccess>()->teardown(); + break; + case Eject: + connect(device.as<Solid::OpticalDrive>(), + SIGNAL(ejectDone(Solid::ErrorType, QVariant, const QString &)), + this, + SLOT(slotStorageResult(Solid::ErrorType, QVariant))); + device.as<Solid::OpticalDrive>()->eject(); + break; + } + + m_loop.exec(); + + if (m_error) + { + cerr << tr("Error: %1").arg(m_errorString) << endl; + return false; + } + + return true; +} + +bool SolidHardware::listen() +{ + Solid::DeviceNotifier *notifier = Solid::DeviceNotifier::instance(); + bool a = connect(notifier, SIGNAL(deviceAdded(QString)), this, SLOT(deviceAdded(QString))); + bool d = connect(notifier, SIGNAL(deviceRemoved(QString)), this, SLOT(deviceRemoved(QString))); + + if (!a || !d) { + return false; + } + + cout << "Listening to add/remove events: " << endl; + m_loop.exec(); + return true; +} + +void SolidHardware::deviceAdded(const QString &udi) +{ + cout << "Device Added:" << endl; + cout << "udi = '" << udi << "'" << endl; +} + +void SolidHardware::deviceRemoved(const QString &udi) +{ + cout << "Device Removed:" << endl; + cout << "udi = '" << udi << "'" << endl; +} + +void SolidHardware::slotStorageResult(Solid::ErrorType error, const QVariant &errorData) +{ + if (error) { + m_error = 1; + m_errorString = errorData.toString(); + } + m_loop.exit(); +} + +#include "solid-hardware.moc" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/src/tools/solid-hardware/solid-hardware.h new/solid-4.98.0/src/tools/solid-hardware/solid-hardware.h --- old/solid-4.97.0/src/tools/solid-hardware/solid-hardware.h 1970-01-01 01:00:00.000000000 +0100 +++ new/solid-4.98.0/src/tools/solid-hardware/solid-hardware.h 2014-03-28 19:17:47.000000000 +0100 @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Kevin Ottens <ervin@kde.org> + Copyright (C) 2014 Alejandro Fiestas Olivares <afiestas@kde.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef SOLID_HARDWARE_H +#define SOLID_HARDWARE_H + +#include <QCoreApplication> +#include <QEventLoop> + +#include <solid/storageaccess.h> + +class QCommandLineParser; +class SolidHardware : public QCoreApplication +{ + Q_OBJECT +public: + SolidHardware(int &argc, char **argv) : QCoreApplication(argc, argv), m_error(0) {} + + bool hwList(bool interfaces, bool system); + bool hwCapabilities(const QString &udi); + bool hwProperties(const QString &udi); + bool hwQuery(const QString &parentUdi, const QString &query); + bool listen(); + + enum VolumeCallType { Mount, Unmount, Eject }; + bool hwVolumeCall(VolumeCallType type, const QString &udi); + +private: + QEventLoop m_loop; + int m_error; + QString m_errorString; + +private Q_SLOTS: + void slotStorageResult(Solid::ErrorType error, const QVariant &errorData); + void deviceAdded(const QString &udi); + void deviceRemoved(const QString &udi); +}; + +Q_DECLARE_METATYPE(QList<int>) + +#endif // SOLID_HARDWARE_H diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/solid-4.97.0/tests/CMakeLists.txt new/solid-4.98.0/tests/CMakeLists.txt --- old/solid-4.97.0/tests/CMakeLists.txt 2014-03-01 12:51:52.000000000 +0100 +++ new/solid-4.98.0/tests/CMakeLists.txt 2014-03-28 19:17:47.000000000 +0100 @@ -6,12 +6,12 @@ # solidnettestdbusservice.cpp ) -#QT4_ADD_DBUS_ADAPTOR(solidnettestdbusservice_SRCS ../src/solid/org.kde.Solid.Networking.Client.xml +#qt5_add_dbus_adaptor(solidnettestdbusservice_SRCS ../src/solid/org.kde.Solid.Networking.Client.xml # solidnettestdbusservice.h TestNetworkingService) -#kde4_add_executable(solidnettestdbusservice TEST ${solidnettestdbusservice_SRCS}) - -#target_link_libraries(solidnettestdbusservice Qt5::DBus Qt5::Xml Qt5::Test) +#add_executable(solidnettestdbusservice ${solidnettestdbusservice_SRCS}) +#set_target_properties(solidnettestdbusservice PROPERTIES COMPILE_FLAGS -DSOLID_STATIC_DEFINE=1) +#target_link_libraries(solidnettestdbusservice KF5Solid_static Qt5::DBus Qt5::Xml Qt5::Test) ########### networkingclient ############### -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org
participants (1)
-
root@hilbert.suse.de