nixos-config/scripts/nixos-updater.py
2024-11-24 21:58:43 +08:00

90 lines
2.1 KiB
Python

import requests
import os
import socket
import json
from os import path as osp
from dataclasses import dataclass
"""
This updater consists of several parts:
- Update checker: Check an url for update (if outPath is different from /run/current-system or some specified profile) or maybe use timestamp for update
- Nix copy --from: copy from remote. Need to specify remote url.
- Create a symlink: /run/next-system -> <new system derivation>
- Listen for POST request to trigger system switch (optional)
"""
@dataclass
class GarnixConfig:
token: str
@dataclass
class Config:
check_type: str
check_url: str
remote_url: str
garnix: GarnixConfig
hostname: str = socket.gethostname()
class Nix:
def __init__(self, args):
self.args = args
def copy_from_remote(self):
# run nix copy with subprocess
pass
def eval(self):
class Updater:
def __init__(self, config: Config):
self.config = config
# TODO: Make this configurable
self.current_drv = os.readlink("/run/current-system")
self.next_dev = None
# checkers take an url and returns the outPath of the latest success build
def garnix_checker(self) -> str:
domain = "garnix.io"
build_endpoint = "/api/build/commit"
# Latest commit from git
# Check build status of this commit
resp = requests.get(
f"https://{domain}{build_endpoint}/40b1e9ff23aaa5f555420dd22414c3f137a02cfe"
)
# Raise error if status code is not valid
# Fetch outPath from eval endpoint
# TODO: In theory, this could be done by parsing raw log from garnix.
# Try to evaluate locally if eval endpoint is not configured
resp = resp.json()
# TODO
return "null"
def hydra_checker(self) -> str:
# TODO
return "null"
# Check for update
def poll(self) -> str | None:
cfg = self.config
if cfg.check_type == "garnix":
pass
elif cfg.check_type == "hydra":
pass
else:
pass
pass
if __name__ == "__main__":
pass