feat(cli): add configurable backend image fallback tags via CLI options (#8817)

* feat(cli): add configurable backend image fallback tags via CLI options

- Add three new CLI flags: --backend-images-release-tag, --backend-images-branch-tag, --backend-dev-suffix
- Add corresponding fields to SystemState for passing configuration
- Add WithBackendImagesReleaseTag, WithBackendImagesBranchTag, WithBackendDevSuffix options
- Modify getFallbackTagValues to use SystemState instead of environment variables
- Pass CLI options through to SystemState in run.go

Signed-off-by: localai-bot <localai-bot@users.noreply.github.com>

* fix: add missing os import in core/gallery/backends.go

Signed-off-by: localai-bot <localai-bot@users.noreply.github.com>

---------

Signed-off-by: localai-bot <localai-bot@users.noreply.github.com>
Co-authored-by: localai-bot <localai-bot@users.noreply.github.com>
This commit is contained in:
LocalAI [bot]
2026-03-08 21:16:37 +01:00
committed by GitHub
parent 05b7cce633
commit 2334556a8f
3 changed files with 48 additions and 23 deletions

View File

@@ -35,6 +35,9 @@ type RunCMD struct {
Galleries string `env:"LOCALAI_GALLERIES,GALLERIES" help:"JSON list of galleries" group:"models" default:"${galleries}"`
AutoloadGalleries bool `env:"LOCALAI_AUTOLOAD_GALLERIES,AUTOLOAD_GALLERIES" group:"models" default:"true"`
AutoloadBackendGalleries bool `env:"LOCALAI_AUTOLOAD_BACKEND_GALLERIES,AUTOLOAD_BACKEND_GALLERIES" group:"backends" default:"true"`
BackendImagesReleaseTag string `env:"LOCALAI_BACKEND_IMAGES_RELEASE_TAG,BACKEND_IMAGES_RELEASE_TAG" help:"Fallback release tag for backend images" group:"backends" default:"latest"`
BackendImagesBranchTag string `env:"LOCALAI_BACKEND_IMAGES_BRANCH_TAG,BACKEND_IMAGES_BRANCH_TAG" help:"Fallback branch tag for backend images" group:"backends" default:"master"`
BackendDevSuffix string `env:"LOCALAI_BACKEND_DEV_SUFFIX,BACKEND_DEV_SUFFIX" help:"Development suffix for backend images" group:"backends" default:"development"`
PreloadModels string `env:"LOCALAI_PRELOAD_MODELS,PRELOAD_MODELS" help:"A List of models to apply in JSON at start" group:"models"`
Models []string `env:"LOCALAI_MODELS,MODELS" help:"A List of model configuration URLs to load" group:"models"`
PreloadModelsConfig string `env:"LOCALAI_PRELOAD_MODELS_CONFIG,PRELOAD_MODELS_CONFIG" help:"A List of models to apply at startup. Path to a YAML config file" group:"models"`
@@ -125,6 +128,9 @@ func (r *RunCMD) Run(ctx *cliContext.Context) error {
system.WithBackendSystemPath(r.BackendsSystemPath),
system.WithModelPath(r.ModelsPath),
system.WithBackendPath(r.BackendsPath),
system.WithBackendImagesReleaseTag(r.BackendImagesReleaseTag),
system.WithBackendImagesBranchTag(r.BackendImagesBranchTag),
system.WithBackendDevSuffix(r.BackendDevSuffix),
)
if err != nil {
return err

View File

@@ -4,10 +4,10 @@ package gallery
import (
"context"
"os"
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"time"
@@ -25,33 +25,29 @@ const (
runFile = "run.sh"
)
// Environment variables for configurable fallback URI patterns
// Default fallback tag values
const (
// Default fallback tag values
defaultLatestTag = "latest"
defaultMasterTag = "master"
defaultDevSuffix = "development"
// Environment variable names
envLatestTag = "LOCALAI_BACKEND_IMAGES_RELEASE_TAG"
envMasterTag = "LOCALAI_BACKEND_IMAGES_BRANCH_TAG"
envDevSuffix = "LOCALAI_BACKEND_DEV_SUFFIX"
)
// getFallbackTagValues returns the configurable fallback tag values from environment variables
func getFallbackTagValues() (latestTag, masterTag, devSuffix string) {
latestTag = os.Getenv(envLatestTag)
masterTag = os.Getenv(envMasterTag)
devSuffix = os.Getenv(envDevSuffix)
// Use defaults if environment variables are not set
if latestTag == "" {
// getFallbackTagValues returns the configurable fallback tag values from SystemState
func getFallbackTagValues(systemState *system.SystemState) (latestTag, masterTag, devSuffix string) {
// Use SystemState fields if set, otherwise use defaults
if systemState.BackendImagesReleaseTag != "" {
latestTag = systemState.BackendImagesReleaseTag
} else {
latestTag = defaultLatestTag
}
if masterTag == "" {
if systemState.BackendImagesBranchTag != "" {
masterTag = systemState.BackendImagesBranchTag
} else {
masterTag = defaultMasterTag
}
if devSuffix == "" {
if systemState.BackendDevSuffix != "" {
devSuffix = systemState.BackendDevSuffix
} else {
devSuffix = defaultDevSuffix
}
@@ -172,8 +168,8 @@ func InstallBackendFromGallery(ctx context.Context, galleries []config.Gallery,
}
func InstallBackend(ctx context.Context, systemState *system.SystemState, modelLoader *model.ModelLoader, config *GalleryBackend, downloadStatus func(string, string, string, float64)) error {
// Get configurable fallback tag values from environment variables
latestTag, masterTag, devSuffix := getFallbackTagValues()
// Get configurable fallback tag values from SystemState
latestTag, masterTag, devSuffix := getFallbackTagValues(systemState)
// Create base path if it doesn't exist
err := os.MkdirAll(systemState.Backend.BackendsPath, 0750)
@@ -225,7 +221,7 @@ func InstallBackend(ctx context.Context, systemState *system.SystemState, modelL
}
// Try fallback: replace latestTag + "-" with masterTag + "-" in the URI
fallbackURI := strings.Replace(string(config.URI), latestTag + "-", masterTag + "-", 1)
fallbackURI := strings.Replace(string(config.URI), latestTag+"-", masterTag+"-", 1)
if fallbackURI != string(config.URI) {
xlog.Debug("Trying fallback URI", "original", config.URI, "fallback", fallbackURI)
if err := downloader.URI(fallbackURI).DownloadFileWithContext(ctx, backendPath, "", 1, 1, downloadStatus); err == nil {
@@ -234,7 +230,7 @@ func InstallBackend(ctx context.Context, systemState *system.SystemState, modelL
} else {
// Try another fallback: add "-" + devSuffix suffix to the backend name
// For example: master-gpu-nvidia-cuda-13-ace-step -> master-gpu-nvidia-cuda-13-ace-step-development
if !strings.Contains(fallbackURI, "-" + devSuffix) {
if !strings.Contains(fallbackURI, "-"+devSuffix) {
// Extract backend name from URI and add -development
parts := strings.Split(fallbackURI, "-")
if len(parts) >= 2 {
@@ -441,7 +437,7 @@ func ListSystemBackends(systemState *system.SystemState) (SystemBackends, error)
metaMap[dir] = metadata
// Concrete backend entry
// Concrete-backend entry
if _, err := os.Stat(run); err == nil {
backends[dir] = SystemBackend{
Name: dir,

View File

@@ -21,6 +21,11 @@ type SystemState struct {
VRAM uint64
systemCapabilities string
// Backend image fallback tag configuration
BackendImagesReleaseTag string
BackendImagesBranchTag string
BackendDevSuffix string
}
type SystemStateOptions func(*SystemState)
@@ -43,6 +48,24 @@ func WithModelPath(path string) SystemStateOptions {
}
}
func WithBackendImagesReleaseTag(tag string) SystemStateOptions {
return func(s *SystemState) {
s.BackendImagesReleaseTag = tag
}
}
func WithBackendImagesBranchTag(tag string) SystemStateOptions {
return func(s *SystemState) {
s.BackendImagesBranchTag = tag
}
}
func WithBackendDevSuffix(suffix string) SystemStateOptions {
return func(s *SystemState) {
s.BackendDevSuffix = suffix
}
}
func GetSystemState(opts ...SystemStateOptions) (*SystemState, error) {
state := &SystemState{}
for _, opt := range opts {