From 19697a23ba6ce4116349e83ce1733e8e0a2880d9 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Fri, 17 Jun 2016 10:43:20 -0700 Subject: [PATCH] image: Add ImageLayoutVersion and check oci-layout in tar engines Collect the shared stuff in the image/layout utility package. Signed-off-by: W. Trevor King --- image/cas/layout/tar.go | 11 +++++-- image/layout/doc.go | 16 +++++++++ image/layout/tar.go | 58 +++++++++++++++++++++++++++++++++ image/refs/layout/tar.go | 10 ++++-- image/structure/image_layout.go | 21 ++++++++++++ 5 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 image/layout/doc.go create mode 100644 image/layout/tar.go create mode 100644 image/structure/image_layout.go diff --git a/image/cas/layout/tar.go b/image/cas/layout/tar.go index 729b2c76f..4917f3578 100644 --- a/image/cas/layout/tar.go +++ b/image/cas/layout/tar.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/opencontainers/image-spec/image/cas" + "github.com/opencontainers/image-spec/image/layout" ) // TarEngine is a cas.Engine backed by a tar file. @@ -31,10 +32,16 @@ type TarEngine struct { } // GetTarEngine returns a TarEngine. -func GetTarEngine(file ReadSeekCloser) (engine cas.Engine, err error) { - engine = &TarEngine{ +func GetTarEngine(file ReadSeekCloser) (eng cas.Engine, err error) { + engine := &TarEngine{ reader: file, } + + err = layout.CheckVersion(engine.reader) + if err != nil { + return nil, err + } + return engine, nil } diff --git a/image/layout/doc.go b/image/layout/doc.go new file mode 100644 index 000000000..94dd3f42e --- /dev/null +++ b/image/layout/doc.go @@ -0,0 +1,16 @@ +// 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 layout defines utility code shared by refs/layout and cas/layout. +package layout diff --git a/image/layout/tar.go b/image/layout/tar.go new file mode 100644 index 000000000..858c22a5c --- /dev/null +++ b/image/layout/tar.go @@ -0,0 +1,58 @@ +// 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 layout + +import ( + "archive/tar" + "encoding/json" + "errors" + "fmt" + "io" + "os" + + "github.com/opencontainers/image-spec/image/structure" +) + +func CheckVersion(reader io.ReadSeeker) (err error) { + _, err = reader.Seek(0, os.SEEK_SET) + if err != nil { + return err + } + + tarReader := tar.NewReader(reader) + for { + header, err := tarReader.Next() + if err == io.EOF { + return errors.New("oci-layout not found") + } + if err != nil { + return err + } + + if header.Name == "./oci-layout" { + decoder := json.NewDecoder(tarReader) + var version structure.ImageLayoutVersion + err = decoder.Decode(&version) + if err != nil { + return err + } + if version.Version != "1.0.0" { + return fmt.Errorf("unrecognized imageLayoutVersion: %q", version.Version) + } + + return nil + } + } +} diff --git a/image/refs/layout/tar.go b/image/refs/layout/tar.go index 8a08f979e..8331e8c17 100644 --- a/image/refs/layout/tar.go +++ b/image/refs/layout/tar.go @@ -24,6 +24,7 @@ import ( "strings" casLayout "github.com/opencontainers/image-spec/image/cas/layout" + imageLayout "github.com/opencontainers/image-spec/image/layout" "github.com/opencontainers/image-spec/image/refs" "github.com/opencontainers/image-spec/image/structure" ) @@ -34,11 +35,16 @@ type TarEngine struct { } // GetTarEngine returns a TarEngine. -func GetTarEngine(file casLayout.ReadSeekCloser) (engine refs.Engine, err error) { - engine = &TarEngine{ +func GetTarEngine(file casLayout.ReadSeekCloser) (eng refs.Engine, err error) { + engine := &TarEngine{ reader: file, } + err = imageLayout.CheckVersion(engine.reader) + if err != nil { + return nil, err + } + return engine, nil } diff --git a/image/structure/image_layout.go b/image/structure/image_layout.go new file mode 100644 index 000000000..c683ea7b8 --- /dev/null +++ b/image/structure/image_layout.go @@ -0,0 +1,21 @@ +// 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 structure + +// ImageLayoutVersion represents the oci-version content for the image +// layout format. +type ImageLayoutVersion struct { + Version string `json:"imageLayoutVersion"` +}