Skip to content

Commit

Permalink
fix[close #280]: /tmp becomes readonly when running out of space duri…
Browse files Browse the repository at this point in the history
…ng operation

fix: add missing return and imports
  • Loading branch information
mirkobrombin committed Jul 6, 2024
1 parent bc2ca5b commit 5552b57
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 0 deletions.
34 changes: 34 additions & 0 deletions core/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"path/filepath"
"strings"
"syscall"
"time"

"github.com/containers/buildah"
Expand Down Expand Up @@ -137,6 +138,39 @@ func OciExportRootFs(buildImageName string, imageRecipe *ImageRecipe, transDir s
return err
}

// check if there is enough space in dest to copy the image
mountDirStat, err := os.Stat(mountDir)
if err != nil {
PrintVerboseErr("OciExportRootFs", 8.1, err)
return err
}

var mountDirSize int64
if mountDirStat.IsDir() {
mountDirSize, err = getDirSize(mountDir)
if err != nil {
PrintVerboseErr("OciExportRootFs", 8.2, err)
return err
}
} else {
mountDirSize = mountDirStat.Size()
}

var stat syscall.Statfs_t
err = syscall.Statfs(dest, &stat)
if err != nil {
PrintVerboseErr("OciExportRootFs", 8.3, err)
return err
}

availableSpace := stat.Bavail * uint64(stat.Bsize)

if uint64(mountDirSize) > availableSpace {
err := errors.New("not enough space in disk")
PrintVerboseErr("OciExportRootFs", 8.4, err)
return err
}

// copy mount dir contents to dest
err = rsyncCmd(mountDir+"/", dest, []string{"--delete", "--checksum"}, false)
if err != nil {
Expand Down
31 changes: 31 additions & 0 deletions core/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ package core
*/

import (
"bytes"
"errors"
"fmt"
"io"
"os"
"os/exec"
"strconv"
"strings"
)

var abrootDir = "/etc/abroot"
Expand Down Expand Up @@ -122,3 +126,30 @@ func isDeviceLUKSEncrypted(devicePath string) (bool, error) {

return true, nil
}

// getDirSize calculates the total size of a directory recursively.
// FIXME: find a way to avoid using du and any other external command
//
// the walk function in the os package can be used to calculate the size
// of a directory but it needs a solid implementation for links
func getDirSize(path string) (int64, error) {
cmd := exec.Command("du", "-s", "-b", path)
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
return 0, err
}

output := strings.Fields(out.String())
if len(output) == 0 {
return 0, errors.New("failed to get directory size")
}

size, err := strconv.ParseInt(output[0], 10, 64)
if err != nil {
return 0, err
}

return size, nil
}

0 comments on commit 5552b57

Please sign in to comment.