Skip to content
Draft
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
56 changes: 55 additions & 1 deletion images/dvcr-artifact/pkg/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ limitations under the License.

package errors

import "fmt"
import (
"errors"
"fmt"
"os"
"syscall"
)

type ReasonError interface {
error
Expand Down Expand Up @@ -44,3 +49,52 @@ func (e BadImageChecksumError) Reason() string {
func (e BadImageChecksumError) Error() string {
return fmt.Sprintf("%s sum mismatch: %s != %s", e.algorithm, e.expected, e.actual)
}

func NewNoSpaceLeftError(err error) NoSpaceLeftError {
return NoSpaceLeftError{
err: err,
}
}

type NoSpaceLeftError struct {
err error
}

func (e NoSpaceLeftError) Reason() string {
return "NoSpaceLeft"
}

func (e NoSpaceLeftError) Error() string {
return fmt.Sprintf("no space left on device: %v", e.err)
}

func (e NoSpaceLeftError) Unwrap() error {
return e.err
}

func IsNoSpaceLeftError(err error) bool {
if err == nil {
return false
}

var noSpaceErr NoSpaceLeftError
if errors.As(err, &noSpaceErr) {
return true
}

var pathErr *os.PathError
if errors.As(err, &pathErr) {
if pathErr.Err == syscall.ENOSPC {
return true
}
}

var errno syscall.Errno
if errors.As(err, &errno) {
if errno == syscall.ENOSPC {
return true
}
}

return false
}
28 changes: 27 additions & 1 deletion images/dvcr-artifact/pkg/registry/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,18 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"os"
"os/exec"
"path"
"strings"
"syscall"
"time"

"github.com/google/go-containerregistry/pkg/authn"
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1"
v1 "github.com/google/go-containerregistry/pkg/v1"
"github.com/google/go-containerregistry/pkg/v1/empty"
"github.com/google/go-containerregistry/pkg/v1/mutate"
"github.com/google/go-containerregistry/pkg/v1/remote"
Expand Down Expand Up @@ -261,6 +263,9 @@ func (p DataProcessor) inspectAndStreamSourceImage(
klog.Infoln("Streaming from the source")
doneSize, err := io.Copy(streamWriter, io.TeeReader(sourceImageReader, imageInfoWriter))
if err != nil {
if importerrs.IsNoSpaceLeftError(err) {
return importerrs.NewNoSpaceLeftError(err)
}
return fmt.Errorf("error copying from the source: %w", err)
}

Expand Down Expand Up @@ -325,6 +330,15 @@ func (p DataProcessor) uploadLayersAndImage(

klog.Infoln("Uploading layer to registry")
if err := remote.WriteLayer(repo, layer, remoteOpts...); err != nil {
slog.Error(fmt.Sprintf("error uploading layer: %w", err))

if errors.Is(err, syscall.ENOSPC) {
slog.Error(fmt.Sprintf("ENOSPC uploading layer: %w", err))
}

if importerrs.IsNoSpaceLeftError(err) {
return importerrs.NewNoSpaceLeftError(err)
}
return fmt.Errorf("error uploading layer: %w", err)
}
klog.Infoln("Layer uploaded")
Expand Down Expand Up @@ -356,6 +370,9 @@ func (p DataProcessor) uploadLayersAndImage(

klog.Infof("Uploading image %q to registry", p.destImageName)
if err = remote.Write(ref, image, remoteOpts...); err != nil {
if importerrs.IsNoSpaceLeftError(err) {
return importerrs.NewNoSpaceLeftError(err)
}
return fmt.Errorf("error uploading image: %w", err)
}

Expand Down Expand Up @@ -403,6 +420,9 @@ func getImageInfo(ctx context.Context, sourceReader io.ReadCloser) (ImageInfo, e

uncompressedN, err = io.CopyN(tempImageInfoFile, formatSourceReaders.TopReader(), imageInfoSize)
if err != nil && !errors.Is(err, io.EOF) {
if importerrs.IsNoSpaceLeftError(err) {
return ImageInfo{}, importerrs.NewNoSpaceLeftError(err)
}
return ImageInfo{}, fmt.Errorf("error writing to temp file: %w", err)
}

Expand Down Expand Up @@ -430,6 +450,9 @@ func getImageInfo(ctx context.Context, sourceReader io.ReadCloser) (ImageInfo, e
// It's necessary to read everything from the original image to avoid blocking.
_, err = io.Copy(&EmptyWriter{}, sourceReader)
if err != nil {
if importerrs.IsNoSpaceLeftError(err) {
return ImageInfo{}, importerrs.NewNoSpaceLeftError(err)
}
return ImageInfo{}, fmt.Errorf("error copying to nowhere: %w", err)
}

Expand Down Expand Up @@ -458,6 +481,9 @@ func getImageInfo(ctx context.Context, sourceReader io.ReadCloser) (ImageInfo, e
// Count uncompressed size of source image.
n, err := io.Copy(&EmptyWriter{}, formatSourceReaders.TopReader())
if err != nil {
if importerrs.IsNoSpaceLeftError(err) {
return ImageInfo{}, importerrs.NewNoSpaceLeftError(err)
}
return ImageInfo{}, fmt.Errorf("error copying to nowhere: %w", err)
}

Expand Down
Loading