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
6 changes: 6 additions & 0 deletions common/libimage/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"go.podman.io/image/v5/transports"
"go.podman.io/image/v5/types"
"go.podman.io/storage/pkg/fileutils"
"golang.org/x/sys/unix"
)

type LoadOptions struct {
Expand Down Expand Up @@ -110,6 +111,11 @@ 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, unix.ENOSPC) {
return nil, fmt.Errorf("no space left on device")
Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I know it was said in the first reviews to not discard the error, but wasn't the whole point to output a clear error?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can always adjust cosmetics without affecting Go callers with things like fmt.Errorf("OurBetterErrorText%.0w").

And the primary cause of the long error message in containers/podman#26197 is that the caller tries all 4 formats, and outputs a lot of noise. The first precondition to fixing that is making the error type caller-detectable, so that it can choose not to do the list of 4 errors. Afterwards, how exactly we make the error text prettier is much less significant, and can happen on either layer — although I think it’s generally better to do UI work at the higher layers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

But isn't it caller-detectable now? we can check it against ENOSPC

And you want to check it in a higher layer?

}

loadErrors = append(loadErrors, fmt.Errorf("%s: %v", transportName, err))
}

Expand Down
11 changes: 11 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 Down Expand Up @@ -82,6 +83,9 @@ func untar() {
}

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

if err := cmd.Wait(); err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
status := exitErr.ExitCode()
if status == 2 {
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