|
9 | 9 | "encoding/json"
|
10 | 10 | "errors"
|
11 | 11 | "fmt"
|
| 12 | + "github.com/prometheus/procfs" |
12 | 13 | "io"
|
13 | 14 | "net"
|
14 | 15 | "net/http"
|
@@ -194,6 +195,11 @@ type Options struct {
|
194 | 195 | Filesystem billy.Filesystem
|
195 | 196 | }
|
196 | 197 |
|
| 198 | +type TempRemount struct { |
| 199 | + Source string |
| 200 | + Target string |
| 201 | +} |
| 202 | + |
197 | 203 | // DockerConfig represents the Docker configuration file.
|
198 | 204 | type DockerConfig configfile.ConfigFile
|
199 | 205 |
|
@@ -516,6 +522,60 @@ func Run(ctx context.Context, options Options) error {
|
516 | 522 | })
|
517 | 523 | }
|
518 | 524 |
|
| 525 | + // temp move of all ro mounts |
| 526 | + var tempRepounts []TempRemount |
| 527 | + |
| 528 | + mountinfos, err := procfs.GetMounts() |
| 529 | + if err != nil { |
| 530 | + logf(codersdk.LogLevelError, "Failed to read mountinfo: %s", err) |
| 531 | + } else { |
| 532 | + prefixes := []string{filepath.Join("/", MagicDir), "/proc", "/sys"} |
| 533 | + for _, mountInfo := range mountinfos { |
| 534 | + logf(codersdk.LogLevelTrace, "Found mountpoint %s", mountInfo.MountPoint) |
| 535 | + if _, ok := mountInfo.Options["ro"]; ok { |
| 536 | + logf(codersdk.LogLevelTrace, "Found ro mountpoint %s ", mountInfo.MountPoint) |
| 537 | + |
| 538 | + relevantMountpoint := true |
| 539 | + for _, prefix := range prefixes { |
| 540 | + if strings.HasPrefix(mountInfo.MountPoint, prefix) { |
| 541 | + logf(codersdk.LogLevelTrace, "Mountpoint %s is NOT relevant (prefix: %s)", mountInfo.MountPoint, prefix) |
| 542 | + relevantMountpoint = false |
| 543 | + break |
| 544 | + } |
| 545 | + } |
| 546 | + if relevantMountpoint { |
| 547 | + logf(codersdk.LogLevelTrace, "Mountpoint %s is relevant", mountInfo.MountPoint) |
| 548 | + |
| 549 | + remount := TempRemount{ |
| 550 | + Source: mountInfo.MountPoint, |
| 551 | + Target: filepath.Join("/", MagicDir, mountInfo.MountPoint), |
| 552 | + } |
| 553 | + |
| 554 | + logf(codersdk.LogLevelTrace, "Remount mountpoint %s to %s", mountInfo.MountPoint, remount.Target) |
| 555 | + |
| 556 | + err := os.MkdirAll(remount.Target, 0750) |
| 557 | + if err == nil { |
| 558 | + err := syscall.Mount(remount.Source, remount.Target, "bind", syscall.MS_BIND, "") |
| 559 | + if err == nil { |
| 560 | + err := syscall.Unmount(remount.Source, 0) |
| 561 | + if err != nil { |
| 562 | + logf(codersdk.LogLevelError, "Could not unmount %s", remount.Source) |
| 563 | + } |
| 564 | + tempRepounts = append(tempRepounts, remount) |
| 565 | + |
| 566 | + } else { |
| 567 | + logf(codersdk.LogLevelError, "Could not bindmount %s to %s", remount.Source, remount.Target) |
| 568 | + } |
| 569 | + } else { |
| 570 | + logf(codersdk.LogLevelError, "Could not create temp mountpoint %s for %s", remount.Target, remount.Source) |
| 571 | + } |
| 572 | + |
| 573 | + } |
| 574 | + |
| 575 | + } |
| 576 | + } |
| 577 | + } |
| 578 | + |
519 | 579 | build := func() (v1.Image, error) {
|
520 | 580 | _, err := options.Filesystem.Stat(MagicFile)
|
521 | 581 | if err == nil && options.SkipRebuild {
|
@@ -652,6 +712,24 @@ func Run(ctx context.Context, options Options) error {
|
652 | 712 | closeAfterBuild()
|
653 | 713 | }
|
654 | 714 |
|
| 715 | + for _, remount := range tempRepounts { |
| 716 | + logf(codersdk.LogLevelTrace, "Cleanup mountpoint %s", remount.Target) |
| 717 | + err := os.MkdirAll(remount.Source, 0750) |
| 718 | + if err == nil { |
| 719 | + err := syscall.Mount(remount.Target, remount.Source, "bind", syscall.MS_BIND, "") |
| 720 | + if err == nil { |
| 721 | + err := syscall.Unmount(remount.Target, 0) |
| 722 | + if err != nil { |
| 723 | + logf(codersdk.LogLevelError, "Could not unmount %s", remount.Target) |
| 724 | + } |
| 725 | + } else { |
| 726 | + logf(codersdk.LogLevelError, "Could not bindmount %s to %s", remount.Target, remount.Source) |
| 727 | + } |
| 728 | + } else { |
| 729 | + logf(codersdk.LogLevelError, "Could not create mountpoint %s for %s", remount.Source, remount.Target) |
| 730 | + } |
| 731 | + } |
| 732 | + |
655 | 733 | // Create the magic file to indicate that this build
|
656 | 734 | // has already been ran before!
|
657 | 735 | file, err := options.Filesystem.Create(MagicFile)
|
|
0 commit comments