Moteur : corrections de relecture de la construction des arguments

buildServeArgs se disait pure, mais la traduction des drapeaux de chargement
qu'elle appelle écrivait encore sur stderr quand un --load-mode dio tombait sur
un moteur ancien. La note est désormais rendue comme les autres et affichée
par cmdServe, au même rang qu'avant (avant la note NGL).

- normalizeLoadFlags / downgradeLoadMode rendent la note au lieu de l'écrire.
- Table de tests : cas dio sur moteur ancien (drapeau retiré, une note), et
  TestNormalizeLoadFlags vérifie que seul ce cas produit une note.
- Aucun changement de ligne de commande.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Opus 5.5 committed 2026-10-03 22:27:04 +02:00
1 parent 76f5697487
commit 03eb56aee3
3 files changed
+28 -9

No files matched your search

+14 -8
View File
@@ -165,7 +165,10 @@ func hasAnyFlag(args []string, flags ...string) bool {
// //
// none → --no-mmap · mlock → --mlock --no-mmap · mmap+mlock → --mlock // none → --no-mmap · mlock → --mlock --no-mmap · mmap+mlock → --mlock
// auto, mmap, dio → rien (défaut de l'ancien moteur) // auto, mmap, dio → rien (défaut de l'ancien moteur)
func normalizeLoadFlags(args []string, supportsLoadMode bool) []string { //
// La note éventuelle (dio abandonné) est RENDUE, pas affichée : buildServeArgs
// reste pure et c'est cmdServe qui l'écrit, à sa place parmi les autres notes.
func normalizeLoadFlags(args []string, supportsLoadMode bool) ([]string, string) {
if !supportsLoadMode { if !supportsLoadMode {
return downgradeLoadMode(args) return downgradeLoadMode(args)
} }
@@ -185,7 +188,7 @@ func normalizeLoadFlags(args []string, supportsLoadMode bool) []string {
} }
} }
if explicit || !(mlock || nommap || mmap) { if explicit || !(mlock || nommap || mmap) {
return out return out, ""
} }
mode := "mmap" mode := "mmap"
switch { switch {
@@ -196,12 +199,12 @@ func normalizeLoadFlags(args []string, supportsLoadMode bool) []string {
case nommap: case nommap:
mode = "none" mode = "none"
} }
return append(out, "--load-mode", mode) return append(out, "--load-mode", mode), ""
} }
// downgradeLoadMode retraduit un --load-mode pour un moteur qui ne le connaît // downgradeLoadMode retraduit un --load-mode pour un moteur qui ne le connaît
// pas : le lui passer tel quel le ferait sortir en erreur au démarrage. // pas : le lui passer tel quel le ferait sortir en erreur au démarrage.
func downgradeLoadMode(args []string) []string { func downgradeLoadMode(args []string) ([]string, string) {
mode, found := "", false mode, found := "", false
kept := make([]string, 0, len(args)) kept := make([]string, 0, len(args))
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
@@ -221,7 +224,7 @@ func downgradeLoadMode(args []string) []string {
kept = append(kept, a) kept = append(kept, a)
} }
if !found { if !found {
return args return args, ""
} }
add := func(flag string) { add := func(flag string) {
for _, a := range kept { for _, a := range kept {
@@ -240,9 +243,9 @@ func downgradeLoadMode(args []string) []string {
case "mmap+mlock": case "mmap+mlock":
add("--mlock") add("--mlock")
case "dio": case "dio":
fmt.Fprintf(os.Stderr, "[loki serve] ce moteur ne connaît pas --load-mode dio (DirectIO) : chargement par défaut\n") return kept, "ce moteur ne connaît pas --load-mode dio (DirectIO) : chargement par défaut"
} }
return kept return kept, ""
} }
// cmdServe replaces the historic start.sh: read config.env, build the // cmdServe replaces the historic start.sh: read config.env, build the
@@ -418,7 +421,10 @@ func buildServeArgs(cfg map[string]string, extra []string, bin string, si serveS
// l'utilisateur a écrit à la main décide des défauts que Loki a le droit // l'utilisateur a écrit à la main décide des défauts que Loki a le droit
// d'ajouter (voir hasAnyFlag). Il est aussi traduit vers les drapeaux de // d'ajouter (voir hasAnyFlag). Il est aussi traduit vers les drapeaux de
// chargement actuels quand le moteur les attend (voir normalizeLoadFlags). // chargement actuels quand le moteur les attend (voir normalizeLoadFlags).
extra = normalizeLoadFlags(extra, helpSupportsLoadMode(si.Help)) extra, loadNote := normalizeLoadFlags(extra, helpSupportsLoadMode(si.Help))
if loadNote != "" {
notes = append(notes, loadNote)
}
args = []string{bin, args = []string{bin,
"-m", si.Model, "-m", si.Model,
+8
View File
@@ -148,6 +148,14 @@ func TestBuildServeArgs(t *testing.T) {
si: serveSysInfo{Help: helpOld}, si: serveSysInfo{Help: helpOld},
want: with("--parallel", "1", "-ngl", "28", "--no-mmap"), want: with("--parallel", "1", "-ngl", "28", "--no-mmap"),
}, },
{
// dio n'existe pas sur l'ancien moteur : retiré, et dit par une note
// RENDUE (buildServeArgs n'écrit rien elle-même).
name: "--load-mode dio sur moteur ancien : retiré, une note",
cfg: map[string]string{"NGL": "28", "EXTRA_ARGS": "--load-mode dio -fa on"},
si: serveSysInfo{Help: helpOld},
want: with("--parallel", "1", "-ngl", "28", "-fa", "on"), wantNotes: 1,
},
{ {
name: "sélection GPU : variables d'environnement, ligne inchangée", name: "sélection GPU : variables d'environnement, ligne inchangée",
cfg: map[string]string{"NGL": "28", "CUDA_VISIBLE_DEVICES": "1,0"}, cfg: map[string]string{"NGL": "28", "CUDA_VISIBLE_DEVICES": "1,0"},
+6 -1
View File
@@ -60,10 +60,15 @@ func TestNormalizeLoadFlags(t *testing.T) {
} }
for _, c := range cases { for _, c := range cases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
got := normalizeLoadFlags(c.in, c.supports) got, note := normalizeLoadFlags(c.in, c.supports)
if !reflect.DeepEqual(got, c.want) { if !reflect.DeepEqual(got, c.want) {
t.Fatalf("got %q, want %q", got, c.want) t.Fatalf("got %q, want %q", got, c.want)
} }
// Seul « dio » abandonné sur un moteur ancien se signale : les autres
// traductions gardent le sens demandé.
if wantNote := c.name == "moteur ancien : dio abandonné"; (note != "") != wantNote {
t.Fatalf("note = %q, attendue : %v", note, wantNote)
}
}) })
} }
} }