Skip to content
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

feat: temporarily remount read-only mounts before cleaning container fs #183

Merged
merged 22 commits into from
May 14, 2024

Conversation

johnstcn
Copy link
Member

@johnstcn johnstcn commented May 13, 2024

This PR is a continuation of @janLo's original PR #51 with some additional changes:

  • Brings original PR up to date with latest main
  • Moves the temp-remount logic into a separate package
  • Refactors for ease of testing and adds unit tests

Manual verification:

  • (Existing behaviour): On Docker runtime, dockerd fails to start after running:

      docker run -it --rm \     
        -e GIT_URL=https://github.com/coder/envbuilder \                     
        -e INIT_SCRIPT=bash \
        ghcr.io/coder/envbuilder:latest
  • (New behaviour): Using sysbox-runc runtime*, dockerd starts succesfully:

    docker run -it --rm \     
      -e GIT_URL=https://github.com/coder/envbuilder \                     
      -e INIT_SCRIPT=bash \
      envbuilder:latest # local built image
  • Existing sample devcontainer builds successfully on Docker runtime:

      docker run -it --rm \     
        -e GIT_URL=https://github.com/coder/envbuilder-starter-devcontainer \                     
        -e INIT_SCRIPT=bash \
        envbuilder:latest # local built image

* Lima config used: https://gist.github.com/johnstcn/b9d6854b3aedb551af1a7588e2a5af94

janLo and others added 8 commits August 17, 2023 10:17
tgt := filepath.Join("/", dest, src)
err := m.MkdirAll(tgt, 0o750)
if err != nil {
return remount, fmt.Errorf("create temp mountpoint %s: %w", dest, err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we return nil for remount here? And should we perhaps restore the mounts on error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to leave the responsibility to the caller. Is there a strong reason to do it ourselves?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say the main reason is meeting expectations, i.e. returning an err and a non-nil value that is actionable can lead to some bad assumptions, especially if the behavior changes at some point.

It's OK to leave as-is, though.

internal/util/remount.go Outdated Show resolved Hide resolved
internal/util/remount.go Outdated Show resolved Hide resolved
"github.com/prometheus/procfs"
)

// TempRemount iterates through all read-only mounted filesystems, bind-mounts them at dest,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an interesting question, should we or should we not limit this to read-only mounted filesystems? If we think about how a docker container is run with -v /path:/path, the contents of the docker container can never populate the mounted /path.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this would actually make sense given the below behaviour:

$ echo 'important stuff' >> /opt/important-stuff/tps-reports.txt
$ ls -l /opt/important-stuff/tps-reports.txt 
-rw-r--r-- 1 cian 16 May 13 21:12 /opt/important-stuff/tps-reports.txt
$ docker run -it --rm \
    -v /opt/important-stuff:/opt/important-stuff \
    -e GIT_URL=https://github.com/coder/envbuilder-starter-devcontainer \
    -e INIT_SCRIPT=bash \
    envbuilder:latest
[...]
devcontainer # ls -l /opt/important-stuff/
total 0
devcontainer # exit
$ cat /opt/important-stuff/tps-reports.txt
important stuff

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might merge this as-is and investigate rw mounts in a follow up, if that's OK?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

envbuilder.go Outdated Show resolved Hide resolved
envbuilder.go Outdated Show resolved Hide resolved
envbuilder.go Show resolved Hide resolved
Copy link
Contributor

@dannykopping dannykopping left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, minor Qs and nits

@@ -394,6 +396,14 @@ func Run(ctx context.Context, options Options) error {
})
}

// temp move of all ro mounts
tempRemountDest := filepath.Join("/", MagicDir)
ignorePrefixes := []string{tempRemountDest, "/proc", "/sys"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be configurable?
Will we only ever support UNIX-based builds?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kaniko is currently Linux-only to the best of my knowledge.

envbuilder.go Outdated Show resolved Hide resolved
internal/util/remount.go Outdated Show resolved Hide resolved
internal/util/remount.go Outdated Show resolved Hide resolved
internal/util/remount.go Outdated Show resolved Hide resolved
internal/util/remount.go Outdated Show resolved Hide resolved
//
// Generated by this command:
//
// mockgen -source ./internal/util/remount.go -package ebutil mounter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auto mockgen in Makefile as a side issue?

@@ -0,0 +1,98 @@
// Code generated by MockGen. DO NOT EDIT.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you use the mock to have it tested without the OS? Maybe it is more natural to write a real Linux-only test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests that modify the underlying system are extremely obnoxious and tend to be flaky. I'd prefer to just keep the mock test for now. This still gets tested by the integration tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still gets tested by the integration tests

Ok, that answers my concerns 👍

Copy link
Member

@mafredri mafredri left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor observations, but otherwise LGTM, nice work!

internal/ebutil/remount.go Outdated Show resolved Hide resolved
internal/ebutil/remount.go Outdated Show resolved Hide resolved
@johnstcn johnstcn merged commit b8e2947 into main May 14, 2024
3 checks passed
@johnstcn johnstcn deleted the cj/janl/sysbox-issues branch May 14, 2024 11:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants