Update non-module dependencies

Dependabot was apparently not picking these up (and
several haven't had a release for a long time anyway).

Also move from github.com/go-check/check to its newly
declared (and go.mod-enforced) name gopkg.in/check.v1.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
This commit is contained in:
Miloslav Trmač
2021-08-23 15:36:56 +02:00
parent 5da1b0f304
commit c399909f04
43 changed files with 506 additions and 592 deletions

7
go.mod
View File

@@ -9,10 +9,9 @@ require (
github.com/containers/storage v1.34.1 github.com/containers/storage v1.34.1
github.com/docker/docker v20.10.8+incompatible github.com/docker/docker v20.10.8+incompatible
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/go-check/check v0.0.0-20180628173108-788fd7840127
github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
github.com/opencontainers/image-tools v0.0.0-20170926011501-6d941547fa1d github.com/opencontainers/image-tools v1.0.0-rc3
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/russross/blackfriday v2.0.0+incompatible // indirect github.com/russross/blackfriday v2.0.0+incompatible // indirect
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1
@@ -20,6 +19,6 @@ require (
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
go4.org v0.0.0-20190218023631-ce4c26f7be8e // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )

14
go.sum
View File

@@ -318,8 +318,6 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127 h1:0gkP6mzaMqkmpcJYCFOLkIBwI7xFExG03bbkOkCvUPI=
github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@@ -612,10 +610,11 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 h1:yN8BPXVwMBAm3Cuvh1L5XE8XpvYRMdsVLd82ILprhUU=
github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-tools v0.0.0-20170926011501-6d941547fa1d h1:X9WSFjjZNqYRqO2MenUgqE2nj/oydcfIzXJ0R/SVnnA= github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283 h1:TVzvdjOalkJBNkbpPVMAr4KV9QRf2IjfxdyxwAK78Gs=
github.com/opencontainers/image-tools v0.0.0-20170926011501-6d941547fa1d/go.mod h1:A9btVpZLzttF4iFaKNychhPyrhfOjJ1OF5KrA8GcLj4= github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-tools v1.0.0-rc3 h1:ZR837lBIxq6mmwEqfYrbLMuf75eBSHhccVHy6lsBeM4=
github.com/opencontainers/image-tools v1.0.0-rc3/go.mod h1:A9btVpZLzttF4iFaKNychhPyrhfOjJ1OF5KrA8GcLj4=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -826,8 +825,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go4.org v0.0.0-20190218023631-ce4c26f7be8e h1:m9LfARr2VIOW0vsV19kEKp/sWQvZnGobA8JHui/XJoY=
go4.org v0.0.0-20190218023631-ce4c26f7be8e/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1236,8 +1233,9 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"github.com/go-check/check" "gopkg.in/check.v1"
) )
const blockedRegistriesConf = "./fixtures/blocked-registries.conf" const blockedRegistriesConf = "./fixtures/blocked-registries.conf"

View File

@@ -6,7 +6,7 @@ import (
"testing" "testing"
"github.com/containers/skopeo/version" "github.com/containers/skopeo/version"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
const ( const (

View File

@@ -17,10 +17,10 @@ import (
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/go-check/check"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/opencontainers/image-tools/image" "github.com/opencontainers/image-tools/image"
"gopkg.in/check.v1"
) )
func init() { func init() {

View File

@@ -13,7 +13,7 @@ import (
"time" "time"
"github.com/docker/docker/pkg/homedir" "github.com/docker/docker/pkg/homedir"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
var adminKUBECONFIG = map[string]string{ var adminKUBECONFIG = map[string]string{

View File

@@ -6,7 +6,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
/* /*

View File

@@ -9,7 +9,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
const ( const (

View File

@@ -9,7 +9,7 @@ import (
"strings" "strings"
"github.com/containers/image/v5/signature" "github.com/containers/image/v5/signature"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
const ( const (

View File

@@ -14,8 +14,8 @@ import (
"github.com/containers/image/v5/docker/reference" "github.com/containers/image/v5/docker/reference"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/containers/image/v5/types" "github.com/containers/image/v5/types"
"github.com/go-check/check"
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1" imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
"gopkg.in/check.v1"
) )
const ( const (

View File

@@ -11,7 +11,7 @@ import (
"time" "time"
"github.com/containers/image/v5/manifest" "github.com/containers/image/v5/manifest"
"github.com/go-check/check" "gopkg.in/check.v1"
) )
const skopeoBinary = "skopeo" const skopeoBinary = "skopeo"

View File

@@ -14,9 +14,21 @@
"architecture": { "architecture": {
"type": "string" "type": "string"
}, },
"variant": {
"type": "string"
},
"os": { "os": {
"type": "string" "type": "string"
}, },
"os.version": {
"type": "string"
},
"os.features": {
"type": "array",
"items": {
"type": "string"
}
},
"config": { "config": {
"type": "object", "type": "object",
"properties": { "properties": {

View File

@@ -15,10 +15,9 @@
package schema package schema
import ( import (
"bufio"
"encoding/json" "encoding/json"
"io" "io"
"go4.org/errorutil"
) )
// A SyntaxError is a description of a JSON syntax error // A SyntaxError is a description of a JSON syntax error
@@ -36,7 +35,21 @@ func (e *SyntaxError) Error() string { return e.msg }
// If the given error is not a *json.SyntaxError it is returned unchanged. // If the given error is not a *json.SyntaxError it is returned unchanged.
func WrapSyntaxError(r io.Reader, err error) error { func WrapSyntaxError(r io.Reader, err error) error {
if serr, ok := err.(*json.SyntaxError); ok { if serr, ok := err.(*json.SyntaxError); ok {
line, col, _ := errorutil.HighlightBytePosition(r, serr.Offset) buf := bufio.NewReader(r)
line := 0
col := 0
for i := int64(0); i < serr.Offset; i++ {
b, berr := buf.ReadByte()
if berr != nil {
break
}
if b == '\n' {
line++
col = 1
} else {
col++
}
}
return &SyntaxError{serr.Error(), line, col, serr.Offset} return &SyntaxError{serr.Error(), line, col, serr.Offset}
} }

View File

@@ -20,6 +20,8 @@ import (
"bytes" "bytes"
"compress/gzip" "compress/gzip"
"encoding/base64" "encoding/base64"
"fmt"
"io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
@@ -114,7 +116,24 @@ func (f *_escFile) Close() error {
} }
func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) { func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) {
return nil, nil if !f.isDir {
return nil, fmt.Errorf(" escFile.Readdir: '%s' is not directory", f.name)
}
fis, ok := _escDirs[f.local]
if !ok {
return nil, fmt.Errorf(" escFile.Readdir: '%s' is directory, but we have no info about content of this dir, local=%s", f.name, f.local)
}
limit := count
if count <= 0 || limit > len(fis) {
limit = len(fis)
}
if len(fis) == 0 && count > 0 {
return nil, io.EOF
}
return fis[0:limit], nil
} }
func (f *_escFile) Stat() (os.FileInfo, error) { func (f *_escFile) Stat() (os.FileInfo, error) {
@@ -205,27 +224,29 @@ func _escFSMustString(useLocal bool, name string) string {
var _escData = map[string]*_escFile{ var _escData = map[string]*_escFile{
"/config-schema.json": { "/config-schema.json": {
name: "config-schema.json",
local: "config-schema.json", local: "config-schema.json",
size: 2771, size: 2969,
modtime: 1515512099, modtime: 1625865937,
compressed: ` compressed: `
H4sIAAAAAAAC/+RWQY/TPBC951dE2T22m+/wnXot3JCKVAGHFarcZNLOEnvMeIKIUP87itNCkjpp6apc H4sIAAAAAAAC/+RWsW7bQAzd9RWCkjGJOnTymnYrkAJG2yEojLNE2Ux1xyuPMioU/vdCJzvx2SfZteEu
OEUaz7z35nns+EcUx0kOLmO0gmSSRZysLJglGVFogOMlmQJ38dpChgVmymfNmrJHl+1Bq6ZkL2IXafri XSnyvcdHSuLvJE2zElzBaAXJZJM0e7JgHsmIQgOcPpKpcJFOLRRYYaF81l1XduuKJWjVlSxF7CTPXxyZ
yMzb6BPxLs1ZFTL/7/+0jT20dZifStwiTcmCyU5szpe12SlqtYM08/xtpdQWmlravkAmbcwyWWBBcMki +z76QLzIS1aV3L97n/exm74Oy22Jm+Q5WTDFls35sj47R60WkBeev6+U1kJXS/MXKKSPWSYLLAgum6Rd
btqJ4yRjUAL5r0Cn1AmjaeF8vCDWSpqVXAnMBTUkfu3QpiSqkj3xBFQ/m7M9CmRSMVxbQ+7azKMXgeyO O2maFQxKoHwN7JQ6YTQ9nI9XxFpJ96RUAveCGjL/bN2nZKqRJfEIVJjNxRIFCmkYTq1ZKUZl5NR0cqdn
Iz4ecMXHPzjgXmSEscPqc95+t+Qgf08sblj/yFB4A6FwT80IPKQ5FGiwGRWXamXXHnnVagzjm29jshSz PqyAXT/WUysqUJ34KIliVu2bdyigd/MGwNN0HZBsJhrB35mrj0dm6+NfHHAQGWR+ZfU5H39ZclB+Jha3
qpNZdwkF9FDGRCNxfBghFa4toZEhNxlYNT099wj6dJMSJ2RekNqXO5A8qcJUZdlH6uJ8Dlqw1Pk/2/tH X3/LUPk1gMo9dIt8k5dQocFu4V2ulZ165KdeYxzfrIZkhdYN2DfayNbGQ1Lh1hIGG9RP08BT19NzQBDS
KisN7sb+b536e3f1ifgLmt0bvOmcv1NbKO9tyTqw8fe0ZC1k17gzqrzakqj7PV2/TCSFe831m2NRbDB3 jUockXlEaih3T/KoCtPUdYi0i/M9asGjLv/b3r9S3WhwZ/Z/7tZfu6tvxD/QLD7gWe/5JzWH+tqWTCOD
f/+uO+ZPdd+jBVPpsx1PSlUDuyTseDRgTRi+Vsj+P/wc8GCoLuoinjzfoxPiOmR636yAUWPbM75BwbfD v6YlUyE7xYVR9cmWRD+/TCSVu+TzW2JVzbB0//5bt8kf6z6gBdPog4lntWqBXRZ3PNljzRh+Nsj+mniO
Zbem3hGB8T5/U1ze1FlA42ZbvwKDtIazP98fAIC2Um/8RIyDbIlKUGZkPvunLDoynM9N/1n1+9nUP5dR eLCvLtlF3Hq+RCfE7WX/1L3xDA8oegEdd2vsGoqs9+FldHyodxGNs3l7AQZpDQd/vr8AAG2lnfmNGAaZ
MzuH6GcAAAD//0pj2wvTCgAA E9WgzMB+hm9ZsmE43JvwOHy75sL3Mul2Z538CQAA//9C38scmQsAAA==
`, `,
}, },
"/content-descriptor.json": { "/content-descriptor.json": {
name: "content-descriptor.json",
local: "content-descriptor.json", local: "content-descriptor.json",
size: 1079, size: 1079,
modtime: 1537191585, modtime: 1625865919,
compressed: ` compressed: `
H4sIAAAAAAAC/5yTsW7cMAyGdz8F4QTIkos6BB2MIEu7d2i3ooNOok5Mz5JK8RBci7x7QcvX2G2RILfZ H4sIAAAAAAAC/5yTsW7cMAyGdz8F4QTIkos6BB2MIEu7d2i3ooNOok5Mz5JK8RBci7x7QcvX2G2RILfZ
xP+Rn2zqVwfQe6yOqQjl1A/QfyqYPuQklhIy6BMmgY9zKDN8LugokLMTca0tLquLOFrFo0gZjHmoOW1a xP+Rn2zqVwfQe6yOqQjl1A/QfyqYPuQklhIy6BMmgY9zKDN8LugokLMTca0tLquLOFrFo0gZjHmoOW1a
@@ -238,9 +259,10 @@ dIbaEm+G3WzZM/44EKMqff37riz3dL0uHcC37qn7HQAA//9DKIMKNwQAAA==
}, },
"/defs-descriptor.json": { "/defs-descriptor.json": {
name: "defs-descriptor.json",
local: "defs-descriptor.json", local: "defs-descriptor.json",
size: 844, size: 844,
modtime: 1537191664, modtime: 1625865919,
compressed: ` compressed: `
H4sIAAAAAAAC/5SST2/TTBDG7/kU826jt0DiOHBAqlWKKnrnUE6t0mi6O7aneP9od6IqVPnuaG03SYtA H4sIAAAAAAAC/5SST2/TTBDG7/kU826jt0DiOHBAqlWKKnrnUE6t0mi6O7aneP9od6IqVPnuaG03SYtA
cLC1+2jmefwbz9MEQBlKOnIQ9k5VoK6oZsf5liBgFNabDiOIh6+B3BfvBNlRhKuxzUe4DqS5Zo29x3ww cLC1+2jmefwbz9MEQBlKOnIQ9k5VoK6oZsf5liBgFNabDiOIh6+B3BfvBNlRhKuxzUe4DqS5Zo29x3ww
@@ -254,9 +276,10 @@ TAMAAA==
}, },
"/defs.json": { "/defs.json": {
name: "defs.json",
local: "defs.json", local: "defs.json",
size: 1670, size: 1670,
modtime: 1515512099, modtime: 1625865903,
compressed: ` compressed: `
H4sIAAAAAAAC/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8 H4sIAAAAAAAC/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8
3zmeMbcAgByxKa2qnTKa5EC+4klp1a8aaBs8grtY054vpnXgLgi7GvUXo12hNFo41FiqkyqLoTwceTOA 3zmeMbcAgByxKa2qnTKa5EC+4klp1a8aaBs8grtY054vpnXgLgi7GvUXo12hNFo41FiqkyqLoTwceTOA
@@ -269,9 +292,10 @@ fIvD7in0ryMEy+fK1G6UfmdTE+tvpoL+1wV/AgAA//96IpqyhgYAAA==
}, },
"/image-index-schema.json": { "/image-index-schema.json": {
name: "image-index-schema.json",
local: "image-index-schema.json", local: "image-index-schema.json",
size: 2993, size: 2993,
modtime: 1515512099, modtime: 1625865919,
compressed: ` compressed: `
H4sIAAAAAAAC/6yWz0/jOhDH7/0rRgGJC5CnJ/QOFeLy9sJpD4v2suJg7EkybGNnx1Ogu+r/vrJN2qRJ H4sIAAAAAAAC/6yWz0/jOhDH7/0rRgGJC5CnJ/QOFeLy9sJpD4v2suJg7EkybGNnx1Ogu+r/vrJN2qRJ
C4Te2rHnO5/vxL/+zAAyg14zNULOZnPIvjZo/3dWFFlkuK1ViXBrDb7AtwY1FaRVnHoeck+9rrBWIa8S C4Te2rHnO5/vxL/+zAAyg14zNULOZnPIvjZo/3dWFFlkuK1ViXBrDb7AtwY1FaRVnHoeck+9rrBWIa8S
@@ -289,9 +313,10 @@ VmZjL8HOE24GcD9bz/4GAAD//yCnv52xCwAA
}, },
"/image-layout-schema.json": { "/image-layout-schema.json": {
name: "image-layout-schema.json",
local: "image-layout-schema.json", local: "image-layout-schema.json",
size: 439, size: 439,
modtime: 1515512099, modtime: 1625865903,
compressed: ` compressed: `
H4sIAAAAAAAC/2yPQUvEMBCF7/0VQ/Sg4DYVPOW6pwVhD4IX8VDTaTvLNonJVFik/12SaRXRU5g38+W9 H4sIAAAAAAAC/2yPQUvEMBCF7/0VQ/Sg4DYVPOW6pwVhD4IX8VDTaTvLNonJVFik/12SaRXRU5g38+W9
91kBqA6TjRSYvFMG1DGg23vHLTmMcJjaAeGxvfiZ4cmOOLXqLlPXSQYDamQORutT8m4nau3joLvY9rxr 91kBqA6TjRSYvFMG1DGg23vHLTmMcJjaAeGxvfiZ4cmOOLXqLlPXSQYDamQORutT8m4nau3joLvY9rxr
@@ -302,9 +327,10 @@ HrRoV8JRtyHJaO0DOruZpYLJtaZsrM/FWEi+BMysfzuhXbUQfcDIhEkZyG2yQyYl8TPGJLVk97fth1yA
}, },
"/image-manifest-schema.json": { "/image-manifest-schema.json": {
name: "image-manifest-schema.json",
local: "image-manifest-schema.json", local: "image-manifest-schema.json",
size: 921, size: 921,
modtime: 1515512099, modtime: 1625865903,
compressed: ` compressed: `
H4sIAAAAAAAC/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv H4sIAAAAAAAC/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv
zTdv/dEAiB59x+QCWSNaEHcOzT9rgiKDDOtJDQj/lSGNPsC9w440dSpNL6J97rsRJxWtYwiulXLjrVlm zTdv/dEAiB59x+QCWSNaEHcOzT9rgiKDDOtJDQj/lSGNPsC9w440dSpNL6J97rsRJxWtYwiulXLjrVlm
@@ -317,7 +343,21 @@ Dj+ZAwAA
}, },
"/": { "/": {
name: "/",
local: `.`,
isDir: true, isDir: true,
local: "", },
}
var _escDirs = map[string][]os.FileInfo{
".": {
_escData["/config-schema.json"],
_escData["/content-descriptor.json"],
_escData["/defs-descriptor.json"],
_escData["/defs.json"],
_escData["/image-index-schema.json"],
_escData["/image-layout-schema.json"],
_escData["/image-manifest-schema.json"],
}, },
} }

View File

@@ -23,7 +23,7 @@ import (
"regexp" "regexp"
digest "github.com/opencontainers/go-digest" digest "github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go/v1" v1 "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/xeipuuv/gojsonschema" "github.com/xeipuuv/gojsonschema"
) )
@@ -168,6 +168,7 @@ func validateIndex(r io.Reader) error {
} }
if manifest.Platform != nil { if manifest.Platform != nil {
checkPlatform(manifest.Platform.OS, manifest.Platform.Architecture) checkPlatform(manifest.Platform.OS, manifest.Platform.Architecture)
checkArchitecture(manifest.Platform.Architecture, manifest.Platform.Variant)
} }
} }
@@ -189,6 +190,7 @@ func validateConfig(r io.Reader) error {
} }
checkPlatform(header.OS, header.Architecture) checkPlatform(header.OS, header.Architecture)
checkArchitecture(header.Architecture, header.Variant)
envRegexp := regexp.MustCompile(`^[^=]+=.*$`) envRegexp := regexp.MustCompile(`^[^=]+=.*$`)
for _, e := range header.Config.Env { for _, e := range header.Config.Env {
@@ -200,6 +202,31 @@ func validateConfig(r io.Reader) error {
return nil return nil
} }
func checkArchitecture(Architecture string, Variant string) {
validCombins := map[string][]string{
"arm": {"", "v6", "v7", "v8"},
"arm64": {"", "v8"},
"386": {""},
"amd64": {""},
"ppc64": {""},
"ppc64le": {""},
"mips64": {""},
"mips64le": {""},
"s390x": {""},
}
for arch, variants := range validCombins {
if arch == Architecture {
for _, variant := range variants {
if variant == Variant {
return
}
}
fmt.Printf("warning: combination of architecture %q and variant %q is not valid.\n", Architecture, Variant)
}
}
fmt.Printf("warning: architecture %q is not supported yet.\n", Architecture)
}
func checkPlatform(OS string, Architecture string) { func checkPlatform(OS string, Architecture string) {
validCombins := map[string][]string{ validCombins := map[string][]string{
"android": {"arm"}, "android": {"arm"},
@@ -219,7 +246,7 @@ func checkPlatform(OS string, Architecture string) {
return return
} }
} }
fmt.Printf("warning: combination of %q and %q is invalid.\n", OS, Architecture) fmt.Printf("warning: combination of os %q and architecture %q is invalid.\n", OS, Architecture)
} }
} }
fmt.Printf("warning: operating system %q of the bundle is not supported yet.\n", OS) fmt.Printf("warning: operating system %q of the bundle is not supported yet.\n", OS)

View File

@@ -53,4 +53,10 @@ const (
// AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image. // AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image.
AnnotationDescription = "org.opencontainers.image.description" AnnotationDescription = "org.opencontainers.image.description"
// AnnotationBaseImageDigest is the annotation key for the digest of the image's base image.
AnnotationBaseImageDigest = "org.opencontainers.image.base.digest"
// AnnotationBaseImageName is the annotation key for the image reference of the image's base image.
AnnotationBaseImageName = "org.opencontainers.image.base.name"
) )

View File

@@ -89,9 +89,20 @@ type Image struct {
// Architecture is the CPU architecture which the binaries in this image are built to run on. // Architecture is the CPU architecture which the binaries in this image are built to run on.
Architecture string `json:"architecture"` Architecture string `json:"architecture"`
// Variant is the variant of the specified CPU architecture which image binaries are intended to run on.
Variant string `json:"variant,omitempty"`
// OS is the name of the operating system which the image is built to run on. // OS is the name of the operating system which the image is built to run on.
OS string `json:"os"` OS string `json:"os"`
// OSVersion is an optional field specifying the operating system
// version, for example on Windows `10.0.14393.1066`.
OSVersion string `json:"os.version,omitempty"`
// OSFeatures is an optional field specifying an array of strings,
// each listing a required OS feature (for example on Windows `win32k`).
OSFeatures []string `json:"os.features,omitempty"`
// Config defines the execution parameters which should be used as a base when running a container using the image. // Config defines the execution parameters which should be used as a base when running a container using the image.
Config ImageConfig `json:"config,omitempty"` Config ImageConfig `json:"config,omitempty"`

View File

@@ -15,13 +15,11 @@
package image package image
import ( import (
"encoding/json"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"github.com/opencontainers/image-spec/schema"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@@ -47,7 +45,7 @@ func Autodetect(path string) (string, error) {
return TypeImageLayout, nil return TypeImageLayout, nil
} }
f, err := os.Open(path) f, err := os.Open(path) // nolint: errcheck, gosec
if err != nil { if err != nil {
return "", errors.Wrap(err, "unable to open file") // os.Open includes the filename return "", errors.Wrap(err, "unable to open file") // os.Open includes the filename
} }
@@ -65,48 +63,7 @@ func Autodetect(path string) (string, error) {
return TypeImage, nil return TypeImage, nil
case "application/zip": case "application/zip":
return TypeImageZip, nil return TypeImageZip, nil
case "text/plain; charset=utf-8":
// might be a JSON file, will be handled below
default:
return "", errors.New("unknown file type")
} }
if _, err := f.Seek(0, io.SeekStart); err != nil { return "", errors.New("unknown file type")
return "", errors.Wrap(err, "unable to seek")
}
header := struct {
SchemaVersion int `json:"schemaVersion"`
MediaType string `json:"mediaType"`
Config interface{} `json:"config"`
}{}
if err := json.NewDecoder(f).Decode(&header); err != nil {
if _, errSeek := f.Seek(0, io.SeekStart); errSeek != nil {
return "", errors.Wrap(err, "unable to seek")
}
e := errors.Wrap(
schema.WrapSyntaxError(f, err),
"unable to parse JSON",
)
return "", e
}
switch {
case header.MediaType == string(schema.ValidatorMediaTypeManifest):
return TypeManifest, nil
case header.MediaType == string(schema.ValidatorMediaTypeImageIndex):
return TypeImageIndex, nil
case header.MediaType == "" && header.SchemaVersion == 0 && header.Config != nil:
// config files don't have mediaType/schemaVersion header
return TypeConfig, nil
}
return "", errors.New("unknown media type")
} }

View File

@@ -20,7 +20,6 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os"
"path/filepath" "path/filepath"
"strconv" "strconv"
"strings" "strings"
@@ -31,16 +30,11 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
type config v1.Image func findConfig(w walker, d *v1.Descriptor) (*v1.Image, error) {
var c v1.Image
func findConfig(w walker, d *v1.Descriptor) (*config, error) {
var c config
cpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex()) cpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex())
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { switch err := w.find(cpath, func(path string, r io.Reader) error {
if info.IsDir() || filepath.Clean(path) != cpath {
return nil
}
buf, err := ioutil.ReadAll(r) buf, err := ioutil.ReadAll(r)
if err != nil { if err != nil {
return errors.Wrapf(err, "%s: error reading config", path) return errors.Wrapf(err, "%s: error reading config", path)
@@ -65,7 +59,7 @@ func findConfig(w walker, d *v1.Descriptor) (*config, error) {
} }
} }
func (c *config) runtimeSpec(rootfs string) (*specs.Spec, error) { func runtimeSpec(c *v1.Image, rootfs string) (*specs.Spec, error) {
if c.OS != "linux" { if c.OS != "linux" {
return nil, fmt.Errorf("%s: unsupported OS", c.OS) return nil, fmt.Errorf("%s: unsupported OS", c.OS)
} }

View File

@@ -20,6 +20,7 @@ import (
"io" "io"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -27,8 +28,8 @@ import (
const indexPath = "index.json" const indexPath = "index.json"
func listReferences(w walker) (map[string]*v1.Descriptor, error) { func listReferences(w walker) ([]v1.Descriptor, error) {
refs := make(map[string]*v1.Descriptor) var descs []v1.Descriptor
var index v1.Index var index v1.Index
if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { if err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
@@ -39,10 +40,54 @@ func listReferences(w walker) (map[string]*v1.Descriptor, error) {
if err := json.NewDecoder(r).Decode(&index); err != nil { if err := json.NewDecoder(r).Decode(&index); err != nil {
return err return err
} }
descs = index.Manifests
for i := 0; i < len(index.Manifests); i++ { return nil
if index.Manifests[i].Annotations[v1.AnnotationRefName] != "" { }); err != nil {
refs[index.Manifests[i].Annotations[v1.AnnotationRefName]] = &index.Manifests[i] return nil, err
}
return descs, nil
}
func findDescriptor(w walker, names []string) ([]v1.Descriptor, error) {
var descs []v1.Descriptor
var index v1.Index
dpath := "index.json"
if err := w.find(dpath, func(path string, r io.Reader) error {
if err := json.NewDecoder(r).Decode(&index); err != nil {
return err
}
descs = index.Manifests
for _, name := range names {
argsParts := strings.Split(name, "=")
if len(argsParts) != 2 {
return fmt.Errorf("each ref must contain two parts")
}
switch argsParts[0] {
case "name":
for i := 0; i < len(descs); i++ {
if descs[i].Annotations[v1.AnnotationRefName] != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
case "platform.os":
for i := 0; i < len(descs); i++ {
if descs[i].Platform != nil && index.Manifests[i].Platform.OS != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
case "digest":
for i := 0; i < len(descs); i++ {
if string(descs[i].Digest) != argsParts[1] {
descs = append(descs[:i], descs[i+1:]...)
}
}
default:
return fmt.Errorf("criteria %q unimplemented", argsParts[0])
} }
} }
@@ -50,38 +95,14 @@ func listReferences(w walker) (map[string]*v1.Descriptor, error) {
}); err != nil { }); err != nil {
return nil, err return nil, err
} }
return refs, nil
}
func findDescriptor(w walker, name string) (*v1.Descriptor, error) { if len(descs) == 0 {
var d v1.Descriptor return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not match", names)
var index v1.Index } else if len(descs) > 1 {
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not unique", names)
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
if info.IsDir() || filepath.Clean(path) != indexPath {
return nil
}
if err := json.NewDecoder(r).Decode(&index); err != nil {
return err
}
for i := 0; i < len(index.Manifests); i++ {
if index.Manifests[i].Annotations[v1.AnnotationRefName] == name {
d = index.Manifests[i]
return errEOW
}
}
return nil
}); err {
case nil:
return nil, fmt.Errorf("index.json: descriptor %q not found", name)
case errEOW:
return &d, nil
default:
return nil, err
} }
return descs, nil
} }
func validateDescriptor(d *v1.Descriptor, w walker, mts []string) error { func validateDescriptor(d *v1.Descriptor, w walker, mts []string) error {

View File

@@ -12,5 +12,5 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// Package image defines methods for validating, and unpacking OCI images. // Package image defines methods for validating, unpacking OCI images and creating OCI runtime bundle.
package image package image

View File

@@ -41,7 +41,7 @@ func ValidateZip(src string, refs []string, out *log.Logger) error {
// ValidateFile opens the tar file given by the filename, then calls ValidateReader // ValidateFile opens the tar file given by the filename, then calls ValidateReader
func ValidateFile(tarFile string, refs []string, out *log.Logger) error { func ValidateFile(tarFile string, refs []string, out *log.Logger) error {
f, err := os.Open(tarFile) f, err := os.Open(tarFile) // nolint: errcheck, gosec
if err != nil { if err != nil {
return errors.Wrap(err, "unable to open file") return errors.Wrap(err, "unable to open file")
} }
@@ -65,36 +65,35 @@ var validRefMediaTypes = []string{
} }
func validate(w walker, refs []string, out *log.Logger) error { func validate(w walker, refs []string, out *log.Logger) error {
if err := layoutValidate(w); err != nil { var descs []v1.Descriptor
return err var err error
}
ds, err := listReferences(w) if err = layoutValidate(w); err != nil {
if err != nil {
return err return err
} }
if len(refs) == 0 && len(ds) == 0 {
// TODO(runcom): ugly, we'll need a better way and library
// to express log levels.
// see https://github.com/opencontainers/image-spec/issues/288
out.Print("WARNING: no descriptors found")
}
if len(refs) == 0 { if len(refs) == 0 {
for ref := range ds { out.Print("No ref specified, verify all refs")
refs = append(refs, ref) descs, err = listReferences(w)
if err != nil {
return err
}
if len(descs) == 0 {
// TODO(runcom): ugly, we'll need a better way and library
// to express log levels.
// see https://github.com/opencontainers/image-spec/issues/288
out.Print("WARNING: no descriptors found")
return nil
}
} else {
descs, err = findDescriptor(w, refs)
if err != nil {
return err
} }
} }
for _, ref := range refs { for _, desc := range descs {
d, ok := ds[ref] d := &desc
if !ok {
// TODO(runcom):
// soften this error to a warning if the user didn't ask for any specific reference
// with --ref but she's just validating the whole image.
return fmt.Errorf("reference %s not found", ref)
}
if err = validateDescriptor(d, w, validRefMediaTypes); err != nil { if err = validateDescriptor(d, w, validRefMediaTypes); err != nil {
return err return err
} }
@@ -105,7 +104,7 @@ func validate(w walker, refs []string, out *log.Logger) error {
return err return err
} }
if err := m.validate(w); err != nil { if err := validateManifest(m, w); err != nil {
return err return err
} }
} }
@@ -131,15 +130,15 @@ func validate(w walker, refs []string, out *log.Logger) error {
return err return err
} }
if err := m.validate(w); err != nil { if err := validateManifest(m, w); err != nil {
return err return err
} }
} }
} }
}
if out != nil { if out != nil && len(refs) > 0 {
out.Printf("reference %q: OK", ref) out.Printf("reference %v: OK", refs)
}
} }
return nil return nil
@@ -148,46 +147,47 @@ func validate(w walker, refs []string, out *log.Logger) error {
// UnpackLayout walks through the file tree given by src and, using the layers // 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 // 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. // the given destination directory or returns an error if the unpacking failed.
func UnpackLayout(src, dest, ref, platform string) error { func UnpackLayout(src, dest, platform string, refs []string) error {
return unpack(newPathWalker(src), dest, ref, platform) return unpack(newPathWalker(src), dest, platform, refs)
} }
// UnpackZip opens and walks through the zip file given by src and, using the layers // 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 // 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. // the given destination directory or returns an error if the unpacking failed.
func UnpackZip(src, dest, ref, platform string) error { func UnpackZip(src, dest, platform string, refs []string) error {
return unpack(newZipWalker(src), dest, ref, platform) return unpack(newZipWalker(src), dest, platform, refs)
} }
// UnpackFile opens the file pointed by tarFileName and calls Unpack on it. // UnpackFile opens the file pointed by tarFileName and calls Unpack on it.
func UnpackFile(tarFileName, dest, ref, platform string) error { func UnpackFile(tarFileName, dest, platform string, refs []string) error {
f, err := os.Open(tarFileName) f, err := os.Open(tarFileName) // nolint: errcheck, gosec
if err != nil { if err != nil {
return errors.Wrap(err, "unable to open file") return errors.Wrap(err, "unable to open file")
} }
defer f.Close() defer f.Close()
return Unpack(f, dest, ref, platform) return Unpack(f, dest, platform, refs)
} }
// Unpack walks through the tar stream and, using the layers specified in // Unpack walks through the tar stream and, using the layers specified in
// the manifest pointed to by the given ref, unpacks all layers in the given // the manifest pointed to by the given ref, unpacks all layers in the given
// destination directory or returns an error if the unpacking failed. // destination directory or returns an error if the unpacking failed.
// The destination will be created if it does not exist. // The destination will be created if it does not exist.
func Unpack(r io.ReadSeeker, dest, refName, platform string) error { func Unpack(r io.ReadSeeker, dest, platform string, refs []string) error {
return unpack(newTarWalker(r), dest, refName, platform) return unpack(newTarWalker(r), dest, platform, refs)
} }
func unpack(w walker, dest, refName, platform string) error { func unpack(w walker, dest, platform string, refs []string) error {
if err := layoutValidate(w); err != nil { if err := layoutValidate(w); err != nil {
return err return err
} }
ref, err := findDescriptor(w, refName) descs, err := findDescriptor(w, refs)
if err != nil { if err != nil {
return err return err
} }
ref := &descs[0]
if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil { if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil {
return err return err
} }
@@ -198,11 +198,11 @@ func unpack(w walker, dest, refName, platform string) error {
return err return err
} }
if err := m.validate(w); err != nil { if err := validateManifest(m, w); err != nil {
return err return err
} }
return m.unpack(w, dest) return unpackManifest(m, w, dest)
} }
if ref.MediaType == validRefMediaTypes[1] { if ref.MediaType == validRefMediaTypes[1] {
@@ -221,7 +221,7 @@ func unpack(w walker, dest, refName, platform string) error {
} }
for _, m := range manifests { for _, m := range manifests {
return m.unpack(w, dest) return unpackManifest(m, w, dest)
} }
} }
@@ -231,46 +231,47 @@ func unpack(w walker, dest, refName, platform string) error {
// CreateRuntimeBundleLayout walks through the file tree given by src and // CreateRuntimeBundleLayout walks through the file tree given by src and
// creates an OCI runtime bundle in the given destination dest // creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed. // or returns an error if the unpacking failed.
func CreateRuntimeBundleLayout(src, dest, ref, root, platform string) error { func CreateRuntimeBundleLayout(src, dest, root, platform string, refs []string) error {
return createRuntimeBundle(newPathWalker(src), dest, ref, root, platform) return createRuntimeBundle(newPathWalker(src), dest, root, platform, refs)
} }
// CreateRuntimeBundleZip opens and walks through the zip file given by src // CreateRuntimeBundleZip opens and walks through the zip file given by src
// and creates an OCI runtime bundle in the given destination dest // and creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed. // or returns an error if the unpacking failed.
func CreateRuntimeBundleZip(src, dest, ref, root, platform string) error { func CreateRuntimeBundleZip(src, dest, root, platform string, refs []string) error {
return createRuntimeBundle(newZipWalker(src), dest, ref, root, platform) return createRuntimeBundle(newZipWalker(src), dest, root, platform, refs)
} }
// CreateRuntimeBundleFile opens the file pointed by tarFile and calls // CreateRuntimeBundleFile opens the file pointed by tarFile and calls
// CreateRuntimeBundle. // CreateRuntimeBundle.
func CreateRuntimeBundleFile(tarFile, dest, ref, root, platform string) error { func CreateRuntimeBundleFile(tarFile, dest, root, platform string, refs []string) error {
f, err := os.Open(tarFile) f, err := os.Open(tarFile) // nolint: errcheck, gosec
if err != nil { if err != nil {
return errors.Wrap(err, "unable to open file") return errors.Wrap(err, "unable to open file")
} }
defer f.Close() defer f.Close()
return createRuntimeBundle(newTarWalker(f), dest, ref, root, platform) return createRuntimeBundle(newTarWalker(f), dest, root, platform, refs)
} }
// CreateRuntimeBundle walks through the given tar stream and // CreateRuntimeBundle walks through the given tar stream and
// creates an OCI runtime bundle in the given destination dest // creates an OCI runtime bundle in the given destination dest
// or returns an error if the unpacking failed. // or returns an error if the unpacking failed.
func CreateRuntimeBundle(r io.ReadSeeker, dest, ref, root, platform string) error { func CreateRuntimeBundle(r io.ReadSeeker, dest, root, platform string, refs []string) error {
return createRuntimeBundle(newTarWalker(r), dest, ref, root, platform) return createRuntimeBundle(newTarWalker(r), dest, root, platform, refs)
} }
func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error { func createRuntimeBundle(w walker, dest, rootfs, platform string, refs []string) error {
if err := layoutValidate(w); err != nil { if err := layoutValidate(w); err != nil {
return err return err
} }
ref, err := findDescriptor(w, refName) descs, err := findDescriptor(w, refs)
if err != nil { if err != nil {
return err return err
} }
ref := &descs[0]
if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil { if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil {
return err return err
} }
@@ -281,7 +282,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error
return err return err
} }
if err := m.validate(w); err != nil { if err := validateManifest(m, w); err != nil {
return err return err
} }
@@ -311,7 +312,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error
return nil return nil
} }
func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) { func createBundle(w walker, m *v1.Manifest, dest, rootfs string) (retErr error) {
c, err := findConfig(w, &m.Config) c, err := findConfig(w, &m.Config)
if err != nil { if err != nil {
return err return err
@@ -319,7 +320,7 @@ func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) {
if _, err = os.Stat(dest); err != nil { if _, err = os.Stat(dest); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
if err2 := os.MkdirAll(dest, 0755); err2 != nil { if err2 := os.MkdirAll(dest, 0750); err2 != nil {
return err2 return err2
} }
defer func() { defer func() {
@@ -334,11 +335,11 @@ func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) {
} }
} }
if err = m.unpack(w, filepath.Join(dest, rootfs)); err != nil { if err = unpackManifest(m, w, filepath.Join(dest, rootfs)); err != nil {
return err return err
} }
spec, err := c.runtimeSpec(rootfs) spec, err := runtimeSpec(c, rootfs)
if err != nil { if err != nil {
return err return err
} }
@@ -353,8 +354,8 @@ func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) {
} }
// filertManifest returns a filtered list of manifests // filertManifest returns a filtered list of manifests
func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*manifest, error) { func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*v1.Manifest, error) {
var manifests []*manifest var manifests []*v1.Manifest
argsParts := strings.Split(platform, ":") argsParts := strings.Split(platform, ":")
if len(argsParts) != 2 { if len(argsParts) != 2 {
@@ -372,7 +373,7 @@ func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*ma
return manifests, err return manifests, err
} }
if err := m.validate(w); err != nil { if err := validateManifest(m, w); err != nil {
return manifests, err return manifests, err
} }
if strings.EqualFold(manifest.Platform.OS, argsParts[0]) && strings.EqualFold(manifest.Platform.Architecture, argsParts[1]) { if strings.EqualFold(manifest.Platform.OS, argsParts[0]) && strings.EqualFold(manifest.Platform.Architecture, argsParts[1]) {
@@ -381,7 +382,7 @@ func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*ma
} }
if len(manifests) == 0 { if len(manifests) == 0 {
return manifests, fmt.Errorf("There is no matching manifest") return manifests, fmt.Errorf("there is no matching manifest")
} }
return manifests, nil return manifests, nil

View File

@@ -48,14 +48,13 @@ func layoutValidate(w walker) error {
return fmt.Errorf("index.json is a directory") return fmt.Errorf("index.json is a directory")
} }
var index v1.Index
buf, err := ioutil.ReadAll(r) buf, err := ioutil.ReadAll(r)
if err != nil { if err != nil {
return errors.Wrap(err, "error reading index.json") return errors.Wrap(err, "error reading index.json")
} }
if err := json.Unmarshal(buf, &index); err != nil { if err := schema.ValidatorMediaTypeImageIndex.Validate(bytes.NewReader(buf)); err != nil {
return errors.Wrap(err, "index.json format mismatch") return errors.Wrap(err, "index.json validation failed")
} }
return nil return nil
@@ -74,7 +73,7 @@ func layoutValidate(w walker) error {
} }
if err := schema.ValidatorMediaTypeLayoutHeader.Validate(bytes.NewReader(buf)); err != nil { if err := schema.ValidatorMediaTypeLayoutHeader.Validate(bytes.NewReader(buf)); err != nil {
return errors.Wrap(err, "oci-layout: imageLayout validation failed") return errors.Wrap(err, "oci-layout validation failed")
} }
if err := json.Unmarshal(buf, &imageLayout); err != nil { if err := json.Unmarshal(buf, &imageLayout); err != nil {

View File

@@ -29,26 +29,17 @@ import (
"strings" "strings"
"time" "time"
"github.com/sirupsen/logrus"
"github.com/opencontainers/image-spec/schema" "github.com/opencontainers/image-spec/schema"
"github.com/opencontainers/image-spec/specs-go/v1" "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/sirupsen/logrus"
) )
type manifest struct { func findManifest(w walker, d *v1.Descriptor) (*v1.Manifest, error) {
Config v1.Descriptor `json:"config"` var m v1.Manifest
Layers []v1.Descriptor `json:"layers"`
}
func findManifest(w walker, d *v1.Descriptor) (*manifest, error) {
var m manifest
mpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex()) mpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex())
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { switch err := w.find(mpath, func(path string, r io.Reader) error {
if info.IsDir() || filepath.Clean(path) != mpath {
return nil
}
buf, err := ioutil.ReadAll(r) buf, err := ioutil.ReadAll(r)
if err != nil { if err != nil {
return errors.Wrapf(err, "%s: error reading manifest", path) return errors.Wrapf(err, "%s: error reading manifest", path)
@@ -73,7 +64,7 @@ func findManifest(w walker, d *v1.Descriptor) (*manifest, error) {
} }
} }
func (m *manifest) validate(w walker) error { func validateManifest(m *v1.Manifest, w walker) error {
if err := validateDescriptor(&m.Config, w, []string{v1.MediaTypeImageConfig}); err != nil { if err := validateDescriptor(&m.Config, w, []string{v1.MediaTypeImageConfig}); err != nil {
return errors.Wrap(err, "config validation failed") return errors.Wrap(err, "config validation failed")
} }
@@ -94,7 +85,7 @@ func (m *manifest) validate(w walker) error {
return nil return nil
} }
func (m *manifest) unpack(w walker, dest string) (retErr error) { func unpackManifest(m *v1.Manifest, w walker, dest string) (retErr error) {
// error out if the dest directory is not empty // error out if the dest directory is not empty
s, err := ioutil.ReadDir(dest) s, err := ioutil.ReadDir(dest)
if err != nil && !os.IsNotExist(err) { // We'll create the dir later if err != nil && !os.IsNotExist(err) { // We'll create the dir later
@@ -113,18 +104,10 @@ func (m *manifest) unpack(w walker, dest string) (retErr error) {
} }
}() }()
for _, d := range m.Layers { for _, d := range m.Layers {
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error { lpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex())
if info.IsDir() { switch err := w.find(lpath, func(path string, r io.Reader) error {
return nil
}
dd, err := filepath.Rel(filepath.Join("blobs", string(d.Digest.Algorithm())), filepath.Clean(path))
if err != nil || d.Digest.Hex() != dd {
return nil
}
if err := unpackLayer(d.MediaType, path, dest, r); err != nil { if err := unpackLayer(d.MediaType, path, dest, r); err != nil {
return errors.Wrap(err, "error unpack: extracting layer") return errors.Wrap(err, "unpack: error extracting layer")
} }
return errEOW return errEOW
@@ -218,85 +201,15 @@ loop:
return errors.Wrapf(err, "error advancing tar stream") return errors.Wrapf(err, "error advancing tar stream")
} }
hdr.Name = filepath.Clean(hdr.Name) var whiteout bool
if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) { whiteout, err = unpackLayerEntry(dest, hdr, tr, &entries)
// Not the root directory, ensure that the parent directory exists
parent := filepath.Dir(hdr.Name)
parentPath := filepath.Join(dest, parent)
if _, err2 := os.Lstat(parentPath); err2 != nil && os.IsNotExist(err2) {
if err3 := os.MkdirAll(parentPath, 0755); err3 != nil {
return err3
}
}
}
path := filepath.Join(dest, hdr.Name)
if entries[path] {
return fmt.Errorf("duplicate entry for %s", path)
}
entries[path] = true
rel, err := filepath.Rel(dest, path)
if err != nil { if err != nil {
return err return err
} }
info := hdr.FileInfo() if whiteout {
if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return fmt.Errorf("%q is outside of %q", hdr.Name, dest)
}
if strings.HasPrefix(info.Name(), ".wh.") {
path = strings.Replace(path, ".wh.", "", 1)
if err := os.RemoveAll(path); err != nil {
return errors.Wrap(err, "unable to delete whiteout path")
}
continue loop continue loop
} }
switch hdr.Typeflag {
case tar.TypeDir:
if fi, err := os.Lstat(path); !(err == nil && fi.IsDir()) {
if err2 := os.MkdirAll(path, info.Mode()); err2 != nil {
return errors.Wrap(err2, "error creating directory")
}
}
case tar.TypeReg, tar.TypeRegA:
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode())
if err != nil {
return errors.Wrap(err, "unable to open file")
}
if _, err := io.Copy(f, tr); err != nil {
f.Close()
return errors.Wrap(err, "unable to copy")
}
f.Close()
case tar.TypeLink:
target := filepath.Join(dest, hdr.Linkname)
if !strings.HasPrefix(target, dest) {
return fmt.Errorf("invalid hardlink %q -> %q", target, hdr.Linkname)
}
if err := os.Link(target, path); err != nil {
return err
}
case tar.TypeSymlink:
target := filepath.Join(filepath.Dir(path), hdr.Linkname)
if !strings.HasPrefix(target, dest) {
return fmt.Errorf("invalid symlink %q -> %q", path, hdr.Linkname)
}
if err := os.Symlink(hdr.Linkname, path); err != nil {
return err
}
case tar.TypeXGlobalHeader:
return nil
}
// Directory mtimes must be handled at the end to avoid further // Directory mtimes must be handled at the end to avoid further
// file creation in them to modify the directory mtime // file creation in them to modify the directory mtime
if hdr.Typeflag == tar.TypeDir { if hdr.Typeflag == tar.TypeDir {
@@ -315,3 +228,104 @@ loop:
} }
return nil return nil
} }
// unpackLayerEntry unpacks a single entry from a layer.
func unpackLayerEntry(dest string, header *tar.Header, reader io.Reader, entries *map[string]bool) (whiteout bool, err error) {
header.Name = filepath.Clean(header.Name)
if !strings.HasSuffix(header.Name, string(os.PathSeparator)) {
// Not the root directory, ensure that the parent directory exists
parent := filepath.Dir(header.Name)
parentPath := filepath.Join(dest, parent)
if _, err2 := os.Lstat(parentPath); err2 != nil && os.IsNotExist(err2) {
if err3 := os.MkdirAll(parentPath, 0750); err3 != nil {
return false, err3
}
}
}
path := filepath.Join(dest, header.Name)
if (*entries)[path] {
return false, fmt.Errorf("duplicate entry for %s", path)
}
(*entries)[path] = true
rel, err := filepath.Rel(dest, path)
if err != nil {
return false, err
}
info := header.FileInfo()
if strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return false, fmt.Errorf("%q is outside of %q", header.Name, dest)
}
if strings.HasPrefix(info.Name(), ".wh.") {
path = strings.Replace(path, ".wh.", "", 1)
if err = os.RemoveAll(path); err != nil {
return true, errors.Wrap(err, "unable to delete whiteout path")
}
return true, nil
}
if header.Typeflag != tar.TypeDir {
err = os.RemoveAll(path)
if err != nil && !os.IsNotExist(err) {
return false, err
}
}
switch header.Typeflag {
case tar.TypeDir:
fi, err := os.Lstat(path)
if err != nil && !os.IsNotExist(err) {
return false, err
}
if os.IsNotExist(err) || !fi.IsDir() {
err = os.RemoveAll(path)
if err != nil && !os.IsNotExist(err) {
return false, err
}
err = os.MkdirAll(path, info.Mode())
if err != nil {
return false, err
}
}
case tar.TypeReg, tar.TypeRegA:
f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode())
if err != nil {
return false, errors.Wrap(err, "unable to open file")
}
if _, err := io.Copy(f, reader); err != nil {
defer f.Close()
return false, errors.Wrap(err, "unable to copy")
}
defer f.Close()
case tar.TypeLink:
target := filepath.Join(dest, header.Linkname)
if !strings.HasPrefix(target, dest) {
return false, fmt.Errorf("invalid hardlink %q -> %q", target, header.Linkname)
}
if err := os.Link(target, path); err != nil {
return false, err
}
case tar.TypeSymlink:
target := filepath.Join(filepath.Dir(path), header.Linkname)
if !strings.HasPrefix(target, dest) {
return false, fmt.Errorf("invalid symlink %q -> %q", path, header.Linkname)
}
if err := os.Symlink(header.Linkname, path); err != nil {
return false, err
}
case tar.TypeXGlobalHeader:
return false, nil
}
return false, nil
}

View File

@@ -34,6 +34,8 @@ var (
// walkFunc is a function type that gets called for each file or directory visited by the Walker. // walkFunc is a function type that gets called for each file or directory visited by the Walker.
type walkFunc func(path string, _ os.FileInfo, _ io.Reader) error type walkFunc func(path string, _ os.FileInfo, _ io.Reader) error
type findFunc func(path string, r io.Reader) error
// walker is the interface that defines how to access a given archival format // walker is the interface that defines how to access a given archival format
type walker interface { type walker interface {
@@ -43,6 +45,9 @@ type walker interface {
// get will copy an arbitrary blob, defined by desc, in to dst. returns // get will copy an arbitrary blob, defined by desc, in to dst. returns
// the number of bytes copied on success. // the number of bytes copied on success.
get(desc v1.Descriptor, dst io.Writer) (int64, error) get(desc v1.Descriptor, dst io.Writer) (int64, error)
// find calls findFunc for handling content of path
find(path string, ff findFunc) error
} }
// tarWalker exposes access to image layouts in a tar file. // tarWalker exposes access to image layouts in a tar file.
@@ -120,6 +125,34 @@ func (w *tarWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
return bytes, nil return bytes, nil
} }
func (w *tarWalker) find(path string, ff findFunc) error {
done := false
f := func(relpath string, info os.FileInfo, rdr io.Reader) error {
var err error
if done {
return nil
}
if filepath.Clean(relpath) == path && !info.IsDir() {
if err = ff(relpath, rdr); err != nil {
return err
}
done = true
}
return nil
}
if err := w.walk(f); err != nil {
return errors.Wrapf(err, "find failed: unable to walk")
}
if !done {
return os.ErrNotExist
}
return nil
}
type eofReader struct{} type eofReader struct{}
func (eofReader) Read(_ []byte) (int, error) { func (eofReader) Read(_ []byte) (int, error) {
@@ -153,7 +186,7 @@ func (w *pathWalker) walk(f walkFunc) error {
return f(rel, info, eofReader{}) return f(rel, info, eofReader{})
} }
file, err := os.Open(path) file, err := os.Open(path) // nolint: errcheck, gosec
if err != nil { if err != nil {
return errors.Wrap(err, "unable to open file") // os.Open includes the path return errors.Wrap(err, "unable to open file") // os.Open includes the path
} }
@@ -175,7 +208,7 @@ func (w *pathWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
return 0, fmt.Errorf("object is dir") return 0, fmt.Errorf("object is dir")
} }
fp, err := os.Open(name) fp, err := os.Open(name) // nolint: errcheck, gosec
if err != nil { if err != nil {
return 0, errors.Wrapf(err, "get failed") return 0, errors.Wrapf(err, "get failed")
} }
@@ -188,6 +221,27 @@ func (w *pathWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
return nbytes, nil return nbytes, nil
} }
func (w *pathWalker) find(path string, ff findFunc) error {
name := filepath.Join(w.root, path)
info, err := os.Stat(name)
if err != nil {
return err
}
if info.IsDir() {
return fmt.Errorf("object is dir")
}
file, err := os.Open(name) // nolint: errcheck, gosec
if err != nil {
return errors.Wrap(err, "unable to open file") // os.Open includes the path
}
defer file.Close()
return ff(name, file)
}
type zipWalker struct { type zipWalker struct {
fileName string fileName string
} }
@@ -249,3 +303,31 @@ func (w *zipWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
return bytes, nil return bytes, nil
} }
func (w *zipWalker) find(path string, ff findFunc) error {
done := false
f := func(relpath string, info os.FileInfo, rdr io.Reader) error {
var err error
if done {
return nil
}
if filepath.Clean(relpath) == path && !info.IsDir() {
if err = ff(relpath, rdr); err != nil {
return err
}
done = true
}
return nil
}
if err := w.walk(f); err != nil {
return errors.Wrapf(err, "find failed: unable to walk")
}
if !done {
return os.ErrNotExist
}
return nil
}

8
vendor/go4.org/AUTHORS generated vendored
View File

@@ -1,8 +0,0 @@
# This is the official list of go4 authors for copyright purposes.
# This is distinct from the CONTRIBUTORS file, which is the list of
# people who have contributed, even if they don't own the copyright on
# their work.
Mathieu Lonjaret <mathieu.lonjaret@gmail.com>
Daniel Theophanes <kardianos@gmail.com>
Google

202
vendor/go4.org/LICENSE generated vendored
View File

@@ -1,202 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright {yyyy} {name of copyright owner}
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.

View File

@@ -1,58 +0,0 @@
/*
Copyright 2011 Google Inc.
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 errorutil helps make better error messages.
package errorutil // import "go4.org/errorutil"
import (
"bufio"
"bytes"
"fmt"
"io"
"strings"
)
// HighlightBytePosition takes a reader and the location in bytes of a parse
// error (for instance, from json.SyntaxError.Offset) and returns the line, column,
// and pretty-printed context around the error with an arrow indicating the exact
// position of the syntax error.
func HighlightBytePosition(f io.Reader, pos int64) (line, col int, highlight string) {
line = 1
br := bufio.NewReader(f)
lastLine := ""
thisLine := new(bytes.Buffer)
for n := int64(0); n < pos; n++ {
b, err := br.ReadByte()
if err != nil {
break
}
if b == '\n' {
lastLine = thisLine.String()
thisLine.Reset()
line++
col = 1
} else {
col++
thisLine.WriteByte(b)
}
}
if line > 1 {
highlight += fmt.Sprintf("%5d: %s\n", line-1, lastLine)
}
highlight += fmt.Sprintf("%5d: %s\n", line, thisLine.String())
highlight += fmt.Sprintf("%s^\n", strings.Repeat(" ", col+5))
return
}

View File

@@ -11,7 +11,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"io" "io"
"math/rand" "io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@@ -143,17 +143,11 @@ func (td *tempDir) newPath() string {
td.Lock() td.Lock()
defer td.Unlock() defer td.Unlock()
if td.path == "" { if td.path == "" {
var err error path, err := ioutil.TempDir("", "check-")
for i := 0; i != 100; i++ { if err != nil {
path := fmt.Sprintf("%s%ccheck-%d", os.TempDir(), os.PathSeparator, rand.Int())
if err = os.Mkdir(path, 0700); err == nil {
td.path = path
break
}
}
if td.path == "" {
panic("Couldn't create temporary directory: " + err.Error()) panic("Couldn't create temporary directory: " + err.Error())
} }
td.path = path
} }
result := filepath.Join(td.path, strconv.Itoa(td.counter)) result := filepath.Join(td.path, strconv.Itoa(td.counter))
td.counter++ td.counter++

View File

@@ -161,6 +161,10 @@ func (checker *notNilChecker) Check(params []interface{}, names []string) (resul
// Equals checker. // Equals checker.
func diffworthy(a interface{}) bool { func diffworthy(a interface{}) bool {
if a == nil {
return false
}
t := reflect.TypeOf(a) t := reflect.TypeOf(a)
switch t.Kind() { switch t.Kind() {
case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct, reflect.String, reflect.Ptr: case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct, reflect.String, reflect.Ptr:

5
vendor/gopkg.in/check.v1/go.mod generated vendored Normal file
View File

@@ -0,0 +1,5 @@
module gopkg.in/check.v1
go 1.11
require github.com/kr/pretty v0.2.1

5
vendor/gopkg.in/check.v1/go.sum generated vendored Normal file
View File

@@ -0,0 +1,5 @@
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=

View File

@@ -155,8 +155,9 @@ func (c *C) Fatalf(format string, args ...interface{}) {
// //
// Some checkers may not need the expected argument (e.g. IsNil). // Some checkers may not need the expected argument (e.g. IsNil).
// //
// Extra arguments provided to the function are logged next to the reported // If the last value in args implements CommentInterface, it is used to log
// problem when the matching fails. // additional information instead of being passed to the checker (see Commentf
// for an example).
func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool { func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool {
return c.internalCheck("Check", obtained, checker, args...) return c.internalCheck("Check", obtained, checker, args...)
} }
@@ -167,8 +168,9 @@ func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bo
// //
// Some checkers may not need the expected argument (e.g. IsNil). // Some checkers may not need the expected argument (e.g. IsNil).
// //
// Extra arguments provided to the function are logged next to the reported // If the last value in args implements CommentInterface, it is used to log
// problem when the matching fails. // additional information instead of being passed to the checker (see Commentf
// for an example).
func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) { func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) {
if !c.internalCheck("Assert", obtained, checker, args...) { if !c.internalCheck("Assert", obtained, checker, args...) {
c.stopNow() c.stopNow()

10
vendor/modules.txt vendored
View File

@@ -206,8 +206,6 @@ github.com/docker/go-metrics
github.com/docker/go-units github.com/docker/go-units
# github.com/ghodss/yaml v1.0.0 # github.com/ghodss/yaml v1.0.0
github.com/ghodss/yaml github.com/ghodss/yaml
# github.com/go-check/check v0.0.0-20180628173108-788fd7840127
github.com/go-check/check
# github.com/gogo/protobuf v1.3.2 # github.com/gogo/protobuf v1.3.2
github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/gogoproto
github.com/gogo/protobuf/proto github.com/gogo/protobuf/proto
@@ -271,11 +269,11 @@ github.com/modern-go/reflect2
github.com/mtrmac/gpgme github.com/mtrmac/gpgme
# github.com/opencontainers/go-digest v1.0.0 # github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/go-digest github.com/opencontainers/go-digest
# github.com/opencontainers/image-spec v1.0.2-0.20190823105129-775207bd45b6 # github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
github.com/opencontainers/image-spec/schema github.com/opencontainers/image-spec/schema
github.com/opencontainers/image-spec/specs-go github.com/opencontainers/image-spec/specs-go
github.com/opencontainers/image-spec/specs-go/v1 github.com/opencontainers/image-spec/specs-go/v1
# github.com/opencontainers/image-tools v0.0.0-20170926011501-6d941547fa1d # github.com/opencontainers/image-tools v1.0.0-rc3
github.com/opencontainers/image-tools/image github.com/opencontainers/image-tools/image
# github.com/opencontainers/runc v1.0.1 # github.com/opencontainers/runc v1.0.1
github.com/opencontainers/runc/libcontainer/user github.com/opencontainers/runc/libcontainer/user
@@ -355,8 +353,6 @@ go.opencensus.io/internal
go.opencensus.io/trace go.opencensus.io/trace
go.opencensus.io/trace/internal go.opencensus.io/trace/internal
go.opencensus.io/trace/tracestate go.opencensus.io/trace/tracestate
# go4.org v0.0.0-20190218023631-ce4c26f7be8e
go4.org/errorutil
# golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 # golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/crypto/cast5 golang.org/x/crypto/cast5
golang.org/x/crypto/ed25519 golang.org/x/crypto/ed25519
@@ -471,6 +467,8 @@ google.golang.org/protobuf/types/descriptorpb
google.golang.org/protobuf/types/known/anypb google.golang.org/protobuf/types/known/anypb
google.golang.org/protobuf/types/known/durationpb google.golang.org/protobuf/types/known/durationpb
google.golang.org/protobuf/types/known/timestamppb google.golang.org/protobuf/types/known/timestamppb
# gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
gopkg.in/check.v1
# gopkg.in/square/go-jose.v2 v2.5.1 # gopkg.in/square/go-jose.v2 v2.5.1
gopkg.in/square/go-jose.v2 gopkg.in/square/go-jose.v2
gopkg.in/square/go-jose.v2/cipher gopkg.in/square/go-jose.v2/cipher