Skip to content

Commit

Permalink
Implement new calaos-os API with calaos-ct backend
Browse files Browse the repository at this point in the history
  • Loading branch information
raoulh committed Aug 6, 2023
1 parent 1d2ff33 commit fc56616
Show file tree
Hide file tree
Showing 12 changed files with 891 additions and 145 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ qrc_fonts_mobile.cpp
qrc_img_mobile.cpp
qrc_lang.cpp
qrc_qml_mobile.cpp
qrc_qml_shared.cpp
qrc_qml_shared.cpp
desktop.pro.user*
mobile.pro.user*
8 changes: 7 additions & 1 deletion desktop.pro
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ PKGCONFIG += x11 xext
QML_IMPORT_PATH = $$PWD/qml

SOURCES += src/HardwareUtils_desktop.cpp \
src/CalaosOsAPI.cpp \
src/CalaosWidget.cpp \
src/CalaosWidgetModel.cpp \
src/ControlPanelModel.cpp \
Expand All @@ -42,9 +43,12 @@ SOURCES += src/HardwareUtils_desktop.cpp \
src/XUtils.cpp \
src/ScreenManager.cpp \
src/UserInfoModel.cpp \
src/UsbDisk.cpp
src/UsbDisk.cpp \
src/AsyncJobs.cpp \
src/NetworkRequest.cpp

HEADERS += src/HardwareUtils_desktop.h \
src/CalaosOsAPI.h \
src/CalaosWidget.h \
src/CalaosWidgetModel.h \
src/ControlPanelModel.h \
Expand All @@ -54,6 +58,8 @@ HEADERS += src/HardwareUtils_desktop.h \
src/ScreenManager.h \
src/UserInfoModel.h \
src/UsbDisk.h \
src/AsyncJobs.h \
src/NetworkRequest.h \
src/version.h

linux {
Expand Down
67 changes: 58 additions & 9 deletions src/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "WeatherInfo.h"
#include "ScreenManager.h"
#include "UserInfoModel.h"
#include "CalaosOsAPI.h"
#elif defined (Q_OS_ANDROID) || defined (Q_OS_IOS)
#include <QtGui/qpa/qplatformwindow.h>
#endif
Expand Down Expand Up @@ -124,7 +125,46 @@ void Application::createQmlApp()
update_appVersion(PKG_VERSION_STR);

update_hasInstall(QFile::exists("/.calaos-live"));
update_isSnapshotBoot(Machine::isBootReadOnly());

#ifdef CALAOS_DESKTOP

CalaosOsAPI::Instance()->getFsStatus(
[this](bool success, const QJsonObject &o)
{
if (!success)
{
qDebug() << "Failed to get fs status for rollback";
return;
}

if (!o["filesystems"].isArray())
{
update_isSnapshotBoot(false);
return;
}

auto a = o["filesystems"].toArray();
if (a.isEmpty())
{
update_isSnapshotBoot(false);
return;
}

auto obj = a.at(0).toObject();

if (obj["target"].toString() == "/" &&
obj["source"].toString() == "rootfs" &&
obj["fstype"].toString() == "overlay")
{
update_isSnapshotBoot(true);
return;
}

update_isSnapshotBoot(false);
});
#else
update_isSnapshotBoot(false);
#endif

update_applicationStatus(Common::NotConnected);

Expand Down Expand Up @@ -550,28 +590,37 @@ void Application::rebootMachine()
{
qInfo() << "Full reboot requested";
#ifdef CALAOS_DESKTOP
QProcess::startDetached("/bin/sh", QStringList() <<
"-c" <<
"sync; reboot");
CalaosOsAPI::Instance()->rebootMachine({});
#endif
}

void Application::restartApp()
{
qInfo() << "Restart of calaos_home requested";
#ifdef CALAOS_DESKTOP
this->quit();
QProcess::startDetached(arguments()[0], arguments());
CalaosOsAPI::Instance()->restartApp({});
#endif
}

void Application::rollbackSnapshot()
{
qInfo() << "Rollback calaos os";
#ifdef CALAOS_DESKTOP
QProcess::startDetached("/bin/sh", QStringList() <<
"-c" <<
"calaos_rollback.sh && reboot");
CalaosOsAPI::Instance()->rollbackSnapshot([this](bool success)
{
if (!success)
{
QFAppDispatcher *appDispatcher = QFAppDispatcher::instance(&engine);
QVariantMap m = {{ "title", "Error" },
{ "message", "Failed to rollback calaos os to previous version. An error occured. Please check logs" },
{ "button", "Close" }};
appDispatcher->dispatch("showNotificationMsg", m);
}
else
{
CalaosOsAPI::Instance()->rebootMachine({});
}
});
#endif
}

Expand Down
71 changes: 71 additions & 0 deletions src/AsyncJobs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "AsyncJobs.h"
#include <QVariant>

void AsyncJob::start(const QVariant &previous_data)
{
jobFunc(this, previous_data);
}

AsyncJobs::AsyncJobs(QObject *parent):
QObject(parent)
{
}

AsyncJobs::~AsyncJobs()
{
}

void AsyncJobs::append(AsyncJob *j)
{
if (!j) return;

//reparent object to handle jobs memory from AsyncJobs
j->setParent(this);
jobs.enqueue(j);
}

void AsyncJobs::prepend(AsyncJob *j)
{
if (!j) return;

//reparent object to handle jobs memory from AsyncJobs
j->setParent(this);
jobs.prepend(j);
}

void AsyncJobs::start()
{
if (running) return;
running = true;

//start running or queued jobs if any
dequeueStartJob({});
}

void AsyncJobs::dequeueStartJob(const QVariant &data)
{
if (jobs.isEmpty())
{
//end of job queue, emit finished signal
//and delete job runner
emit finished(data);
deleteLater();
return;
}

currentJob = jobs.dequeue();
connect(currentJob, SIGNAL(done(QVariant)), this, SLOT(jobDone(QVariant)));
connect(currentJob, SIGNAL(error()), this, SLOT(jobFailed()));
currentJob->start(data);
}

void AsyncJobs::jobFailed()
{
emit failed(currentJob);
deleteLater();
}

void AsyncJobs::jobDone(const QVariant &data)
{
dequeueStartJob(data);
}
77 changes: 77 additions & 0 deletions src/AsyncJobs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef ASYNCJOBS_H
#define ASYNCJOBS_H

#include <QObject>
#include <QByteArray>
#include <QQueue>
#include <functional>
#include <QVariant>

/*
* Classes for running jobs
* It handles chaining the jobs to start the next one after one has completed successfuly.
* It also handles failure: when a job fails, the job queue is stopped.
*
* The AsyncJobs manages the job queue and it autodeletes itself when finished for convenience.
*
* AsyncJobs queue support adding more jobs to the queue dynamically (even from the callback from
* one running job). This is usefull to add jobs to the queue that are different based on the result
* of the data received from the previous job.
*/

class AsyncJob;

typedef std::function<void(AsyncJob *job, const QVariant &data)> AsyncFunc;

class AsyncJob: public QObject
{
Q_OBJECT
public:
AsyncJob(AsyncFunc jobfn):
jobFunc(std::move(jobfn))
{}

public slots:
virtual void start(const QVariant &previous_data);

virtual void emitSuccess(const QVariant &data = {}) { emit done(data); }
virtual void emitFailed() { emit error(); }

signals:
void done(const QVariant &data);
void error();

protected:
//callback with data from previous Job
AsyncFunc jobFunc = [](AsyncJob *, const QVariant &) {};
};

class AsyncJobs: public QObject
{
Q_OBJECT
public:
AsyncJobs(QObject *parent = nullptr);
virtual ~AsyncJobs();

void append(AsyncJob *j);
void prepend(AsyncJob *j);

public slots:
void start();

signals:
void finished(const QVariant &data);
void failed(AsyncJob *job);

private slots:
void dequeueStartJob(const QVariant &data);
void jobDone(const QVariant &data);
void jobFailed();

private:
QQueue<AsyncJob *> jobs;
bool running = false;
AsyncJob *currentJob = nullptr;
};

#endif // ASYNCJOBS_H
Loading

0 comments on commit fc56616

Please sign in to comment.