Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
60ac8e4
Refactor: Support clip v2 OCI index-only images
cursoragent Oct 27, 2025
83ee0c9
feat: Use fuse-overlayfs as fallback for overlay mounts
cursoragent Oct 27, 2025
8e5d9d5
Refactor mount logic to prefer fuse-overlayfs for FUSE lowerdirs
cursoragent Oct 27, 2025
0e65c7e
feat: Update build container entrypoint and clipVersion
cursoragent Oct 27, 2025
ab41b69
Fix: Improve container keepalive command
cursoragent Oct 27, 2025
e733e59
bump clip version
luke-beamcloud Oct 27, 2025
976fbbe
Refactor image pulling to use correct archive path and OCI storage
cursoragent Oct 27, 2025
bb04eca
Refactor image pulling to handle OCI and S3 storage types
cursoragent Oct 27, 2025
663b53f
feat: Ensure runtime directories exist in rootfs
cursoragent Oct 27, 2025
b038d2e
feat: Implement Clip v2 build using buildah bud
cursoragent Oct 27, 2025
7f1c54c
Test: Add v2 Dockerfile rendering and skip runc for clip v2
cursoragent Oct 27, 2025
cc0e94f
Refactor: Improve image building and worker image handling
cursoragent Oct 27, 2025
9960976
Refactor: Remove SHELL directive for OCI builds and default registry URL
cursoragent Oct 27, 2025
2ef7747
Refactor: Use Clip's CreateFromOCIImage for archiving
cursoragent Oct 27, 2025
d9e42b9
feat: Add buildRegistry to ImageServiceConfig
cursoragent Oct 27, 2025
3a0f547
feat: Add insecure registry option for buildah push
cursoragent Oct 27, 2025
712707f
Refactor image pulling logic to handle S3 fallback
cursoragent Oct 27, 2025
476152e
Refactor Dockerfile generation for Python and build steps
cursoragent Oct 27, 2025
7a4f932
feat: Handle insecure registries for image builds
cursoragent Oct 27, 2025
34f5614
fix build error
luke-beamcloud Oct 27, 2025
0502616
feat: Support Clip v2 image builds and OCI runtime specs
cursoragent Oct 27, 2025
440f826
Refactor image building and archiving for Clip v2
cursoragent Oct 28, 2025
bcea28f
Refactor image building and pulling logic
cursoragent Oct 28, 2025
9efded2
Refactor image building and archiving to use remote references
cursoragent Oct 28, 2025
92b9042
feat: Skip runc container for Clip v2 builds
cursoragent Oct 28, 2025
d07d887
feat: Improve Clip v2 build handling and exit logic
cursoragent Oct 28, 2025
5d22f95
feat: Increment container wait group before finalizing
cursoragent Oct 28, 2025
c6b02bb
Refactor: Skip container wait for v2 builds and add nil check
cursoragent Oct 28, 2025
f33e8ea
feat: Improve image build and container run logic
cursoragent Oct 28, 2025
a71a88a
Refactor image build to always stream logs and improve v2 build output
cursoragent Oct 28, 2025
5a0f1a2
Refactor: Remove unused archiving stage logic in BuildImage
cursoragent Oct 28, 2025
7b11e82
feat: Add initial OCI runtime spec for v2 builds
cursoragent Oct 28, 2025
d88bfae
Refactor: Extract env and defaults from image config for OCI spec
cursoragent Oct 28, 2025
af457a7
Refactor: Ensure PATH env var is set correctly
cursoragent Oct 28, 2025
e6e5474
Refactor: Cache OCI runtime spec outside mount
cursoragent Oct 28, 2025
ac67482
Refactor: Simplify container entrypoint and env var handling
cursoragent Oct 28, 2025
736a90b
feat: Add exec option to overlay mount
cursoragent Oct 28, 2025
91d58ad
feat: Harden fuse-overlayfs mount flags
cursoragent Oct 28, 2025
988007a
Refactor: Use kernel overlayfs for all mounts
cursoragent Oct 28, 2025
67e38f0
wip
luke-beamcloud Oct 28, 2025
3ce63b7
Add essential directories to container rootfs
cursoragent Oct 28, 2025
365a3db
Harden overlayfs mount options for FUSE lowers
cursoragent Oct 28, 2025
76e6401
feat: Mount tmpfs over runtime directories for stability
cursoragent Oct 28, 2025
7c335c2
fix exec import
luke-beamcloud Oct 28, 2025
f7a9b54
Refactor: Simplify overlayfs mount options
cursoragent Oct 28, 2025
fde4d7c
Refactor container spec and environment handling for v2
cursoragent Oct 28, 2025
4391415
fix panic
luke-beamcloud Oct 28, 2025
b41cef8
wip
luke-beamcloud Oct 28, 2025
52e1141
wip
luke-beamcloud Oct 28, 2025
28c78cf
wip
luke-beamcloud Oct 28, 2025
fd1b0a4
bump clip
luke-beamcloud Oct 28, 2025
0c3fa1a
feat: Derive initial spec from image if missing
cursoragent Oct 28, 2025
1e9706b
Refactor: Support Clip v2 builds and standard pip
cursoragent Oct 29, 2025
ed42e85
Refactor image building for Clip v2 compatibility
cursoragent Oct 29, 2025
2ce3b51
Refactor image ID generation and container request logic
cursoragent Oct 29, 2025
455c384
Refactor: derive OCI spec from source image metadata
cursoragent Oct 29, 2025
f4d92b1
Refactor: Simplify environment variable assignment in Worker
cursoragent Oct 29, 2025
65c260d
feat: Cache and use source image refs for v2 images
cursoragent Oct 29, 2025
0f13e5a
feat: Skip python install for beta9 base images
cursoragent Oct 29, 2025
ae757b4
clean up logging
luke-beamcloud Oct 29, 2025
1084ac2
wip
luke-beamcloud Oct 29, 2025
5b69223
Integrate and refine clipv2 build pipeline (#1464)
luke-lombardi Oct 30, 2025
6d6562d
Fix custom dockerfile image pull issue (#1465)
luke-lombardi Oct 30, 2025
3a47c50
Fix and test workspace directory creation (#1466)
luke-lombardi Oct 30, 2025
7da417b
wip
luke-beamcloud Oct 30, 2025
daad097
Fix; complete runtime secret passing for image credentials (#1472)
luke-lombardi Oct 31, 2025
8892dde
fix build error
luke-beamcloud Oct 31, 2025
6321a85
Fix image credential tests (#1476)
luke-lombardi Oct 31, 2025
236e6a6
Fix image credential attachment on first build (#1477)
luke-lombardi Oct 31, 2025
0d07a0e
Fix authenticated image inspect for builds (#1478)
luke-lombardi Oct 31, 2025
23c4f3b
wip
luke-beamcloud Oct 31, 2025
cb7506a
Fix CLIP image credential management (#1479)
luke-lombardi Oct 31, 2025
22c3a79
remove md files
luke-beamcloud Oct 31, 2025
ff1c399
fix credential helpers for clip v2 (#1481)
luke-lombardi Nov 1, 2025
39d5a4f
Fix credential secret upsert logic for tagged images (#1483)
luke-lombardi Nov 1, 2025
061fff5
remove test
luke-beamcloud Nov 1, 2025
3cfbeb9
clean up some comments
luke-beamcloud Nov 1, 2025
fd72075
disable checkpoints temporarily
luke-beamcloud Nov 1, 2025
94db1ff
cleanup
luke-beamcloud Nov 1, 2025
dce97cf
wip
luke-beamcloud Nov 1, 2025
d77e197
rename svc
luke-beamcloud Nov 1, 2025
97d1f2d
remove comment
luke-beamcloud Nov 1, 2025
b407c05
wip
luke-beamcloud Nov 1, 2025
40eb72c
bump clip
luke-beamcloud Nov 1, 2025
97e6539
Integrate OCI image metadata into index (#1485)
luke-lombardi Nov 1, 2025
a3178a9
Fix v2 clip image authentication and env issues (#1486)
luke-lombardi Nov 1, 2025
8001876
Debug CLIP V2 env and secrets handling (#1487)
luke-lombardi Nov 1, 2025
9935f09
bump clip
luke-beamcloud Nov 3, 2025
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ test
**/nvidia-device-plugin.yaml.skip
manifests/**/charts/**
build.sh
oci*
.coverage
.htmlcov
okteto.yaml
Expand Down
14 changes: 10 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ require (
github.com/aws/aws-sdk-go-v2/credentials v1.17.24
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.9
github.com/aws/aws-sdk-go-v2/service/ec2 v1.144.0
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.4
github.com/aws/aws-sdk-go-v2/service/ecr v1.27.0
github.com/aws/aws-sdk-go-v2/service/s3 v1.58.0
github.com/beam-cloud/blobcache-v2 v0.0.0-20250503151236-e2403183f563
github.com/beam-cloud/clip v0.0.0-20250815141247-71e2dd6c441d
github.com/beam-cloud/clip v0.0.0-20251103022546-c75714e105c1
github.com/beam-cloud/go-runc v0.0.0-20250911154456-bb45084abfe1
github.com/beam-cloud/goproc v0.1.5
github.com/beam-cloud/redislock v0.0.0-20250201162619-1b534b3be324
Expand All @@ -29,6 +29,7 @@ require (
github.com/go-playground/validator/v10 v10.26.0
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/gofrs/uuid v4.4.0+incompatible
github.com/google/go-containerregistry v0.19.1
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/google/uuid v1.6.0
github.com/gorilla/websocket v1.5.3
Expand Down Expand Up @@ -112,7 +113,11 @@ require (
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/aws/aws-sdk-go v1.55.6 // indirect
github.com/beam-cloud/rendezvous v0.0.0-20250415141250-2a0f81633db8 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/docker/cli v27.5.0+incompatible // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/docker-credential-helpers v0.8.2 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
github.com/go-playground/locales v0.14.1 // indirect
Expand All @@ -127,6 +132,7 @@ require (
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/vbatts/tar-split v0.11.6 // indirect
github.com/winfsp/cgofuse v1.5.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
Expand Down Expand Up @@ -167,7 +173,7 @@ require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/coder/websocket v1.8.12 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
github.com/cyphar/filepath-securejoin v0.3.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dblohm7/wingoes v0.0.0-20240119213807-a09d6be7affa // indirect
Expand Down Expand Up @@ -298,7 +304,7 @@ require (
github.com/tklauser/numcpus v0.7.0 // indirect
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
github.com/ulikunitz/xz v0.5.12 // indirect
github.com/urfave/cli v1.22.14 // indirect
github.com/urfave/cli v1.22.15 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fastrand v1.1.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
Expand Down
18 changes: 10 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.13 h1:THZJJ6TU/FOiM7DZFnisYV9d49o
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.13/go.mod h1:VISUTg6n+uBaYIWPBaIG0jk7mbBxm7DUqBtU2cUDDWI=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.144.0 h1:1KE7EgE5xiPZ6H19hdF27B/p/CGhB2UNO5wcpOHe0JM=
github.com/aws/aws-sdk-go-v2/service/ec2 v1.144.0/go.mod h1:hIsHE0PaWAQakLCshKS7VKWMGXaqrAFp4m95s2W9E6c=
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.4 h1:pwSMMRVj2myoqRpPMDWBEjLqQlIgJ4ujMaMdc/sFd0U=
github.com/aws/aws-sdk-go-v2/service/ecr v1.24.4/go.mod h1:AOHmGMoPtSY9Zm2zBuwUJQBisIvYAZeA1n7b6f4e880=
github.com/aws/aws-sdk-go-v2/service/ecr v1.27.0 h1:e9RAM6FgxAN3ca3LKaCr20+YnMqg8vhX/k6WDA8BpT8=
github.com/aws/aws-sdk-go-v2/service/ecr v1.27.0/go.mod h1:Fa36Bp93PNtMtKHoyIvQnJY8EGTR0UQqRo3NfjW0hT0=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3 h1:eAh2A4b5IzM/lum78bZ590jy36+d/aFLgKF/4Vd1xPE=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA=
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.15 h1:2jyRZ9rVIMisyQRnhSS/SqlckveoxXneIumECVFP91Y=
Expand All @@ -136,8 +136,8 @@ github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxY
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
github.com/beam-cloud/blobcache-v2 v0.0.0-20250503151236-e2403183f563 h1:kn8/lBy5kRSLpFAX/xV5GDg31R38Kv8Tp6qcuhpJAfQ=
github.com/beam-cloud/blobcache-v2 v0.0.0-20250503151236-e2403183f563/go.mod h1:RrA2ruMma4/dN9Sa6wwhyAO1uI6di+tlLB5wuM7TuvQ=
github.com/beam-cloud/clip v0.0.0-20250815141247-71e2dd6c441d h1:M6RtY4ANRr+NbbCCkL9l8Vksl5mW0F5hWCctaLAD4I8=
github.com/beam-cloud/clip v0.0.0-20250815141247-71e2dd6c441d/go.mod h1:JqYuoB5waiXZrLmBO0rKM+Kl4iRWqfWb+pI+lk3BX+Q=
github.com/beam-cloud/clip v0.0.0-20251103022546-c75714e105c1 h1:ZMtCArgCE4prVx28dkzjOw5FAw+0/ljoeKnHIuczSxE=
github.com/beam-cloud/clip v0.0.0-20251103022546-c75714e105c1/go.mod h1:Tt5HW/Mp3twQHzal5RE3FYACcxaMaT+QyTBo8aGbsyI=
github.com/beam-cloud/geesefs v0.0.0-20250921162405-f983757f032a h1:JQVvP0qKA39xp5ckKGcwkvgMO6BxatnzvgnMz97tt1g=
github.com/beam-cloud/geesefs v0.0.0-20250921162405-f983757f032a/go.mod h1:utihEuMyzBOeZ6oU2ozzZkJmyzbYBuYrxsLUo1DfZXs=
github.com/beam-cloud/geesefs/s3ext v0.0.0-20250606164905-2f3593d03f4f h1:XzHOu+erxeBO6D3fKVbd5DAlipl+PYZ3u+Ywb8m7Ovk=
Expand Down Expand Up @@ -200,9 +200,9 @@ github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GK
github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
Expand Down Expand Up @@ -793,8 +793,8 @@ github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oW
github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/urfave/cli v1.22.15 h1:nuqt+pdC/KqswQKhETJjo7pvn/k4xMUxgW6liI7XpnM=
github.com/urfave/cli v1.22.15/go.mod h1:wSan1hmo5zeyLGBjRJbzRTNk8gwoYa2B9n4q9dmRIc0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G8=
Expand Down Expand Up @@ -1069,6 +1069,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.4.0 h1:ZazjZUfuVeZGLAmlKKuyv3IKP5orXcwtOwDQH6YVr6o=
gotest.tools/v3 v3.4.0/go.mod h1:CtbdzLSsqVhDgMtKsx03ird5YTGB3ar27v0u/yKBW5g=
gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987 h1:TU8z2Lh3Bbq77w0t1eG8yRlLcNHzZu3x6mhoH2Mk0c8=
gvisor.dev/gvisor v0.0.0-20240722211153-64c016c92987/go.mod h1:sxc3Uvk/vHcd3tj7/DHVBoR5wvWT/MmRq2pj7HRJnwU=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
169 changes: 139 additions & 30 deletions pkg/abstractions/image/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,37 +276,31 @@ func (b *Build) getContainerStatus() (*pb.RunCStatusResponse, error) {

// generateContainerRequest generates a container request for the build container
func (b *Build) generateContainerRequest() (*types.ContainerRequest, error) {
baseImageID, err := getImageID(&BuildOpts{
BaseImageRegistry: b.opts.BaseImageRegistry,
BaseImageName: b.opts.BaseImageName,
BaseImageTag: b.opts.BaseImageTag,
BaseImageDigest: b.opts.BaseImageDigest,
ExistingImageUri: b.opts.ExistingImageUri,
EnvVars: b.opts.EnvVars,
Dockerfile: b.opts.Dockerfile,
BuildCtxObject: b.opts.BuildCtxObject,
})
containerImageID, err := b.getContainerImageID()
if err != nil {
return nil, err
}

sourceImage := getSourceImage(b.opts)

// Allow config to override default build container settings
cpu := defaultBuildContainerCpu
memory := defaultBuildContainerMemory

if b.config.ImageService.BuildContainerCpu > 0 {
cpu = b.config.ImageService.BuildContainerCpu
cpu := b.config.ImageService.BuildContainerCpu
if cpu <= 0 {
cpu = defaultBuildContainerCpu
}
memory := b.config.ImageService.BuildContainerMemory
if memory <= 0 {
memory = defaultBuildContainerMemory
}

if b.config.ImageService.BuildContainerMemory > 0 {
memory = b.config.ImageService.BuildContainerMemory
// Only set SourceImage if base image fields are populated
// For custom Dockerfiles, the FROM instruction specifies the base image
var sourceImagePtr *string
if b.opts.BaseImageName != "" && b.opts.BaseImageRegistry != "" {
sourceImage := getSourceImage(b.opts)
sourceImagePtr = &sourceImage
}

containerRequest := &types.ContainerRequest{
req := &types.ContainerRequest{
BuildOptions: types.BuildOptions{
SourceImage: &sourceImage,
SourceImage: sourceImagePtr,
SourceImageCreds: b.opts.BaseImageCreds,
Dockerfile: &b.opts.Dockerfile,
BuildCtxObject: &b.opts.BuildCtxObject,
Expand All @@ -316,29 +310,55 @@ func (b *Build) generateContainerRequest() (*types.ContainerRequest, error) {
Env: b.opts.EnvVars,
Cpu: cpu,
Memory: memory,
ImageId: baseImageID,
ImageId: containerImageID,
WorkspaceId: b.authInfo.Workspace.ExternalId,
Workspace: *b.authInfo.Workspace,
EntryPoint: []string{"tail", "-f", "/dev/null"},
Mounts: b.mounts,
}

if b.opts.BuildCtxObject != "" {
containerRequest.Stub.Object.ExternalId = b.opts.BuildCtxObject
containerRequest.Mounts = append(containerRequest.Mounts, types.Mount{
req.Stub.Object.ExternalId = b.opts.BuildCtxObject
req.Mounts = append(req.Mounts, types.Mount{
MountPath: types.WorkerUserCodeVolume,
ReadOnly: false,
})
}

if b.opts.Gpu != "" {
containerRequest.GpuRequest = []string{b.opts.Gpu}
containerRequest.GpuCount = 1
req.GpuRequest = []string{b.opts.Gpu}
req.GpuCount = 1
} else {
containerRequest.PoolSelector = b.config.ImageService.BuildContainerPoolSelector
req.PoolSelector = b.config.ImageService.BuildContainerPoolSelector
}

return req, nil
}

// getContainerImageID returns the image ID to use for the build container
// V2: final image ID (buildah builds complete image)
// V1: base image ID (container starts with base, then commands are executed inside)
// For custom Dockerfiles: use the final image ID since we're building from scratch
func (b *Build) getContainerImageID() (string, error) {
isV2 := b.config.ImageService.ClipVersion == 2
hasCustomDockerfile := b.opts.Dockerfile != "" && b.opts.BaseImageName == ""

// For v2 builds OR custom Dockerfiles, use the final image ID
if isV2 || hasCustomDockerfile {
return b.imageID, nil
}

return containerRequest, nil
// For v1 builds with beta9 base images, calculate base image ID without build steps/commands
return getImageID(&BuildOpts{
BaseImageRegistry: b.opts.BaseImageRegistry,
BaseImageName: b.opts.BaseImageName,
BaseImageTag: b.opts.BaseImageTag,
BaseImageDigest: b.opts.BaseImageDigest,
ExistingImageUri: b.opts.ExistingImageUri,
EnvVars: b.opts.EnvVars,
Dockerfile: b.opts.Dockerfile,
BuildCtxObject: b.opts.BuildCtxObject,
})
}

func genContainerId() string {
Expand All @@ -363,6 +383,27 @@ func generatePipInstallCommand(pythonPackages []string, pythonVersion string, vi
return command
}

// generateStandardPipInstallCommand generates a pip install command for v2 dockerfile builds
// using standard Python/pip (not uv-b9 which is only available in v1 mounted environments).
func generateStandardPipInstallCommand(pythonPackages []string, pythonVersion string, virtualEnv bool) string {
flagLines, packages := parseFlagLinesAndPackages(pythonPackages)

// Use standard pip with the specified python version
command := fmt.Sprintf("%s -m pip install", pythonVersion)
if !virtualEnv {
command += " --break-system-packages"
}

if len(flagLines) > 0 {
command += " " + strings.Join(flagLines, " ")
}
if len(packages) > 0 {
command += " " + strings.Join(packages, " ")
}

return command
}

func generateMicromambaInstallCommand(pythonPackages []string) string {
flagLines, packages := parseFlagLinesAndPackages(pythonPackages)

Expand Down Expand Up @@ -401,8 +442,71 @@ func parseFlagLinesAndPackages(pythonPackages []string) ([]string, []string) {
return flagLines, packages
}

// parseBuildStepsForDockerfile generates RUN commands for v2 dockerfile builds using standard pip.
// This function coalesces pip and mamba commands into single RUN statements where possible.
func parseBuildStepsForDockerfile(buildSteps []BuildStep, pythonVersion string, virtualEnv bool) []string {
commands := []string{}
var (
mambaStart int = -1
mambaGroup []string
pipStart int = -1
pipGroup []string
)

for _, step := range buildSteps {
if step.Type == shellCommandType {
commands = append(commands, step.Command)
}

flagCmd := containsFlag(step.Command)

// Flush any pending pip or mamba groups
if pipStart != -1 && (step.Type != pipCommandType || flagCmd) {
pipStart, pipGroup = flushStandardPipCommand(commands, pipStart, pipGroup, pythonVersion, virtualEnv)
}

if mambaStart != -1 && (step.Type != micromambaCommandType || flagCmd) {
mambaStart, mambaGroup = flushMambaCommand(commands, mambaStart, mambaGroup)
}

if step.Type == pipCommandType {
if pipStart == -1 {
pipStart = len(commands)
commands = append(commands, "")
}
pipGroup = append(pipGroup, step.Command)

if flagCmd {
pipStart, pipGroup = flushStandardPipCommand(commands, pipStart, pipGroup, pythonVersion, virtualEnv)
}
}

if step.Type == micromambaCommandType {
if mambaStart == -1 {
mambaStart = len(commands)
commands = append(commands, "")
}
mambaGroup = append(mambaGroup, step.Command)

if flagCmd {
mambaStart, mambaGroup = flushMambaCommand(commands, mambaStart, mambaGroup)
}
}
}

if mambaStart != -1 {
commands[mambaStart] = generateMicromambaInstallCommand(mambaGroup)
}

if pipStart != -1 {
commands[pipStart] = generateStandardPipInstallCommand(pipGroup, pythonVersion, virtualEnv)
}

return commands
}

// Generate the commands to run in the container. This function will coalesce pip and mamba commands
// into a single command if they are adjacent to each other.
// into a single command if they are adjacent to each other. Uses uv-b9 for v1 builds.
func parseBuildSteps(buildSteps []BuildStep, pythonVersion string, virtualEnv bool) []string {
commands := []string{}
var (
Expand Down Expand Up @@ -474,6 +578,11 @@ func flushPipCommand(commands []string, pipStart int, pipGroup []string, pythonV
return -1, nil
}

func flushStandardPipCommand(commands []string, pipStart int, pipGroup []string, pythonVersion string, virtualEnv bool) (int, []string) {
commands[pipStart] = generateStandardPipInstallCommand(pipGroup, pythonVersion, virtualEnv)
return -1, nil
}

func containsFlag(s string) bool {
flags := []string{
"--no-deps",
Expand Down
18 changes: 10 additions & 8 deletions pkg/abstractions/image/build_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"strings"

"github.com/beam-cloud/beta9/pkg/common"
reg "github.com/beam-cloud/beta9/pkg/registry"
"github.com/beam-cloud/beta9/pkg/types"
)

Expand Down Expand Up @@ -61,19 +62,20 @@ func (o *BuildOpts) setCustomImageBuildOptions() error {
return err
}

if len(o.ExistingImageCreds) > 0 && o.ExistingImageUri != "" {
token, err := GetRegistryToken(o)
if err != nil {
return err
}
o.BaseImageCreds = token
}

// Set base image details
o.BaseImageRegistry = baseImage.Registry
o.BaseImageName = baseImage.Repo
o.BaseImageTag = baseImage.Tag
o.BaseImageDigest = baseImage.Digest

// Convert credentials to skopeo format if provided
if len(o.ExistingImageCreds) > 0 {
o.BaseImageCreds, err = reg.GetRegistryTokenForImage(o.ExistingImageUri, o.ExistingImageCreds)
if err != nil {
return err
}
}

return nil
}

Expand Down
Loading
Loading