Files
runtime/apps/runner/pkg/docker/image_pull.go
zeekay ea80dc3638 feat: Add new Dockerfiles and improve containerization
- Add main Dockerfile for production builds
- Add Dockerfile.runtime for secure code execution
- Add Dockerfile.runtime.fixed with improved configuration
- Include .dockerignore for build optimization
- Add integration documentation and publishing guides
- Update API and CLI components for better runtime support
- Enhance sandbox and container management features
2025-08-16 23:03:39 -05:00

91 lines
2.0 KiB
Go

// Copyright 2025 Hanzo Industries Inc.
// SPDX-License-Identifier: AGPL-3.0
package docker
import (
"context"
"encoding/base64"
"encoding/json"
"io"
"strings"
"github.com/hanzoai/common-go/pkg/timer"
"github.com/hanzoai/runner/internal/constants"
"github.com/hanzoai/runner/internal/util"
"github.com/hanzoai/runner/pkg/api/dto"
"github.com/hanzoai/runner/pkg/models/enums"
"github.com/docker/docker/api/types/image"
"github.com/docker/docker/api/types/registry"
"github.com/docker/docker/pkg/jsonmessage"
log "github.com/sirupsen/logrus"
)
func (d *DockerClient) PullImage(ctx context.Context, imageName string, reg *dto.RegistryDTO) error {
defer timer.Timer()()
tag := "latest"
lastColonIndex := strings.LastIndex(imageName, ":")
if lastColonIndex != -1 {
tag = imageName[lastColonIndex+1:]
}
if tag != "latest" {
exists, err := d.ImageExists(ctx, imageName, true)
if err != nil {
return err
}
if exists {
return nil
}
}
log.Infof("Pulling image %s...", imageName)
sandboxIdValue := ctx.Value(constants.ID_KEY)
if sandboxIdValue != nil {
sandboxId := sandboxIdValue.(string)
d.cache.SetSandboxState(ctx, sandboxId, enums.SandboxStatePullingSnapshot)
}
responseBody, err := d.apiClient.ImagePull(ctx, imageName, image.PullOptions{
RegistryAuth: getRegistryAuth(reg),
})
if err != nil {
return err
}
defer responseBody.Close()
err = jsonmessage.DisplayJSONMessagesStream(responseBody, io.Writer(&util.DebugLogWriter{}), 0, true, nil)
if err != nil {
return err
}
log.Infof("Image %s pulled successfully", imageName)
return nil
}
func getRegistryAuth(reg *dto.RegistryDTO) string {
if reg == nil {
// Sometimes registry auth fails if "" is sent, so sending "empty" instead
return "empty"
}
authConfig := registry.AuthConfig{
Username: reg.Username,
Password: reg.Password,
}
encodedJSON, err := json.Marshal(authConfig)
if err != nil {
// Sometimes registry auth fails if "" is sent, so sending "empty" instead
return "empty"
}
return base64.URLEncoding.EncodeToString(encodedJSON)
}