File indexing completed on 2024-11-17 04:55:44

0001 /*
0002  *   SPDX-FileCopyrightText: 2020 Aleix Pol Gonzalez <aleixpol@kde.org>
0003  *   SPDX-FileCopyrightText: 2021 Mariam Fahmy Sobhy <mariamfahmy66@gmail.com>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0006  */
0007 
0008 #pragma once
0009 
0010 #include "RpmOstreeDBusInterface.h"
0011 #include "RpmOstreeResource.h"
0012 #include "RpmOstreeTransaction.h"
0013 
0014 #include <resources/AbstractResourcesBackend.h>
0015 #include <resources/StandardBackendUpdater.h>
0016 
0017 #include <AppStreamQt/pool.h>
0018 #include <QTimer>
0019 
0020 class DiscoverAction;
0021 
0022 /*
0023  * This backend currently uses a mix of DBus calls and direct `rpm-ostree`
0024  * command line calls to operate. This is de to the fact that support for direct
0025  * Peer to Peer DBus connections (used for all rpm-ostree transactions) appear
0026  * to not work properly with Qt for an unknown reason.
0027  *
0028  * TODO: Replace code calling the command line by calls via the DBus interface
0029  */
0030 class RpmOstreeBackend : public AbstractResourcesBackend
0031 {
0032     Q_OBJECT
0033 public:
0034     explicit RpmOstreeBackend(QObject *parent = nullptr);
0035 
0036     /* Convenience function to set the fetching status and emit the
0037      * corresponding signal */
0038     void setFetching(bool);
0039 
0040     int updatesCount() const override;
0041     AbstractBackendUpdater *backendUpdater() const override;
0042     AbstractReviewsBackend *reviewsBackend() const override;
0043     ResultsStream *search(const AbstractResourcesBackend::Filters &search) override;
0044 
0045     /* Returns true if we are running on an ostree/rpm-ostree managed system */
0046     bool isValid() const override;
0047 
0048     Transaction *installApplication(AbstractResource *) override;
0049     Transaction *installApplication(AbstractResource *, const AddonList &) override;
0050     Transaction *removeApplication(AbstractResource *) override;
0051 
0052     bool isFetching() const override;
0053     void checkForUpdates() override;
0054     QString displayName() const override;
0055     bool hasApplications() const override;
0056 
0057 public Q_SLOTS:
0058     /* Fetch or refresh the list of deployments */
0059     void refreshDeployments();
0060 
0061     /* Look for a new Major version and offer it as an update */
0062     void lookForNextMajorVersion();
0063 
0064     /* Rebase to the next major version */
0065     void rebaseToNewVersion();
0066 
0067     /* Called when the Transaction changes state. Mostly to cleanup once it's done  */
0068     void transactionStatusChanged(Transaction::Status status);
0069 
0070 private:
0071     /* Once rpm-ostree has effectively stated, registrer ourselves as update
0072      * driver to the rpm-ostreed daemon to make sure that it does not exit while
0073      * we are running and then initialize the rest of the backend. */
0074     void initializeBackend();
0075 
0076     /* Check if a transaction has been started outside of Discover */
0077     bool hasExternalTransaction();
0078 
0079     /* Helper to setup a Transaction and connect all signals/slots */
0080     void setupTransaction(RpmOstreeTransaction::Operation op, QString arg = {});
0081 
0082     /* Called when a new major version is found to setup user facing actions */
0083     void foundNewMajorVersion(const QString &newMajorVersion);
0084 
0085     /* Set to true once we've successfully registrered with rpm-ostree */
0086     bool m_registrered;
0087 
0088     /* The list of available deployments */
0089     QVector<RpmOstreeResource *> m_resources;
0090 
0091     /* The currently booted deployment */
0092     RpmOstreeResource *m_currentlyBootedDeployment;
0093 
0094     /* The current transaction in progress, if any */
0095     RpmOstreeTransaction *m_transaction;
0096 
0097     /* DBus path to the currently booted OS DBus interface */
0098     QString m_bootedObjectPath;
0099 
0100     /* Watcher for rpm-ostree DBus service  */
0101     QDBusServiceWatcher *m_watcher;
0102 
0103     /* Timer for DBus retries */
0104     QTimer *m_dbusActivationTimer;
0105 
0106     /* Qt bindings to the main rpm-ostree DBus interface */
0107     OrgProjectatomicRpmostree1SysrootInterface *m_interface;
0108 
0109     /* We're re-using the standard backend updater logic */
0110     StandardBackendUpdater *m_updater;
0111 
0112     /* Used when refreshing the list of deployments */
0113     bool m_fetching;
0114 
0115     /* AppStream pool to be able to the distribution major release versions */
0116     QScopedPointer<AppStream::Pool> m_appdata;
0117 
0118     /* Enable development branches and releases. This is mostly usuelful for
0119      * testing and should not be enabled by default. We might add an hidden
0120      * option in the future.
0121      * Behaviour for Fedora: Enable rebasing to Rawhide */
0122     bool m_developmentEnabled;
0123 
0124     /* Custom message that takes into account major upgrades. To display when:
0125      * - A new major version is available
0126      * - An update to the current version is available or pending a reboot */
0127     QSharedPointer<InlineMessage> m_rebootBeforeRebaseMessage;
0128 
0129     /* Custom message that takes into account major upgrades. To display when:
0130      * - A new major version is available
0131      * - No update to the current version are available or pending a reboot */
0132     QSharedPointer<InlineMessage> m_rebaseAvailableMessage;
0133 };