Add main.lua
This commit is contained in:
206
main.lua
Normal file
206
main.lua
Normal file
@@ -0,0 +1,206 @@
|
||||
-- ============================================================
|
||||
-- startup.lua – Auto-updater pour repo Gitea privé
|
||||
-- ============================================================
|
||||
|
||||
-- ============================================================
|
||||
-- Chargement de la configuration
|
||||
-- ============================================================
|
||||
|
||||
local function loadConfig(path)
|
||||
if not fs.exists(path) then
|
||||
error("[Config] Fichier '" .. path .. "' introuvable !")
|
||||
end
|
||||
|
||||
local config = {}
|
||||
local f = fs.open(path, "r")
|
||||
local line = f.readLine()
|
||||
while line do
|
||||
-- Ignorer les lignes vides et les commentaires (#)
|
||||
if line ~= "" and not line:match("^%s*#") then
|
||||
local key, value = line:match("^([^=]+)=(.+)$")
|
||||
if key and value then
|
||||
config[trim(key)] = trim(value)
|
||||
end
|
||||
end
|
||||
line = f.readLine()
|
||||
end
|
||||
f.close()
|
||||
return config
|
||||
end
|
||||
|
||||
local function validateConfig(cfg)
|
||||
local required = { "gitea_base", "user", "repo", "branch", "program", "remote_ver", "check_interval" }
|
||||
for _, key in ipairs(required) do
|
||||
if not cfg[key] then
|
||||
error("[Config] Clé manquante dans config.cfg : '" .. key .. "'")
|
||||
end
|
||||
end
|
||||
cfg.check_interval = tonumber(cfg.check_interval)
|
||||
if not cfg.check_interval then
|
||||
error("[Config] 'check_interval' doit être un nombre.")
|
||||
end
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Utilitaires fichiers
|
||||
-- ============================================================
|
||||
|
||||
local function readFile(path)
|
||||
if not fs.exists(path) then return nil end
|
||||
local f = fs.open(path, "r")
|
||||
local content = f.readAll()
|
||||
f.close()
|
||||
return content
|
||||
end
|
||||
|
||||
local function writeFile(path, content)
|
||||
local f = fs.open(path, "w")
|
||||
f.write(content)
|
||||
f.close()
|
||||
end
|
||||
|
||||
function trim(s)
|
||||
return s:gsub("%s+", "")
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Gestion du token
|
||||
-- ============================================================
|
||||
|
||||
local function loadToken(path)
|
||||
local token = readFile(path or ".token")
|
||||
if not token then
|
||||
error("[Updater] Fichier '.token' introuvable !\n"
|
||||
.. "Crée-le avec : echo 'ton_token' > .token")
|
||||
end
|
||||
return trim(token)
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- HTTP avec auth Gitea
|
||||
-- ============================================================
|
||||
|
||||
local function buildRawUrl(cfg, filepath)
|
||||
return cfg.gitea_base
|
||||
.. "/" .. cfg.user
|
||||
.. "/" .. cfg.repo
|
||||
.. "/raw/branch/" .. cfg.branch
|
||||
.. "/" .. filepath
|
||||
end
|
||||
|
||||
local function fetchWithToken(url, token)
|
||||
local ok, res = pcall(function()
|
||||
return http.get(url, {
|
||||
["Authorization"] = "token " .. token,
|
||||
["Accept"] = "application/json",
|
||||
})
|
||||
end)
|
||||
|
||||
if not ok or not res then
|
||||
return nil, "Requête échouée vers : " .. url
|
||||
end
|
||||
|
||||
local code = res.getResponseCode()
|
||||
if code == 401 then
|
||||
res.close()
|
||||
return nil, "Token invalide ou expiré (401)"
|
||||
elseif code == 404 then
|
||||
res.close()
|
||||
return nil, "Fichier introuvable sur le repo (404)"
|
||||
elseif code ~= 200 then
|
||||
res.close()
|
||||
return nil, "Erreur HTTP " .. code
|
||||
end
|
||||
|
||||
local content = res.readAll()
|
||||
res.close()
|
||||
return content, nil
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Logique de mise à jour
|
||||
-- ============================================================
|
||||
|
||||
local function checkAndUpdate(cfg, token)
|
||||
print("[Updater] Vérification des mises à jour...")
|
||||
|
||||
local remoteVersion, err = fetchWithToken(buildRawUrl(cfg, cfg.remote_ver), token)
|
||||
if not remoteVersion then
|
||||
print("[Updater] " .. err)
|
||||
return false
|
||||
end
|
||||
remoteVersion = trim(remoteVersion)
|
||||
|
||||
local localVersion = readFile(".version")
|
||||
if localVersion then localVersion = trim(localVersion) end
|
||||
|
||||
if remoteVersion == localVersion then
|
||||
print("[Updater] Déjà à jour (v" .. remoteVersion .. ").")
|
||||
return false
|
||||
end
|
||||
|
||||
local prevVersion = localVersion or "aucune"
|
||||
print("[Updater] Mise à jour : v" .. prevVersion .. " → v" .. remoteVersion)
|
||||
|
||||
local newProgram, dlErr = fetchWithToken(buildRawUrl(cfg, cfg.program), token)
|
||||
if not newProgram then
|
||||
print("[Updater] Échec du téléchargement : " .. dlErr)
|
||||
return false
|
||||
end
|
||||
|
||||
writeFile(cfg.program, newProgram)
|
||||
writeFile(".version", remoteVersion)
|
||||
print("[Updater] Mise à jour appliquée (v" .. remoteVersion .. ").")
|
||||
return true
|
||||
end
|
||||
|
||||
-- ============================================================
|
||||
-- Programme principal
|
||||
-- ============================================================
|
||||
|
||||
local function runProgram(cfg)
|
||||
print("[Updater] Lancement de " .. cfg.program .. "...")
|
||||
shell.run(cfg.program)
|
||||
print("[Updater] Le programme s'est arrêté.")
|
||||
end
|
||||
|
||||
local function watcherLoop(cfg, token)
|
||||
while true do
|
||||
sleep(cfg.check_interval)
|
||||
local updated = checkAndUpdate(cfg, token)
|
||||
if updated then
|
||||
print("[Updater] Redémarrage dans 2 secondes...")
|
||||
sleep(2)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function main()
|
||||
print("=== Auto-updater Gitea ===")
|
||||
|
||||
local cfg = loadConfig("config.cfg")
|
||||
validateConfig(cfg)
|
||||
print("[Config] Configuration chargée.")
|
||||
|
||||
local token = loadToken(".token")
|
||||
print("[Updater] Token chargé.")
|
||||
|
||||
checkAndUpdate(cfg, token)
|
||||
|
||||
if not fs.exists(cfg.program) then
|
||||
print("[Updater] Aucun programme disponible. Abandon.")
|
||||
return
|
||||
end
|
||||
|
||||
parallel.waitForAny(
|
||||
function() runProgram(cfg) end,
|
||||
function() watcherLoop(cfg, token) end
|
||||
)
|
||||
|
||||
print("[Updater] Redémarrage du système...")
|
||||
sleep(1)
|
||||
os.reboot()
|
||||
end
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user