Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions common/libimage/errno_unix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build !windows

package libimage

import "syscall"

const ErrNoSpace = syscall.ENOSPC
Comment thread
zvenigorodsky marked this conversation as resolved.
5 changes: 5 additions & 0 deletions common/libimage/errno_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package libimage

import "syscall"

const ErrNoSpace = syscall.ERROR_DISK_FULL
6 changes: 6 additions & 0 deletions common/libimage/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ func (r *Runtime) Load(ctx context.Context, path string, options *LoadOptions) (
return loadedImages, err
}
logrus.Debugf("Error loading %s (%s): %v", path, transportName, err)

if errors.Is(err, ErrNoSpace) {
// %.0w makes err visible to error.Unwrap() without including any text
return nil, fmt.Errorf("no space left on device%.0w", err)
}

Comment thread
zvenigorodsky marked this conversation as resolved.
loadErrors = append(loadErrors, fmt.Errorf("%s: %v", transportName, err))
}

Expand Down
13 changes: 13 additions & 0 deletions storage/pkg/chrootarchive/archive_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"io"
"io/fs"
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
Expand All @@ -29,6 +30,7 @@ func (dst *unpackDestination) Close() error {
return dst.root.Close()
}

const statusCodeENOSPC = 2
// tarOptionsDescriptor is passed as an extra file
const tarOptionsDescriptor = 3

Expand Down Expand Up @@ -82,6 +84,9 @@ func untar() {
}

if err := archive.Unpack(os.Stdin, dst, &options); err != nil {
if errors.Is(err, unix.ENOSPC) {
os.Exit(statusCodeENOSPC)
}
fatal(err)
}
// fully consume stdin in case it is zero padded
Expand Down Expand Up @@ -155,6 +160,14 @@ func invokeUnpack(decompressedArchive io.Reader, dest *unpackDestination, option
w.Close()

if err := cmd.Wait(); err != nil {
var exitErr *exec.ExitError
if errors.As(err, exitErr) {
status := exitErr.ExitCode()
if status == statusCodeENOSPC {
return unix.ENOSPC
}
}

errorOut := fmt.Errorf("unpacking failed (error: %w; output: %s)", err, output)
// when `xz -d -c -q | storage-untar ...` failed on storage-untar side,
// we need to exhaust `xz`'s output, otherwise the `xz` side will be
Expand Down