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