Files
runtime/apps/cli/cmd/common/build.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

141 lines
4.0 KiB
Go

// Copyright 2025 Hanzo Industries Inc.
// SPDX-License-Identifier: AGPL-3.0
package common
import (
"context"
"fmt"
"net/url"
"os"
"path/filepath"
"github.com/hanzoai/apiclient"
apiclient_cli "github.com/hanzoai/runtime/cli/apiclient"
"github.com/hanzoai/runtime/cli/pkg/minio"
)
// Create MinIO client from access parameters
func CreateMinioClient(accessParams *apiclient.StorageAccessDto) (*minio.Client, error) {
storageURL, err := url.Parse(accessParams.StorageUrl)
if err != nil {
return nil, fmt.Errorf("invalid storage URL: %w", err)
}
minioClient, err := minio.NewClient(
storageURL.Host,
accessParams.AccessKey,
accessParams.Secret,
accessParams.Bucket,
storageURL.Scheme == "https",
accessParams.SessionToken,
)
if err != nil {
return nil, fmt.Errorf("failed to create storage client: %w", err)
}
return minioClient, nil
}
// List existing objects in MinIO
func ListExistingObjects(ctx context.Context, minioClient *minio.Client, orgID string) (map[string]bool, error) {
objects, err := minioClient.ListObjects(ctx, orgID)
if err != nil {
return nil, fmt.Errorf("failed to list objects: %w", err)
}
existingObjects := make(map[string]bool)
for _, obj := range objects {
existingObjects[obj] = true
}
return existingObjects, nil
}
// getContextHashes processes context paths and returns their hashes
func getContextHashes(ctx context.Context, apiClient *apiclient.APIClient, contextPaths []string) ([]string, error) {
contextHashes := []string{}
if len(contextPaths) == 0 {
return contextHashes, nil
}
// Get storage access parameters
accessParams, res, err := apiClient.ObjectStorageAPI.GetPushAccess(ctx).Execute()
if err != nil {
return nil, apiclient_cli.HandleErrorResponse(res, err)
}
// Create MinIO client
minioClient, err := CreateMinioClient(accessParams)
if err != nil {
return nil, fmt.Errorf("failed to create storage client: %w", err)
}
// List existing objects to avoid re-uploading
existingObjects, err := ListExistingObjects(ctx, minioClient, accessParams.OrganizationId)
if err != nil {
return nil, fmt.Errorf("failed to list existing objects: %w", err)
}
// Process each context path
for _, contextPath := range contextPaths {
absPath, err := filepath.Abs(contextPath)
if err != nil {
return nil, fmt.Errorf("invalid context path %s: %w", contextPath, err)
}
fileInfo, err := os.Stat(absPath)
if err != nil {
return nil, fmt.Errorf("failed to access context path %s: %w", contextPath, err)
}
if fileInfo.IsDir() {
// Process directory
dirHashes, err := minioClient.ProcessDirectory(ctx, absPath, accessParams.OrganizationId, existingObjects)
if err != nil {
return nil, fmt.Errorf("failed to process directory %s: %w", absPath, err)
}
contextHashes = append(contextHashes, dirHashes...)
} else {
// Process single file
hash, err := minioClient.ProcessFile(ctx, absPath, accessParams.OrganizationId, existingObjects)
if err != nil {
return nil, fmt.Errorf("failed to process file %s: %w", absPath, err)
}
contextHashes = append(contextHashes, hash)
}
}
return contextHashes, nil
}
func GetCreateBuildInfoDto(ctx context.Context, dockerfilePath string, contextPaths []string) (*apiclient.CreateBuildInfo, error) {
dockerfileAbsPath, err := filepath.Abs(dockerfilePath)
if err != nil {
return nil, fmt.Errorf("invalid dockerfile path: %w", err)
}
if _, err := os.Stat(dockerfileAbsPath); os.IsNotExist(err) {
return nil, fmt.Errorf("dockerfile does not exist: %s", dockerfileAbsPath)
}
dockerfileContent, err := os.ReadFile(dockerfileAbsPath)
if err != nil {
return nil, fmt.Errorf("failed to read dockerfile: %w", err)
}
apiClient, err := apiclient_cli.GetApiClient(nil, nil)
if err != nil {
return nil, err
}
contextHashes, err := getContextHashes(ctx, apiClient, contextPaths)
if err != nil {
return nil, err
}
return &apiclient.CreateBuildInfo{
DockerfileContent: string(dockerfileContent),
ContextHashes: contextHashes,
}, nil
}