LocalAI/pkg/oci/image.go
Ettore Di Giacinto efde0eaf83
Some checks are pending
build backend container images / backend-jobs (bark, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-bark, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-bark) (push) Waiting to run
build backend container images / backend-jobs (bark, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-bark, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-bark) (push) Waiting to run
build backend container images / backend-jobs (bark, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-bark, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-bark) (push) Waiting to run
build backend container images / backend-jobs (bark, ubuntu:22.04, , ./, , , ./backend/Dockerfile.go, latest-bark-cpp, linux/amd64, ubuntu-latest, true, -bark-cpp) (push) Waiting to run
build backend container images / backend-jobs (bark, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-bark, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-bark) (push) Waiting to run
Tests extras backends / tests-rerankers (push) Waiting to run
build backend container images / backend-jobs (bark, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-bark, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-bark) (push) Waiting to run
build backend container images / backend-jobs (chatterbox, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-chatterbox, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-chatterbox) (push) Waiting to run
build backend container images / backend-jobs (chatterbox, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-chatterbox, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-chatterbox) (push) Waiting to run
build backend container images / backend-jobs (coqui, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-coqui, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-coqui) (push) Waiting to run
build backend container images / backend-jobs (coqui, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-coqui, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-coqui) (push) Waiting to run
build backend container images / backend-jobs (coqui, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-coqui, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-coqui) (push) Waiting to run
build backend container images / backend-jobs (coqui, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-coqui, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-coqui) (push) Waiting to run
build backend container images / backend-jobs (coqui, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-coqui, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-coqui) (push) Waiting to run
build backend container images / backend-jobs (diffusers, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-diffusers, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-diffusers) (push) Waiting to run
build backend container images / backend-jobs (diffusers, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-diffusers, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-diffusers) (push) Waiting to run
build backend container images / backend-jobs (diffusers, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-diffusers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-diffusers) (push) Waiting to run
build backend container images / backend-jobs (diffusers, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-diffusers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-diffusers) (push) Waiting to run
build backend container images / backend-jobs (faster-whisper, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-faster-whisper, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-faster-whisper) (push) Waiting to run
build backend container images / backend-jobs (faster-whisper, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-faster-whisper, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-faster-whisper) (push) Waiting to run
build backend container images / backend-jobs (faster-whisper, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-faster-whisper, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-faster-whisper) (push) Waiting to run
build backend container images / backend-jobs (faster-whisper, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-faster-whisper, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-faster-whisper) (push) Waiting to run
build backend container images / backend-jobs (faster-whisper, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-faster-whisper, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-faster-whisper) (push) Waiting to run
build backend container images / backend-jobs (kokoro, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-kokoro, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-kokoro) (push) Waiting to run
build backend container images / backend-jobs (kokoro, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-kokoro, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-kokoro) (push) Waiting to run
build backend container images / backend-jobs (kokoro, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-kokoro, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-kokoro) (push) Waiting to run
build backend container images / backend-jobs (kokoro, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-kokoro, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-kokoro) (push) Waiting to run
build backend container images / backend-jobs (kokoro, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-kokoro, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-kokoro) (push) Waiting to run
build backend container images / backend-jobs (rerankers, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-rerankers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-rerankers) (push) Waiting to run
build backend container images / backend-jobs (transformers, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-transformers, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-transformers) (push) Waiting to run
build backend container images / backend-jobs (transformers, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-transformers, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-transformers) (push) Waiting to run
build backend container images / backend-jobs (transformers, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-transformers, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-transformers) (push) Waiting to run
build backend container images / backend-jobs (transformers, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-transformers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-transformers) (push) Waiting to run
build backend container images / backend-jobs (transformers, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-transformers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-transformers) (push) Waiting to run
Explorer deployment / build-linux (push) Waiting to run
generate and publish intel docker caches / generate_caches (intel/oneapi-basekit:2025.1.0-0-devel-ubuntu22.04, linux/amd64, ubuntu-latest) (push) Waiting to run
build container images / core-image-build (-aio-gpu-nvidia-cuda-11, ubuntu:22.04, cublas, 11, 7, true, latest-gpu-nvidia-cuda-11, latest-aio-gpu-nvidia-cuda-11, --jobs=4 --output-sync=target, linux/amd64, ubuntu-latest, false, false, -cublas-cuda11) (push) Waiting to run
build container images / core-image-build (-aio-gpu-nvidia-cuda-12, ubuntu:22.04, cublas, 12, 0, true, latest-gpu-nvidia-cuda-12, latest-aio-gpu-nvidia-cuda-12, --jobs=4 --output-sync=target, linux/amd64, ubuntu-latest, false, false, -cublas-cuda12) (push) Waiting to run
build container images / core-image-build (-aio-gpu-vulkan, ubuntu:22.04, vulkan, true, latest-gpu-vulkan, latest-aio-gpu-vulkan, --jobs=4 --output-sync=target, linux/amd64, ubuntu-latest, false, false, -vulkan) (push) Waiting to run
build container images / gh-runner (nvcr.io/nvidia/l4t-jetpack:r36.4.0, cublas, 12, 0, true, latest-nvidia-l4t-arm64, --jobs=4 --output-sync=target, linux/arm64, ubuntu-24.04-arm, true, false, -nvidia-l4t-arm64) (push) Waiting to run
Security Scan / tests (push) Waiting to run
build backend container images / backend-jobs (rerankers, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-rerankers, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-rerankers) (push) Waiting to run
build backend container images / backend-jobs (rerankers, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-rerankers, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-rerankers) (push) Waiting to run
build backend container images / backend-jobs (rerankers, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-rerankers, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-rerankers) (push) Waiting to run
build backend container images / backend-jobs (rerankers, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-rerankers, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-rerankers) (push) Waiting to run
build backend container images / backend-jobs (vllm, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f16-vllm, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f16-vllm) (push) Waiting to run
build backend container images / backend-jobs (vllm, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, ./backend, , , ./backend/Dockerfile.python, latest-gpu-intel-sycl-f32-vllm, linux/amd64, ubuntu-latest, true, -gpu-intel-sycl-f32-vllm) (push) Waiting to run
build backend container images / backend-jobs (vllm, rocm/dev-ubuntu-22.04:6.1, hipblas, ./backend, , , ./backend/Dockerfile.python, latest-gpu-rocm-hipblas-vllm, linux/amd64, ubuntu-latest, true, -gpu-rocm-hipblas-vllm) (push) Waiting to run
build backend container images / backend-jobs (vllm, ubuntu:22.04, cublas, ./backend, 11, 7, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-11-vllm, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-11-vllm) (push) Waiting to run
build backend container images / backend-jobs (vllm, ubuntu:22.04, cublas, ./backend, 12, 0, ./backend/Dockerfile.python, latest-gpu-nvidia-cuda-12-vllm, linux/amd64, ubuntu-latest, true, -gpu-nvidia-cuda-12-vllm) (push) Waiting to run
GPU tests / ubuntu-latest (1.21.x) (push) Waiting to run
build container images / hipblas-jobs (-aio-gpu-hipblas, rocm/dev-ubuntu-22.04:6.1, hipblas, true, ubuntu:22.04, latest-gpu-hipblas, latest-aio-gpu-hipblas, --jobs=3 --output-sync=target, linux/amd64, ubuntu-latest, false, -hipblas) (push) Waiting to run
build container images / core-image-build (-aio-cpu, ubuntu:22.04, , true, latest-cpu, latest-aio-cpu, --jobs=4 --output-sync=target, linux/amd64,linux/arm64, ubuntu-latest, false, auto, ) (push) Waiting to run
build container images / core-image-build (-aio-gpu-intel-f16, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f16, true, ubuntu:22.04, latest-gpu-intel-f16, latest-aio-gpu-intel-f16, --jobs=3 --output-sync=target, linux/amd64, ubuntu-latest, false, -sycl-f16) (push) Waiting to run
build container images / core-image-build (-aio-gpu-intel-f32, quay.io/go-skynet/intel-oneapi-base:latest, sycl_f32, true, ubuntu:22.04, latest-gpu-intel-f32, latest-aio-gpu-intel-f32, --jobs=3 --output-sync=target, linux/amd64, ubuntu-latest, false, -sycl-f32) (push) Waiting to run
Tests extras backends / tests-transformers (push) Waiting to run
tests / tests-linux (1.21.x) (push) Waiting to run
tests / tests-aio-container (push) Waiting to run
tests / tests-apple (1.21.x) (push) Waiting to run
Tests extras backends / tests-diffusers (push) Waiting to run
Tests extras backends / tests-coqui (push) Waiting to run
feat(backend gallery): display download progress (#5687)
Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
2025-06-18 23:49:44 +02:00

207 lines
5.2 KiB
Go

package oci
import (
"context"
"errors"
"fmt"
"io"
"net/http"
"runtime"
"strconv"
"strings"
"syscall"
"time"
"github.com/containerd/containerd/archive"
registrytypes "github.com/docker/docker/api/types/registry"
"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/logs"
"github.com/google/go-containerregistry/pkg/name"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
)
// ref: https://github.com/mudler/luet/blob/master/pkg/helpers/docker/docker.go#L117
type staticAuth struct {
auth *registrytypes.AuthConfig
}
func (s staticAuth) Authorization() (*authn.AuthConfig, error) {
if s.auth == nil {
return nil, nil
}
return &authn.AuthConfig{
Username: s.auth.Username,
Password: s.auth.Password,
Auth: s.auth.Auth,
IdentityToken: s.auth.IdentityToken,
RegistryToken: s.auth.RegistryToken,
}, nil
}
var defaultRetryBackoff = remote.Backoff{
Duration: 1.0 * time.Second,
Factor: 3.0,
Jitter: 0.1,
Steps: 3,
}
var defaultRetryPredicate = func(err error) bool {
if err == nil {
return false
}
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, io.EOF) || errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET) || strings.Contains(err.Error(), "connection refused") {
logs.Warn.Printf("retrying %v", err)
return true
}
return false
}
type progressWriter struct {
written int64
total int64
fileName string
downloadStatus func(string, string, string, float64)
}
func formatBytes(bytes int64) string {
const unit = 1024
if bytes < unit {
return strconv.FormatInt(bytes, 10) + " B"
}
div, exp := int64(unit), 0
for n := bytes / unit; n >= unit; n /= unit {
div *= unit
exp++
}
return fmt.Sprintf("%.1f %ciB", float64(bytes)/float64(div), "KMGTPE"[exp])
}
func (pw *progressWriter) Write(p []byte) (int, error) {
n := len(p)
pw.written += int64(n)
if pw.total > 0 {
percentage := float64(pw.written) / float64(pw.total) * 100
//log.Debug().Msgf("Downloading %s: %s/%s (%.2f%%)", pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
pw.downloadStatus(pw.fileName, formatBytes(pw.written), formatBytes(pw.total), percentage)
} else {
pw.downloadStatus(pw.fileName, formatBytes(pw.written), "", 0)
}
return n, nil
}
// ExtractOCIImage will extract a given targetImage into a given targetDestination
func ExtractOCIImage(img v1.Image, targetDestination string, downloadStatus func(string, string, string, float64)) error {
var reader io.Reader
reader = mutate.Extract(img)
if downloadStatus != nil {
var totalSize int64
layers, err := img.Layers()
if err != nil {
return err
}
for _, layer := range layers {
size, err := layer.Size()
if err != nil {
return err
}
totalSize += size
}
reader = io.TeeReader(reader, &progressWriter{total: totalSize, downloadStatus: downloadStatus})
}
_, err := archive.Apply(context.Background(),
targetDestination, reader,
archive.WithNoSameOwner())
return err
}
func ParseImageParts(image string) (tag, repository, dstimage string) {
tag = "latest"
repository = "library"
if strings.Contains(image, ":") {
parts := strings.Split(image, ":")
image = parts[0]
tag = parts[1]
}
if strings.Contains("/", image) {
parts := strings.Split(image, "/")
repository = parts[0]
image = parts[1]
}
dstimage = image
return tag, repository, image
}
// GetImage if returns the proper image to pull with transport and auth
// tries local daemon first and then fallbacks into remote
// if auth is nil, it will try to use the default keychain https://github.com/google/go-containerregistry/tree/main/pkg/authn#tldr-for-consumers-of-this-package
func GetImage(targetImage, targetPlatform string, auth *registrytypes.AuthConfig, t http.RoundTripper) (v1.Image, error) {
var platform *v1.Platform
var image v1.Image
var err error
if targetPlatform != "" {
platform, err = v1.ParsePlatform(targetPlatform)
if err != nil {
return image, err
}
} else {
platform, err = v1.ParsePlatform(fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH))
if err != nil {
return image, err
}
}
ref, err := name.ParseReference(targetImage)
if err != nil {
return image, err
}
if t == nil {
t = http.DefaultTransport
}
tr := transport.NewRetry(t,
transport.WithRetryBackoff(defaultRetryBackoff),
transport.WithRetryPredicate(defaultRetryPredicate),
)
opts := []remote.Option{
remote.WithTransport(tr),
remote.WithPlatform(*platform),
}
if auth != nil {
opts = append(opts, remote.WithAuth(staticAuth{auth}))
} else {
opts = append(opts, remote.WithAuthFromKeychain(authn.DefaultKeychain))
}
image, err = remote.Image(ref, opts...)
return image, err
}
func GetOCIImageSize(targetImage, targetPlatform string, auth *registrytypes.AuthConfig, t http.RoundTripper) (int64, error) {
var size int64
var img v1.Image
var err error
img, err = GetImage(targetImage, targetPlatform, auth, t)
if err != nil {
return size, err
}
layers, _ := img.Layers()
for _, layer := range layers {
s, _ := layer.Size()
size += s
}
return size, nil
}