Merge branch 'master' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
d8e76719a9
@ -36,6 +36,9 @@ set( libSources
|
|||||||
locale/Lookup.cpp
|
locale/Lookup.cpp
|
||||||
locale/TranslatableConfiguration.cpp
|
locale/TranslatableConfiguration.cpp
|
||||||
|
|
||||||
|
# Network service
|
||||||
|
network/Manager.cpp
|
||||||
|
|
||||||
# Partition service
|
# Partition service
|
||||||
partition/PartitionSize.cpp
|
partition/PartitionSize.cpp
|
||||||
|
|
||||||
@ -194,6 +197,16 @@ if ( ECM_FOUND AND BUILD_TESTING )
|
|||||||
Qt5::Test
|
Qt5::Test
|
||||||
)
|
)
|
||||||
calamares_automoc( libcalamareslocaletest )
|
calamares_automoc( libcalamareslocaletest )
|
||||||
|
|
||||||
|
ecm_add_test(
|
||||||
|
network/Tests.cpp
|
||||||
|
TEST_NAME
|
||||||
|
libcalamaresnetworktest
|
||||||
|
LINK_LIBRARIES
|
||||||
|
calamares
|
||||||
|
Qt5::Test
|
||||||
|
)
|
||||||
|
calamares_automoc( libcalamaresnetworktest )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if( BUILD_TESTING )
|
if( BUILD_TESTING )
|
||||||
|
@ -24,9 +24,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "Handler.h"
|
#include "Handler.h"
|
||||||
|
|
||||||
#include <QNetworkAccessManager>
|
#include "network/Manager.h"
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
|
|
||||||
#include <QtTest/QtTest>
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
@ -197,27 +195,9 @@ GeoIPTests::testSplitTZ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static QByteArray
|
|
||||||
synchronous_get( const char* urlstring )
|
|
||||||
{
|
|
||||||
QUrl url( urlstring );
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
QEventLoop loop;
|
|
||||||
|
|
||||||
qDebug() << "Fetching" << url;
|
|
||||||
|
|
||||||
QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit );
|
|
||||||
|
|
||||||
QNetworkRequest request( url );
|
|
||||||
QNetworkReply* reply = manager.get( request );
|
|
||||||
loop.exec();
|
|
||||||
reply->deleteLater();
|
|
||||||
return reply->readAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_GET( t, selector, url ) \
|
#define CHECK_GET( t, selector, url ) \
|
||||||
{ \
|
{ \
|
||||||
auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \
|
auto tz = GeoIP##t( selector ).processReply( CalamaresUtils::Network::Manager::instance().synchronousGet( QUrl( url ) ) ); \
|
||||||
qDebug() << tz; \
|
qDebug() << tz; \
|
||||||
QCOMPARE( default_tz, tz ); \
|
QCOMPARE( default_tz, tz ); \
|
||||||
auto tz2 = CalamaresUtils::GeoIP::Handler( "" #t, url, selector ).get(); \
|
auto tz2 = CalamaresUtils::GeoIP::Handler( "" #t, url, selector ).get(); \
|
||||||
@ -236,7 +216,7 @@ GeoIPTests::testGet()
|
|||||||
|
|
||||||
GeoIPJSON default_handler;
|
GeoIPJSON default_handler;
|
||||||
// Call the KDE service the definitive source.
|
// Call the KDE service the definitive source.
|
||||||
auto default_tz = default_handler.processReply( synchronous_get( "https://geoip.kde.org/v1/calamares" ) );
|
auto default_tz = default_handler.processReply( CalamaresUtils::Network::Manager::instance().synchronousGet( QUrl( "https://geoip.kde.org/v1/calamares" ) ) );
|
||||||
|
|
||||||
// This is bogus, because the test isn't always run by me
|
// This is bogus, because the test isn't always run by me
|
||||||
// QCOMPARE( default_tz.first, QStringLiteral("Europe") );
|
// QCOMPARE( default_tz.first, QStringLiteral("Europe") );
|
||||||
|
@ -23,14 +23,11 @@
|
|||||||
#include "GeoIPXML.h"
|
#include "GeoIPXML.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "network/Manager.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/NamedEnum.h"
|
#include "utils/NamedEnum.h"
|
||||||
#include "utils/Variant.h"
|
#include "utils/Variant.h"
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
static const NamedEnumTable< CalamaresUtils::GeoIP::Handler::Type >&
|
static const NamedEnumTable< CalamaresUtils::GeoIP::Handler::Type >&
|
||||||
@ -87,22 +84,6 @@ Handler::Handler( const QString& implementation, const QString& url, const QStri
|
|||||||
|
|
||||||
Handler::~Handler() {}
|
Handler::~Handler() {}
|
||||||
|
|
||||||
static QByteArray
|
|
||||||
synchronous_get( const QString& urlstring )
|
|
||||||
{
|
|
||||||
QUrl url( urlstring );
|
|
||||||
QNetworkAccessManager manager;
|
|
||||||
QEventLoop loop;
|
|
||||||
|
|
||||||
QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit );
|
|
||||||
|
|
||||||
QNetworkRequest request( url );
|
|
||||||
QNetworkReply* reply = manager.get( request );
|
|
||||||
loop.exec();
|
|
||||||
reply->deleteLater();
|
|
||||||
return reply->readAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::unique_ptr< Interface >
|
static std::unique_ptr< Interface >
|
||||||
create_interface( Handler::Type t, const QString& selector )
|
create_interface( Handler::Type t, const QString& selector )
|
||||||
{
|
{
|
||||||
@ -131,7 +112,7 @@ do_query( Handler::Type type, const QString& url, const QString& selector )
|
|||||||
return RegionZonePair();
|
return RegionZonePair();
|
||||||
}
|
}
|
||||||
|
|
||||||
return interface->processReply( synchronous_get( url ) );
|
return interface->processReply( CalamaresUtils::Network::Manager::instance().synchronousGet( url ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString
|
static QString
|
||||||
@ -143,7 +124,7 @@ do_raw_query( Handler::Type type, const QString& url, const QString& selector )
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return interface->rawReply( synchronous_get( url ) );
|
return interface->rawReply( CalamaresUtils::Network::Manager::instance().synchronousGet( url ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
RegionZonePair
|
RegionZonePair
|
||||||
|
177
src/libcalamares/network/Manager.cpp
Normal file
177
src/libcalamares/network/Manager.cpp
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@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 "Manager.h"
|
||||||
|
|
||||||
|
#include <QEventLoop>
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QNetworkReply>
|
||||||
|
#include <QNetworkRequest>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
|
namespace CalamaresUtils
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
void
|
||||||
|
RequestOptions::applyToRequest( QNetworkRequest* request ) const
|
||||||
|
{
|
||||||
|
if ( m_flags & Flag::FollowRedirect )
|
||||||
|
{
|
||||||
|
// Follows all redirects except unsafe ones (https to http).
|
||||||
|
request->setAttribute( QNetworkRequest::FollowRedirectsAttribute, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_flags & Flag::FakeUserAgent )
|
||||||
|
{
|
||||||
|
// Not everybody likes the default User Agent used by this class (looking at you,
|
||||||
|
// sourceforge.net), so let's set a more descriptive one.
|
||||||
|
request->setRawHeader( "User-Agent", "Mozilla/5.0 (compatible; Calamares)" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Manager::Private
|
||||||
|
{
|
||||||
|
std::unique_ptr< QNetworkAccessManager > m_nam;
|
||||||
|
QUrl m_hasInternetUrl;
|
||||||
|
bool m_hasInternet;
|
||||||
|
|
||||||
|
Private();
|
||||||
|
};
|
||||||
|
|
||||||
|
Manager::Private::Private()
|
||||||
|
: m_nam( std::make_unique< QNetworkAccessManager >() )
|
||||||
|
, m_hasInternet( false )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::Manager()
|
||||||
|
: d( std::make_unique< Private >() )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::~Manager() {}
|
||||||
|
|
||||||
|
Manager&
|
||||||
|
Manager::instance()
|
||||||
|
{
|
||||||
|
static auto* s_manager = new Manager();
|
||||||
|
return *s_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Manager::hasInternet()
|
||||||
|
{
|
||||||
|
return d->m_hasInternet;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Manager::checkHasInternet()
|
||||||
|
{
|
||||||
|
bool hasInternet = d->m_nam->networkAccessible() == QNetworkAccessManager::Accessible;
|
||||||
|
|
||||||
|
if ( !hasInternet && ( d->m_nam->networkAccessible() == QNetworkAccessManager::UnknownAccessibility ) )
|
||||||
|
{
|
||||||
|
hasInternet = synchronousPing( d->m_hasInternetUrl );
|
||||||
|
}
|
||||||
|
d->m_hasInternet = hasInternet;
|
||||||
|
return hasInternet;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Manager::setCheckHasInternetUrl( const QUrl& url )
|
||||||
|
{
|
||||||
|
d->m_hasInternetUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Does a request synchronously, returns the request itself
|
||||||
|
*
|
||||||
|
* The extra options for the request are taken from @p options,
|
||||||
|
* including the timeout setting.
|
||||||
|
*
|
||||||
|
* On failure, returns nullptr (e.g. bad URL, timeout). The request
|
||||||
|
* is marked for later automatic deletion, so don't store the pointer.
|
||||||
|
*/
|
||||||
|
static QPair< RequestStatus, QNetworkReply* >
|
||||||
|
synchronousRun( const std::unique_ptr< QNetworkAccessManager >& nam, const QUrl& url, const RequestOptions& options )
|
||||||
|
{
|
||||||
|
QNetworkRequest request = QNetworkRequest( url );
|
||||||
|
QNetworkReply* reply = nam->get( request );
|
||||||
|
QEventLoop loop;
|
||||||
|
QTimer timer;
|
||||||
|
|
||||||
|
// Bail out early if the request is bad
|
||||||
|
if ( reply->error() )
|
||||||
|
{
|
||||||
|
reply->deleteLater();
|
||||||
|
return qMakePair( RequestStatus( RequestStatus::Failed ), nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
options.applyToRequest( &request );
|
||||||
|
if ( options.hasTimeout() )
|
||||||
|
{
|
||||||
|
timer.setSingleShot( true );
|
||||||
|
QObject::connect( &timer, &QTimer::timeout, &loop, &QEventLoop::quit );
|
||||||
|
timer.start( options.timeout() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect( reply, &QNetworkReply::finished, &loop, &QEventLoop::quit );
|
||||||
|
loop.exec();
|
||||||
|
if ( options.hasTimeout() && !timer.isActive() )
|
||||||
|
{
|
||||||
|
reply->deleteLater();
|
||||||
|
return qMakePair( RequestStatus( RequestStatus::Timeout ), nullptr );
|
||||||
|
}
|
||||||
|
|
||||||
|
reply->deleteLater();
|
||||||
|
return qMakePair( RequestStatus( RequestStatus::Ok ), reply );
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestStatus
|
||||||
|
Manager::synchronousPing( const QUrl& url, const RequestOptions& options )
|
||||||
|
{
|
||||||
|
if ( !url.isValid() )
|
||||||
|
{
|
||||||
|
return RequestStatus::Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reply = synchronousRun( d->m_nam, url, options );
|
||||||
|
if ( reply.first )
|
||||||
|
{
|
||||||
|
return reply.second->bytesAvailable() ? RequestStatus::Ok : RequestStatus::Empty;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return reply.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray
|
||||||
|
Manager::synchronousGet( const QUrl& url, const RequestOptions& options )
|
||||||
|
{
|
||||||
|
if ( !url.isValid() )
|
||||||
|
{
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto reply = synchronousRun( d->m_nam, url, options );
|
||||||
|
return reply.first ? reply.second->readAll() : QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Network
|
||||||
|
} // namespace CalamaresUtils
|
148
src/libcalamares/network/Manager.h
Normal file
148
src/libcalamares/network/Manager.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@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 LIBCALAMARES_NETWORK_MANAGER_H
|
||||||
|
#define LIBCALAMARES_NETWORK_MANAGER_H
|
||||||
|
|
||||||
|
#include "DllMacro.h"
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class QNetworkRequest;
|
||||||
|
|
||||||
|
namespace CalamaresUtils
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class DLLEXPORT RequestOptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using milliseconds = std::chrono::milliseconds;
|
||||||
|
|
||||||
|
enum Flag
|
||||||
|
{
|
||||||
|
FollowRedirect = 0x1,
|
||||||
|
FakeUserAgent = 0x100
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS( Flags, Flag )
|
||||||
|
|
||||||
|
RequestOptions()
|
||||||
|
: m_flags( Flags() )
|
||||||
|
, m_timeout( -1 )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestOptions( Flags f, milliseconds timeout = milliseconds( -1 ) )
|
||||||
|
: m_flags( f )
|
||||||
|
, m_timeout( timeout )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void applyToRequest( QNetworkRequest* ) const;
|
||||||
|
|
||||||
|
bool hasTimeout() const { return m_timeout > milliseconds( 0 ); }
|
||||||
|
auto timeout() const { return m_timeout; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Flags m_flags;
|
||||||
|
milliseconds m_timeout;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS( RequestOptions::Flags );
|
||||||
|
|
||||||
|
struct RequestStatus
|
||||||
|
{
|
||||||
|
enum State
|
||||||
|
{
|
||||||
|
Ok,
|
||||||
|
Timeout, // Timeout exceeded
|
||||||
|
Failed, // bad Url
|
||||||
|
Empty // for ping(), response is empty
|
||||||
|
};
|
||||||
|
|
||||||
|
RequestStatus( State s = Ok )
|
||||||
|
: status( s )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
operator bool() const { return status == Ok; }
|
||||||
|
|
||||||
|
State status;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DLLEXPORT Manager : QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Manager();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** @brief Gets the single Manager instance.
|
||||||
|
*
|
||||||
|
* Typical code will use `auto& nam = Manager::instance();`
|
||||||
|
* to keep the reference.
|
||||||
|
*/
|
||||||
|
static Manager& instance();
|
||||||
|
virtual ~Manager();
|
||||||
|
|
||||||
|
/** @brief Checks if the given @p url returns data.
|
||||||
|
*
|
||||||
|
* Returns a RequestStatus, which converts to @c true if the ping
|
||||||
|
* was successful. Other status reasons convert to @c false,
|
||||||
|
* typically because of no data, a Url error or no network access.
|
||||||
|
*
|
||||||
|
* May return Empty if the request was successful but returned
|
||||||
|
* no data at all.
|
||||||
|
*/
|
||||||
|
RequestStatus synchronousPing( const QUrl& url, const RequestOptions& options = RequestOptions() );
|
||||||
|
|
||||||
|
/** @brief Downloads the data from a given @p url
|
||||||
|
*
|
||||||
|
* Returns the data as a QByteArray, or an empty
|
||||||
|
* array if any error occurred (or no data was returned).
|
||||||
|
*/
|
||||||
|
QByteArray synchronousGet( const QUrl& url, const RequestOptions& options = RequestOptions() );
|
||||||
|
|
||||||
|
/// @brief Set the URL which is used for the general "is there internet" check.
|
||||||
|
void setCheckHasInternetUrl( const QUrl& url );
|
||||||
|
/** @brief Do an explicit check for internet connectivity.
|
||||||
|
*
|
||||||
|
* This **may** do a ping to the configured check URL, but can also
|
||||||
|
* use other mechanisms.
|
||||||
|
*/
|
||||||
|
bool checkHasInternet();
|
||||||
|
/** @brief Is there internet connectivity?
|
||||||
|
*
|
||||||
|
* This returns the result of the last explicit check, or if there
|
||||||
|
* is other information about the state of the internet connection,
|
||||||
|
* whatever is known. @c true means you can expect (all) internet
|
||||||
|
* connectivity to be present.
|
||||||
|
*/
|
||||||
|
bool hasInternet();
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Private;
|
||||||
|
std::unique_ptr< Private > d;
|
||||||
|
};
|
||||||
|
} // namespace Network
|
||||||
|
} // namespace CalamaresUtils
|
||||||
|
#endif // LIBCALAMARES_NETWORK_MANAGER_H
|
48
src/libcalamares/network/Tests.cpp
Normal file
48
src/libcalamares/network/Tests.cpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@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 "Tests.h"
|
||||||
|
|
||||||
|
#include "Manager.h"
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
|
||||||
|
QTEST_GUILESS_MAIN( NetworkTests )
|
||||||
|
|
||||||
|
NetworkTests::NetworkTests() {}
|
||||||
|
|
||||||
|
NetworkTests::~NetworkTests() {}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetworkTests::initTestCase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetworkTests::testInstance()
|
||||||
|
{
|
||||||
|
auto& nam = CalamaresUtils::Network::Manager::instance();
|
||||||
|
QVERIFY( !nam.hasInternet() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
NetworkTests::testPing()
|
||||||
|
{
|
||||||
|
auto& nam = CalamaresUtils::Network::Manager::instance();
|
||||||
|
QVERIFY( nam.synchronousPing( QUrl( "https://www.kde.org" ) ) );
|
||||||
|
}
|
38
src/libcalamares/network/Tests.h
Normal file
38
src/libcalamares/network/Tests.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2019, Adriaan de Groot <groot@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 LIBCALAMARES_NETWORK_TESTS_H
|
||||||
|
#define LIBCALAMARES_NETWORK_TESTS_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class NetworkTests : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
NetworkTests();
|
||||||
|
~NetworkTests() override;
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void initTestCase();
|
||||||
|
|
||||||
|
void testInstance();
|
||||||
|
void testPing();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -101,7 +101,4 @@ public:
|
|||||||
#define CALAMARES_PLUGIN_FACTORY_DEFINITION( name, pluginRegistrations ) \
|
#define CALAMARES_PLUGIN_FACTORY_DEFINITION( name, pluginRegistrations ) \
|
||||||
K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY( name, CalamaresPluginFactory, pluginRegistrations )
|
K_PLUGIN_FACTORY_DEFINITION_WITH_BASEFACTORY( name, CalamaresPluginFactory, pluginRegistrations )
|
||||||
|
|
||||||
|
|
||||||
Q_DECLARE_INTERFACE( CalamaresPluginFactory, CalamaresPluginFactory_iid )
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,21 +1,32 @@
|
|||||||
# Netinstall module
|
# Netinstall module
|
||||||
|
|
||||||
The netinstall module allows distribution maintainers to ship minimal ISOs with only a basic set of preinstall packages.
|
The netinstall module allows distribution maintainers to ship minimal ISOs with
|
||||||
At installation time, the user is presented with the choice to install groups of packages from a predefined list.
|
only a basic set of preinstall packages. At installation time, the user is
|
||||||
|
presented with the choice to install groups of packages from a predefined list.
|
||||||
|
|
||||||
Calamares will then invoke the correct backend to install the packages.
|
Calamares will then invoke the correct backend to install the packages.
|
||||||
|
|
||||||
## Configuration of the packages
|
|
||||||
|
|
||||||
Every distribution can choose which groups to display and which packages should be in the groups.
|
## Module Configuration
|
||||||
|
|
||||||
The *netinstall.conf* file should have this format:
|
The `netinstall.conf` file is self-describing, and at the very
|
||||||
|
lease should contain a *groupsUrl* key:
|
||||||
|
|
||||||
|
```
|
||||||
----
|
----
|
||||||
groupsUrl: <URL to YAML file>
|
groupsUrl: <URL to YAML file>
|
||||||
|
```
|
||||||
|
|
||||||
The URL must point to a YAML file. Here is a short example of how the YAML file should look.
|
The URL must point to a YAML file, the *groups* file. See below for
|
||||||
|
the format of that groups file. The URL may be a local file.
|
||||||
|
|
||||||
|
|
||||||
|
## Groups Configuration
|
||||||
|
|
||||||
|
Here is a short example
|
||||||
|
of how the YAML file should look.
|
||||||
|
|
||||||
|
```
|
||||||
- name: "Group name"
|
- name: "Group name"
|
||||||
description: "Description of the group"
|
description: "Description of the group"
|
||||||
packages:
|
packages:
|
||||||
@ -24,63 +35,82 @@ The URL must point to a YAML file. Here is a short example of how the YAML file
|
|||||||
- grub
|
- grub
|
||||||
- name: "Second group name"
|
- name: "Second group name"
|
||||||
...
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
The file is composed of a list of entry, each describing one group. The keys *name*, *description* and *packages* are required.
|
The file is composed of a list of entries, each describing one group. The
|
||||||
|
keys *name*, *description* and *packages* are required for each group.
|
||||||
|
|
||||||
More keys are supported:
|
More keys (per group) are supported:
|
||||||
|
|
||||||
- hidden: if true, do not show the group on the page. Defaults to false.
|
- *hidden*: if true, do not show the group on the page. Defaults to false.
|
||||||
- selected: if true, display the group as selected. Defaults to false.
|
- *selected*: if true, display the group as selected. Defaults to false.
|
||||||
- critical: if true, make the installation process fail if installing
|
- critical*: if true, make the installation process fail if installing
|
||||||
any of the packages in the group fails. Otherwise, just log a warning.
|
any of the packages in the group fails. Otherwise, just log a warning.
|
||||||
Defaults to false.
|
Defaults to false.
|
||||||
- subgroups: if present this follows the same structure as the top level
|
- *subgroups*: if present this follows the same structure as the top level
|
||||||
of the YAML file, allowing there to be sub-groups of packages to an
|
of the YAML file, allowing there to be sub-groups of packages to an
|
||||||
arbitary depth
|
arbitary depth
|
||||||
- pre-install: an optional command to run within the new system before
|
- *pre-install*: an optional command to run within the new system before
|
||||||
the group's packages are installed. It will run before each package in
|
the group's packages are installed. It will run before each package in
|
||||||
the group is installed.
|
the group is installed.
|
||||||
- post-install: an optional command to run within the new system after
|
- *post-install*: an optional command to run within the new system after
|
||||||
the group's packages are installed. It will run after each package in
|
the group's packages are installed. It will run after each package in
|
||||||
the group is installed.
|
the group is installed.
|
||||||
|
|
||||||
If you set both *hidden* and *selected* for a group, you are basically creating a "default" group of packages
|
If you set both *hidden* and *selected* for a group, you are basically creating
|
||||||
which will always be installed in the user's system.
|
a "default" group of packages which will always be installed in the user's
|
||||||
|
system.
|
||||||
|
|
||||||
## Configuration of the module
|
> The note below applies to Calamares up-to-and-including 3.2.13, but will
|
||||||
|
> change in a later release.
|
||||||
|
|
||||||
Here is the set of instructions to have the module work in your Calamares. As of July 2016, this has been successfully
|
The *pre-install* and *post-install* commands are **not** passed to
|
||||||
tested using the live installation of Chakra Fermi.
|
a shell; see the **packages** module configuration (i.e. `packages.conf`)
|
||||||
|
for details. To use a full shell pipeline, call the shell explicitly.
|
||||||
|
|
||||||
First, if the module is used, we need to require a working Internet connection, otherwise the module will be
|
|
||||||
unable to fetch the package groups and to perform the installation. Requirements for the Calamares instance
|
|
||||||
are configured in the **welcome.conf** file (configuration for the **welcome** module). Make sure *internet*
|
|
||||||
is listed below *required*.
|
|
||||||
|
|
||||||
In the *settings.conf* file, decide where the **netinstall** page should be displayed. I put it just after the
|
|
||||||
**welcome** page, but any position between that and just before **partition** should make no difference.
|
|
||||||
|
|
||||||
If not present, add the **packages** job in the **exec** list. This is the job that calls the package manager
|
## Overall Configuration
|
||||||
to install packages. Make sure it is configured to use the correct package manager for your distribution; this
|
|
||||||
is configured in src/modules/packages/packages.conf.
|
|
||||||
|
|
||||||
The **exec** list in *settings.conf* should contain the following items in
|
Here is the set of instructions to have the module work in your Calamares.
|
||||||
|
|
||||||
|
First, if the module is used, we need to require a working Internet connection,
|
||||||
|
otherwise the module will be unable to fetch the package groups and to perform
|
||||||
|
the installation. Requirements for the Calamares instance are configured in the
|
||||||
|
`welcome.conf` file (configuration for the **welcome** module). Make sure
|
||||||
|
*internet* is listed under the *required* checks.
|
||||||
|
|
||||||
|
In the `settings.conf` file, decide where the **netinstall** page should be
|
||||||
|
displayed. I put it just after the **welcome** page, but any position between
|
||||||
|
that and just before **partition** should make no difference.
|
||||||
|
|
||||||
|
If not present, add the **packages** job in the *exec* list. This is the job
|
||||||
|
that calls the package manager to install packages. Make sure it is configured
|
||||||
|
to use the correct package manager for your distribution; this is configured in
|
||||||
|
`packages.conf`.
|
||||||
|
|
||||||
|
The *exec* list in `settings.conf` should contain the following items in
|
||||||
order (it's ok for other jobs to be listed inbetween them, though):
|
order (it's ok for other jobs to be listed inbetween them, though):
|
||||||
|
|
||||||
|
```
|
||||||
- unpackfs
|
- unpackfs
|
||||||
- networkcfg
|
- networkcfg
|
||||||
- packages
|
- packages
|
||||||
|
```
|
||||||
|
|
||||||
**unpackfs** creates the chroot where the installation is performed, and unpacks the root image with the filesystem
|
**unpackfs** creates the chroot where the installation is performed, and unpacks
|
||||||
structure; **networkcfg** set ups a working network in the chroot; and finally **packages** can install packages
|
the root image with the filesystem structure; **networkcfg** set ups a working
|
||||||
in the chroot.
|
network in the chroot; and finally **packages** can install packages in the
|
||||||
|
chroot.
|
||||||
|
|
||||||
## Common issues
|
## Common issues
|
||||||
|
|
||||||
If launching the package manager command returns you negative exit statuses and nothing is actually invoked, this
|
If launching the package manager command returns you negative exit statuses and
|
||||||
is likely an error in the setup of the chroot; check that the parameter **rootMountPoint** is set to the correct
|
nothing is actually invoked, this is likely an error in the setup of the chroot;
|
||||||
value in the Calamares configuration.
|
check that the parameter **rootMountPoint** is set to the correct value in the
|
||||||
|
Calamares configuration.
|
||||||
|
|
||||||
If the command is run, but exits with error, check that the network is working in the chroot. Make sure /etc/resolv.conf
|
If the command is run, but exits with error, check that the network is
|
||||||
exists and that it's not empty.
|
working in the chroot. Make sure `/etc/resolv.conf` exists and that
|
||||||
|
it's not empty.
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
# groupsUrl: http://example.org/netinstall.php
|
# groupsUrl: http://example.org/netinstall.php
|
||||||
# or it can be a locally installed file:
|
# or it can be a locally installed file:
|
||||||
# groupsUrl: file:///usr/share/calamares/netinstall.yaml
|
# groupsUrl: file:///usr/share/calamares/netinstall.yaml
|
||||||
|
#
|
||||||
|
# Note that the contents of the groups file is the **important**
|
||||||
|
# part of the configuration of this module. It specifies what
|
||||||
|
# the user may select and what commands are to be run.
|
||||||
|
#
|
||||||
|
# The format of the groups file is documented in `README.md`.
|
||||||
|
#
|
||||||
# groupsUrl: file:///usr/share/calamares/netinstall.yaml
|
# groupsUrl: file:///usr/share/calamares/netinstall.yaml
|
||||||
|
|
||||||
# If the installation can proceed without netinstall (e.g. the Live CD
|
# If the installation can proceed without netinstall (e.g. the Live CD
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# Example configuration with groups and packages, taken from Chakra Linux.
|
||||||
|
#
|
||||||
|
# This example is rather limited. See `README.md` for full documentation
|
||||||
|
# on the configuration format.
|
||||||
- name: "Default"
|
- name: "Default"
|
||||||
description: "Default group"
|
description: "Default group"
|
||||||
hidden: true
|
hidden: true
|
||||||
|
@ -52,6 +52,37 @@ PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @brief size the given @p pixmap to @p size
|
||||||
|
*
|
||||||
|
* This is "smart" in the sense that it tries to keep the image un-scaled
|
||||||
|
* (if it's just a little too big) and otherwise scales as needed.
|
||||||
|
*
|
||||||
|
* Returns a copy if any modifications are done.
|
||||||
|
*/
|
||||||
|
static QPixmap
|
||||||
|
smartClip( const QPixmap& pixmap, QSize size )
|
||||||
|
{
|
||||||
|
auto pixSize = pixmap.size();
|
||||||
|
if ( ( pixSize.width() <= size.width() ) && ( pixSize.height() <= size.height() ) )
|
||||||
|
{
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// only slightly bigger? Trim the edges
|
||||||
|
constexpr int margin = 16;
|
||||||
|
if ( ( pixSize.width() <= size.width() + margin ) && ( pixSize.height() <= size.height() + margin ) )
|
||||||
|
{
|
||||||
|
int x = pixSize.width() <= size.width() ? 0 : ( pixSize.width() - size.width() / 2 );
|
||||||
|
int new_width = pixSize.width() <= size.width() ? pixSize.width() : size.width();
|
||||||
|
int y = pixSize.height() <= size.height() ? 0 : ( pixSize.height() - size.height() / 2 );
|
||||||
|
int new_height = pixSize.height() <= size.height() ? pixSize.height() : size.height();
|
||||||
|
|
||||||
|
return pixmap.copy( x, y, new_width, new_height );
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixmap.scaled( size, Qt::KeepAspectRatio );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PackageChooserPage::currentChanged( const QModelIndex& index )
|
PackageChooserPage::currentChanged( const QModelIndex& index )
|
||||||
{
|
{
|
||||||
@ -66,8 +97,17 @@ PackageChooserPage::currentChanged( const QModelIndex& index )
|
|||||||
const auto* model = ui->products->model();
|
const auto* model = ui->products->model();
|
||||||
|
|
||||||
ui->productName->setText( model->data( index, PackageListModel::NameRole ).toString() );
|
ui->productName->setText( model->data( index, PackageListModel::NameRole ).toString() );
|
||||||
ui->productScreenshot->setPixmap( model->data( index, PackageListModel::ScreenshotRole ).value< QPixmap >() );
|
|
||||||
ui->productDescription->setText( model->data( index, PackageListModel::DescriptionRole ).toString() );
|
ui->productDescription->setText( model->data( index, PackageListModel::DescriptionRole ).toString() );
|
||||||
|
|
||||||
|
QPixmap currentScreenshot = model->data( index, PackageListModel::ScreenshotRole ).value< QPixmap >();
|
||||||
|
if ( currentScreenshot.isNull() )
|
||||||
|
{
|
||||||
|
ui->productScreenshot->setPixmap( m_introduction.screenshot );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ui->productScreenshot->setPixmap( smartClip( currentScreenshot, ui->productScreenshot->size() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 1.7 KiB |
@ -37,21 +37,36 @@
|
|||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="productName">
|
<widget class="QLabel" name="productName">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>Product Name</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="productScreenshot">
|
<widget class="QLabel" name="productScreenshot">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>TextLabel</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="productDescription">
|
<widget class="QLabel" name="productDescription">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>2</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TextLabel</string>
|
<string>Long Product Description</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
@ -87,9 +87,25 @@ update_system: false
|
|||||||
# pre-script: touch /tmp/installing-vi
|
# pre-script: touch /tmp/installing-vi
|
||||||
# post-script: rm -f /tmp/installing-vi
|
# post-script: rm -f /tmp/installing-vi
|
||||||
#
|
#
|
||||||
# The pre- and post-scripts are optional, but you cannot leave both out: using
|
# The pre- and post-scripts are optional, but you cannot leave both out
|
||||||
# "package: vi" with neither script option will trick Calamares into
|
# if you do use the *package* key: using "package: vi" with neither script
|
||||||
# trying to install a package named "package: vi", which is unlikely to work.
|
# option will trick Calamares into trying to install a package named
|
||||||
|
# "package: vi", which is unlikely to work.
|
||||||
|
#
|
||||||
|
# The pre- and post-scripts are **not** executed by a shell unless you
|
||||||
|
# explicitly invoke `/bin/sh` in them. The command-lines are passed
|
||||||
|
# to exec(), which does not understand shell syntax. In other words:
|
||||||
|
#
|
||||||
|
# pre-script: ls | wc -l
|
||||||
|
#
|
||||||
|
# Will fail, because `|` is passed as a command-line argument to ls,
|
||||||
|
# as are `wc`, and `-l`. No shell pipeline is set up, and ls is likely
|
||||||
|
# to complain. Invoke the shell explicitly:
|
||||||
|
#
|
||||||
|
# pre-script: /bin/sh -c \"ls | wc -l\"
|
||||||
|
#
|
||||||
|
# The above note on shell-expansion applies to versions up-to-and-including
|
||||||
|
# Calamares 3.2.12, but will change in future.
|
||||||
#
|
#
|
||||||
# Any package name may be localized; this is used to install localization
|
# Any package name may be localized; this is used to install localization
|
||||||
# packages for software based on the selected system locale. By including
|
# packages for software based on the selected system locale. By including
|
||||||
|
@ -18,12 +18,10 @@
|
|||||||
|
|
||||||
#include "TrackingJobs.h"
|
#include "TrackingJobs.h"
|
||||||
|
|
||||||
|
#include "network/Manager.h"
|
||||||
#include "utils/CalamaresUtilsSystem.h"
|
#include "utils/CalamaresUtilsSystem.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
@ -31,13 +29,11 @@
|
|||||||
|
|
||||||
TrackingInstallJob::TrackingInstallJob( const QString& url )
|
TrackingInstallJob::TrackingInstallJob( const QString& url )
|
||||||
: m_url( url )
|
: m_url( url )
|
||||||
, m_networkManager( nullptr )
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackingInstallJob::~TrackingInstallJob()
|
TrackingInstallJob::~TrackingInstallJob()
|
||||||
{
|
{
|
||||||
delete m_networkManager;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
@ -61,48 +57,23 @@ TrackingInstallJob::prettyStatusMessage() const
|
|||||||
Calamares::JobResult
|
Calamares::JobResult
|
||||||
TrackingInstallJob::exec()
|
TrackingInstallJob::exec()
|
||||||
{
|
{
|
||||||
m_networkManager = new QNetworkAccessManager();
|
using CalamaresUtils::Network::Manager;
|
||||||
|
using CalamaresUtils::Network::RequestOptions;
|
||||||
|
using CalamaresUtils::Network::RequestStatus;
|
||||||
|
|
||||||
QNetworkRequest request;
|
auto result = Manager::instance().synchronousPing(
|
||||||
request.setUrl( QUrl( m_url ) );
|
QUrl( m_url ),
|
||||||
// Follows all redirects except unsafe ones (https to http).
|
RequestOptions( RequestOptions::FollowRedirect | RequestOptions::FakeUserAgent,
|
||||||
request.setAttribute( QNetworkRequest::FollowRedirectsAttribute, true );
|
RequestOptions::milliseconds( 5000 ) ) );
|
||||||
// Not everybody likes the default User Agent used by this class (looking at you,
|
if ( result.status == RequestStatus::Timeout )
|
||||||
// sourceforge.net), so let's set a more descriptive one.
|
|
||||||
request.setRawHeader( "User-Agent", "Mozilla/5.0 (compatible; Calamares)" );
|
|
||||||
|
|
||||||
QTimer timeout;
|
|
||||||
timeout.setSingleShot( true );
|
|
||||||
|
|
||||||
QEventLoop loop;
|
|
||||||
|
|
||||||
connect( m_networkManager, &QNetworkAccessManager::finished, this, &TrackingInstallJob::dataIsHere );
|
|
||||||
connect( m_networkManager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit );
|
|
||||||
connect( &timeout, &QTimer::timeout, &loop, &QEventLoop::quit );
|
|
||||||
|
|
||||||
m_networkManager->get( request ); // The semaphore is released when data is received
|
|
||||||
timeout.start( std::chrono::milliseconds( 5000 ) );
|
|
||||||
|
|
||||||
loop.exec();
|
|
||||||
|
|
||||||
if ( !timeout.isActive() )
|
|
||||||
{
|
{
|
||||||
cWarning() << "install-tracking request timed out.";
|
cWarning() << "install-tracking request timed out.";
|
||||||
return Calamares::JobResult::error( tr( "Internal error in install-tracking." ),
|
return Calamares::JobResult::error( tr( "Internal error in install-tracking." ),
|
||||||
tr( "HTTP request timed out." ) );
|
tr( "HTTP request timed out." ) );
|
||||||
}
|
}
|
||||||
timeout.stop();
|
|
||||||
|
|
||||||
return Calamares::JobResult::ok();
|
return Calamares::JobResult::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
TrackingInstallJob::dataIsHere( QNetworkReply* reply )
|
|
||||||
{
|
|
||||||
cDebug() << "Installation feedback request OK";
|
|
||||||
reply->deleteLater();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TrackingMachineNeonJob::prettyName() const
|
TrackingMachineNeonJob::prettyName() const
|
||||||
{
|
{
|
||||||
|
@ -21,13 +21,10 @@
|
|||||||
|
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
|
|
||||||
class QNetworkAccessManager;
|
|
||||||
class QNetworkReply;
|
|
||||||
class QSemaphore;
|
class QSemaphore;
|
||||||
|
|
||||||
class TrackingInstallJob : public Calamares::Job
|
class TrackingInstallJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
TrackingInstallJob( const QString& url );
|
TrackingInstallJob( const QString& url );
|
||||||
~TrackingInstallJob() override;
|
~TrackingInstallJob() override;
|
||||||
@ -37,13 +34,8 @@ public:
|
|||||||
QString prettyStatusMessage() const override;
|
QString prettyStatusMessage() const override;
|
||||||
Calamares::JobResult exec() override;
|
Calamares::JobResult exec() override;
|
||||||
|
|
||||||
public slots:
|
|
||||||
void dataIsHere( QNetworkReply* );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_url;
|
const QString m_url;
|
||||||
|
|
||||||
QNetworkAccessManager* m_networkManager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrackingMachineNeonJob : public Calamares::Job
|
class TrackingMachineNeonJob : public Calamares::Job
|
||||||
|
@ -25,12 +25,14 @@
|
|||||||
#include "partman_devices.h"
|
#include "partman_devices.h"
|
||||||
|
|
||||||
#include "modulesystem/Requirement.h"
|
#include "modulesystem/Requirement.h"
|
||||||
|
#include "network/Manager.h"
|
||||||
#include "widgets/WaitingWidget.h"
|
#include "widgets/WaitingWidget.h"
|
||||||
#include "utils/CalamaresUtilsGui.h"
|
#include "utils/CalamaresUtilsGui.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/Retranslator.h"
|
#include "utils/Retranslator.h"
|
||||||
#include "utils/CalamaresUtilsSystem.h"
|
#include "utils/CalamaresUtilsSystem.h"
|
||||||
#include "utils/Units.h"
|
#include "utils/Units.h"
|
||||||
|
#include "utils/Variant.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
#include "JobQueue.h"
|
#include "JobQueue.h"
|
||||||
@ -42,13 +44,9 @@
|
|||||||
#include <QDBusInterface>
|
#include <QDBusInterface>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QEventLoop>
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QNetworkAccessManager>
|
|
||||||
#include <QNetworkRequest>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
@ -245,16 +243,16 @@ GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( configurationMap.contains( "internetCheckUrl" ) &&
|
QUrl checkInternetUrl;
|
||||||
configurationMap.value( "internetCheckUrl" ).type() == QVariant::String )
|
QString checkInternetSetting = CalamaresUtils::getString( configurationMap, "internetCheckUrl" );
|
||||||
|
if ( !checkInternetSetting.isEmpty() )
|
||||||
{
|
{
|
||||||
m_checkHasInternetUrl = configurationMap.value( "internetCheckUrl" ).toString().trimmed();
|
checkInternetUrl = QUrl( checkInternetSetting.trimmed() );
|
||||||
if ( m_checkHasInternetUrl.isEmpty() ||
|
if ( !checkInternetUrl.isValid() )
|
||||||
!QUrl( m_checkHasInternetUrl ).isValid() )
|
|
||||||
{
|
{
|
||||||
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl
|
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is invalid in welcome.conf" << checkInternetSetting
|
||||||
<< "reverting to default (http://example.com).";
|
<< "reverting to default (http://example.com).";
|
||||||
m_checkHasInternetUrl = "http://example.com";
|
checkInternetUrl = QUrl( "http://example.com" );
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,10 +260,13 @@ GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
{
|
{
|
||||||
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is undefined in welcome.conf,"
|
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is undefined in welcome.conf,"
|
||||||
"reverting to default (http://example.com).";
|
"reverting to default (http://example.com).";
|
||||||
|
checkInternetUrl = "http://example.com";
|
||||||
m_checkHasInternetUrl = "http://example.com";
|
|
||||||
incompleteConfiguration = true;
|
incompleteConfiguration = true;
|
||||||
}
|
}
|
||||||
|
if ( checkInternetUrl.isValid() )
|
||||||
|
{
|
||||||
|
CalamaresUtils::Network::Manager::instance().setCheckHasInternetUrl( checkInternetUrl );
|
||||||
|
}
|
||||||
|
|
||||||
if ( incompleteConfiguration )
|
if ( incompleteConfiguration )
|
||||||
{
|
{
|
||||||
@ -357,22 +358,8 @@ GeneralRequirements::checkHasPower()
|
|||||||
bool
|
bool
|
||||||
GeneralRequirements::checkHasInternet()
|
GeneralRequirements::checkHasInternet()
|
||||||
{
|
{
|
||||||
// default to true in the QNetworkAccessManager::UnknownAccessibility case
|
auto& nam = CalamaresUtils::Network::Manager::instance();
|
||||||
QNetworkAccessManager qnam;
|
bool hasInternet = nam.checkHasInternet();
|
||||||
bool hasInternet = qnam.networkAccessible() == QNetworkAccessManager::Accessible;
|
|
||||||
|
|
||||||
if ( !hasInternet && qnam.networkAccessible() == QNetworkAccessManager::UnknownAccessibility )
|
|
||||||
{
|
|
||||||
QNetworkRequest req = QNetworkRequest( QUrl( m_checkHasInternetUrl ) );
|
|
||||||
QNetworkReply* reply = qnam.get( req );
|
|
||||||
QEventLoop loop;
|
|
||||||
connect( reply, &QNetworkReply::finished,
|
|
||||||
&loop, &QEventLoop::quit );
|
|
||||||
loop.exec();
|
|
||||||
if( reply->bytesAvailable() )
|
|
||||||
hasInternet = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Calamares::JobQueue::instance()->globalStorage()->insert( "hasInternet", hasInternet );
|
Calamares::JobQueue::instance()->globalStorage()->insert( "hasInternet", hasInternet );
|
||||||
return hasInternet;
|
return hasInternet;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,6 @@ private:
|
|||||||
|
|
||||||
qreal m_requiredStorageGiB;
|
qreal m_requiredStorageGiB;
|
||||||
qreal m_requiredRamGiB;
|
qreal m_requiredRamGiB;
|
||||||
QString m_checkHasInternetUrl;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // REQUIREMENTSCHECKER_H
|
#endif // REQUIREMENTSCHECKER_H
|
||||||
|
Loading…
Reference in New Issue
Block a user