mirror of
https://github.com/containers/skopeo.git
synced 2025-09-06 17:20:57 +00:00
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:
7
go.mod
7
go.mod
@@ -9,10 +9,9 @@ require (
|
||||
github.com/containers/storage v1.34.1
|
||||
github.com/docker/docker v20.10.8+incompatible
|
||||
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/image-spec v1.0.2-0.20190823105129-775207bd45b6
|
||||
github.com/opencontainers/image-tools v0.0.0-20170926011501-6d941547fa1d
|
||||
github.com/opencontainers/image-spec v1.0.2-0.20210819154149-5ad6f50d6283
|
||||
github.com/opencontainers/image-tools v1.0.0-rc3
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/russross/blackfriday v2.0.0+incompatible // indirect
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
@@ -20,6 +19,6 @@ require (
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/stretchr/testify v1.7.0
|
||||
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
|
||||
)
|
||||
|
14
go.sum
14
go.sum
@@ -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 v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
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/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=
|
||||
@@ -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/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.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-tools v0.0.0-20170926011501-6d941547fa1d h1:X9WSFjjZNqYRqO2MenUgqE2nj/oydcfIzXJ0R/SVnnA=
|
||||
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 h1:TVzvdjOalkJBNkbpPVMAr4KV9QRf2IjfxdyxwAK78Gs=
|
||||
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.1.1/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/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
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-20180904163835-0709b304e793/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 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-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-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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const blockedRegistriesConf = "./fixtures/blocked-registries.conf"
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/containers/skopeo/version"
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -17,10 +17,10 @@ import (
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/go-check/check"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/opencontainers/image-tools/image"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@@ -13,7 +13,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/homedir"
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var adminKUBECONFIG = map[string]string{
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/containers/image/v5/signature"
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -14,8 +14,8 @@ import (
|
||||
"github.com/containers/image/v5/docker/reference"
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/containers/image/v5/types"
|
||||
"github.com/go-check/check"
|
||||
imgspecv1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@@ -11,7 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/containers/image/v5/manifest"
|
||||
"github.com/go-check/check"
|
||||
"gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
const skopeoBinary = "skopeo"
|
||||
|
12
vendor/github.com/opencontainers/image-spec/schema/config-schema.json
generated
vendored
12
vendor/github.com/opencontainers/image-spec/schema/config-schema.json
generated
vendored
@@ -14,9 +14,21 @@
|
||||
"architecture": {
|
||||
"type": "string"
|
||||
},
|
||||
"variant": {
|
||||
"type": "string"
|
||||
},
|
||||
"os": {
|
||||
"type": "string"
|
||||
},
|
||||
"os.version": {
|
||||
"type": "string"
|
||||
},
|
||||
"os.features": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
19
vendor/github.com/opencontainers/image-spec/schema/error.go
generated
vendored
19
vendor/github.com/opencontainers/image-spec/schema/error.go
generated
vendored
@@ -15,10 +15,9 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"go4.org/errorutil"
|
||||
)
|
||||
|
||||
// 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.
|
||||
func WrapSyntaxError(r io.Reader, err error) error {
|
||||
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}
|
||||
}
|
||||
|
||||
|
80
vendor/github.com/opencontainers/image-spec/schema/fs.go
generated
vendored
80
vendor/github.com/opencontainers/image-spec/schema/fs.go
generated
vendored
@@ -20,6 +20,8 @@ import (
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -114,7 +116,24 @@ func (f *_escFile) Close() 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) {
|
||||
@@ -205,27 +224,29 @@ func _escFSMustString(useLocal bool, name string) string {
|
||||
var _escData = map[string]*_escFile{
|
||||
|
||||
"/config-schema.json": {
|
||||
name: "config-schema.json",
|
||||
local: "config-schema.json",
|
||||
size: 2771,
|
||||
modtime: 1515512099,
|
||||
size: 2969,
|
||||
modtime: 1625865937,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/+RWQY/TPBC951dE2T22m+/wnXot3JCKVAGHFarcZNLOEnvMeIKIUP87itNCkjpp6apc
|
||||
OEUaz7z35nns+EcUx0kOLmO0gmSSRZysLJglGVFogOMlmQJ38dpChgVmymfNmrJHl+1Bq6ZkL2IXafri
|
||||
yMzb6BPxLs1ZFTL/7/+0jT20dZifStwiTcmCyU5szpe12SlqtYM08/xtpdQWmlravkAmbcwyWWBBcMki
|
||||
btqJ4yRjUAL5r0Cn1AmjaeF8vCDWSpqVXAnMBTUkfu3QpiSqkj3xBFQ/m7M9CmRSMVxbQ+7azKMXgeyO
|
||||
Iz4ecMXHPzjgXmSEscPqc95+t+Qgf08sblj/yFB4A6FwT80IPKQ5FGiwGRWXamXXHnnVagzjm29jshSz
|
||||
qpNZdwkF9FDGRCNxfBghFa4toZEhNxlYNT099wj6dJMSJ2RekNqXO5A8qcJUZdlH6uJ8Dlqw1Pk/2/tH
|
||||
KisN7sb+b536e3f1ifgLmt0bvOmcv1NbKO9tyTqw8fe0ZC1k17gzqrzakqj7PV2/TCSFe831m2NRbDB3
|
||||
f/+uO+ZPdd+jBVPpsx1PSlUDuyTseDRgTRi+Vsj+P/wc8GCoLuoinjzfoxPiOmR636yAUWPbM75BwbfD
|
||||
Zbem3hGB8T5/U1ze1FlA42ZbvwKDtIazP98fAIC2Um/8RIyDbIlKUGZkPvunLDoynM9N/1n1+9nUP5dR
|
||||
MzuH6GcAAAD//0pj2wvTCgAA
|
||||
H4sIAAAAAAAC/+RWsW7bQAzd9RWCkjGJOnTymnYrkAJG2yEojLNE2Ux1xyuPMioU/vdCJzvx2SfZteEu
|
||||
XSnyvcdHSuLvJE2zElzBaAXJZJM0e7JgHsmIQgOcPpKpcJFOLRRYYaF81l1XduuKJWjVlSxF7CTPXxyZ
|
||||
+z76QLzIS1aV3L97n/exm74Oy22Jm+Q5WTDFls35sj47R60WkBeev6+U1kJXS/MXKKSPWSYLLAgum6Rd
|
||||
O2maFQxKoHwN7JQ6YTQ9nI9XxFpJ96RUAveCGjL/bN2nZKqRJfEIVJjNxRIFCmkYTq1ZKUZl5NR0cqdn
|
||||
PqyAXT/WUysqUJ34KIliVu2bdyigd/MGwNN0HZBsJhrB35mrj0dm6+NfHHAQGWR+ZfU5H39ZclB+Jha3
|
||||
X3/LUPk1gMo9dIt8k5dQocFu4V2ulZ165KdeYxzfrIZkhdYN2DfayNbGQ1Lh1hIGG9RP08BT19NzQBDS
|
||||
jUockXlEaih3T/KoCtPUdYi0i/M9asGjLv/b3r9S3WhwZ/Z/7tZfu6tvxD/QLD7gWe/5JzWH+tqWTCOD
|
||||
v6YlUyE7xYVR9cmWRD+/TCSVu+TzW2JVzbB0//5bt8kf6z6gBdPog4lntWqBXRZ3PNljzRh+Nsj+mniO
|
||||
eLCvLtlF3Hq+RCfE7WX/1L3xDA8oegEdd2vsGoqs9+FldHyodxGNs3l7AQZpDQd/vr8AAG2lnfmNGAaZ
|
||||
E9WgzMB+hm9ZsmE43JvwOHy75sL3Mul2Z538CQAA//9C38scmQsAAA==
|
||||
`,
|
||||
},
|
||||
|
||||
"/content-descriptor.json": {
|
||||
name: "content-descriptor.json",
|
||||
local: "content-descriptor.json",
|
||||
size: 1079,
|
||||
modtime: 1537191585,
|
||||
modtime: 1625865919,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/5yTsW7cMAyGdz8F4QTIkos6BB2MIEu7d2i3ooNOok5Mz5JK8RBci7x7QcvX2G2RILfZ
|
||||
xP+Rn2zqVwfQe6yOqQjl1A/QfyqYPuQklhIy6BMmgY9zKDN8LugokLMTca0tLquLOFrFo0gZjHmoOW1a
|
||||
@@ -238,9 +259,10 @@ dIbaEm+G3WzZM/44EKMqff37riz3dL0uHcC37qn7HQAA//9DKIMKNwQAAA==
|
||||
},
|
||||
|
||||
"/defs-descriptor.json": {
|
||||
name: "defs-descriptor.json",
|
||||
local: "defs-descriptor.json",
|
||||
size: 844,
|
||||
modtime: 1537191664,
|
||||
modtime: 1625865919,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/5SST2/TTBDG7/kU826jt0DiOHBAqlWKKnrnUE6t0mi6O7aneP9od6IqVPnuaG03SYtA
|
||||
cLC1+2jmefwbz9MEQBlKOnIQ9k5VoK6oZsf5liBgFNabDiOIh6+B3BfvBNlRhKuxzUe4DqS5Zo29x3ww
|
||||
@@ -254,9 +276,10 @@ TAMAAA==
|
||||
},
|
||||
|
||||
"/defs.json": {
|
||||
name: "defs.json",
|
||||
local: "defs.json",
|
||||
size: 1670,
|
||||
modtime: 1515512099,
|
||||
modtime: 1625865903,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/7STza6bMBCF9zzFyO2S9oJtbGDb7hMpy6oLSiaJq2AjY6RWEe9e8RNChFuJKneRgGc8
|
||||
3zmeMbcAgByxKa2qnTKa5EC+4klp1a8aaBs8grtY054vpnXgLgi7GvUXo12hNFo41FiqkyqLoTwceTOA
|
||||
@@ -269,9 +292,10 @@ fIvD7in0ryMEy+fK1G6UfmdTE+tvpoL+1wV/AgAA//96IpqyhgYAAA==
|
||||
},
|
||||
|
||||
"/image-index-schema.json": {
|
||||
name: "image-index-schema.json",
|
||||
local: "image-index-schema.json",
|
||||
size: 2993,
|
||||
modtime: 1515512099,
|
||||
modtime: 1625865919,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/6yWz0/jOhDH7/0rRgGJC5CnJ/QOFeLy9sJpD4v2suJg7EkybGNnx1Ogu+r/vrJN2qRJ
|
||||
C4Te2rHnO5/vxL/+zAAyg14zNULOZnPIvjZo/3dWFFlkuK1ViXBrDb7AtwY1FaRVnHoeck+9rrBWIa8S
|
||||
@@ -289,9 +313,10 @@ VmZjL8HOE24GcD9bz/4GAAD//yCnv52xCwAA
|
||||
},
|
||||
|
||||
"/image-layout-schema.json": {
|
||||
name: "image-layout-schema.json",
|
||||
local: "image-layout-schema.json",
|
||||
size: 439,
|
||||
modtime: 1515512099,
|
||||
modtime: 1625865903,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/2yPQUvEMBCF7/0VQ/Sg4DYVPOW6pwVhD4IX8VDTaTvLNonJVFik/12SaRXRU5g38+W9
|
||||
91kBqA6TjRSYvFMG1DGg23vHLTmMcJjaAeGxvfiZ4cmOOLXqLlPXSQYDamQORutT8m4nau3joLvY9rxr
|
||||
@@ -302,9 +327,10 @@ HrRoV8JRtyHJaO0DOruZpYLJtaZsrM/FWEi+BMysfzuhXbUQfcDIhEkZyG2yQyYl8TPGJLVk97fth1yA
|
||||
},
|
||||
|
||||
"/image-manifest-schema.json": {
|
||||
name: "image-manifest-schema.json",
|
||||
local: "image-manifest-schema.json",
|
||||
size: 921,
|
||||
modtime: 1515512099,
|
||||
modtime: 1625865903,
|
||||
compressed: `
|
||||
H4sIAAAAAAAC/5ySMW8iMRCF+/0VI0MJ+O501bZXUZxSJEoTpXB2x7uDWNsZmygo4r9HtnHAkCKifTvv
|
||||
zTdv/dEAiB59x+QCWSNaEHcOzT9rgiKDDOtJDQj/lSGNPsC9w440dSpNL6J97rsRJxWtYwiulXLjrVlm
|
||||
@@ -317,7 +343,21 @@ Dj+ZAwAA
|
||||
},
|
||||
|
||||
"/": {
|
||||
name: "/",
|
||||
local: `.`,
|
||||
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"],
|
||||
},
|
||||
}
|
||||
|
31
vendor/github.com/opencontainers/image-spec/schema/validator.go
generated
vendored
31
vendor/github.com/opencontainers/image-spec/schema/validator.go
generated
vendored
@@ -23,7 +23,7 @@ import (
|
||||
"regexp"
|
||||
|
||||
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/xeipuuv/gojsonschema"
|
||||
)
|
||||
@@ -168,6 +168,7 @@ func validateIndex(r io.Reader) error {
|
||||
}
|
||||
if manifest.Platform != nil {
|
||||
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)
|
||||
checkArchitecture(header.Architecture, header.Variant)
|
||||
|
||||
envRegexp := regexp.MustCompile(`^[^=]+=.*$`)
|
||||
for _, e := range header.Config.Env {
|
||||
@@ -200,6 +202,31 @@ func validateConfig(r io.Reader) error {
|
||||
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) {
|
||||
validCombins := map[string][]string{
|
||||
"android": {"arm"},
|
||||
@@ -219,7 +246,7 @@ func checkPlatform(OS string, Architecture string) {
|
||||
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)
|
||||
|
6
vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go
generated
vendored
6
vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go
generated
vendored
@@ -53,4 +53,10 @@ const (
|
||||
|
||||
// AnnotationDescription is the annotation key for the human-readable description of the software packaged in the image.
|
||||
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"
|
||||
)
|
||||
|
11
vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go
generated
vendored
11
vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go
generated
vendored
@@ -89,9 +89,20 @@ type Image struct {
|
||||
// Architecture is the CPU architecture which the binaries in this image are built to run on.
|
||||
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 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 ImageConfig `json:"config,omitempty"`
|
||||
|
||||
|
47
vendor/github.com/opencontainers/image-tools/image/autodetect.go
generated
vendored
47
vendor/github.com/opencontainers/image-tools/image/autodetect.go
generated
vendored
@@ -15,13 +15,11 @@
|
||||
package image
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
@@ -47,7 +45,7 @@ func Autodetect(path string) (string, error) {
|
||||
return TypeImageLayout, nil
|
||||
}
|
||||
|
||||
f, err := os.Open(path)
|
||||
f, err := os.Open(path) // nolint: errcheck, gosec
|
||||
if err != nil {
|
||||
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
|
||||
case "application/zip":
|
||||
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.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")
|
||||
}
|
||||
|
14
vendor/github.com/opencontainers/image-tools/image/config.go
generated
vendored
14
vendor/github.com/opencontainers/image-tools/image/config.go
generated
vendored
@@ -20,7 +20,6 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -31,16 +30,11 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type config v1.Image
|
||||
|
||||
func findConfig(w walker, d *v1.Descriptor) (*config, error) {
|
||||
var c config
|
||||
func findConfig(w walker, d *v1.Descriptor) (*v1.Image, error) {
|
||||
var c v1.Image
|
||||
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 {
|
||||
if info.IsDir() || filepath.Clean(path) != cpath {
|
||||
return nil
|
||||
}
|
||||
switch err := w.find(cpath, func(path string, r io.Reader) error {
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
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" {
|
||||
return nil, fmt.Errorf("%s: unsupported OS", c.OS)
|
||||
}
|
||||
|
89
vendor/github.com/opencontainers/image-tools/image/descriptor.go
generated
vendored
89
vendor/github.com/opencontainers/image-tools/image/descriptor.go
generated
vendored
@@ -20,6 +20,7 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
@@ -27,8 +28,8 @@ import (
|
||||
|
||||
const indexPath = "index.json"
|
||||
|
||||
func listReferences(w walker) (map[string]*v1.Descriptor, error) {
|
||||
refs := make(map[string]*v1.Descriptor)
|
||||
func listReferences(w walker) ([]v1.Descriptor, error) {
|
||||
var descs []v1.Descriptor
|
||||
var index v1.Index
|
||||
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
descs = index.Manifests
|
||||
|
||||
for i := 0; i < len(index.Manifests); i++ {
|
||||
if index.Manifests[i].Annotations[v1.AnnotationRefName] != "" {
|
||||
refs[index.Manifests[i].Annotations[v1.AnnotationRefName]] = &index.Manifests[i]
|
||||
return nil
|
||||
}); err != nil {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
return refs, nil
|
||||
}
|
||||
|
||||
func findDescriptor(w walker, name string) (*v1.Descriptor, error) {
|
||||
var d v1.Descriptor
|
||||
var index v1.Index
|
||||
|
||||
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
|
||||
if info.IsDir() || filepath.Clean(path) != indexPath {
|
||||
return nil
|
||||
if len(descs) == 0 {
|
||||
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not match", names)
|
||||
} else if len(descs) > 1 {
|
||||
return nil, fmt.Errorf("index.json: descriptor retrieved by refs %v is not unique", names)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
2
vendor/github.com/opencontainers/image-tools/image/doc.go
generated
vendored
2
vendor/github.com/opencontainers/image-tools/image/doc.go
generated
vendored
@@ -12,5 +12,5 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// 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
|
||||
|
113
vendor/github.com/opencontainers/image-tools/image/image.go
generated
vendored
113
vendor/github.com/opencontainers/image-tools/image/image.go
generated
vendored
@@ -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
|
||||
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 {
|
||||
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 {
|
||||
if err := layoutValidate(w); err != nil {
|
||||
var descs []v1.Descriptor
|
||||
var err error
|
||||
|
||||
if err = layoutValidate(w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ds, err := listReferences(w)
|
||||
if len(refs) == 0 {
|
||||
out.Print("No ref specified, verify all refs")
|
||||
descs, err = listReferences(w)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(refs) == 0 && len(ds) == 0 {
|
||||
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
|
||||
}
|
||||
|
||||
if len(refs) == 0 {
|
||||
for ref := range ds {
|
||||
refs = append(refs, ref)
|
||||
} else {
|
||||
descs, err = findDescriptor(w, refs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, ref := range refs {
|
||||
d, ok := ds[ref]
|
||||
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)
|
||||
}
|
||||
|
||||
for _, desc := range descs {
|
||||
d := &desc
|
||||
if err = validateDescriptor(d, w, validRefMediaTypes); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +104,7 @@ func validate(w walker, refs []string, out *log.Logger) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.validate(w); err != nil {
|
||||
if err := validateManifest(m, w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -131,15 +130,15 @@ func validate(w walker, refs []string, out *log.Logger) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.validate(w); err != nil {
|
||||
if err := validateManifest(m, w); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if out != nil {
|
||||
out.Printf("reference %q: OK", ref)
|
||||
}
|
||||
|
||||
if out != nil && len(refs) > 0 {
|
||||
out.Printf("reference %v: OK", refs)
|
||||
}
|
||||
|
||||
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
|
||||
// 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, platform string) error {
|
||||
return unpack(newPathWalker(src), dest, ref, platform)
|
||||
func UnpackLayout(src, dest, platform string, refs []string) error {
|
||||
return unpack(newPathWalker(src), dest, platform, refs)
|
||||
}
|
||||
|
||||
// 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)
|
||||
func UnpackZip(src, dest, platform string, refs []string) error {
|
||||
return unpack(newZipWalker(src), dest, platform, refs)
|
||||
}
|
||||
|
||||
// UnpackFile opens the file pointed by tarFileName and calls Unpack on it.
|
||||
func UnpackFile(tarFileName, dest, ref, platform string) error {
|
||||
f, err := os.Open(tarFileName)
|
||||
func UnpackFile(tarFileName, dest, platform string, refs []string) error {
|
||||
f, err := os.Open(tarFileName) // nolint: errcheck, gosec
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to open file")
|
||||
}
|
||||
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
|
||||
// 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, platform string) error {
|
||||
return unpack(newTarWalker(r), dest, refName, platform)
|
||||
func Unpack(r io.ReadSeeker, dest, platform string, refs []string) error {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
ref, err := findDescriptor(w, refName)
|
||||
descs, err := findDescriptor(w, refs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ref := &descs[0]
|
||||
if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -198,11 +198,11 @@ func unpack(w walker, dest, refName, platform string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.validate(w); err != nil {
|
||||
if err := validateManifest(m, w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return m.unpack(w, dest)
|
||||
return unpackManifest(m, w, dest)
|
||||
}
|
||||
|
||||
if ref.MediaType == validRefMediaTypes[1] {
|
||||
@@ -221,7 +221,7 @@ func unpack(w walker, dest, refName, platform string) error {
|
||||
}
|
||||
|
||||
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
|
||||
// creates an OCI runtime bundle in the given destination dest
|
||||
// or returns an error if the unpacking failed.
|
||||
func CreateRuntimeBundleLayout(src, dest, ref, root, platform string) error {
|
||||
return createRuntimeBundle(newPathWalker(src), dest, ref, root, platform)
|
||||
func CreateRuntimeBundleLayout(src, dest, root, platform string, refs []string) error {
|
||||
return createRuntimeBundle(newPathWalker(src), dest, root, platform, refs)
|
||||
}
|
||||
|
||||
// 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)
|
||||
func CreateRuntimeBundleZip(src, dest, root, platform string, refs []string) error {
|
||||
return createRuntimeBundle(newZipWalker(src), dest, root, platform, refs)
|
||||
}
|
||||
|
||||
// CreateRuntimeBundleFile opens the file pointed by tarFile and calls
|
||||
// CreateRuntimeBundle.
|
||||
func CreateRuntimeBundleFile(tarFile, dest, ref, root, platform string) error {
|
||||
f, err := os.Open(tarFile)
|
||||
func CreateRuntimeBundleFile(tarFile, dest, root, platform string, refs []string) error {
|
||||
f, err := os.Open(tarFile) // nolint: errcheck, gosec
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to open file")
|
||||
}
|
||||
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
|
||||
// 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, platform string) error {
|
||||
return createRuntimeBundle(newTarWalker(r), dest, ref, root, platform)
|
||||
func CreateRuntimeBundle(r io.ReadSeeker, dest, root, platform string, refs []string) error {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
|
||||
ref, err := findDescriptor(w, refName)
|
||||
descs, err := findDescriptor(w, refs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ref := &descs[0]
|
||||
if err = validateDescriptor(ref, w, validRefMediaTypes); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -281,7 +282,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.validate(w); err != nil {
|
||||
if err := validateManifest(m, w); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -311,7 +312,7 @@ func createRuntimeBundle(w walker, dest, refName, rootfs, platform string) error
|
||||
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)
|
||||
if err != nil {
|
||||
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 os.IsNotExist(err) {
|
||||
if err2 := os.MkdirAll(dest, 0755); err2 != nil {
|
||||
if err2 := os.MkdirAll(dest, 0750); err2 != nil {
|
||||
return err2
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
spec, err := c.runtimeSpec(rootfs)
|
||||
spec, err := runtimeSpec(c, rootfs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -353,8 +354,8 @@ func createBundle(w walker, m *manifest, dest, rootfs string) (retErr error) {
|
||||
}
|
||||
|
||||
// filertManifest returns a filtered list of manifests
|
||||
func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*manifest, error) {
|
||||
var manifests []*manifest
|
||||
func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*v1.Manifest, error) {
|
||||
var manifests []*v1.Manifest
|
||||
|
||||
argsParts := strings.Split(platform, ":")
|
||||
if len(argsParts) != 2 {
|
||||
@@ -372,7 +373,7 @@ func filterManifest(w walker, Manifests []v1.Descriptor, platform string) ([]*ma
|
||||
return manifests, err
|
||||
}
|
||||
|
||||
if err := m.validate(w); err != nil {
|
||||
if err := validateManifest(m, w); err != nil {
|
||||
return manifests, err
|
||||
}
|
||||
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 {
|
||||
return manifests, fmt.Errorf("There is no matching manifest")
|
||||
return manifests, fmt.Errorf("there is no matching manifest")
|
||||
}
|
||||
|
||||
return manifests, nil
|
||||
|
7
vendor/github.com/opencontainers/image-tools/image/layout.go
generated
vendored
7
vendor/github.com/opencontainers/image-tools/image/layout.go
generated
vendored
@@ -48,14 +48,13 @@ func layoutValidate(w walker) error {
|
||||
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")
|
||||
if err := schema.ValidatorMediaTypeImageIndex.Validate(bytes.NewReader(buf)); err != nil {
|
||||
return errors.Wrap(err, "index.json validation failed")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -74,7 +73,7 @@ func layoutValidate(w walker) error {
|
||||
}
|
||||
|
||||
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 {
|
||||
|
212
vendor/github.com/opencontainers/image-tools/image/manifest.go
generated
vendored
212
vendor/github.com/opencontainers/image-tools/image/manifest.go
generated
vendored
@@ -29,26 +29,17 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/opencontainers/image-spec/schema"
|
||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type manifest struct {
|
||||
Config v1.Descriptor `json:"config"`
|
||||
Layers []v1.Descriptor `json:"layers"`
|
||||
}
|
||||
|
||||
func findManifest(w walker, d *v1.Descriptor) (*manifest, error) {
|
||||
var m manifest
|
||||
func findManifest(w walker, d *v1.Descriptor) (*v1.Manifest, error) {
|
||||
var m v1.Manifest
|
||||
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 {
|
||||
if info.IsDir() || filepath.Clean(path) != mpath {
|
||||
return nil
|
||||
}
|
||||
|
||||
switch err := w.find(mpath, func(path string, r io.Reader) error {
|
||||
buf, err := ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
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 {
|
||||
return errors.Wrap(err, "config validation failed")
|
||||
}
|
||||
@@ -94,7 +85,7 @@ func (m *manifest) validate(w walker) error {
|
||||
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
|
||||
s, err := ioutil.ReadDir(dest)
|
||||
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 {
|
||||
switch err := w.walk(func(path string, info os.FileInfo, r io.Reader) error {
|
||||
if info.IsDir() {
|
||||
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
|
||||
}
|
||||
|
||||
lpath := filepath.Join("blobs", string(d.Digest.Algorithm()), d.Digest.Hex())
|
||||
switch err := w.find(lpath, func(path string, r io.Reader) error {
|
||||
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
|
||||
@@ -218,85 +201,15 @@ loop:
|
||||
return errors.Wrapf(err, "error advancing tar stream")
|
||||
}
|
||||
|
||||
hdr.Name = filepath.Clean(hdr.Name)
|
||||
if !strings.HasSuffix(hdr.Name, string(os.PathSeparator)) {
|
||||
// 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)
|
||||
var whiteout bool
|
||||
whiteout, err = unpackLayerEntry(dest, hdr, tr, &entries)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
info := hdr.FileInfo()
|
||||
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")
|
||||
}
|
||||
|
||||
if whiteout {
|
||||
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
|
||||
// file creation in them to modify the directory mtime
|
||||
if hdr.Typeflag == tar.TypeDir {
|
||||
@@ -315,3 +228,104 @@ loop:
|
||||
}
|
||||
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
|
||||
}
|
||||
|
86
vendor/github.com/opencontainers/image-tools/image/walker.go
generated
vendored
86
vendor/github.com/opencontainers/image-tools/image/walker.go
generated
vendored
@@ -34,6 +34,8 @@ var (
|
||||
// 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 findFunc func(path string, r io.Reader) error
|
||||
|
||||
// walker is the interface that defines how to access a given archival format
|
||||
type walker interface {
|
||||
|
||||
@@ -43,6 +45,9 @@ type walker interface {
|
||||
// get will copy an arbitrary blob, defined by desc, in to dst. returns
|
||||
// the number of bytes copied on success.
|
||||
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.
|
||||
@@ -120,6 +125,34 @@ func (w *tarWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
|
||||
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{}
|
||||
|
||||
func (eofReader) Read(_ []byte) (int, error) {
|
||||
@@ -153,7 +186,7 @@ func (w *pathWalker) walk(f walkFunc) error {
|
||||
return f(rel, info, eofReader{})
|
||||
}
|
||||
|
||||
file, err := os.Open(path)
|
||||
file, err := os.Open(path) // nolint: errcheck, gosec
|
||||
if err != nil {
|
||||
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")
|
||||
}
|
||||
|
||||
fp, err := os.Open(name)
|
||||
fp, err := os.Open(name) // nolint: errcheck, gosec
|
||||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
fileName string
|
||||
}
|
||||
@@ -249,3 +303,31 @@ func (w *zipWalker) get(desc v1.Descriptor, dst io.Writer) (int64, error) {
|
||||
|
||||
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
8
vendor/go4.org/AUTHORS
generated
vendored
@@ -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
202
vendor/go4.org/LICENSE
generated
vendored
@@ -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.
|
||||
|
58
vendor/go4.org/errorutil/highlight.go
generated
vendored
58
vendor/go4.org/errorutil/highlight.go
generated
vendored
@@ -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
|
||||
}
|
0
vendor/github.com/go-check/check/.gitignore → vendor/gopkg.in/check.v1/.gitignore
generated
vendored
0
vendor/github.com/go-check/check/.gitignore → vendor/gopkg.in/check.v1/.gitignore
generated
vendored
0
vendor/github.com/go-check/check/.travis.yml → vendor/gopkg.in/check.v1/.travis.yml
generated
vendored
0
vendor/github.com/go-check/check/.travis.yml → vendor/gopkg.in/check.v1/.travis.yml
generated
vendored
0
vendor/github.com/go-check/check/LICENSE → vendor/gopkg.in/check.v1/LICENSE
generated
vendored
0
vendor/github.com/go-check/check/LICENSE → vendor/gopkg.in/check.v1/LICENSE
generated
vendored
0
vendor/github.com/go-check/check/README.md → vendor/gopkg.in/check.v1/README.md
generated
vendored
0
vendor/github.com/go-check/check/README.md → vendor/gopkg.in/check.v1/README.md
generated
vendored
0
vendor/github.com/go-check/check/TODO → vendor/gopkg.in/check.v1/TODO
generated
vendored
0
vendor/github.com/go-check/check/TODO → vendor/gopkg.in/check.v1/TODO
generated
vendored
14
vendor/github.com/go-check/check/check.go → vendor/gopkg.in/check.v1/check.go
generated
vendored
14
vendor/github.com/go-check/check/check.go → vendor/gopkg.in/check.v1/check.go
generated
vendored
@@ -11,7 +11,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/rand"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -143,17 +143,11 @@ func (td *tempDir) newPath() string {
|
||||
td.Lock()
|
||||
defer td.Unlock()
|
||||
if td.path == "" {
|
||||
var err error
|
||||
for i := 0; i != 100; i++ {
|
||||
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 == "" {
|
||||
path, err := ioutil.TempDir("", "check-")
|
||||
if err != nil {
|
||||
panic("Couldn't create temporary directory: " + err.Error())
|
||||
}
|
||||
td.path = path
|
||||
}
|
||||
result := filepath.Join(td.path, strconv.Itoa(td.counter))
|
||||
td.counter++
|
4
vendor/github.com/go-check/check/checkers.go → vendor/gopkg.in/check.v1/checkers.go
generated
vendored
4
vendor/github.com/go-check/check/checkers.go → vendor/gopkg.in/check.v1/checkers.go
generated
vendored
@@ -161,6 +161,10 @@ func (checker *notNilChecker) Check(params []interface{}, names []string) (resul
|
||||
// Equals checker.
|
||||
|
||||
func diffworthy(a interface{}) bool {
|
||||
if a == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
t := reflect.TypeOf(a)
|
||||
switch t.Kind() {
|
||||
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
5
vendor/gopkg.in/check.v1/go.mod
generated
vendored
Normal 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
5
vendor/gopkg.in/check.v1/go.sum
generated
vendored
Normal 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=
|
10
vendor/github.com/go-check/check/helpers.go → vendor/gopkg.in/check.v1/helpers.go
generated
vendored
10
vendor/github.com/go-check/check/helpers.go → vendor/gopkg.in/check.v1/helpers.go
generated
vendored
@@ -155,8 +155,9 @@ func (c *C) Fatalf(format string, args ...interface{}) {
|
||||
//
|
||||
// Some checkers may not need the expected argument (e.g. IsNil).
|
||||
//
|
||||
// Extra arguments provided to the function are logged next to the reported
|
||||
// problem when the matching fails.
|
||||
// If the last value in args implements CommentInterface, it is used to log
|
||||
// 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 {
|
||||
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).
|
||||
//
|
||||
// Extra arguments provided to the function are logged next to the reported
|
||||
// problem when the matching fails.
|
||||
// If the last value in args implements CommentInterface, it is used to log
|
||||
// additional information instead of being passed to the checker (see Commentf
|
||||
// for an example).
|
||||
func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) {
|
||||
if !c.internalCheck("Assert", obtained, checker, args...) {
|
||||
c.stopNow()
|
0
vendor/github.com/go-check/check/printer.go → vendor/gopkg.in/check.v1/printer.go
generated
vendored
0
vendor/github.com/go-check/check/printer.go → vendor/gopkg.in/check.v1/printer.go
generated
vendored
0
vendor/github.com/go-check/check/reporter.go → vendor/gopkg.in/check.v1/reporter.go
generated
vendored
0
vendor/github.com/go-check/check/reporter.go → vendor/gopkg.in/check.v1/reporter.go
generated
vendored
0
vendor/github.com/go-check/check/run.go → vendor/gopkg.in/check.v1/run.go
generated
vendored
0
vendor/github.com/go-check/check/run.go → vendor/gopkg.in/check.v1/run.go
generated
vendored
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@@ -206,8 +206,6 @@ github.com/docker/go-metrics
|
||||
github.com/docker/go-units
|
||||
# github.com/ghodss/yaml v1.0.0
|
||||
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/gogoproto
|
||||
github.com/gogo/protobuf/proto
|
||||
@@ -271,11 +269,11 @@ github.com/modern-go/reflect2
|
||||
github.com/mtrmac/gpgme
|
||||
# github.com/opencontainers/go-digest v1.0.0
|
||||
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/specs-go
|
||||
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/runc v1.0.1
|
||||
github.com/opencontainers/runc/libcontainer/user
|
||||
@@ -355,8 +353,6 @@ go.opencensus.io/internal
|
||||
go.opencensus.io/trace
|
||||
go.opencensus.io/trace/internal
|
||||
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/cast5
|
||||
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/durationpb
|
||||
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
|
||||
gopkg.in/square/go-jose.v2/cipher
|
||||
|
Reference in New Issue
Block a user