-
Notifications
You must be signed in to change notification settings - Fork 16
sandbox: dynamic directory mount & snapshot in go + adds detach #246
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
thomasjpfan
wants to merge
31
commits into
main
Choose a base branch
from
thomasjpfan/sb-image-mount-v3
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,304
−28
Open
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
876d3b7
Only image mount
thomasjpfan 2caf2ba
Less changes
thomasjpfan ffe8c14
Introduce detach back
thomasjpfan 1175ead
Make sure terminate actually calls terminate
thomasjpfan 4cb11a9
Remove the need for ALPN workaround
thomasjpfan a994b38
Add docs
thomasjpfan 0a07097
Fix lint
thomasjpfan 42a301a
Simplify tls implemetnation
thomasjpfan 812a561
Give terminate error a higher priority
thomasjpfan 9c89b64
Make diff smaller
thomasjpfan 5dc47e5
Less diff
thomasjpfan 982ccc2
Ensure that sandbox is attached before running any operation
thomasjpfan 6c3a2a8
Less diff
thomasjpfan 3eba12d
Remove ts detach
thomasjpfan b37410f
Allow for terminate to happen
thomasjpfan d06531d
Use two mutexes
thomasjpfan 367125b
Use atomic bool
thomasjpfan 831f1dd
Remove profile.TaskCommandRouterInsecure
thomasjpfan 7365519
Terminate no longer detaches
thomasjpfan f9c6f6c
Add detach everywhere
thomasjpfan 10db500
Update examples
thomasjpfan c395951
Add changelog
thomasjpfan e49f593
Add example to readme
thomasjpfan ec85b2b
Add ensureAttached to be extra safe
thomasjpfan 11b08c3
Use a better error message
thomasjpfan fb06f43
Add detach and params to Sandbox.Terminate
thomasjpfan a4a0084
Update changelog
thomasjpfan f08632d
Fix linter
thomasjpfan ac9e6f0
Do not detach
thomasjpfan 4c46034
Add terminate back in
thomasjpfan a07297a
Switch order
thomasjpfan File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,7 +30,7 @@ func main() { | |
| } | ||
| fmt.Printf("Started Sandbox: %s\n", sb.SandboxID) | ||
| defer func() { | ||
| if err := sb.Terminate(context.Background()); err != nil { | ||
| if err := sb.Terminate(context.Background(), true, nil); err != nil { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Deferred terminate fails after manual detach in examplesMedium Severity Deferred Additional Locations (1) |
||
| log.Fatalf("Failed to terminate Sandbox %s: %v", sb.SandboxID, err) | ||
| } | ||
| }() | ||
|
|
@@ -52,11 +52,14 @@ func main() { | |
| } | ||
| fmt.Printf("Filesystem snapshot created with Image ID: %s\n", snapshotImage.ImageID) | ||
|
|
||
| err = sb.Terminate(ctx) | ||
| err = sb.Terminate(ctx, false, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to terminate Sandbox %s: %v", sb.SandboxID, err) | ||
| } | ||
| fmt.Println("Terminated first Sandbox") | ||
| if err := sb.Detach(); err != nil { | ||
| log.Fatalf("Failed to detach Sandbox %s: %v", sb.SandboxID, err) | ||
| } | ||
|
|
||
| // Create new Sandbox from snapshot Image | ||
| sb2, err := mc.Sandboxes.Create(ctx, app, snapshotImage, nil) | ||
|
|
@@ -66,7 +69,7 @@ func main() { | |
| fmt.Printf("Started new Sandbox from snapshot: %s\n", sb2.SandboxID) | ||
|
|
||
| defer func() { | ||
| if err := sb2.Terminate(context.Background()); err != nil { | ||
| if err := sb2.Terminate(context.Background(), true, nil); err != nil { | ||
| log.Fatalf("Failed to terminate Sandbox %s: %v", sb2.SandboxID, err) | ||
| } | ||
| }() | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| // This example shows how to mount Images in the Sandbox filesystem and take snapshots | ||
| // of them. | ||
| // | ||
| // The feature is still experimental in the sense that the API is subject to change. | ||
| // | ||
| // High level, it allows you to: | ||
| // - Mount any Modal Image at a specific directory within the Sandbox filesystem. | ||
| // - Take a snapshot of that directory, which will create a new Modal Image with | ||
| // the updated contents of the directory. | ||
| // | ||
| // You can only snapshot directories that have previously been mounted using | ||
| // `Sandbox.ExperimentalMountImage`. If you want to mount an empty directory, | ||
| // you can pass nil as the image parameter. | ||
| // | ||
| // For exmaple, you can use this to mount user specific dependencies into a running | ||
| // Sandbox, that is started with a base Image with shared system dependencies. This | ||
| // way, you can update system dependencies and user projects independently. | ||
|
|
||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
| "io" | ||
| "log" | ||
|
|
||
| "github.com/modal-labs/libmodal/modal-go" | ||
| ) | ||
|
|
||
| func main() { | ||
| ctx := context.Background() | ||
| mc, err := modal.NewClient() | ||
| if err != nil { | ||
| log.Fatalf("Failed to create client: %v", err) | ||
| } | ||
|
|
||
| app, err := mc.Apps.FromName(ctx, "libmodal-example", &modal.AppFromNameParams{CreateIfMissing: true}) | ||
| if err != nil { | ||
| log.Fatalf("Failed to get or create App: %v", err) | ||
| } | ||
|
|
||
| // The base Image you use for the Sandbox must have a /usr/bin/mount binary. | ||
| baseImage := mc.Images.FromRegistry("debian:12-slim", nil).DockerfileCommands([]string{ | ||
| "RUN apt-get update && apt-get install -y git", | ||
| }, nil) | ||
|
|
||
| sb, err := mc.Sandboxes.Create(ctx, app, baseImage, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to create Sandbox: %v", err) | ||
| } | ||
| defer func() { | ||
| if err := sb.Terminate(context.Background(), true, nil); err != nil { | ||
| log.Fatalf("Failed to terminate Sandbox %s: %v", sb.SandboxID, err) | ||
| } | ||
| }() | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| fmt.Printf("Started first Sandbox: %s\n", sb.SandboxID) | ||
|
|
||
| // You must mount an Image at a directory in the Sandbox filesystem before you | ||
| // can snapshot it. You can pass nil as the image parameter to mount an | ||
| // empty directory. | ||
| // | ||
| // The target directory must exist before you can mount it: | ||
| mkdirProc, err := sb.Exec(ctx, []string{"mkdir", "-p", "/repo"}, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to exec mkdir: %v", err) | ||
| } | ||
| if exitCode, err := mkdirProc.Wait(ctx); err != nil || exitCode != 0 { | ||
| log.Fatalf("Failed to wait for mkdir: exit code: %d, err: %v", exitCode, err) | ||
| } | ||
| if err := sb.ExperimentalMountImage(ctx, "/repo", nil); err != nil { | ||
| log.Fatalf("Failed to mount image: %v", err) | ||
| } | ||
|
|
||
| gitClone, err := sb.Exec(ctx, []string{ | ||
| "git", | ||
| "clone", | ||
| "https://github.com/modal-labs/libmodal.git", | ||
| "/repo", | ||
| }, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to exec git clone: %v", err) | ||
| } | ||
| if exitCode, err := gitClone.Wait(ctx); err != nil || exitCode != 0 { | ||
| log.Fatalf("Failed to wait for git clone: exit code: %d, err: %v", exitCode, err) | ||
| } | ||
|
|
||
| repoSnapshot, err := sb.ExperimentalSnapshotDirectory(ctx, "/repo") | ||
| if err != nil { | ||
| log.Fatalf("Failed to snapshot directory: %v", err) | ||
| } | ||
| fmt.Printf("Took a snapshot of the /repo directory, Image ID: %s\n", repoSnapshot.ImageID) | ||
|
|
||
| if err := sb.Terminate(ctx, false, nil); err != nil { | ||
| log.Fatalf("Failed to terminate Sandbox: %v", err) | ||
| } | ||
| if err := sb.Detach(); err != nil { | ||
| log.Fatalf("Failed to detach Sandbox %s: %v", sb.SandboxID, err) | ||
| } | ||
|
|
||
| // Start a new Sandbox, and mount the repo directory: | ||
| sb2, err := mc.Sandboxes.Create(ctx, app, baseImage, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to create second Sandbox: %v", err) | ||
| } | ||
| defer func() { | ||
| if err := sb2.Terminate(context.Background(), true, nil); err != nil { | ||
| log.Fatalf("Failed to terminate Sandbox %s: %v", sb2.SandboxID, err) | ||
| } | ||
| }() | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| fmt.Printf("Started second Sandbox: %s\n", sb2.SandboxID) | ||
|
|
||
| mkdirProc2, err := sb2.Exec(ctx, []string{"mkdir", "-p", "/repo"}, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to exec mkdir in sb2: %v", err) | ||
| } | ||
| if exitCode, err := mkdirProc2.Wait(ctx); err != nil || exitCode != 0 { | ||
| log.Fatalf("Failed to wait for mkdir in sb2: exit code: %d, err: %v", exitCode, err) | ||
| } | ||
| if err := sb2.ExperimentalMountImage(ctx, "/repo", repoSnapshot); err != nil { | ||
| log.Fatalf("Failed to mount snapshot in sb2: %v", err) | ||
| } | ||
|
|
||
| repoLs, err := sb2.Exec(ctx, []string{"ls", "/repo"}, nil) | ||
| if err != nil { | ||
| log.Fatalf("Failed to exec ls: %v", err) | ||
| } | ||
| if exitCode, err := repoLs.Wait(ctx); err != nil || exitCode != 0 { | ||
| log.Fatalf("Failed to wait for ls: exit code: %d, err: %v", exitCode, err) | ||
| } | ||
| output, err := io.ReadAll(repoLs.Stdout) | ||
| if err != nil { | ||
| log.Fatalf("Failed to read stdout: %v", err) | ||
| } | ||
| fmt.Printf("Contents of /repo directory in new Sandbox sb2:\n%s", output) | ||
|
|
||
| if err := sb2.Terminate(ctx, true, nil); err != nil { | ||
| log.Fatalf("Failed to terminate sb2: %v", err) | ||
| } | ||
| if err := mc.Images.Delete(ctx, repoSnapshot.ImageID, nil); err != nil { | ||
| log.Fatalf("Failed to delete snapshot image: %v", err) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.