Skip to content
Merged
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
12 changes: 12 additions & 0 deletions image/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ var validRefMediaTypes = []string{
}

func validate(w walker, refs []string, out *log.Logger) error {
if err := layoutValidate(w); err != nil {
return err
}

ds, err := listReferences(w)
if err != nil {
return err
Expand Down Expand Up @@ -130,6 +134,10 @@ func Unpack(r io.ReadSeeker, dest, refName string) error {
}

func unpack(w walker, dest, refName string) error {
if err := layoutValidate(w); err != nil {
return err
}

ref, err := findDescriptor(w, refName)
if err != nil {
return err
Expand Down Expand Up @@ -178,6 +186,10 @@ func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root string) error {
}

func createRuntimeBundle(w walker, dest, refName, rootfs string) error {
if err := layoutValidate(w); err != nil {
return err
}

ref, err := findDescriptor(w, refName)
if err != nil {
return err
Expand Down
104 changes: 104 additions & 0 deletions image/layout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2016 The Linux Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package image

import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"strings"

"github.com/opencontainers/image-spec/schema"
"github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)

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") {
blobsExist = true
if !info.IsDir() {
return fmt.Errorf("blobs is not a directory")
}

return nil
}

if strings.EqualFold(path, "index.json") {
indexExist = true
if info.IsDir() {
return fmt.Errorf("index.json is a directory")
}

var index v1.Index
buf, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "error reading index.json")
}

if err := json.Unmarshal(buf, &index); err != nil {
return errors.Wrap(err, "index.json format mismatch")
}

return nil
}

if strings.EqualFold(path, "oci-layout") {
layoutExist = true
if info.IsDir() {
return fmt.Errorf("oci-layout is a directory")
}

var imageLayout v1.ImageLayout
buf, err := ioutil.ReadAll(r)
if err != nil {
return errors.Wrap(err, "error reading oci-layout")
}

if err := schema.ValidatorMediaTypeLayoutHeader.Validate(bytes.NewReader(buf)); err != nil {
return errors.Wrap(err, "oci-layout: imageLayout validation failed")
}

if err := json.Unmarshal(buf, &imageLayout); err != nil {
return errors.Wrap(err, "oci-layout format mismatch")
}

return nil
}

return nil
}); err != nil {
return err
}

if !blobsExist {
return fmt.Errorf("image layout must contain blobs directory")
}

if !indexExist {
return fmt.Errorf("image layout must contain index.json file")
}

if !layoutExist {
return fmt.Errorf("image layout must contain oci-layout file")
}

return nil
}