Updates from Gitea, step 3: install from Gitea, and IRC steps aside for it

A release downloads straight into the inactive slot through the existing
install path: the signature is checked after 160 bytes, before anything
is written, the hash at the end. Tried on the device against the real
server: a download cut short, a flipped byte in the signature and one in
the image are each refused with the running firmware untouched; the real
v0.10.0 installed, restarted, and confirmed itself on Probation.

A TLS connection to Gitea peaks at about 52 KB of heap whether or not the
certificate is verified. With IRC connected (66 KB free) a check left 3 KB
and a download 836 bytes. A check, list or install a person asks for now
makes IRC step aside (holdForUpdate) and come back after: the lowest free
heap during a full download with IRC connected is 38 KB. The daily check
never interrupts IRC; with IRC up it waits. A TLS connection starts with
80 KB free (it was 55).

Debug Builds get test knobs: update probe <host>, update damage cut|flip,
update pretend <version>.

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:51:10 +02:00
co-authored by Claude Sonnet 5.5
parent 5754ae5b57
commit 510ce42a99
10 changed files with 120 additions and 10 deletions
+18
View File
@@ -184,6 +184,7 @@ void setup() {
update = new UpdateService(nvs, *wifi, *savedNetworks, *storageService, bus, settings);
fileOps = new FileOps(*storageService, filesInUse);
update->enableDailyCheck();
update->holdMemory = [](bool hold) { irc->holdForUpdate(hold); }; // see UpdateService::holdMemory
irc = new IrcService(nvs, "roro_" + identity::defaultShortName(), *wifi, *storageService, *clockService, bus);
notifier = new Notifier(bus, settings);
notifier->onShow = [](uint32_t now, uint32_t until) { power->onNotification(now, until); };
@@ -466,6 +467,13 @@ static void printReleases(bool list) {
static void updateStep() {
if (!updateWatch || update->giteaBusy()) return;
#ifdef RORO_DEBUG
if (updateWatch == 3) {
console.printf("update: probe: %s\n", update->probeResult().c_str());
updateWatch = 0;
return;
}
#endif
printReleases(updateWatch == 2);
updateWatch = 0;
}
@@ -492,6 +500,16 @@ static void updateCommand(const String& args) {
std::string why = update->requestInstall(rest.c_str(), force);
console.printf("update: %s\n", why.empty() ? "installing" : why.c_str());
#ifdef RORO_DEBUG
} else if (args.startsWith("probe ")) { // update probe <host> [path]: is that server's certificate accepted?
String rest = args.substring(6);
int space = rest.indexOf(' ');
update->requestProbe((space < 0 ? rest : rest.substring(0, space)).c_str(), space < 0 ? "/" : rest.substring(space + 1).c_str());
updateWatch = 3;
} else if (args.startsWith("damage ")) { // update damage cut <bytes> | flip <offset>: for the next download
long n = args.substring(args.lastIndexOf(' ') + 1).toInt();
args.startsWith("damage cut") ? update->damageNextDownload(n, -1) : update->damageNextDownload(-1, n);
console.printf("update: the next download will be %s at byte %ld\n", args.startsWith("damage cut") ? "cut" : "damaged", n);
} else if (args.startsWith("pretend ")) { // update pretend v0.9.0 | off: what the comparisons take as running
update->pretendVersion(args.substring(8) == "off" ? "" : args.substring(8).c_str());
console.printf("update: running %s\n", update->runningVersion().c_str());