Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/runner/cmd/runner/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ type Config struct {
AWSSecretAccessKey string `envconfig:"AWS_SECRET_ACCESS_KEY"`
AWSDefaultBucket string `envconfig:"AWS_DEFAULT_BUCKET"`
ResourceLimitsDisabled bool `envconfig:"RESOURCE_LIMITS_DISABLED"`
DaemonStartTimeoutSec int `envconfig:"DAEMON_START_TIMEOUT_SEC"`
BoxStartTimeoutSec int `envconfig:"BOX_START_TIMEOUT_SEC"`
UseSnapshotEntrypoint bool `envconfig:"USE_SNAPSHOT_ENTRYPOINT"`
Domain string `envconfig:"RUNNER_DOMAIN" validate:"omitempty,hostname|ip"`
Expand Down
1 change: 0 additions & 1 deletion apps/runner/cmd/runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ func run() int {
VolumeCleanupInterval: cfg.VolumeCleanupInterval,
VolumeCleanupDryRun: cfg.VolumeCleanupDryRun,
VolumeCleanupExclusionPeriod: cfg.VolumeCleanupExclusionPeriod,
ToolboxReadyTimeout: time.Duration(cfg.DaemonStartTimeoutSec) * time.Second,
})
if err != nil {
logger.Error("Error creating BoxLite client", "error", err)
Expand Down
14 changes: 0 additions & 14 deletions apps/runner/pkg/boxlite/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ type Client struct {
volumeMutexesMutex sync.Mutex
volumeCleanupMutex sync.Mutex
toolboxPortMutex sync.Mutex
toolboxReadyTimeout time.Duration
lastVolumeCleanup time.Time
volumeCleanup volumeCleanupConfig
}
Expand All @@ -56,7 +55,6 @@ type ClientConfig struct {
VolumeCleanupInterval time.Duration
VolumeCleanupDryRun bool
VolumeCleanupExclusionPeriod time.Duration
ToolboxReadyTimeout time.Duration
}

func networkSpec(blockAll *bool, allowList *string) boxlite.NetworkSpec {
Expand Down Expand Up @@ -136,11 +134,6 @@ func buildImageRegistries(insecureRegistries []string, ghcrUsername, ghcrToken s

// NewClient creates a new BoxLite client backed by the BoxLite VM runtime.
func NewClient(ctx context.Context, config ClientConfig) (*Client, error) {
toolboxReadyTimeout := config.ToolboxReadyTimeout
if toolboxReadyTimeout <= 0 {
toolboxReadyTimeout = 30 * time.Second
}

var opts []boxlite.RuntimeOption
if config.HomeDir != "" {
opts = append(opts, boxlite.WithHomeDir(config.HomeDir))
Expand Down Expand Up @@ -171,7 +164,6 @@ func NewClient(ctx context.Context, config ClientConfig) (*Client, error) {
awsAccessKeyId: config.AWSAccessKeyId,
awsSecretAccessKey: config.AWSSecretAccessKey,
volumeMutexes: make(map[string]*sync.Mutex),
toolboxReadyTimeout: toolboxReadyTimeout,
volumeCleanup: volumeCleanupConfig{
interval: config.VolumeCleanupInterval,
dryRun: config.VolumeCleanupDryRun,
Expand Down Expand Up @@ -305,9 +297,6 @@ func (c *Client) Create(ctx context.Context, boxDto dto.CreateBoxDTO) (string, s
if err := bx.Start(ctx); err != nil {
return bx.ID(), "", fmt.Errorf("failed to start box: %w", err)
}
if err := c.waitForToolboxReady(ctx, boxDto.Id); err != nil {
return bx.ID(), "", err
}
}

return bx.ID(), "boxlite", nil
Expand All @@ -326,9 +315,6 @@ func (c *Client) Start(ctx context.Context, boxId string, authToken *string, met
if err := bx.Start(ctx); err != nil {
return "", err
}
if err := c.waitForToolboxReady(ctx, boxId); err != nil {
return "", err
}
return "boxlite", nil
}

Expand Down
52 changes: 0 additions & 52 deletions apps/runner/pkg/boxlite/toolbox_ports.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
)

const (
Expand Down Expand Up @@ -62,55 +59,6 @@ func (c *Client) ToolboxHostPort(boxID string) (int, error) {
return c.readToolboxHostPort(boxID)
}

func (c *Client) waitForToolboxReady(ctx context.Context, boxID string) error {
hostPort, err := c.ToolboxHostPort(boxID)
if err != nil {
return fmt.Errorf("toolbox host port not available for box %s: %w", boxID, err)
}

timeout := c.toolboxReadyTimeout
if timeout <= 0 {
timeout = 30 * time.Second
}
readyCtx, cancel := context.WithTimeout(ctx, timeout)
defer cancel()

url := fmt.Sprintf("http://127.0.0.1:%d/version", hostPort)
client := http.Client{Timeout: time.Second}
ticker := time.NewTicker(200 * time.Millisecond)
defer ticker.Stop()

var lastErr error
for {
req, reqErr := http.NewRequestWithContext(readyCtx, http.MethodGet, url, nil)
if reqErr != nil {
return reqErr
}

resp, reqErr := client.Do(req)
if reqErr == nil {
_, _ = io.Copy(io.Discard, resp.Body)
_ = resp.Body.Close()
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
c.logger.InfoContext(ctx, "box toolbox is ready", "box", boxID, "hostPort", hostPort)
return nil
}
lastErr = fmt.Errorf("unexpected status %d from %s", resp.StatusCode, url)
} else {
lastErr = reqErr
}

select {
case <-readyCtx.Done():
if lastErr != nil {
return fmt.Errorf("box toolbox not ready after %s (box=%s hostPort=%d): %w", timeout, boxID, hostPort, lastErr)
}
return fmt.Errorf("box toolbox not ready after %s (box=%s hostPort=%d)", timeout, boxID, hostPort)
case <-ticker.C:
}
}
}

func (c *Client) removeToolboxPortRecord(ctx context.Context, boxID string) error {
c.toolboxPortMutex.Lock()
defer c.toolboxPortMutex.Unlock()
Expand Down
60 changes: 0 additions & 60 deletions apps/runner/pkg/boxlite/toolbox_ports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ package boxlite
import (
"io"
"log/slog"
"net"
"net/http"
"testing"
"time"
)

func TestReserveToolboxHostPortPersistsRecord(t *testing.T) {
Expand Down Expand Up @@ -55,60 +52,3 @@ func TestRemoveToolboxPortRecord(t *testing.T) {
}
}

func TestWaitForToolboxReadyReturnsAfterVersionEndpointResponds(t *testing.T) {
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
t.Fatalf("listen: %v", err)
}
mux := http.NewServeMux()
mux.HandleFunc("/version", func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"version":"test"}`))
})
server := &http.Server{Handler: mux}
go func() {
_ = server.Serve(listener)
}()
defer server.Close()

port := listener.Addr().(*net.TCPAddr).Port
client := &Client{
homeDir: t.TempDir(),
logger: slog.New(slog.NewTextHandler(io.Discard, nil)),
toolboxReadyTimeout: time.Second,
}
if err := client.writeToolboxPortRecord(toolboxPortRecord{
BoxID: "box-1",
GuestPort: ToolboxGuestPort,
HostPort: port,
}); err != nil {
t.Fatalf("writeToolboxPortRecord: %v", err)
}

if err := client.waitForToolboxReady(t.Context(), "box-1"); err != nil {
t.Fatalf("waitForToolboxReady: %v", err)
}
}

func TestWaitForToolboxReadyTimesOutWhenEndpointDoesNotRespond(t *testing.T) {
port, err := findAvailableLocalPort()
if err != nil {
t.Fatalf("findAvailableLocalPort: %v", err)
}
client := &Client{
homeDir: t.TempDir(),
logger: slog.New(slog.NewTextHandler(io.Discard, nil)),
toolboxReadyTimeout: 20 * time.Millisecond,
}
if err := client.writeToolboxPortRecord(toolboxPortRecord{
BoxID: "box-1",
GuestPort: ToolboxGuestPort,
HostPort: port,
}); err != nil {
t.Fatalf("writeToolboxPortRecord: %v", err)
}

if err := client.waitForToolboxReady(t.Context(), "box-1"); err == nil {
t.Fatal("expected waitForToolboxReady to time out")
}
}
Loading