mirror of
https://github.com/hanzoai/runtime.git
synced 2026-10-30 18:23:13 +00:00
- 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
115 lines
2.8 KiB
Go
115 lines
2.8 KiB
Go
// Copyright 2025 Hanzo Industries Inc.
|
|
// SPDX-License-Identifier: AGPL-3.0
|
|
|
|
package docker
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/hanzoai/common-go/pkg/timer"
|
|
"github.com/hanzoai/runner/internal/constants"
|
|
"github.com/hanzoai/runner/pkg/api/dto"
|
|
"github.com/hanzoai/runner/pkg/common"
|
|
"github.com/hanzoai/runner/pkg/models/enums"
|
|
"github.com/docker/docker/errdefs"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func (d *DockerClient) Create(ctx context.Context, sandboxDto dto.CreateSandboxDTO) (string, error) {
|
|
defer timer.Timer()()
|
|
|
|
startTime := time.Now()
|
|
defer func() {
|
|
obs, err := common.ContainerOperationDuration.GetMetricWithLabelValues("create")
|
|
if err == nil {
|
|
obs.Observe(time.Since(startTime).Seconds())
|
|
}
|
|
}()
|
|
|
|
state, err := d.DeduceSandboxState(ctx, sandboxDto.Id)
|
|
if err != nil && state == enums.SandboxStateError {
|
|
return "", err
|
|
}
|
|
|
|
if state == enums.SandboxStateStarted || state == enums.SandboxStatePullingSnapshot || state == enums.SandboxStateStarting {
|
|
return sandboxDto.Id, nil
|
|
}
|
|
|
|
if state == enums.SandboxStateStopped || state == enums.SandboxStateCreating {
|
|
err = d.Start(ctx, sandboxDto.Id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return sandboxDto.Id, nil
|
|
}
|
|
|
|
d.cache.SetSandboxState(ctx, sandboxDto.Id, enums.SandboxStateCreating)
|
|
|
|
ctx = context.WithValue(ctx, constants.ID_KEY, sandboxDto.Id)
|
|
err = d.PullImage(ctx, sandboxDto.Snapshot, sandboxDto.Registry)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
d.cache.SetSandboxState(ctx, sandboxDto.Id, enums.SandboxStateCreating)
|
|
|
|
err = d.validateImageArchitecture(ctx, sandboxDto.Snapshot)
|
|
if err != nil {
|
|
log.Errorf("ERROR: %s.\n", err.Error())
|
|
return "", err
|
|
}
|
|
|
|
volumeMountPathBinds := make([]string, 0)
|
|
if sandboxDto.Volumes != nil {
|
|
volumeMountPathBinds, err = d.getVolumesMountPathBinds(ctx, sandboxDto.Volumes)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
|
|
containerConfig, hostConfig, networkingConfig, err := d.getContainerConfigs(ctx, sandboxDto, volumeMountPathBinds)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
c, err := d.apiClient.ContainerCreate(ctx, containerConfig, hostConfig, networkingConfig, nil, sandboxDto.Id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
err = d.Start(ctx, sandboxDto.Id)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return c.ID, nil
|
|
}
|
|
|
|
func (p *DockerClient) validateImageArchitecture(ctx context.Context, image string) error {
|
|
defer timer.Timer()()
|
|
|
|
inspect, _, err := p.apiClient.ImageInspectWithRaw(ctx, image)
|
|
if err != nil {
|
|
if errdefs.IsNotFound(err) {
|
|
return err
|
|
}
|
|
return fmt.Errorf("failed to inspect image: %w", err)
|
|
}
|
|
|
|
arch := strings.ToLower(inspect.Architecture)
|
|
validArchs := []string{"amd64", "x86_64"}
|
|
|
|
for _, validArch := range validArchs {
|
|
if arch == validArch {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
return common.NewConflictError(fmt.Errorf("image %s architecture (%s) is not x64 compatible", image, inspect.Architecture))
|
|
}
|