mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-20 21:48:47 +02:00
v0.4.4 : le bouton mise a jour redemarre automatiquement jean-link
Apres une MAJ depuis l'UI, plus besoin de SSH sur le serveur pour finir : sur Linux/systemd le service jean-link est relance tout seul (differe + --no-block, la reponse HTTP part d'abord ; jean.service/llama-server n'est PAS touche pour ne pas recharger le modele). La cle E2E survit au restart, l'UI se reconnecte seule. Poste client/Windows : comportement inchange (message d'indice).
This commit is contained in:
1 parent
6cb678d42d
commit
e0e5118063
6 files changed
+41
-7
No files matched your search
@@ -16,7 +16,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
const Version = "0.4.3"
|
const Version = "0.4.4"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Migration one-shot des anciens skills (SKILLS/<nom>/SKILL.md) vers la
|
// Migration one-shot des anciens skills (SKILLS/<nom>/SKILL.md) vers la
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+6
-1
@@ -672,7 +672,12 @@ async function applyUpdate(){
|
|||||||
msg.textContent='Téléchargement et installation…';
|
msg.textContent='Téléchargement et installation…';
|
||||||
try{
|
try{
|
||||||
const r=await jpost('/api/update/apply',{});
|
const r=await jpost('/api/update/apply',{});
|
||||||
if(r.ok){ msg.innerHTML='✓ Installé en <b>v'+r.version+'</b>.<br>'+(r.restart||''); }
|
if(r.ok){
|
||||||
|
msg.innerHTML='✓ Installé en <b>v'+r.version+'</b>.<br>'+(r.restart||'');
|
||||||
|
// Redémarrage auto du service côté serveur : le flux va se couper puis
|
||||||
|
// reconnecter tout seul (connectStream boucle). On rafraîchit l'état après.
|
||||||
|
if(r.restarting){ toast('mise à jour appliquée — reconnexion…'); setTimeout(loadAll, 6000); }
|
||||||
|
}
|
||||||
else { msg.textContent='Échec : '+(r.error||'inconnu'); }
|
else { msg.textContent='Échec : '+(r.error||'inconnu'); }
|
||||||
}catch(e){ msg.textContent='Erreur pendant la mise à jour (réessaie).'; }
|
}catch(e){ msg.textContent='Erreur pendant la mise à jour (réessaie).'; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -263,14 +264,42 @@ func handleUpdateCheck(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// handleUpdateApply (POST /api/update/apply) : télécharge et installe la dernière
|
// handleUpdateApply (POST /api/update/apply) : télécharge et installe la dernière
|
||||||
// version, puis renvoie la version installée + l'indice de redémarrage.
|
// version. Sur un serveur Linux/systemd, relance ensuite AUTOMATIQUEMENT le service
|
||||||
|
// jean-link (celui qui sert l'UI, le chat et le tunnel) pour appliquer la MAJ sans
|
||||||
|
// avoir à SSH — voir restartAfterUpdate. Renvoie la version + le message de statut.
|
||||||
func handleUpdateApply(w http.ResponseWriter, r *http.Request) {
|
func handleUpdateApply(w http.ResponseWriter, r *http.Request) {
|
||||||
newVer, err := applyUpdate()
|
newVer, err := applyUpdate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sendJSON(w, 200, map[string]any{"ok": false, "error": err.Error()})
|
sendJSON(w, 200, map[string]any{"ok": false, "error": err.Error()})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sendJSON(w, 200, map[string]any{"ok": true, "version": newVer, "restart": restartHintText()})
|
restarting, msg := restartAfterUpdate()
|
||||||
|
if !restarting {
|
||||||
|
msg = restartHintText()
|
||||||
|
}
|
||||||
|
sendJSON(w, 200, map[string]any{"ok": true, "version": newVer, "restart": msg, "restarting": restarting})
|
||||||
|
}
|
||||||
|
|
||||||
|
// restartAfterUpdate relance le service jean-link juste après une MAJ déclenchée
|
||||||
|
// depuis l'UI, pour éviter le SSH manuel. Conditions : Linux/systemd + jean-link
|
||||||
|
// actif (le service tourne en root → systemctl passe sans sudo). On NE touche PAS à
|
||||||
|
// jean.service (llama-server) pour ne pas recharger le modèle (long et inattendu
|
||||||
|
// depuis un bouton « mettre à jour »). Le redémarrage est DIFFÉRÉ (la réponse HTTP
|
||||||
|
// doit partir d'abord) et lancé en --no-block : systemd enregistre le job puis nous
|
||||||
|
// arrête/relance ; la clé E2E (.e2e_key) survit au restart, donc pas de ré-appairage
|
||||||
|
// et l'UI se reconnecte toute seule (boucle de reconnexion du flux). Renvoie
|
||||||
|
// (déclenché, message). Non-serveur (poste client, Windows) → (false, "").
|
||||||
|
func restartAfterUpdate() (bool, string) {
|
||||||
|
if runtime.GOOS != "linux" || !linkServiceActive() {
|
||||||
|
return false, ""
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
time.Sleep(1500 * time.Millisecond) // laisser la réponse HTTP atteindre le client
|
||||||
|
// --no-block : on enregistre le job puis on rend la main ; systemd exécute le
|
||||||
|
// stop/start même si ce process (et le client systemctl) sont tués entre-temps.
|
||||||
|
_ = exec.Command("systemctl", "--no-block", "restart", linkServiceName).Run()
|
||||||
|
}()
|
||||||
|
return true, "Service " + linkServiceName + " redémarré automatiquement — la page va se reconnecter seule (le modèle n'est pas rechargé)."
|
||||||
}
|
}
|
||||||
|
|
||||||
func restartHintText() string {
|
func restartHintText() string {
|
||||||
|
|||||||
+3
-3
@@ -3,13 +3,13 @@
|
|||||||
"FileVersion": {
|
"FileVersion": {
|
||||||
"Major": 0,
|
"Major": 0,
|
||||||
"Minor": 4,
|
"Minor": 4,
|
||||||
"Patch": 3,
|
"Patch": 4,
|
||||||
"Build": 0
|
"Build": 0
|
||||||
},
|
},
|
||||||
"ProductVersion": {
|
"ProductVersion": {
|
||||||
"Major": 0,
|
"Major": 0,
|
||||||
"Minor": 4,
|
"Minor": 4,
|
||||||
"Patch": 3,
|
"Patch": 4,
|
||||||
"Build": 0
|
"Build": 0
|
||||||
},
|
},
|
||||||
"FileFlagsMask": "3f",
|
"FileFlagsMask": "3f",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"LegalCopyright": "Copyright (c) 2026 Jean contributors. MIT License.",
|
"LegalCopyright": "Copyright (c) 2026 Jean contributors. MIT License.",
|
||||||
"OriginalFilename": "jean.exe",
|
"OriginalFilename": "jean.exe",
|
||||||
"ProductName": "Jean",
|
"ProductName": "Jean",
|
||||||
"ProductVersion": "0.4.3",
|
"ProductVersion": "0.4.4",
|
||||||
"Comments": "https://github.com/nathaninline/jean — projet open source (MIT)"
|
"Comments": "https://github.com/nathaninline/jean — projet open source (MIT)"
|
||||||
},
|
},
|
||||||
"VarFileInfo": {
|
"VarFileInfo": {
|
||||||
|
|||||||
Reference in new issue
Block a user