Skip to content

Commit

Permalink
ociarchive: Add new ImageStructureNotFound
Browse files Browse the repository at this point in the history
This is for containers/skopeo#2114
which is in turn a dependency of coreos/rpm-ostree#4598

Basically I want to map ENOENT to a clear error, because the build
tooling wants to treat "target image is not present" differently
from "DNS lookup failed" or "we got EPERM".

There's a bit of code motion here because we need to move
the `os.Open()` call before creating a temporary directory.

Signed-off-by: Colin Walters <[email protected]>
  • Loading branch information
cgwalters committed Sep 18, 2023
1 parent 27b3a7e commit 6e50f30
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 6 deletions.
12 changes: 12 additions & 0 deletions oci/archive/oci_src.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ func (e ImageNotFoundError) Error() string {
return fmt.Sprintf("no descriptor found for reference %q", e.ref.image)
}

// ImageStructureNotFoundError occurs when the archive file does not exist.
type ImageStructureNotFoundError struct {
// ref is the image reference
ref ociArchiveReference
// path is the file path that was not present
path string
}

func (e ImageStructureNotFoundError) Error() string {
return fmt.Sprintf("no archive file present for reference %q", e.ref.image)
}

type ociArchiveImageSource struct {
impl.Compat

Expand Down
19 changes: 13 additions & 6 deletions oci/archive/oci_transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io/fs"
"os"
"strings"

Expand Down Expand Up @@ -171,18 +172,24 @@ func createOCIRef(sys *types.SystemContext, image string) (tempDirOCIRef, error)

// creates the temporary directory and copies the tarred content to it
func createUntarTempDir(sys *types.SystemContext, ref ociArchiveReference) (tempDirOCIRef, error) {
src := ref.resolvedFile
arch, err := os.Open(src)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return tempDirOCIRef{}, ImageStructureNotFoundError{ref: ref, path: src}
} else {
return tempDirOCIRef{}, err
}
}
defer arch.Close()

tempDirRef, err := createOCIRef(sys, ref.image)
if err != nil {
return tempDirOCIRef{}, fmt.Errorf("creating oci reference: %w", err)
}
src := ref.resolvedFile
dst := tempDirRef.tempDirectory

// TODO: This can take quite some time, and should ideally be cancellable using a context.Context.
arch, err := os.Open(src)
if err != nil {
return tempDirOCIRef{}, err
}
defer arch.Close()
if err := archive.NewDefaultArchiver().Untar(arch, dst, &archive.TarOptions{NoLchown: true}); err != nil {
if err := tempDirRef.deleteTempDir(); err != nil {
return tempDirOCIRef{}, fmt.Errorf("deleting temp directory %q: %w", tempDirRef.tempDirectory, err)
Expand Down

0 comments on commit 6e50f30

Please sign in to comment.