Skip to content

Commit 5dfbd0f

Browse files
committed
feat(cli): add command to create custom OCI images from directories
Signed-off-by: Ettore Di Giacinto <[email protected]>
1 parent fc02bc0 commit 5dfbd0f

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

core/cli/util.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,24 @@ import (
44
"encoding/json"
55
"errors"
66
"fmt"
7+
"os"
8+
"path/filepath"
9+
"strings"
710

11+
"github.com/mholt/archiver/v3"
812
"github.com/rs/zerolog/log"
913

1014
gguf "github.com/gpustack/gguf-parser-go"
1115
cliContext "github.com/mudler/LocalAI/core/cli/context"
1216
"github.com/mudler/LocalAI/core/config"
1317
"github.com/mudler/LocalAI/core/gallery"
1418
"github.com/mudler/LocalAI/pkg/downloader"
19+
"github.com/mudler/LocalAI/pkg/oci"
1520
)
1621

1722
type UtilCMD struct {
1823
GGUFInfo GGUFInfoCMD `cmd:"" name:"gguf-info" help:"Get information about a GGUF file"`
24+
CreateImage CreateImageCMD `cmd:"" name:"create-image" help:"Create an OCI image from a file or a directory"`
1925
HFScan HFScanCMD `cmd:"" name:"hf-scan" help:"Checks installed models for known security issues. WARNING: this is a best-effort feature and may not catch everything!"`
2026
UsecaseHeuristic UsecaseHeuristicCMD `cmd:"" name:"usecase-heuristic" help:"Checks a specific model config and prints what usecase LocalAI will offer for it."`
2127
}
@@ -36,6 +42,35 @@ type UsecaseHeuristicCMD struct {
3642
ModelsPath string `env:"LOCALAI_MODELS_PATH,MODELS_PATH" type:"path" default:"${basepath}/models" help:"Path containing models used for inferencing" group:"storage"`
3743
}
3844

45+
type CreateImageCMD struct {
46+
Input []string `arg:"" help:"Input file or directory to create an OCI image from"`
47+
Output string `default:"image.tar" help:"Output OCI image name"`
48+
ImageName string `default:"localai" help:"Image name"`
49+
Platform string `default:"linux/amd64" help:"Platform of the image"`
50+
}
51+
52+
func (u *CreateImageCMD) Run(ctx *cliContext.Context) error {
53+
log.Info().Msg("Creating OCI image from input")
54+
55+
dir, err := os.MkdirTemp("", "localai")
56+
if err != nil {
57+
return err
58+
}
59+
defer os.RemoveAll(dir)
60+
err = archiver.Archive(u.Input, filepath.Join(dir, "archive.tar"))
61+
if err != nil {
62+
return err
63+
}
64+
log.Info().Msgf("Creating '%s' as '%s' from %v", u.Output, u.Input, u.Input)
65+
66+
platform := strings.Split(u.Platform, "/")
67+
if len(platform) != 2 {
68+
return fmt.Errorf("invalid platform: %s", u.Platform)
69+
}
70+
71+
return oci.CreateTar(filepath.Join(dir, "archive.tar"), u.Output, u.ImageName, platform[1], platform[0])
72+
}
73+
3974
func (u *GGUFInfoCMD) Run(ctx *cliContext.Context) error {
4075
if u.Args == nil || len(u.Args) == 0 {
4176
return fmt.Errorf("no GGUF file provided")

0 commit comments

Comments
 (0)