Skip to content

Commit c35cebd

Browse files
committed
fix(embed): use go-rice for large backend assets
Golang embed FS has a hard limit that we might exceed when providing many binary alternatives. Signed-off-by: Ettore Di Giacinto <[email protected]>
1 parent 72111c5 commit c35cebd

File tree

11 files changed

+67
-27
lines changed

11 files changed

+67
-27
lines changed

.github/workflows/test.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ jobs:
9696
9797
go install google.golang.org/protobuf/cmd/[email protected]
9898
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
99+
go install github.com/GeertJohan/go.rice/rice@latest
99100
100101
# The python3-grpc-tools package in 22.04 is too old
101102
pip install --user grpcio-tools
@@ -183,6 +184,7 @@ jobs:
183184
rm protoc.zip
184185
go install google.golang.org/protobuf/cmd/[email protected]
185186
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
187+
go install github.com/GeertJohan/go.rice/rice@latest
186188
PATH="$PATH:$HOME/go/bin" make protogen-go
187189
- name: Build images
188190
run: |
@@ -222,6 +224,7 @@ jobs:
222224
run: |
223225
brew install protobuf grpc make protoc-gen-go protoc-gen-go-grpc libomp llvm
224226
pip install --user --no-cache-dir grpcio-tools
227+
go install github.com/GeertJohan/go.rice/rice@latest
225228
- name: Test
226229
run: |
227230
export C_INCLUDE_PATH=/usr/local/include

Dockerfile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ EOT
4646
RUN curl -L -s https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz | tar -C /usr/local -xz
4747
ENV PATH=$PATH:/root/go/bin:/usr/local/go/bin
4848

49-
# Install grpc compilers
49+
# Install grpc compilers and rice
5050
RUN go install google.golang.org/protobuf/cmd/[email protected] && \
51-
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af
51+
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@1958fcbe2ca8bd93af633f11e97d44e567e945af && \
52+
go install github.com/GeertJohan/go.rice/rice@latest
5253

5354
COPY --chmod=644 custom-ca-certs/* /usr/local/share/ca-certificates/
5455
RUN update-ca-certificates

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ clean: ## Remove build related file
320320
rm -rf $(BINARY_NAME)
321321
rm -rf release/
322322
rm -rf backend-assets/*
323+
rm -f rice-box.go
323324
$(MAKE) -C backend/cpp/grpc clean
324325
$(MAKE) -C backend/go/bark clean
325326
$(MAKE) -C backend/cpp/llama clean
@@ -348,6 +349,7 @@ ifneq ($(BACKEND_LIBS),)
348349
$(MAKE) backend-assets/lib
349350
cp -f $(BACKEND_LIBS) backend-assets/lib/
350351
endif
352+
go generate ./...
351353
CGO_LDFLAGS="$(CGO_LDFLAGS)" $(GOCMD) build -ldflags "$(LD_FLAGS)" -tags "$(GO_TAGS)" -o $(BINARY_NAME) ./
352354

353355
build-minimal:
@@ -424,6 +426,7 @@ test: prepare test-models/testmodel.ggml grpcs
424426
@echo 'Running tests'
425427
export GO_TAGS="tts debug"
426428
$(MAKE) prepare-test
429+
go generate ./...
427430
HUGGINGFACE_GRPC=$(abspath ./)/backend/python/transformers/run.sh TEST_DIR=$(abspath ./)/test-dir/ FIXTURES=$(abspath ./)/tests/fixtures CONFIG_FILE=$(abspath ./)/test-models/config.yaml MODELS_PATH=$(abspath ./)/test-models \
428431
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter="!llama-gguf" --flake-attempts $(TEST_FLAKES) --fail-fast -v -r $(TEST_PATHS)
429432
$(MAKE) test-llama-gguf
@@ -455,18 +458,22 @@ teardown-e2e:
455458
docker stop $$(docker ps -q --filter ancestor=localai-tests)
456459

457460
test-llama-gguf: prepare-test
461+
go generate ./...
458462
TEST_DIR=$(abspath ./)/test-dir/ FIXTURES=$(abspath ./)/tests/fixtures CONFIG_FILE=$(abspath ./)/test-models/config.yaml MODELS_PATH=$(abspath ./)/test-models \
459463
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter="llama-gguf" --flake-attempts $(TEST_FLAKES) -v -r $(TEST_PATHS)
460464

461465
test-tts: prepare-test
466+
go generate ./...
462467
TEST_DIR=$(abspath ./)/test-dir/ FIXTURES=$(abspath ./)/tests/fixtures CONFIG_FILE=$(abspath ./)/test-models/config.yaml MODELS_PATH=$(abspath ./)/test-models \
463468
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter="tts" --flake-attempts $(TEST_FLAKES) -v -r $(TEST_PATHS)
464469

465470
test-stablediffusion: prepare-test
471+
go generate ./...
466472
TEST_DIR=$(abspath ./)/test-dir/ FIXTURES=$(abspath ./)/tests/fixtures CONFIG_FILE=$(abspath ./)/test-models/config.yaml MODELS_PATH=$(abspath ./)/test-models \
467473
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter="stablediffusion" --flake-attempts $(TEST_FLAKES) -v -r $(TEST_PATHS)
468474

469475
test-stores: backend-assets/grpc/local-store
476+
go generate ./...
470477
mkdir -p tests/integration/backend-assets/grpc
471478
cp -f backend-assets/grpc/local-store tests/integration/backend-assets/grpc/
472479
$(GOCMD) run github.com/onsi/ginkgo/v2/ginkgo --label-filter="stores" --flake-attempts $(TEST_FLAKES) -v -r tests/integration

assets.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
package main
22

3-
import "embed"
3+
import (
4+
rice "github.com/GeertJohan/go.rice"
5+
)
46

5-
//go:embed backend-assets/*
6-
var backendAssets embed.FS
7+
//go:generate rice embed-go
8+
9+
var backendAssets *rice.Box
10+
11+
func init() {
12+
var err error
13+
backendAssets, err = rice.FindBox("backend-assets")
14+
if err != nil {
15+
panic(err)
16+
}
17+
}

core/cli/context/context.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package cliContext
22

3-
import "embed"
3+
import (
4+
rice "github.com/GeertJohan/go.rice"
5+
)
46

57
type Context struct {
68
Debug bool `env:"LOCALAI_DEBUG,DEBUG" default:"false" hidden:"" help:"DEPRECATED, use --log-level=debug instead. Enable debug logging"`
79
LogLevel *string `env:"LOCALAI_LOG_LEVEL" enum:"error,warn,info,debug,trace" help:"Set the level of logs to output [${enum}]"`
810

911
// This field is not a command line argument/flag, the struct tag excludes it from the parsed CLI
10-
BackendAssets embed.FS `kong:"-"`
12+
BackendAssets *rice.Box `kong:"-"`
1113
}

core/config/application_config.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ package config
22

33
import (
44
"context"
5-
"embed"
65
"encoding/json"
76
"regexp"
87
"time"
98

9+
rice "github.com/GeertJohan/go.rice"
1010
"github.com/mudler/LocalAI/pkg/xsysinfo"
1111
"github.com/rs/zerolog/log"
1212
)
@@ -47,7 +47,7 @@ type ApplicationConfig struct {
4747

4848
Galleries []Gallery
4949

50-
BackendAssets embed.FS
50+
BackendAssets *rice.Box
5151
AssetsDestination string
5252

5353
ExternalGRPCBackends map[string]string
@@ -198,7 +198,7 @@ func WithBackendAssetsOutput(out string) AppOption {
198198
}
199199
}
200200

201-
func WithBackendAssets(f embed.FS) AppOption {
201+
func WithBackendAssets(f *rice.Box) AppOption {
202202
return func(o *ApplicationConfig) {
203203
o.BackendAssets = f
204204
}

core/http/app_test.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package http_test
33
import (
44
"bytes"
55
"context"
6-
"embed"
76
"encoding/json"
87
"fmt"
98
"io"
@@ -24,6 +23,7 @@ import (
2423
. "github.com/onsi/gomega"
2524
"gopkg.in/yaml.v3"
2625

26+
rice "github.com/GeertJohan/go.rice"
2727
openaigo "github.com/otiai10/openaigo"
2828
"github.com/sashabaranov/go-openai"
2929
"github.com/sashabaranov/go-openai/jsonschema"
@@ -264,8 +264,15 @@ func getRequest(url string, header http.Header) (error, int, []byte) {
264264

265265
const bertEmbeddingsURL = `https://gist.githubusercontent.com/mudler/0a080b166b87640e8644b09c2aee6e3b/raw/f0e8c26bb72edc16d9fbafbfd6638072126ff225/bert-embeddings-gallery.yaml`
266266

267-
//go:embed backend-assets/*
268-
var backendAssets embed.FS
267+
var backendAssets *rice.Box
268+
269+
func init() {
270+
var err error
271+
backendAssets, err = rice.FindBox("backend-assets")
272+
if err != nil {
273+
panic(err)
274+
}
275+
}
269276

270277
var _ = Describe("API test", func() {
271278

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ require (
7575
cloud.google.com/go/auth v0.4.1 // indirect
7676
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
7777
cloud.google.com/go/compute/metadata v0.5.0 // indirect
78+
github.com/GeertJohan/go.rice v1.0.3 // indirect
79+
github.com/daaku/go.zipexe v1.0.2 // indirect
7880
github.com/dustin/go-humanize v1.0.1 // indirect
7981
github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect
8082
github.com/fasthttp/websocket v1.5.3 // indirect

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25
2121
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
2222
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
2323
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
24+
github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0=
25+
github.com/GeertJohan/go.rice v1.0.3 h1:k5viR+xGtIhF61125vCE1cmJ5957RQGXG6dmbaWZSmI=
26+
github.com/GeertJohan/go.rice v1.0.3/go.mod h1:XVdrU4pW00M4ikZed5q56tPf1v2KwnIKeIdc9CBYNt4=
2427
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
2528
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
2629
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
@@ -39,6 +42,7 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEV
3942
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
4043
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
4144
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
45+
github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
4246
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
4347
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
4448
github.com/alecthomas/chroma/v2 v2.8.0 h1:w9WJUjFFmHHB2e8mRpL9jjy3alYDlU0QLDezj1xE264=
@@ -108,6 +112,8 @@ github.com/creachadair/otp v0.5.0 h1:q3Th7CXm2zlmCdBjw5tEPFOj4oWJMnVL5HXlq0sNKS0
108112
github.com/creachadair/otp v0.5.0/go.mod h1:0kceI87EnYFNYSTL121goJVAnk3eJhaed9H0nMuJUkA=
109113
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
110114
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
115+
github.com/daaku/go.zipexe v1.0.2 h1:Zg55YLYTr7M9wjKn8SY/WcpuuEi+kR2u4E8RhvpyXmk=
116+
github.com/daaku/go.zipexe v1.0.2/go.mod h1:5xWogtqlYnfBXkSB1o9xysukNP9GTvaNkqzUZbt3Bw8=
111117
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2 h1:flLYmnQFZNo04x2NPehMbf30m7Pli57xwZ0NFqR/hb0=
112118
github.com/dave-gray101/v2keyauth v0.0.0-20240624150259-c45d584d25e2/go.mod h1:NtWqRzAp/1tw+twkW8uuBenEVVYndEAZACWU3F3xdoQ=
113119
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -531,6 +537,7 @@ github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJE
531537
github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
532538
github.com/nikolalohinski/gonja/v2 v2.3.2 h1:UgLFfqi7L9XfX0PEcE4eUpvGojVQL5KhBfJJaBp7ZxY=
533539
github.com/nikolalohinski/gonja/v2 v2.3.2/go.mod h1:1Wcc/5huTu6y36e0sOFR1XQoFlylw3c3H3L5WOz0RDg=
540+
github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc=
534541
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
535542
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
536543
github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY=
@@ -772,6 +779,7 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
772779
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
773780
github.com/valyala/fasthttp v1.55.0 h1:Zkefzgt6a7+bVKHnu/YaYSOPfNYNisSVBo/unVCf8k8=
774781
github.com/valyala/fasthttp v1.55.0/go.mod h1:NkY9JtkrpPKmgwV3HTaS2HWaJss9RSIsRVfcxxoHiOM=
782+
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
775783
github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8=
776784
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
777785
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=

pkg/assets/extract.go

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
package assets
22

33
import (
4-
"embed"
54
"fmt"
6-
"io/fs"
75
"os"
86
"path/filepath"
97

8+
rice "github.com/GeertJohan/go.rice"
109
"github.com/mudler/LocalAI/pkg/library"
1110
)
1211

1312
func ResolvePath(dir string, paths ...string) string {
1413
return filepath.Join(append([]string{dir, "backend-assets"}, paths...)...)
1514
}
1615

17-
func ExtractFiles(content embed.FS, extractDir string) error {
16+
func ExtractFiles(content *rice.Box, extractDir string) error {
1817
// Create the target directory if it doesn't exist
1918
err := os.MkdirAll(extractDir, 0750)
2019
if err != nil {
2120
return fmt.Errorf("failed to create directory: %v", err)
2221
}
2322

24-
// Walk through the embedded FS and extract files
25-
err = fs.WalkDir(content, ".", func(path string, d fs.DirEntry, err error) error {
23+
// Walk through the rice box and extract files
24+
err = content.Walk("", func(path string, info os.FileInfo, err error) error {
2625
if err != nil {
2726
return err
2827
}
2928

3029
// Reconstruct the directory structure in the target directory
3130
targetFile := filepath.Join(extractDir, path)
32-
if d.IsDir() {
31+
if info.IsDir() {
3332
// Create the directory in the target directory
3433
err := os.MkdirAll(targetFile, 0750)
3534
if err != nil {
@@ -38,8 +37,8 @@ func ExtractFiles(content embed.FS, extractDir string) error {
3837
return nil
3938
}
4039

41-
// Read the file from the embedded FS
42-
fileData, err := content.ReadFile(path)
40+
// Read the file from the rice box
41+
fileData, err := content.Bytes(path)
4342
if err != nil {
4443
return fmt.Errorf("failed to read file: %v", err)
4544
}

pkg/assets/list.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
package assets
22

33
import (
4-
"embed"
5-
"io/fs"
4+
"os"
65

6+
rice "github.com/GeertJohan/go.rice"
77
"github.com/rs/zerolog/log"
88
)
99

10-
func ListFiles(content embed.FS) (files []string) {
11-
err := fs.WalkDir(content, ".", func(path string, d fs.DirEntry, err error) error {
10+
func ListFiles(content *rice.Box) (files []string) {
11+
err := content.Walk("", func(path string, info os.FileInfo, err error) error {
1212
if err != nil {
1313
return err
1414
}
1515

16-
if d.IsDir() {
16+
if info.IsDir() {
1717
return nil
1818
}
1919

2020
files = append(files, path)
2121
return nil
2222
})
2323
if err != nil {
24-
log.Error().Err(err).Msg("error walking the embedded filesystem")
24+
log.Error().Err(err).Msg("error walking the rice box")
2525
}
2626
return
2727
}

0 commit comments

Comments
 (0)