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
  • Loading branch information
mirkobrombin committed Jul 6, 2024
1 parent bc2ca5b commit 399ee63
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 0 deletions.
33 changes: 33 additions & 0 deletions core/oci.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,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
}

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

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

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

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

// copy mount dir contents to dest
err = rsyncCmd(mountDir+"/", dest, []string{"--delete", "--checksum"}, false)
if err != nil {
Expand Down
26 changes: 26 additions & 0 deletions core/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,29 @@ 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 399ee63

Please sign in to comment.