Updates from Gitea, step 2: the connection (check and list work on the device)

The roots (ISRG X1 and X2), an HTTPS client that reads the answer as a
stream, GiteaReleases (the latest and a list of ten), the Update
Service's requests, install from Gitea through the existing install path,
the daily check's schedule, the Check for updates setting, and console
commands: update check | list | status | install <tag>.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-06 15:20:58 +02:00
co-authored by Claude Sonnet 5.5
parent b0e8226943
commit 5754ae5b57
12 changed files with 616 additions and 3 deletions
+33
View File
@@ -4,9 +4,13 @@
#include <string>
#include "update_check.h"
#include "version.h"
#include "event_bus.h"
#include "key_value_store.h"
#include "service.h"
#include "services/gitea_releases.h"
#include "services/storage_service.h"
#include "services/wifi_service.h"
@@ -39,12 +43,34 @@ class UpdateService : public Service {
// Installs an Update File from the SD card (runs on the storage task).
void installFromSd(const std::string& path);
// Updates from Gitea (docs/milestones/R1.md, #6). The requests are done on this Service's task;
// the answers are read from gitea().
GiteaReleases& gitea() { return gitea_; }
void requestCheck() { request_ = Request::Check; }
void requestList() { request_ = Request::List; }
// Downloads `tag` (a release known from the last check or list) into the inactive slot and
// installs it. "" when it started, or why not. A Debug Build doesn't install a release (Q171,
// it would take its Debug Console away) unless `force`, which only the Debug Console passes.
std::string requestInstall(const std::string& tag, bool force = false);
bool giteaBusy() const { return request_ != Request::None || serving_; }
// The daily check (Q165) only runs once the main loop says it may: not in Safe Mode.
void enableDailyCheck() { dailyCheck_ = true; }
// The version that counts as running for comparisons: a Debug Build can pretend to be older.
std::string runningVersion() const { return fakeVersion_.empty() ? versionString() : fakeVersion_; }
void pretendVersion(const std::string& v) { fakeVersion_ = v; }
std::string failedVersion() const; // a release that rolled back here, "" if none
// The main loop calls this once it has drawn a frame (part of Probation).
void firstFrameDrawn() { firstFrame_ = true; }
// True when an installed update is waiting to reboot; the main loop reboots when it's safe.
bool rebootPending() const { return phase_ == Phase::Installed; }
private:
enum class Request : uint8_t { None, Check, BackgroundCheck, List, Install };
void serve(); // on this task: one request
void installFromGitea(const release::Release& release);
void scheduleDailyCheck(uint32_t nowMs); // from tick()
static void taskEntry(void* self);
void listen();
void install(class UpdateSource& source, const char* via);
@@ -62,6 +88,13 @@ class UpdateService : public Service {
std::string incoming_;
bool probation_ = false;
volatile bool firstFrame_ = false;
GiteaReleases gitea_;
volatile Request request_ = Request::None;
volatile bool serving_ = false;
std::string installTag_, fakeVersion_, announced_;
bool dailyCheck_ = false;
uint32_t nextCheckMs_ = 90000; // not before the device has settled
};
} // namespace roro