Update image-tools, and remove the duplicate Sirupsen/logrus vendor

This commit is contained in:
Miloslav Trmač
2017-09-27 00:43:23 +02:00
parent 40a5f48632
commit 700199c944
290 changed files with 39444 additions and 13093 deletions

View File

@@ -1,6 +1,7 @@
# oci-image-tool [![Build Status](https://travis-ci.org/opencontainers/image-tools.svg?branch=master)](https://travis-ci.org/opencontainers/image-tools)[![Go Report Card](https://goreportcard.com/badge/github.com/opencontainers/image-tools)](https://goreportcard.com/report/github.com/opencontainers/image-tools)
`oci-image-tool` is a collection of tools for working with the [OCI image format specification](https://github.com/opencontainers/image-spec).
To build from source code, image-tools requires Go 1.7.x or above.
## Install

View File

@@ -29,6 +29,7 @@ import (
const (
TypeImageLayout = "imageLayout"
TypeImage = "image"
TypeImageZip = "imageZip"
TypeManifest = "manifest"
TypeImageIndex = "imageIndex"
TypeConfig = "config"
@@ -60,8 +61,10 @@ func Autodetect(path string) (string, error) {
mimeType := http.DetectContentType(buf)
switch mimeType {
case "application/x-gzip", "application/octet-stream":
case "application/x-gzip", "application/x-rar-compressed", "application/octet-stream":
return TypeImage, nil
case "application/zip":
return TypeImageZip, nil
case "text/plain; charset=utf-8":
// might be a JSON file, will be handled below

View File

@@ -33,6 +33,12 @@ func ValidateLayout(src string, refs []string, out *log.Logger) error {
return validate(newPathWalker(src), refs, out)
}
// ValidateZip walks through the given file tree and validates the manifest
// pointed to by the given refs or returns an error if the validation failed.
func ValidateZip(src string, refs []string, out *log.Logger) error {
return validate(newZipWalker(src), refs, out)
}
// ValidateFile opens the tar file given by the filename, then calls ValidateReader
func ValidateFile(tarFile string, refs []string, out *log.Logger) error {
f, err := os.Open(tarFile)
@@ -135,18 +141,26 @@ func validate(w walker, refs []string, out *log.Logger) error {
out.Printf("reference %q: OK", ref)
}
}
return nil
}
// UnpackLayout walks through the file tree given by src and, using the layers
// specified in the manifest pointed to by the given ref, unpacks all layers in
// the given destination directory or returns an error if the unpacking failed.
func UnpackLayout(src, dest, ref string, platform string) error {
func UnpackLayout(src, dest, ref, platform string) error {
return unpack(newPathWalker(src), dest, ref, platform)
}
// UnpackZip opens and walks through the zip file given by src and, using the layers
// specified in the manifest pointed to by the given ref, unpacks all layers in
// the given destination directory or returns an error if the unpacking failed.
func UnpackZip(src, dest, ref, platform string) error {
return unpack(newZipWalker(src), dest, ref, platform)
}
// UnpackFile opens the file pointed by tarFileName and calls Unpack on it.
func UnpackFile(tarFileName, dest, ref string, platform string) error {
func UnpackFile(tarFileName, dest, ref, platform string) error {
f, err := os.Open(tarFileName)
if err != nil {
return errors.Wrap(err, "unable to open file")
@@ -160,11 +174,11 @@ func UnpackFile(tarFileName, dest, ref string, platform string) error {
// the manifest pointed to by the given ref, unpacks all layers in the given
// destination directory or returns an error if the unpacking failed.
// The destination will be created if it does not exist.
func Unpack(r io.ReadSeeker, dest, refName string, platform string) error {
func Unpack(r io.ReadSeeker, dest, refName, platform string) error {
return unpack(newTarWalker(r), dest, refName, platform)
}
func unpack(w walker, dest, refName string, platform string) error {
func unpack(w walker, dest, refName, platform string) error {
if err := layoutValidate(w); err != nil {
return err
}
@@ -217,13 +231,20 @@ func unpack(w walker, dest, refName string, platform string) error {
// CreateRuntimeBundleLayout walks through the file tree given by src and
// creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed.
func CreateRuntimeBundleLayout(src, dest, ref, root string, platform string) error {
func CreateRuntimeBundleLayout(src, dest, ref, root, platform string) error {
return createRuntimeBundle(newPathWalker(src), dest, ref, root, platform)
}
// CreateRuntimeBundleZip opens and walks through the zip file given by src
// and creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed.
func CreateRuntimeBundleZip(src, dest, ref, root, platform string) error {
return createRuntimeBundle(newZipWalker(src), dest, ref, root, platform)
}
// CreateRuntimeBundleFile opens the file pointed by tarFile and calls
// CreateRuntimeBundle.
func CreateRuntimeBundleFile(tarFile, dest, ref, root string, platform string) error {
func CreateRuntimeBundleFile(tarFile, dest, ref, root, platform string) error {
f, err := os.Open(tarFile)
if err != nil {
return errors.Wrap(err, "unable to open file")
@@ -236,11 +257,11 @@ func CreateRuntimeBundleFile(tarFile, dest, ref, root string, platform string) e
// CreateRuntimeBundle walks through the given tar stream and
// creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed.
func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root string, platform string) error {
func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root, platform string) error {
return createRuntimeBundle(newTarWalker(r), dest, ref, root, platform)
}
func createRuntimeBundle(w walker, dest, refName, rootfs string, platform string) error {
func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error {
if err := layoutValidate(w); err != nil {
return err
}
@@ -290,7 +311,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs string, platform string
return nil
}
func createBundle(w walker, m *manifest, dest, rootfs string) error {
func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) {
c, err := findConfig(w, &m.Config)
if err != nil {
return err
@@ -301,6 +322,13 @@ func createBundle(w walker, m *manifest, dest, rootfs string) error {
if err2 := os.MkdirAll(dest, 0755); err2 != nil {
return err2
}
defer func() {
if retErr != nil {
if err3 := os.RemoveAll(dest); err3 != nil {
fmt.Printf("Failed to clean up %q: %s\n", dest, err3.Error())
}
}
}()
} else {
return err
}

View File

@@ -21,6 +21,7 @@ import (
"io"
"io/ioutil"
"os"
"path/filepath"
"strings"
"github.com/opencontainers/image-spec/schema"
@@ -32,7 +33,7 @@ func layoutValidate(w walker) error {
var blobsExist, indexExist, layoutExist bool
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
if strings.EqualFold(path, "blobs") {
if strings.EqualFold(filepath.Base(path), "blobs") {
blobsExist = true
if !info.IsDir() {
return fmt.Errorf("blobs is not a directory")
@@ -41,7 +42,7 @@ func layoutValidate(w walker) error {
return nil
}
if strings.EqualFold(path, "index.json") {
if strings.EqualFold(filepath.Base(path), "index.json") {
indexExist = true
if info.IsDir() {
return fmt.Errorf("index.json is a directory")
@@ -60,7 +61,7 @@ func layoutValidate(w walker) error {
return nil
}
if strings.EqualFold(path, "oci-layout") {
if strings.EqualFold(filepath.Base(path), "oci-layout") {
layoutExist = true
if info.IsDir() {
return fmt.Errorf("oci-layout is a directory")

View File

@@ -29,7 +29,7 @@ import (
"strings"
"time"
"github.com/Sirupsen/logrus"
"github.com/sirupsen/logrus"
"github.com/opencontainers/image-spec/schema"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"

View File

@@ -16,6 +16,7 @@ package image
import (
"archive/tar"
"archive/zip"
"fmt"
"io"
"os"
@@ -100,7 +101,7 @@ func (w *tarWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
return nil
}
if path == expectedPath && !info.IsDir() {
if filepath.Clean(path) == expectedPath && !info.IsDir() {
if bytes, err = io.Copy(dst, rdr); err != nil {
return errors.Wrapf(err, "get failed: failed to copy blob to destination")
}
@@ -186,3 +187,65 @@ func (w *pathWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
}
return nbytes, nil
}
type zipWalker struct {
fileName string
}
// newWalkWalker returns a Walker that walks through .zip files.
func newZipWalker(fileName string) walker {
return &zipWalker{fileName}
}
func (w *zipWalker) walk(f walkFunc) error {
r, err := zip.OpenReader(w.fileName)
if err != nil {
return err
}
defer r.Close()
for _, file := range r.File {
rc, err := file.Open()
if err != nil {
return err
}
defer rc.Close()
info := file.FileInfo()
if err := f(file.Name, info, rc); err != nil {
return err
}
}
return nil
}
func (w *zipWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
var bytes int64
done := false
expectedPath := filepath.Join("blobs", string(desc.Digest.Algorithm()), desc.Digest.Hex())
f := func(path string, info os.FileInfo, rdr io.Reader) error {
var err error
if done {
return nil
}
if path == expectedPath && !info.IsDir() {
if bytes, err = io.Copy(dst, rdr); err != nil {
return errors.Wrapf(err, "get failed: failed to copy blob to destination")
}
done = true
}
return nil
}
if err := w.walk(f); err != nil {
return 0, errors.Wrapf(err, "get failed: unable to walk")
}
if !done {
return 0, os.ErrNotExist
}
return bytes, nil
}