mirror of
https://github.com/containers/podman.git
synced 2025-06-27 21:50:18 +08:00
Merge pull request #6926 from containers/dependabot/go_modules/github.com/containers/storage-1.21.0
Bump github.com/containers/storage from 1.20.2 to 1.21.0
This commit is contained in:
6
go.mod
6
go.mod
@ -15,7 +15,7 @@ require (
|
|||||||
github.com/containers/conmon v2.0.18+incompatible
|
github.com/containers/conmon v2.0.18+incompatible
|
||||||
github.com/containers/image/v5 v5.5.1
|
github.com/containers/image/v5 v5.5.1
|
||||||
github.com/containers/psgo v1.5.1
|
github.com/containers/psgo v1.5.1
|
||||||
github.com/containers/storage v1.20.2
|
github.com/containers/storage v1.21.0
|
||||||
github.com/coreos/go-systemd/v22 v22.1.0
|
github.com/coreos/go-systemd/v22 v22.1.0
|
||||||
github.com/cri-o/ocicni v0.2.0
|
github.com/cri-o/ocicni v0.2.0
|
||||||
github.com/cyphar/filepath-securejoin v0.2.2
|
github.com/cyphar/filepath-securejoin v0.2.2
|
||||||
@ -31,7 +31,7 @@ require (
|
|||||||
github.com/google/uuid v1.1.1
|
github.com/google/uuid v1.1.1
|
||||||
github.com/gorilla/mux v1.7.4
|
github.com/gorilla/mux v1.7.4
|
||||||
github.com/gorilla/schema v1.1.0
|
github.com/gorilla/schema v1.1.0
|
||||||
github.com/hashicorp/go-multierror v1.0.0
|
github.com/hashicorp/go-multierror v1.1.0
|
||||||
github.com/hpcloud/tail v1.0.0
|
github.com/hpcloud/tail v1.0.0
|
||||||
github.com/json-iterator/go v1.1.10
|
github.com/json-iterator/go v1.1.10
|
||||||
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
|
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
|
||||||
@ -42,7 +42,7 @@ require (
|
|||||||
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b
|
github.com/opencontainers/runc v1.0.0-rc91.0.20200708210054-ce54a9d4d79b
|
||||||
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
|
||||||
github.com/opencontainers/runtime-tools v0.9.0
|
github.com/opencontainers/runtime-tools v0.9.0
|
||||||
github.com/opencontainers/selinux v1.5.2
|
github.com/opencontainers/selinux v1.6.0
|
||||||
github.com/opentracing/opentracing-go v1.2.0
|
github.com/opentracing/opentracing-go v1.2.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pmezard/go-difflib v1.0.0
|
github.com/pmezard/go-difflib v1.0.0
|
||||||
|
10
go.sum
10
go.sum
@ -86,6 +86,8 @@ github.com/containers/psgo v1.5.1 h1:MQNb7FLbXqBdqz6u4lI2QWizVz4RSTzs1+Nk9XT1iVA
|
|||||||
github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
|
github.com/containers/psgo v1.5.1/go.mod h1:2ubh0SsreMZjSXW1Hif58JrEcFudQyIy9EzPUWfawVU=
|
||||||
github.com/containers/storage v1.20.2 h1:tw/uKRPDnmVrluIzer3dawTFG/bTJLP8IEUyHFhltYk=
|
github.com/containers/storage v1.20.2 h1:tw/uKRPDnmVrluIzer3dawTFG/bTJLP8IEUyHFhltYk=
|
||||||
github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc=
|
github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc=
|
||||||
|
github.com/containers/storage v1.21.0 h1:9VpsAmqwA9P+xQZc2sWZ3sj5NQojvg47P6orW34nYFU=
|
||||||
|
github.com/containers/storage v1.21.0/go.mod h1:I1EIAA7B4OwWRSA0b4yq2AW1wjvvfcY0zLWQuwTa4zw=
|
||||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||||
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
|
github.com/coreos/go-iptables v0.4.5 h1:DpHb9vJrZQEFMcVLFKAAGMUVX0XoRC0ptCthinRYm38=
|
||||||
@ -223,6 +225,8 @@ github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brv
|
|||||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||||
|
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
@ -253,6 +257,8 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
|||||||
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/compress v1.10.8 h1:eLeJ3dr/Y9+XRfJT4l+8ZjmtB5RPJhucH2HeCV5+IZY=
|
github.com/klauspost/compress v1.10.8 h1:eLeJ3dr/Y9+XRfJT4l+8ZjmtB5RPJhucH2HeCV5+IZY=
|
||||||
github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
|
github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
|
||||||
|
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
|
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
|
||||||
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@ -345,6 +351,8 @@ github.com/opencontainers/selinux v1.3.0/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOl
|
|||||||
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
github.com/opencontainers/selinux v1.5.2 h1:F6DgIsjgBIcDksLW4D5RG9bXok6oqZ3nvMwj4ZoFu/Q=
|
github.com/opencontainers/selinux v1.5.2 h1:F6DgIsjgBIcDksLW4D5RG9bXok6oqZ3nvMwj4ZoFu/Q=
|
||||||
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
|
github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
|
||||||
|
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||||
github.com/openshift/imagebuilder v1.1.6 h1:1+YzRxIIefY4QqtCImx6rg+75QrKNfBoPAKxgMo/khM=
|
github.com/openshift/imagebuilder v1.1.6 h1:1+YzRxIIefY4QqtCImx6rg+75QrKNfBoPAKxgMo/khM=
|
||||||
github.com/openshift/imagebuilder v1.1.6/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
github.com/openshift/imagebuilder v1.1.6/go.mod h1:9aJRczxCH0mvT6XQ+5STAQaPWz7OsWcU5/mRkt8IWeo=
|
||||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||||
@ -459,6 +467,8 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp
|
|||||||
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||||
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||||
|
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM=
|
||||||
|
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b h1:6cLsL+2FW6dRAdl5iMtHgRogVCff0QpRi9653YmdcJA=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
|
10
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
10
vendor/github.com/containers/storage/.cirrus.yml
generated
vendored
@ -19,12 +19,12 @@ env:
|
|||||||
###
|
###
|
||||||
FEDORA_NAME: "fedora-32"
|
FEDORA_NAME: "fedora-32"
|
||||||
PRIOR_FEDORA_NAME: "fedora-31"
|
PRIOR_FEDORA_NAME: "fedora-31"
|
||||||
UBUNTU_NAME: "ubuntu-19"
|
UBUNTU_NAME: "ubuntu-20"
|
||||||
PRIOR_UBUNTU_NAME: "ubuntu-18"
|
PRIOR_UBUNTU_NAME: "ubuntu-19"
|
||||||
|
|
||||||
# GCE project where images live
|
# GCE project where images live
|
||||||
IMAGE_PROJECT: "libpod-218412"
|
IMAGE_PROJECT: "libpod-218412"
|
||||||
_BUILT_IMAGE_SUFFIX: "libpod-6224667180531712" # From the packer output of 'build_vm_images_script'
|
_BUILT_IMAGE_SUFFIX: "libpod-6508632441356288"
|
||||||
FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
FEDORA_CACHE_IMAGE_NAME: "${FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
||||||
PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
PRIOR_FEDORA_CACHE_IMAGE_NAME: "${PRIOR_FEDORA_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
||||||
UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
UBUNTU_CACHE_IMAGE_NAME: "${UBUNTU_NAME}-${_BUILT_IMAGE_SUFFIX}"
|
||||||
@ -104,7 +104,7 @@ lint_task:
|
|||||||
env:
|
env:
|
||||||
CIRRUS_WORKING_DIR: "/go/src/github.com/containers/storage"
|
CIRRUS_WORKING_DIR: "/go/src/github.com/containers/storage"
|
||||||
container:
|
container:
|
||||||
image: golang:1.12
|
image: golang:1.13
|
||||||
modules_cache:
|
modules_cache:
|
||||||
fingerprint_script: cat go.sum
|
fingerprint_script: cat go.sum
|
||||||
folder: $GOPATH/pkg/mod
|
folder: $GOPATH/pkg/mod
|
||||||
@ -140,7 +140,7 @@ meta_task:
|
|||||||
|
|
||||||
vendor_task:
|
vendor_task:
|
||||||
container:
|
container:
|
||||||
image: golang:1.13
|
image: golang:1.14
|
||||||
modules_cache:
|
modules_cache:
|
||||||
fingerprint_script: cat go.sum
|
fingerprint_script: cat go.sum
|
||||||
folder: $GOPATH/pkg/mod
|
folder: $GOPATH/pkg/mod
|
||||||
|
2
vendor/github.com/containers/storage/VERSION
generated
vendored
2
vendor/github.com/containers/storage/VERSION
generated
vendored
@ -1 +1 @@
|
|||||||
1.20.2
|
1.21.0
|
||||||
|
18
vendor/github.com/containers/storage/drivers/devmapper/device_setup.go
generated
vendored
18
vendor/github.com/containers/storage/drivers/devmapper/device_setup.go
generated
vendored
@ -23,6 +23,7 @@ type directLVMConfig struct {
|
|||||||
ThinpMetaPercent uint64
|
ThinpMetaPercent uint64
|
||||||
AutoExtendPercent uint64
|
AutoExtendPercent uint64
|
||||||
AutoExtendThreshold uint64
|
AutoExtendThreshold uint64
|
||||||
|
MetaDataSize string
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -121,15 +122,19 @@ func checkDevHasFS(dev string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func verifyBlockDevice(dev string, force bool) error {
|
func verifyBlockDevice(dev string, force bool) error {
|
||||||
realPath, err := filepath.Abs(dev)
|
absPath, err := filepath.Abs(dev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("unable to get absolute path for %s: %s", dev, err)
|
return errors.Errorf("unable to get absolute path for %s: %s", dev, err)
|
||||||
}
|
}
|
||||||
if realPath, err = filepath.EvalSymlinks(realPath); err != nil {
|
realPath, err := filepath.EvalSymlinks(absPath)
|
||||||
|
if err != nil {
|
||||||
return errors.Errorf("failed to canonicalise path for %s: %s", dev, err)
|
return errors.Errorf("failed to canonicalise path for %s: %s", dev, err)
|
||||||
}
|
}
|
||||||
if err := checkDevAvailable(realPath); err != nil {
|
if err := checkDevAvailable(absPath); err != nil {
|
||||||
return err
|
logrus.Infof("block device '%s' not available, checking '%s'", absPath, realPath)
|
||||||
|
if err := checkDevAvailable(realPath); err != nil {
|
||||||
|
return errors.Errorf("neither '%s' nor '%s' are in the output of lvmdiskscan, can't use device.", absPath, realPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if err := checkDevInVG(realPath); err != nil {
|
if err := checkDevInVG(realPath); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -205,8 +210,11 @@ func setupDirectLVM(cfg directLVMConfig) error {
|
|||||||
if cfg.ThinpMetaPercent == 0 {
|
if cfg.ThinpMetaPercent == 0 {
|
||||||
cfg.ThinpMetaPercent = 1
|
cfg.ThinpMetaPercent = 1
|
||||||
}
|
}
|
||||||
|
if cfg.MetaDataSize == "" {
|
||||||
|
cfg.MetaDataSize = "128k"
|
||||||
|
}
|
||||||
|
|
||||||
out, err := exec.Command("pvcreate", "-f", cfg.Device).CombinedOutput()
|
out, err := exec.Command("pvcreate", "--metadatasize", cfg.MetaDataSize, "-f", cfg.Device).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, string(out))
|
return errors.Wrap(err, string(out))
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
generated
vendored
5
vendor/github.com/containers/storage/drivers/devmapper/deviceset.go
generated
vendored
@ -101,6 +101,7 @@ type DeviceSet struct {
|
|||||||
|
|
||||||
// Options
|
// Options
|
||||||
dataLoopbackSize int64
|
dataLoopbackSize int64
|
||||||
|
metaDataSize string
|
||||||
metaDataLoopbackSize int64
|
metaDataLoopbackSize int64
|
||||||
baseFsSize uint64
|
baseFsSize uint64
|
||||||
filesystem string
|
filesystem string
|
||||||
@ -2708,6 +2709,8 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|||||||
devices.mountOptions = joinMountOptions(devices.mountOptions, val)
|
devices.mountOptions = joinMountOptions(devices.mountOptions, val)
|
||||||
case "dm.metadatadev":
|
case "dm.metadatadev":
|
||||||
devices.metadataDevice = val
|
devices.metadataDevice = val
|
||||||
|
case "dm.metadata_size":
|
||||||
|
devices.metaDataSize = val
|
||||||
case "dm.datadev":
|
case "dm.datadev":
|
||||||
devices.dataDevice = val
|
devices.dataDevice = val
|
||||||
case "dm.thinpooldev":
|
case "dm.thinpooldev":
|
||||||
@ -2743,6 +2746,8 @@ func NewDeviceSet(root string, doInit bool, options []string, uidMaps, gidMaps [
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "dm.metaDataSize":
|
||||||
|
lvmSetupConfig.MetaDataSize = val
|
||||||
case "dm.min_free_space":
|
case "dm.min_free_space":
|
||||||
if !strings.HasSuffix(val, "%") {
|
if !strings.HasSuffix(val, "%") {
|
||||||
return nil, fmt.Errorf("devmapper: Option dm.min_free_space requires %% suffix")
|
return nil, fmt.Errorf("devmapper: Option dm.min_free_space requires %% suffix")
|
||||||
|
14
vendor/github.com/containers/storage/go.mod
generated
vendored
14
vendor/github.com/containers/storage/go.mod
generated
vendored
@ -5,24 +5,24 @@ require (
|
|||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5
|
||||||
github.com/Microsoft/hcsshim v0.8.9
|
github.com/Microsoft/hcsshim v0.8.9
|
||||||
github.com/docker/go-units v0.4.0
|
github.com/docker/go-units v0.4.0
|
||||||
github.com/hashicorp/go-multierror v1.0.0
|
github.com/hashicorp/go-multierror v1.1.0
|
||||||
github.com/klauspost/compress v1.10.7
|
github.com/klauspost/compress v1.10.10
|
||||||
github.com/klauspost/pgzip v1.2.4
|
github.com/klauspost/pgzip v1.2.4
|
||||||
github.com/mattn/go-shellwords v1.0.10
|
github.com/mattn/go-shellwords v1.0.10
|
||||||
github.com/mistifyio/go-zfs v2.1.1+incompatible
|
github.com/mistifyio/go-zfs v2.1.1+incompatible
|
||||||
github.com/opencontainers/go-digest v1.0.0
|
github.com/opencontainers/go-digest v1.0.0
|
||||||
github.com/opencontainers/runc v1.0.0-rc90
|
github.com/opencontainers/runc v1.0.0-rc91
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
|
||||||
github.com/opencontainers/selinux v1.5.2
|
github.com/opencontainers/selinux v1.6.0
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
|
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7
|
||||||
github.com/sirupsen/logrus v1.6.0
|
github.com/sirupsen/logrus v1.6.0
|
||||||
github.com/stretchr/testify v1.6.0
|
github.com/stretchr/testify v1.6.1
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2
|
||||||
github.com/tchap/go-patricia v2.3.0+incompatible
|
github.com/tchap/go-patricia v2.3.0+incompatible
|
||||||
github.com/vbatts/tar-split v0.11.1
|
github.com/vbatts/tar-split v0.11.1
|
||||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9
|
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775
|
||||||
gotest.tools v2.2.0+incompatible
|
gotest.tools v2.2.0+incompatible
|
||||||
)
|
)
|
||||||
|
|
||||||
|
63
vendor/github.com/containers/storage/go.sum
generated
vendored
63
vendor/github.com/containers/storage/go.sum
generated
vendored
@ -5,11 +5,17 @@ github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5 h1:ygIc8M6tr
|
|||||||
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
|
||||||
github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk=
|
github.com/Microsoft/hcsshim v0.8.9 h1:VrfodqvztU8YSOvygU+DN1BGaSGxmrNfqOv5oOuX2Bk=
|
||||||
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
|
||||||
|
github.com/checkpoint-restore/go-criu/v4 v4.0.2 h1:jt+rnBIhFtPw0fhtpYGcUOilh4aO9Hj7r+YLEtf30uA=
|
||||||
|
github.com/checkpoint-restore/go-criu/v4 v4.0.2/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
|
||||||
|
github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3 h1:qcqzLJa2xCo9sgdCzpT/SJSYxROTEstuhf7ZBHMirms=
|
||||||
|
github.com/cilium/ebpf v0.0.0-20200507155900-a9f01edf17e3/go.mod h1:XT+cAw5wfvsodedcijoh1l9cf7v1x9FlFB/3VmF/O8s=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f h1:tSNMc+rJDfmYntojat8lljbt1mgKNpTxUZJsSzJ9Y1s=
|
||||||
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1 h1:uict5mhHFTzKLUCufdSLym7z/J0CbBJT59lYbP9wtbg=
|
||||||
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
|
||||||
|
github.com/containerd/console v1.0.0 h1:fU3UuQapBs+zLJu82NhR11Rif1ny2zfMMAyPJzSN5tQ=
|
||||||
|
github.com/containerd/console v1.0.0/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
|
||||||
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
||||||
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
|
||||||
@ -18,6 +24,12 @@ github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDG
|
|||||||
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e h1:Wf6HqHfScWJN9/ZjdUKyjop4mf3Qdd+1TvvltAvM3m8=
|
||||||
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
|
||||||
|
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||||
|
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
|
||||||
|
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -25,6 +37,8 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw
|
|||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68FptL43tDKIq8FladmaTs3Xs7Z8=
|
||||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
|
||||||
|
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||||
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
|
||||||
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
@ -34,20 +48,22 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
|||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
|
||||||
|
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
|
github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI=
|
||||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
|
||||||
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
|
||||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/klauspost/compress v1.10.7 h1:7rix8v8GpI3ZBb0nSozFRgbtXKv+hOe+qfEpZqybrAg=
|
github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
|
||||||
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||||
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
|
github.com/klauspost/pgzip v1.2.4 h1:TQ7CNpYKovDOmqzRHKxJh0BeaBI7UdQZYc6p7pMQh1A=
|
||||||
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
@ -62,16 +78,23 @@ github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvO
|
|||||||
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||||
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
|
github.com/mistifyio/go-zfs v2.1.1+incompatible h1:gAMO1HM9xBRONLHHYnu5iFsOJUiJdNZo6oqSENd4eW8=
|
||||||
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
github.com/mistifyio/go-zfs v2.1.1+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||||
|
github.com/moby/sys/mountinfo v0.1.3 h1:KIrhRO14+AkwKvG/g2yIpNMOUVZ02xNhOw8KY1WsLOI=
|
||||||
|
github.com/moby/sys/mountinfo v0.1.3/go.mod h1:w2t2Avltqx8vE7gX5l+QiBKxODu2TX0+Syr3h52Tw4o=
|
||||||
|
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 h1:7InQ7/zrOh6SlFjaXFubv0xX0HsuC9qJsdqm7bNQpYM=
|
||||||
|
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
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/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 v1.0.0-rc90 h1:4+xo8mtWixbHoEm451+WJNUrq12o2/tDsyK9Vgc/NcA=
|
github.com/opencontainers/runc v1.0.0-rc91 h1:Tp8LWs5G8rFpzTsbRjAtQkPVexhCu0bnANE5IfIhJ6g=
|
||||||
github.com/opencontainers/runc v1.0.0-rc90/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
github.com/opencontainers/runc v1.0.0-rc91/go.mod h1:3Sm6Dt7OT8z88EbdQqqcRN2oCT54jbi72tT/HqgflT8=
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI=
|
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700 h1:eNUVfm/RFLIi1G7flU5/ZRTHvd4kcVuzfRnL6OFlzCI=
|
||||||
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
github.com/opencontainers/selinux v1.5.2 h1:F6DgIsjgBIcDksLW4D5RG9bXok6oqZ3nvMwj4ZoFu/Q=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2 h1:9mv9SC7GWmRWE0J/+oD8w3GsN2KYGKtg6uwLN7hfP5E=
|
||||||
github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
|
||||||
|
github.com/opencontainers/selinux v1.5.1/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
|
||||||
|
github.com/opencontainers/selinux v1.6.0 h1:+bIAS/Za3q5FTwWym4fTB0vObnfCf3G/NC7K6Jx62mY=
|
||||||
|
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
@ -80,6 +103,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
|||||||
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
|
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7 h1:gGBSHPOU7g8YjTbhwn+lvFm2VDEhhA+PwDIlstkgSxE=
|
||||||
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M=
|
||||||
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||||
|
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
|
github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
|
||||||
|
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||||
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I=
|
||||||
@ -89,16 +118,24 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
|
|||||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho=
|
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||||
github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 h1:b6uOv7YOFK0TYG7HtkIgExQo+2RdLuwRft63jn2HWj8=
|
||||||
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||||
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
|
github.com/tchap/go-patricia v2.3.0+incompatible h1:GkY4dP3cEfEASBPPkWd+AmjYxhmDkqO9/zg7R0lSQRs=
|
||||||
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
github.com/tchap/go-patricia v2.3.0+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
|
||||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5 h1:MCfT24H3f//U5+UCrZp1/riVO3B50BovxtDiNn0XKkk=
|
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5 h1:MCfT24H3f//U5+UCrZp1/riVO3B50BovxtDiNn0XKkk=
|
||||||
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||||
|
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
|
||||||
|
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
|
||||||
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
|
github.com/vbatts/tar-split v0.11.1 h1:0Odu65rhcZ3JZaPHxl7tCI3V/C/Q9Zf82UFravl02dE=
|
||||||
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
|
github.com/vbatts/tar-split v0.11.1/go.mod h1:LEuURwDEiWjRjwu46yU3KVGuUdVv/dcnpcEPSzR8z6g=
|
||||||
|
github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0=
|
||||||
|
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k=
|
||||||
|
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
|
||||||
|
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243 h1:R43TdZy32XXSXjJn7M/HhALJ9imq6ztLnChfYJpVDnM=
|
||||||
|
github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||||
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
go.opencensus.io v0.22.0 h1:C9hSCOW830chIVkdja34wa6Ky+IzWllkUinR+BtRZd4=
|
||||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
@ -124,10 +161,14 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775 h1:TC0v2RSO1u2kn1ZugjrFXkRZAEaqMN/RW+OTZkBzmLE=
|
||||||
|
golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
@ -137,6 +178,8 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
||||||
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||||
|
20
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
20
vendor/github.com/containers/storage/pkg/archive/archive.go
generated
vendored
@ -390,16 +390,18 @@ func fillGo18FileTypeBits(mode int64, fi os.FileInfo) int64 {
|
|||||||
return mode
|
return mode
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadSecurityXattrToTarHeader reads security.capability xattr from filesystem
|
// ReadSecurityXattrToTarHeader reads security.capability, security,image
|
||||||
// to a tar header
|
// xattrs from filesystem to a tar header
|
||||||
func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
|
func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
|
||||||
capability, err := system.Lgetxattr(path, "security.capability")
|
for _, xattr := range []string{"security.capability", "security.ima"} {
|
||||||
if err != nil && err != system.EOPNOTSUPP && err != system.ErrNotSupportedPlatform {
|
capability, err := system.Lgetxattr(path, xattr)
|
||||||
return err
|
if err != nil && err != system.EOPNOTSUPP && err != system.ErrNotSupportedPlatform {
|
||||||
}
|
return errors.Wrapf(err, "failed to read %q attribute from %q", xattr, path)
|
||||||
if capability != nil {
|
}
|
||||||
hdr.Xattrs = make(map[string]string)
|
if capability != nil {
|
||||||
hdr.Xattrs["security.capability"] = string(capability)
|
hdr.Xattrs = make(map[string]string)
|
||||||
|
hdr.Xattrs[xattr] = string(capability)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
7
vendor/github.com/containers/storage/pkg/config/config.go
generated
vendored
7
vendor/github.com/containers/storage/pkg/config/config.go
generated
vendored
@ -39,6 +39,10 @@ type ThinpoolOptionsConfig struct {
|
|||||||
// log_level sets the log level of devicemapper.
|
// log_level sets the log level of devicemapper.
|
||||||
LogLevel string `toml:"log_level"`
|
LogLevel string `toml:"log_level"`
|
||||||
|
|
||||||
|
// MetadataSize specifies the size of the metadata for the thinpool
|
||||||
|
// It will be used with the `pvcreate --metadata` option.
|
||||||
|
MetadataSize string `toml:"metadatasize"`
|
||||||
|
|
||||||
// MinFreeSpace specifies the min free space percent in a thin pool
|
// MinFreeSpace specifies the min free space percent in a thin pool
|
||||||
// require for new device creation to
|
// require for new device creation to
|
||||||
MinFreeSpace string `toml:"min_free_space"`
|
MinFreeSpace string `toml:"min_free_space"`
|
||||||
@ -218,6 +222,9 @@ func GetGraphDriverOptions(driverName string, options OptionsConfig) []string {
|
|||||||
if options.Thinpool.LogLevel != "" {
|
if options.Thinpool.LogLevel != "" {
|
||||||
doptions = append(doptions, fmt.Sprintf("dm.libdm_log_level=%s", options.Thinpool.LogLevel))
|
doptions = append(doptions, fmt.Sprintf("dm.libdm_log_level=%s", options.Thinpool.LogLevel))
|
||||||
}
|
}
|
||||||
|
if options.Thinpool.MetadataSize != "" {
|
||||||
|
doptions = append(doptions, fmt.Sprintf("dm.metadata_size=%s", options.Thinpool.MetadataSize))
|
||||||
|
}
|
||||||
if options.Thinpool.MinFreeSpace != "" {
|
if options.Thinpool.MinFreeSpace != "" {
|
||||||
doptions = append(doptions, fmt.Sprintf("dm.min_free_space=%s", options.Thinpool.MinFreeSpace))
|
doptions = append(doptions, fmt.Sprintf("dm.min_free_space=%s", options.Thinpool.MinFreeSpace))
|
||||||
}
|
}
|
||||||
|
5
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
5
vendor/github.com/containers/storage/pkg/lockfile/lockfile_unix.go
generated
vendored
@ -35,9 +35,9 @@ type lockfile struct {
|
|||||||
// necessary.
|
// necessary.
|
||||||
func openLock(path string, ro bool) (int, error) {
|
func openLock(path string, ro bool) (int, error) {
|
||||||
if ro {
|
if ro {
|
||||||
return unix.Open(path, os.O_RDONLY, 0)
|
return unix.Open(path, os.O_RDONLY|unix.O_CLOEXEC, 0)
|
||||||
}
|
}
|
||||||
return unix.Open(path, os.O_RDWR|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR)
|
return unix.Open(path, os.O_RDWR|unix.O_CLOEXEC|os.O_CREATE, unix.S_IRUSR|unix.S_IWUSR|unix.S_IRGRP|unix.S_IROTH)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createLockerForPath returns a Locker object, possibly (depending on the platform)
|
// createLockerForPath returns a Locker object, possibly (depending on the platform)
|
||||||
@ -106,7 +106,6 @@ func (l *lockfile) lock(lType int16, recursive bool) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(fmt.Sprintf("error opening %q: %v", l.file, err))
|
panic(fmt.Sprintf("error opening %q: %v", l.file, err))
|
||||||
}
|
}
|
||||||
unix.CloseOnExec(fd)
|
|
||||||
l.fd = uintptr(fd)
|
l.fd = uintptr(fd)
|
||||||
|
|
||||||
// Optimization: only use the (expensive) fcntl syscall when
|
// Optimization: only use the (expensive) fcntl syscall when
|
||||||
|
6
vendor/github.com/containers/storage/storage.conf
generated
vendored
6
vendor/github.com/containers/storage/storage.conf
generated
vendored
@ -67,7 +67,7 @@ additionalimagestores = [
|
|||||||
# squashed down to the default uid in the container. These images will have no
|
# squashed down to the default uid in the container. These images will have no
|
||||||
# separation between the users in the container. Only supported for the overlay
|
# separation between the users in the container. Only supported for the overlay
|
||||||
# and vfs drivers.
|
# and vfs drivers.
|
||||||
#ignore_chown_errors = false
|
#ignore_chown_errors = "false"
|
||||||
|
|
||||||
# Path to an helper program to use for mounting the file system instead of mounting it
|
# Path to an helper program to use for mounting the file system instead of mounting it
|
||||||
# directly.
|
# directly.
|
||||||
@ -132,6 +132,10 @@ mountopt = "nodev"
|
|||||||
# device.
|
# device.
|
||||||
# mkfsarg = ""
|
# mkfsarg = ""
|
||||||
|
|
||||||
|
# metadata_size is used to set the `pvcreate --metadatasize` options when
|
||||||
|
# creating thin devices. Default is 128k
|
||||||
|
# metadata_size = ""
|
||||||
|
|
||||||
# Size is used to set a maximum size of the container image.
|
# Size is used to set a maximum size of the container image.
|
||||||
# size = ""
|
# size = ""
|
||||||
|
|
||||||
|
90
vendor/github.com/containers/storage/store.go
generated
vendored
90
vendor/github.com/containers/storage/store.go
generated
vendored
@ -265,6 +265,15 @@ type Store interface {
|
|||||||
// Wipe removes all known layers, images, and containers.
|
// Wipe removes all known layers, images, and containers.
|
||||||
Wipe() error
|
Wipe() error
|
||||||
|
|
||||||
|
// MountImage mounts an image to temp directory and returns the mount point.
|
||||||
|
// MountImage allows caller to mount an image. Images will always
|
||||||
|
// be mounted read/only
|
||||||
|
MountImage(id string, mountOptions []string, mountLabel string) (string, error)
|
||||||
|
|
||||||
|
// Unmount attempts to unmount an image, given an ID.
|
||||||
|
// Returns whether or not the layer is still mounted.
|
||||||
|
UnmountImage(id string, force bool) (bool, error)
|
||||||
|
|
||||||
// Mount attempts to mount a layer, image, or container for access, and
|
// Mount attempts to mount a layer, image, or container for access, and
|
||||||
// returns the pathname if it succeeds.
|
// returns the pathname if it succeeds.
|
||||||
// Note if the mountLabel == "", the default label for the container
|
// Note if the mountLabel == "", the default label for the container
|
||||||
@ -346,6 +355,9 @@ type Store interface {
|
|||||||
// Names returns the list of names for a layer, image, or container.
|
// Names returns the list of names for a layer, image, or container.
|
||||||
Names(id string) ([]string, error)
|
Names(id string) ([]string, error)
|
||||||
|
|
||||||
|
// Free removes the store from the list of stores
|
||||||
|
Free()
|
||||||
|
|
||||||
// SetNames changes the list of names for a layer, image, or container.
|
// SetNames changes the list of names for a layer, image, or container.
|
||||||
// Duplicate names are removed from the list automatically.
|
// Duplicate names are removed from the list automatically.
|
||||||
SetNames(id string, names []string) error
|
SetNames(id string, names []string) error
|
||||||
@ -2591,25 +2603,11 @@ func (s *store) Version() ([][2]string, error) {
|
|||||||
return [][2]string{}, nil
|
return [][2]string{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *store) Mount(id, mountLabel string) (string, error) {
|
func (s *store) mount(id string, options drivers.MountOpts) (string, error) {
|
||||||
container, err := s.Container(id)
|
|
||||||
var (
|
|
||||||
uidMap, gidMap []idtools.IDMap
|
|
||||||
mountOpts []string
|
|
||||||
)
|
|
||||||
if err == nil {
|
|
||||||
uidMap, gidMap = container.UIDMap, container.GIDMap
|
|
||||||
id = container.LayerID
|
|
||||||
mountOpts = container.MountOpts()
|
|
||||||
}
|
|
||||||
rlstore, err := s.LayerStore()
|
rlstore, err := s.LayerStore()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.graphLock.Lock()
|
|
||||||
defer s.graphLock.Unlock()
|
|
||||||
|
|
||||||
rlstore.Lock()
|
rlstore.Lock()
|
||||||
defer rlstore.Unlock()
|
defer rlstore.Unlock()
|
||||||
if modified, err := rlstore.Modified(); modified || err != nil {
|
if modified, err := rlstore.Modified(); modified || err != nil {
|
||||||
@ -2630,17 +2628,49 @@ func (s *store) Mount(id, mountLabel string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if rlstore.Exists(id) {
|
if rlstore.Exists(id) {
|
||||||
options := drivers.MountOpts{
|
|
||||||
MountLabel: mountLabel,
|
|
||||||
UidMaps: uidMap,
|
|
||||||
GidMaps: gidMap,
|
|
||||||
Options: mountOpts,
|
|
||||||
}
|
|
||||||
return rlstore.Mount(id, options)
|
return rlstore.Mount(id, options)
|
||||||
}
|
}
|
||||||
return "", ErrLayerUnknown
|
return "", ErrLayerUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *store) MountImage(id string, mountOpts []string, mountLabel string) (string, error) {
|
||||||
|
// Append ReadOnly option to mountOptions
|
||||||
|
img, err := s.Image(id)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := validateMountOptions(mountOpts); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
options := drivers.MountOpts{
|
||||||
|
MountLabel: mountLabel,
|
||||||
|
Options: append(mountOpts, "ro"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.mount(img.TopLayer, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *store) Mount(id, mountLabel string) (string, error) {
|
||||||
|
container, err := s.Container(id)
|
||||||
|
var (
|
||||||
|
uidMap, gidMap []idtools.IDMap
|
||||||
|
mountOpts []string
|
||||||
|
)
|
||||||
|
if err == nil {
|
||||||
|
uidMap, gidMap = container.UIDMap, container.GIDMap
|
||||||
|
id = container.LayerID
|
||||||
|
mountOpts = container.MountOpts()
|
||||||
|
}
|
||||||
|
options := drivers.MountOpts{
|
||||||
|
MountLabel: mountLabel,
|
||||||
|
UidMaps: uidMap,
|
||||||
|
GidMaps: gidMap,
|
||||||
|
Options: mountOpts,
|
||||||
|
}
|
||||||
|
return s.mount(id, options)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *store) Mounted(id string) (int, error) {
|
func (s *store) Mounted(id string) (int, error) {
|
||||||
if layerID, err := s.ContainerLayerID(id); err == nil {
|
if layerID, err := s.ContainerLayerID(id); err == nil {
|
||||||
id = layerID
|
id = layerID
|
||||||
@ -2660,6 +2690,14 @@ func (s *store) Mounted(id string) (int, error) {
|
|||||||
return rlstore.Mounted(id)
|
return rlstore.Mounted(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *store) UnmountImage(id string, force bool) (bool, error) {
|
||||||
|
img, err := s.Image(id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return s.Unmount(img.TopLayer, force)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *store) Unmount(id string, force bool) (bool, error) {
|
func (s *store) Unmount(id string, force bool) (bool, error) {
|
||||||
if layerID, err := s.ContainerLayerID(id); err == nil {
|
if layerID, err := s.ContainerLayerID(id); err == nil {
|
||||||
id = layerID
|
id = layerID
|
||||||
@ -3601,3 +3639,13 @@ func GetMountOptions(driver string, graphDriverOptions []string) ([]string, erro
|
|||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free removes the store from the list of stores
|
||||||
|
func (s *store) Free() {
|
||||||
|
for i := 0; i < len(stores); i++ {
|
||||||
|
if stores[i] == s {
|
||||||
|
stores = append(stores[:i], stores[i+1:]...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
111
vendor/github.com/containers/storage/utils.go
generated
vendored
111
vendor/github.com/containers/storage/utils.go
generated
vendored
@ -2,6 +2,7 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/user"
|
"os/user"
|
||||||
@ -82,31 +83,92 @@ func GetRootlessRuntimeDir(rootlessUID int) (string, error) {
|
|||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRootlessRuntimeDir(rootlessUID int) (string, error) {
|
type rootlessRuntimeDirEnvironment interface {
|
||||||
runtimeDir, err := homedir.GetRuntimeDir()
|
getProcCommandFile() string
|
||||||
|
getRunUserDir() string
|
||||||
|
getTmpPerUserDir() string
|
||||||
|
|
||||||
|
homeDirGetRuntimeDir() (string, error)
|
||||||
|
systemLstat(string) (*system.StatT, error)
|
||||||
|
homedirGet() string
|
||||||
|
}
|
||||||
|
|
||||||
|
type rootlessRuntimeDirEnvironmentImplementation struct {
|
||||||
|
procCommandFile string
|
||||||
|
runUserDir string
|
||||||
|
tmpPerUserDir string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (env rootlessRuntimeDirEnvironmentImplementation) getProcCommandFile() string {
|
||||||
|
return env.procCommandFile
|
||||||
|
}
|
||||||
|
func (env rootlessRuntimeDirEnvironmentImplementation) getRunUserDir() string {
|
||||||
|
return env.runUserDir
|
||||||
|
}
|
||||||
|
func (env rootlessRuntimeDirEnvironmentImplementation) getTmpPerUserDir() string {
|
||||||
|
return env.tmpPerUserDir
|
||||||
|
}
|
||||||
|
func (rootlessRuntimeDirEnvironmentImplementation) homeDirGetRuntimeDir() (string, error) {
|
||||||
|
return homedir.GetRuntimeDir()
|
||||||
|
}
|
||||||
|
func (rootlessRuntimeDirEnvironmentImplementation) systemLstat(path string) (*system.StatT, error) {
|
||||||
|
return system.Lstat(path)
|
||||||
|
}
|
||||||
|
func (rootlessRuntimeDirEnvironmentImplementation) homedirGet() string {
|
||||||
|
return homedir.Get()
|
||||||
|
}
|
||||||
|
|
||||||
|
func isRootlessRuntimeDirOwner(dir string, env rootlessRuntimeDirEnvironment) bool {
|
||||||
|
st, err := env.systemLstat(dir)
|
||||||
|
return err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0700 == 0700 && st.Mode()&0066 == 0000
|
||||||
|
}
|
||||||
|
|
||||||
|
// getRootlessRuntimeDirIsolated is an internal implementation detail of getRootlessRuntimeDir to allow testing.
|
||||||
|
// Everyone but the tests this is intended for should only call getRootlessRuntimeDir, never this function.
|
||||||
|
func getRootlessRuntimeDirIsolated(env rootlessRuntimeDirEnvironment) (string, error) {
|
||||||
|
runtimeDir, err := env.homeDirGetRuntimeDir()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return runtimeDir, nil
|
return runtimeDir, nil
|
||||||
}
|
}
|
||||||
tmpDir := fmt.Sprintf("/run/user/%d", rootlessUID)
|
|
||||||
st, err := system.Stat(tmpDir)
|
initCommand, err := ioutil.ReadFile(env.getProcCommandFile())
|
||||||
if err == nil && int(st.UID()) == os.Getuid() && st.Mode()&0700 == 0700 && st.Mode()&0066 == 0000 {
|
if err != nil || string(initCommand) == "systemd" {
|
||||||
return tmpDir, nil
|
runUserDir := env.getRunUserDir()
|
||||||
|
if isRootlessRuntimeDirOwner(runUserDir, env) {
|
||||||
|
return runUserDir, nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tmpDir = fmt.Sprintf("%s/%d", os.TempDir(), rootlessUID)
|
|
||||||
if err := os.MkdirAll(tmpDir, 0700); err != nil {
|
tmpPerUserDir := env.getTmpPerUserDir()
|
||||||
logrus.Errorf("failed to create %s: %v", tmpDir, err)
|
if _, err := env.systemLstat(tmpPerUserDir); os.IsNotExist(err) {
|
||||||
} else {
|
if err := os.Mkdir(tmpPerUserDir, 0700); err != nil {
|
||||||
return tmpDir, nil
|
logrus.Errorf("failed to create temp directory for user: %v", err)
|
||||||
|
} else {
|
||||||
|
return tmpPerUserDir, nil
|
||||||
|
}
|
||||||
|
} else if isRootlessRuntimeDirOwner(tmpPerUserDir, env) {
|
||||||
|
return tmpPerUserDir, nil
|
||||||
}
|
}
|
||||||
home := homedir.Get()
|
|
||||||
if home == "" {
|
homeDir := env.homedirGet()
|
||||||
return "", errors.Wrapf(err, "neither XDG_RUNTIME_DIR nor HOME was set non-empty")
|
if homeDir == "" {
|
||||||
|
return "", errors.New("neither XDG_RUNTIME_DIR not temp dir nor HOME was set non-empty")
|
||||||
}
|
}
|
||||||
resolvedHome, err := filepath.EvalSymlinks(home)
|
resolvedHomeDir, err := filepath.EvalSymlinks(homeDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.Wrapf(err, "cannot resolve %s", home)
|
return "", errors.Wrapf(err, "cannot resolve %s", homeDir)
|
||||||
}
|
}
|
||||||
return filepath.Join(resolvedHome, "rundir"), nil
|
return filepath.Join(resolvedHomeDir, "rundir"), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRootlessRuntimeDir(rootlessUID int) (string, error) {
|
||||||
|
return getRootlessRuntimeDirIsolated(
|
||||||
|
rootlessRuntimeDirEnvironmentImplementation{
|
||||||
|
"/proc/1/comm",
|
||||||
|
fmt.Sprintf("/run/user/%d", rootlessUID),
|
||||||
|
fmt.Sprintf("%s/containers-user-%d", os.TempDir(), rootlessUID),
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRootlessDirInfo returns the parent path of where the storage for containers and
|
// getRootlessDirInfo returns the parent path of where the storage for containers and
|
||||||
@ -248,3 +310,18 @@ func validRootlessStoragePathFormat(path string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func validateMountOptions(mountOptions []string) error {
|
||||||
|
var Empty struct{}
|
||||||
|
// Add invalid options for ImageMount() here.
|
||||||
|
invalidOptions := map[string]struct{}{
|
||||||
|
"rw": Empty,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, opt := range mountOptions {
|
||||||
|
if _, ok := invalidOptions[opt]; ok {
|
||||||
|
return fmt.Errorf(" %q option not supported", opt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
2
vendor/github.com/hashicorp/go-multierror/.travis.yml
generated
vendored
2
vendor/github.com/hashicorp/go-multierror/.travis.yml
generated
vendored
@ -9,4 +9,4 @@ branches:
|
|||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
script: make test testrace
|
script: env GO111MODULE=on make test testrace
|
||||||
|
40
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
40
vendor/github.com/hashicorp/go-multierror/README.md
generated
vendored
@ -14,9 +14,10 @@ be a list of errors. If the caller knows this, they can unwrap the
|
|||||||
list and access the errors. If the caller doesn't know, the error
|
list and access the errors. If the caller doesn't know, the error
|
||||||
formats to a nice human-readable format.
|
formats to a nice human-readable format.
|
||||||
|
|
||||||
`go-multierror` implements the
|
`go-multierror` is fully compatible with the Go standard library
|
||||||
[errwrap](https://github.com/hashicorp/errwrap) interface so that it can
|
[errors](https://golang.org/pkg/errors/) package, including the
|
||||||
be used with that library, as well.
|
functions `As`, `Is`, and `Unwrap`. This provides a standardized approach
|
||||||
|
for introspecting on error values.
|
||||||
|
|
||||||
## Installation and Docs
|
## Installation and Docs
|
||||||
|
|
||||||
@ -81,6 +82,39 @@ if err := something(); err != nil {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also use the standard [`errors.Unwrap`](https://golang.org/pkg/errors/#Unwrap)
|
||||||
|
function. This will continue to unwrap into subsequent errors until none exist.
|
||||||
|
|
||||||
|
**Extracting an error**
|
||||||
|
|
||||||
|
The standard library [`errors.As`](https://golang.org/pkg/errors/#As)
|
||||||
|
function can be used directly with a multierror to extract a specific error:
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Assume err is a multierror value
|
||||||
|
err := somefunc()
|
||||||
|
|
||||||
|
// We want to know if "err" has a "RichErrorType" in it and extract it.
|
||||||
|
var errRich RichErrorType
|
||||||
|
if errors.As(err, &errRich) {
|
||||||
|
// It has it, and now errRich is populated.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Checking for an exact error value**
|
||||||
|
|
||||||
|
Some errors are returned as exact errors such as the [`ErrNotExist`](https://golang.org/pkg/os/#pkg-variables)
|
||||||
|
error in the `os` package. You can check if this error is present by using
|
||||||
|
the standard [`errors.Is`](https://golang.org/pkg/errors/#Is) function.
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Assume err is a multierror value
|
||||||
|
err := somefunc()
|
||||||
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
|
// err contains os.ErrNotExist
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
**Returning a multierror only if there are errors**
|
**Returning a multierror only if there are errors**
|
||||||
|
|
||||||
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
|
If you build a `multierror.Error`, you can use the `ErrorOrNil` function
|
||||||
|
2
vendor/github.com/hashicorp/go-multierror/go.mod
generated
vendored
2
vendor/github.com/hashicorp/go-multierror/go.mod
generated
vendored
@ -1,3 +1,5 @@
|
|||||||
module github.com/hashicorp/go-multierror
|
module github.com/hashicorp/go-multierror
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
require github.com/hashicorp/errwrap v1.0.0
|
require github.com/hashicorp/errwrap v1.0.0
|
||||||
|
2
vendor/github.com/hashicorp/go-multierror/go.sum
generated
vendored
2
vendor/github.com/hashicorp/go-multierror/go.sum
generated
vendored
@ -1,4 +1,2 @@
|
|||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce h1:prjrVgOk2Yg6w+PflHoszQNLTUh4kaByUcEWM/9uin4=
|
|
||||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
|
||||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||||
|
38
vendor/github.com/hashicorp/go-multierror/group.go
generated
vendored
Normal file
38
vendor/github.com/hashicorp/go-multierror/group.go
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package multierror
|
||||||
|
|
||||||
|
import "sync"
|
||||||
|
|
||||||
|
// Group is a collection of goroutines which return errors that need to be
|
||||||
|
// coalesced.
|
||||||
|
type Group struct {
|
||||||
|
mutex sync.Mutex
|
||||||
|
err *Error
|
||||||
|
wg sync.WaitGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go calls the given function in a new goroutine.
|
||||||
|
//
|
||||||
|
// If the function returns an error it is added to the group multierror which
|
||||||
|
// is returned by Wait.
|
||||||
|
func (g *Group) Go(f func() error) {
|
||||||
|
g.wg.Add(1)
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer g.wg.Done()
|
||||||
|
|
||||||
|
if err := f(); err != nil {
|
||||||
|
g.mutex.Lock()
|
||||||
|
g.err = Append(g.err, err)
|
||||||
|
g.mutex.Unlock()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait blocks until all function calls from the Go method have returned, then
|
||||||
|
// returns the multierror.
|
||||||
|
func (g *Group) Wait() *Error {
|
||||||
|
g.wg.Wait()
|
||||||
|
g.mutex.Lock()
|
||||||
|
defer g.mutex.Unlock()
|
||||||
|
return g.err
|
||||||
|
}
|
67
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
67
vendor/github.com/hashicorp/go-multierror/multierror.go
generated
vendored
@ -1,6 +1,7 @@
|
|||||||
package multierror
|
package multierror
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,3 +50,69 @@ func (e *Error) GoString() string {
|
|||||||
func (e *Error) WrappedErrors() []error {
|
func (e *Error) WrappedErrors() []error {
|
||||||
return e.Errors
|
return e.Errors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unwrap returns an error from Error (or nil if there are no errors).
|
||||||
|
// This error returned will further support Unwrap to get the next error,
|
||||||
|
// etc. The order will match the order of Errors in the multierror.Error
|
||||||
|
// at the time of calling.
|
||||||
|
//
|
||||||
|
// The resulting error supports errors.As/Is/Unwrap so you can continue
|
||||||
|
// to use the stdlib errors package to introspect further.
|
||||||
|
//
|
||||||
|
// This will perform a shallow copy of the errors slice. Any errors appended
|
||||||
|
// to this error after calling Unwrap will not be available until a new
|
||||||
|
// Unwrap is called on the multierror.Error.
|
||||||
|
func (e *Error) Unwrap() error {
|
||||||
|
// If we have no errors then we do nothing
|
||||||
|
if e == nil || len(e.Errors) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have exactly one error, we can just return that directly.
|
||||||
|
if len(e.Errors) == 1 {
|
||||||
|
return e.Errors[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shallow copy the slice
|
||||||
|
errs := make([]error, len(e.Errors))
|
||||||
|
copy(errs, e.Errors)
|
||||||
|
return chain(errs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// chain implements the interfaces necessary for errors.Is/As/Unwrap to
|
||||||
|
// work in a deterministic way with multierror. A chain tracks a list of
|
||||||
|
// errors while accounting for the current represented error. This lets
|
||||||
|
// Is/As be meaningful.
|
||||||
|
//
|
||||||
|
// Unwrap returns the next error. In the cleanest form, Unwrap would return
|
||||||
|
// the wrapped error here but we can't do that if we want to properly
|
||||||
|
// get access to all the errors. Instead, users are recommended to use
|
||||||
|
// Is/As to get the correct error type out.
|
||||||
|
//
|
||||||
|
// Precondition: []error is non-empty (len > 0)
|
||||||
|
type chain []error
|
||||||
|
|
||||||
|
// Error implements the error interface
|
||||||
|
func (e chain) Error() string {
|
||||||
|
return e[0].Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unwrap implements errors.Unwrap by returning the next error in the
|
||||||
|
// chain or nil if there are no more errors.
|
||||||
|
func (e chain) Unwrap() error {
|
||||||
|
if len(e) == 1 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return e[1:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// As implements errors.As by attempting to map to the current value.
|
||||||
|
func (e chain) As(target interface{}) bool {
|
||||||
|
return errors.As(e[0], target)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is implements errors.Is by comparing the current value directly.
|
||||||
|
func (e chain) Is(target error) bool {
|
||||||
|
return errors.Is(e[0], target)
|
||||||
|
}
|
||||||
|
192
vendor/github.com/klauspost/compress/zstd/README.md
generated
vendored
192
vendor/github.com/klauspost/compress/zstd/README.md
generated
vendored
@ -5,11 +5,9 @@ It offers a very wide range of compression / speed trade-off, while being backed
|
|||||||
A high performance compression algorithm is implemented. For now focused on speed.
|
A high performance compression algorithm is implemented. For now focused on speed.
|
||||||
|
|
||||||
This package provides [compression](#Compressor) to and [decompression](#Decompressor) of Zstandard content.
|
This package provides [compression](#Compressor) to and [decompression](#Decompressor) of Zstandard content.
|
||||||
Note that custom dictionaries are not supported yet, so if your code relies on that,
|
Note that custom dictionaries are only supported for decompression.
|
||||||
you cannot use the package as-is.
|
|
||||||
|
|
||||||
This package is pure Go and without use of "unsafe".
|
This package is pure Go and without use of "unsafe".
|
||||||
If a significant speedup can be achieved using "unsafe", it may be added as an option later.
|
|
||||||
|
|
||||||
The `zstd` package is provided as open source software using a Go standard license.
|
The `zstd` package is provided as open source software using a Go standard license.
|
||||||
|
|
||||||
@ -142,80 +140,96 @@ Using the Encoder for both a stream and individual blocks concurrently is safe.
|
|||||||
I have collected some speed examples to compare speed and compression against other compressors.
|
I have collected some speed examples to compare speed and compression against other compressors.
|
||||||
|
|
||||||
* `file` is the input file.
|
* `file` is the input file.
|
||||||
* `out` is the compressor used. `zskp` is this package. `gzstd` is gzip standard library. `zstd` is the Datadog cgo library.
|
* `out` is the compressor used. `zskp` is this package. `zstd` is the Datadog cgo library. `gzstd/gzkp` is gzip standard and this library.
|
||||||
* `level` is the compression level used. For `zskp` level 1 is "fastest", level 2 is "default".
|
* `level` is the compression level used. For `zskp` level 1 is "fastest", level 2 is "default".
|
||||||
* `insize`/`outsize` is the input/output size.
|
* `insize`/`outsize` is the input/output size.
|
||||||
* `millis` is the number of milliseconds used for compression.
|
* `millis` is the number of milliseconds used for compression.
|
||||||
* `mb/s` is megabytes (2^20 bytes) per second.
|
* `mb/s` is megabytes (2^20 bytes) per second.
|
||||||
|
|
||||||
```
|
```
|
||||||
The test data for the Large Text Compression Benchmark is the first
|
Silesia Corpus:
|
||||||
10^9 bytes of the English Wikipedia dump on Mar. 3, 2006.
|
http://sun.aei.polsl.pl/~sdeor/corpus/silesia.zip
|
||||||
http://mattmahoney.net/dc/textdata.html
|
|
||||||
|
|
||||||
file out level insize outsize millis mb/s
|
This package:
|
||||||
enwik9 zskp 1 1000000000 343833033 5840 163.30
|
file out level insize outsize millis mb/s
|
||||||
enwik9 zskp 2 1000000000 317822183 8449 112.87
|
silesia.tar zskp 1 211947520 73101992 643 313.87
|
||||||
enwik9 gzstd 1 1000000000 382578136 13627 69.98
|
silesia.tar zskp 2 211947520 67504318 969 208.38
|
||||||
enwik9 gzstd 3 1000000000 349139651 22344 42.68
|
silesia.tar zskp 3 211947520 65177448 1899 106.44
|
||||||
enwik9 zstd 1 1000000000 357416379 4838 197.12
|
|
||||||
enwik9 zstd 3 1000000000 313734522 7556 126.21
|
cgo zstd:
|
||||||
|
silesia.tar zstd 1 211947520 73605392 543 371.56
|
||||||
|
silesia.tar zstd 3 211947520 66793289 864 233.68
|
||||||
|
silesia.tar zstd 6 211947520 62916450 1913 105.66
|
||||||
|
|
||||||
|
gzip, stdlib/this package:
|
||||||
|
silesia.tar gzstd 1 211947520 80007735 1654 122.21
|
||||||
|
silesia.tar gzkp 1 211947520 80369488 1168 173.06
|
||||||
|
|
||||||
GOB stream of binary data. Highly compressible.
|
GOB stream of binary data. Highly compressible.
|
||||||
https://files.klauspost.com/compress/gob-stream.7z
|
https://files.klauspost.com/compress/gob-stream.7z
|
||||||
|
|
||||||
file out level insize outsize millis mb/s
|
file out level insize outsize millis mb/s
|
||||||
gob-stream zskp 1 1911399616 234981983 5100 357.42
|
gob-stream zskp 1 1911399616 235022249 3088 590.30
|
||||||
gob-stream zskp 2 1911399616 208674003 6698 272.15
|
gob-stream zskp 2 1911399616 205669791 3786 481.34
|
||||||
gob-stream gzstd 1 1911399616 357382641 14727 123.78
|
gob-stream zskp 3 1911399616 185792019 9324 195.48
|
||||||
gob-stream gzstd 3 1911399616 327835097 17005 107.19
|
gob-stream zstd 1 1911399616 249810424 2637 691.26
|
||||||
gob-stream zstd 1 1911399616 250787165 4075 447.22
|
gob-stream zstd 3 1911399616 208192146 3490 522.31
|
||||||
gob-stream zstd 3 1911399616 208191888 5511 330.77
|
gob-stream zstd 6 1911399616 193632038 6687 272.56
|
||||||
|
gob-stream gzstd 1 1911399616 357382641 10251 177.82
|
||||||
|
gob-stream gzkp 1 1911399616 362156523 5695 320.08
|
||||||
|
|
||||||
Highly compressible JSON file. Similar to logs in a lot of ways.
|
The test data for the Large Text Compression Benchmark is the first
|
||||||
https://files.klauspost.com/compress/adresser.001.gz
|
10^9 bytes of the English Wikipedia dump on Mar. 3, 2006.
|
||||||
|
http://mattmahoney.net/dc/textdata.html
|
||||||
|
|
||||||
file out level insize outsize millis mb/s
|
file out level insize outsize millis mb/s
|
||||||
adresser.001 zskp 1 1073741824 18510122 1477 692.83
|
enwik9 zskp 1 1000000000 343848582 3609 264.18
|
||||||
adresser.001 zskp 2 1073741824 19831697 1705 600.59
|
enwik9 zskp 2 1000000000 317276632 5746 165.97
|
||||||
adresser.001 gzstd 1 1073741824 47755503 3079 332.47
|
enwik9 zskp 3 1000000000 294540704 11725 81.34
|
||||||
adresser.001 gzstd 3 1073741824 40052381 3051 335.63
|
enwik9 zstd 1 1000000000 358072021 3110 306.65
|
||||||
adresser.001 zstd 1 1073741824 16135896 994 1030.18
|
enwik9 zstd 3 1000000000 313734672 4784 199.35
|
||||||
adresser.001 zstd 3 1073741824 17794465 905 1131.49
|
enwik9 zstd 6 1000000000 295138875 10290 92.68
|
||||||
|
enwik9 gzstd 1 1000000000 382578136 9604 99.30
|
||||||
|
enwik9 gzkp 1 1000000000 383825945 6544 145.73
|
||||||
|
|
||||||
|
Highly compressible JSON file.
|
||||||
|
https://files.klauspost.com/compress/github-june-2days-2019.json.zst
|
||||||
|
|
||||||
|
file out level insize outsize millis mb/s
|
||||||
|
github-june-2days-2019.json zskp 1 6273951764 699045015 10620 563.40
|
||||||
|
github-june-2days-2019.json zskp 2 6273951764 617881763 11687 511.96
|
||||||
|
github-june-2days-2019.json zskp 3 6273951764 537511906 29252 204.54
|
||||||
|
github-june-2days-2019.json zstd 1 6273951764 766284037 8450 708.00
|
||||||
|
github-june-2days-2019.json zstd 3 6273951764 661889476 10927 547.57
|
||||||
|
github-june-2days-2019.json zstd 6 6273951764 642756859 22996 260.18
|
||||||
|
github-june-2days-2019.json gzstd 1 6273951764 1164400847 29948 199.79
|
||||||
|
github-june-2days-2019.json gzkp 1 6273951764 1128755542 19236 311.03
|
||||||
|
|
||||||
VM Image, Linux mint with a few installed applications:
|
VM Image, Linux mint with a few installed applications:
|
||||||
https://files.klauspost.com/compress/rawstudio-mint14.7z
|
https://files.klauspost.com/compress/rawstudio-mint14.7z
|
||||||
|
|
||||||
file out level insize outsize millis mb/s
|
file out level insize outsize millis mb/s
|
||||||
rawstudio-mint14.tar zskp 1 8558382592 3648168838 33398 244.38
|
rawstudio-mint14.tar zskp 1 8558382592 3667489370 20210 403.84
|
||||||
rawstudio-mint14.tar zskp 2 8558382592 3376721436 50962 160.16
|
rawstudio-mint14.tar zskp 2 8558382592 3364592300 31873 256.07
|
||||||
rawstudio-mint14.tar gzstd 1 8558382592 3926257486 84712 96.35
|
rawstudio-mint14.tar zskp 3 8558382592 3224594213 71751 113.75
|
||||||
rawstudio-mint14.tar gzstd 3 8558382592 3740711978 176344 46.28
|
rawstudio-mint14.tar zstd 1 8558382592 3609250104 17136 476.27
|
||||||
rawstudio-mint14.tar zstd 1 8558382592 3607859742 27903 292.51
|
rawstudio-mint14.tar zstd 3 8558382592 3341679997 29262 278.92
|
||||||
rawstudio-mint14.tar zstd 3 8558382592 3341710879 46700 174.77
|
rawstudio-mint14.tar zstd 6 8558382592 3235846406 77904 104.77
|
||||||
|
rawstudio-mint14.tar gzstd 1 8558382592 3926257486 57722 141.40
|
||||||
|
rawstudio-mint14.tar gzkp 1 8558382592 3970463184 41749 195.49
|
||||||
|
|
||||||
|
CSV data:
|
||||||
|
https://files.klauspost.com/compress/nyc-taxi-data-10M.csv.zst
|
||||||
|
|
||||||
The test data is designed to test archivers in realistic backup scenarios.
|
file out level insize outsize millis mb/s
|
||||||
http://mattmahoney.net/dc/10gb.html
|
nyc-taxi-data-10M.csv zskp 1 3325605752 641339945 8925 355.35
|
||||||
|
nyc-taxi-data-10M.csv zskp 2 3325605752 591748091 11268 281.44
|
||||||
file out level insize outsize millis mb/s
|
nyc-taxi-data-10M.csv zskp 3 3325605752 538490114 19880 159.53
|
||||||
10gb.tar zskp 1 10065157632 4883149814 45715 209.97
|
nyc-taxi-data-10M.csv zstd 1 3325605752 687399637 8233 385.18
|
||||||
10gb.tar zskp 2 10065157632 4638110010 60970 157.44
|
nyc-taxi-data-10M.csv zstd 3 3325605752 598514411 10065 315.07
|
||||||
10gb.tar gzstd 1 10065157632 5198296126 97769 98.18
|
nyc-taxi-data-10M.csv zstd 6 3325605752 570522953 20038 158.27
|
||||||
10gb.tar gzstd 3 10065157632 4932665487 313427 30.63
|
nyc-taxi-data-10M.csv gzstd 1 3325605752 928656485 23876 132.83
|
||||||
10gb.tar zstd 1 10065157632 4940796535 40391 237.65
|
nyc-taxi-data-10M.csv gzkp 1 3325605752 924718719 16388 193.53
|
||||||
10gb.tar zstd 3 10065157632 4638618579 52911 181.42
|
|
||||||
|
|
||||||
Silesia Corpus:
|
|
||||||
http://sun.aei.polsl.pl/~sdeor/corpus/silesia.zip
|
|
||||||
|
|
||||||
file out level insize outsize millis mb/s
|
|
||||||
silesia.tar zskp 1 211947520 73025800 1108 182.26
|
|
||||||
silesia.tar zskp 2 211947520 67674684 1599 126.41
|
|
||||||
silesia.tar gzstd 1 211947520 80007735 2515 80.37
|
|
||||||
silesia.tar gzstd 3 211947520 73133380 4259 47.45
|
|
||||||
silesia.tar zstd 1 211947520 73513991 933 216.64
|
|
||||||
silesia.tar zstd 3 211947520 66793301 1377 146.79
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Converters
|
### Converters
|
||||||
@ -315,13 +329,13 @@ Data compressed with [dictionaries](https://github.com/facebook/zstd#the-case-fo
|
|||||||
|
|
||||||
Dictionaries are added individually to Decoders.
|
Dictionaries are added individually to Decoders.
|
||||||
Dictionaries are generated by the `zstd --train` command and contains an initial state for the decoder.
|
Dictionaries are generated by the `zstd --train` command and contains an initial state for the decoder.
|
||||||
To add a dictionary use the `RegisterDict(data)` with the dictionary data before starting any decompression.
|
To add a dictionary use the `WithDecoderDicts(dicts ...[]byte)` option with the dictionary data.
|
||||||
|
Several dictionaries can be added at once.
|
||||||
|
|
||||||
The dictionary will be used automatically for the data that specifies them.
|
The dictionary will be used automatically for the data that specifies them.
|
||||||
|
|
||||||
A re-used Decoder will still contain the dictionaries registered.
|
A re-used Decoder will still contain the dictionaries registered.
|
||||||
|
|
||||||
When registering a dictionary with the same ID it will override the existing.
|
When registering multiple dictionaries with the same ID, the last one will be used.
|
||||||
|
|
||||||
### Allocation-less operation
|
### Allocation-less operation
|
||||||
|
|
||||||
@ -364,36 +378,42 @@ These are some examples of performance compared to [datadog cgo library](https:/
|
|||||||
The first two are streaming decodes and the last are smaller inputs.
|
The first two are streaming decodes and the last are smaller inputs.
|
||||||
|
|
||||||
```
|
```
|
||||||
BenchmarkDecoderSilesia-8 20 642550210 ns/op 329.85 MB/s 3101 B/op 8 allocs/op
|
BenchmarkDecoderSilesia-8 3 385000067 ns/op 550.51 MB/s 5498 B/op 8 allocs/op
|
||||||
BenchmarkDecoderSilesiaCgo-8 100 384930000 ns/op 550.61 MB/s 451878 B/op 9713 allocs/op
|
BenchmarkDecoderSilesiaCgo-8 6 197666567 ns/op 1072.25 MB/s 270672 B/op 8 allocs/op
|
||||||
|
|
||||||
BenchmarkDecoderEnwik9-2 10 3146000080 ns/op 317.86 MB/s 2649 B/op 9 allocs/op
|
BenchmarkDecoderEnwik9-8 1 2027001600 ns/op 493.34 MB/s 10496 B/op 18 allocs/op
|
||||||
BenchmarkDecoderEnwik9Cgo-2 20 1905900000 ns/op 524.69 MB/s 1125120 B/op 45785 allocs/op
|
BenchmarkDecoderEnwik9Cgo-8 2 979499200 ns/op 1020.93 MB/s 270672 B/op 8 allocs/op
|
||||||
|
|
||||||
BenchmarkDecoder_DecodeAll/z000000.zst-8 200 7049994 ns/op 138.26 MB/s 40 B/op 2 allocs/op
|
Concurrent performance:
|
||||||
BenchmarkDecoder_DecodeAll/z000001.zst-8 100000 19560 ns/op 97.49 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000002.zst-8 5000 297599 ns/op 236.99 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000003.zst-8 2000 725502 ns/op 141.17 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000004.zst-8 200000 9314 ns/op 54.54 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000005.zst-8 10000 137500 ns/op 104.72 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000006.zst-8 500 2316009 ns/op 206.06 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000007.zst-8 20000 64499 ns/op 344.90 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000008.zst-8 50000 24900 ns/op 219.56 MB/s 40 B/op 2 allocs/op
|
|
||||||
BenchmarkDecoder_DecodeAll/z000009.zst-8 1000 2348999 ns/op 154.01 MB/s 40 B/op 2 allocs/op
|
|
||||||
|
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000000.zst-8 500 4268005 ns/op 228.38 MB/s 1228849 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/kppkn.gtb.zst-16 28915 42469 ns/op 4340.07 MB/s 114 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000001.zst-8 100000 15250 ns/op 125.05 MB/s 2096 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/geo.protodata.zst-16 116505 9965 ns/op 11900.16 MB/s 16 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000002.zst-8 10000 147399 ns/op 478.49 MB/s 73776 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/plrabn12.txt.zst-16 8952 134272 ns/op 3588.70 MB/s 915 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000003.zst-8 5000 320798 ns/op 319.27 MB/s 139312 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/lcet10.txt.zst-16 11820 102538 ns/op 4161.90 MB/s 594 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000004.zst-8 200000 10004 ns/op 50.77 MB/s 560 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/asyoulik.txt.zst-16 34782 34184 ns/op 3661.88 MB/s 60 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000005.zst-8 20000 73599 ns/op 195.64 MB/s 19120 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/alice29.txt.zst-16 27712 43447 ns/op 3500.58 MB/s 99 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000006.zst-8 1000 1119003 ns/op 426.48 MB/s 557104 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/html_x_4.zst-16 62826 18750 ns/op 21845.10 MB/s 104 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000007.zst-8 20000 103450 ns/op 215.04 MB/s 71296 B/op 9 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/paper-100k.pdf.zst-16 631545 1794 ns/op 57078.74 MB/s 2 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000008.zst-8 100000 20130 ns/op 271.58 MB/s 6192 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/fireworks.jpeg.zst-16 1690140 712 ns/op 172938.13 MB/s 1 B/op 0 allocs/op
|
||||||
BenchmarkDecoder_DecodeAllCgo/z000009.zst-8 2000 1123500 ns/op 322.00 MB/s 368688 B/op 3 allocs/op
|
BenchmarkDecoder_DecodeAllParallel/urls.10K.zst-16 10432 113593 ns/op 6180.73 MB/s 1143 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallel/html.zst-16 113206 10671 ns/op 9596.27 MB/s 15 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallel/comp-data.bin.zst-16 1530615 779 ns/op 5229.49 MB/s 0 B/op 0 allocs/op
|
||||||
|
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/kppkn.gtb.zst-16 65217 16192 ns/op 11383.34 MB/s 46 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/geo.protodata.zst-16 292671 4039 ns/op 29363.19 MB/s 6 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/plrabn12.txt.zst-16 26314 46021 ns/op 10470.43 MB/s 293 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/lcet10.txt.zst-16 33897 34900 ns/op 12227.96 MB/s 205 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/asyoulik.txt.zst-16 104348 11433 ns/op 10949.01 MB/s 20 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/alice29.txt.zst-16 75949 15510 ns/op 9805.60 MB/s 32 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/html_x_4.zst-16 173910 6756 ns/op 60624.29 MB/s 37 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/paper-100k.pdf.zst-16 923076 1339 ns/op 76474.87 MB/s 1 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/fireworks.jpeg.zst-16 922920 1351 ns/op 91102.57 MB/s 2 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/urls.10K.zst-16 27649 43618 ns/op 16096.19 MB/s 407 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/html.zst-16 279073 4160 ns/op 24614.18 MB/s 6 B/op 0 allocs/op
|
||||||
|
BenchmarkDecoder_DecodeAllParallelCgo/comp-data.bin.zst-16 749938 1579 ns/op 2581.71 MB/s 0 B/op 0 allocs/op
|
||||||
```
|
```
|
||||||
|
|
||||||
This reflects the performance around May 2019, but this may be out of date.
|
This reflects the performance around May 2020, but this may be out of date.
|
||||||
|
|
||||||
# Contributions
|
# Contributions
|
||||||
|
|
||||||
|
4
vendor/github.com/klauspost/compress/zstd/blockenc.go
generated
vendored
4
vendor/github.com/klauspost/compress/zstd/blockenc.go
generated
vendored
@ -444,9 +444,9 @@ func fuzzFseEncoder(data []byte) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// encode will encode the block and append the output in b.output.
|
// encode will encode the block and append the output in b.output.
|
||||||
func (b *blockEnc) encode(raw bool) error {
|
func (b *blockEnc) encode(raw, rawAllLits bool) error {
|
||||||
if len(b.sequences) == 0 {
|
if len(b.sequences) == 0 {
|
||||||
return b.encodeLits(raw)
|
return b.encodeLits(rawAllLits)
|
||||||
}
|
}
|
||||||
// We want some difference
|
// We want some difference
|
||||||
if len(b.literals) > (b.size - (b.size >> 5)) {
|
if len(b.literals) > (b.size - (b.size >> 5)) {
|
||||||
|
20
vendor/github.com/klauspost/compress/zstd/decoder.go
generated
vendored
20
vendor/github.com/klauspost/compress/zstd/decoder.go
generated
vendored
@ -85,6 +85,13 @@ func NewReader(r io.Reader, opts ...DOption) (*Decoder, error) {
|
|||||||
d.current.output = make(chan decodeOutput, d.o.concurrent)
|
d.current.output = make(chan decodeOutput, d.o.concurrent)
|
||||||
d.current.flushed = true
|
d.current.flushed = true
|
||||||
|
|
||||||
|
// Transfer option dicts.
|
||||||
|
d.dicts = make(map[uint32]dict, len(d.o.dicts))
|
||||||
|
for _, dc := range d.o.dicts {
|
||||||
|
d.dicts[dc.id] = dc
|
||||||
|
}
|
||||||
|
d.o.dicts = nil
|
||||||
|
|
||||||
// Create decoders
|
// Create decoders
|
||||||
d.decoders = make(chan *blockDec, d.o.concurrent)
|
d.decoders = make(chan *blockDec, d.o.concurrent)
|
||||||
for i := 0; i < d.o.concurrent; i++ {
|
for i := 0; i < d.o.concurrent; i++ {
|
||||||
@ -399,19 +406,6 @@ func (d *Decoder) Close() {
|
|||||||
d.current.err = ErrDecoderClosed
|
d.current.err = ErrDecoderClosed
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterDict will load a dictionary
|
|
||||||
func (d *Decoder) RegisterDict(b []byte) error {
|
|
||||||
dc, err := loadDict(b)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if d.dicts == nil {
|
|
||||||
d.dicts = make(map[uint32]dict, 1)
|
|
||||||
}
|
|
||||||
d.dicts[dc.id] = *dc
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IOReadCloser returns the decoder as an io.ReadCloser for convenience.
|
// IOReadCloser returns the decoder as an io.ReadCloser for convenience.
|
||||||
// Any changes to the decoder will be reflected, so the returned ReadCloser
|
// Any changes to the decoder will be reflected, so the returned ReadCloser
|
||||||
// can be reused along with the decoder.
|
// can be reused along with the decoder.
|
||||||
|
16
vendor/github.com/klauspost/compress/zstd/decoder_options.go
generated
vendored
16
vendor/github.com/klauspost/compress/zstd/decoder_options.go
generated
vendored
@ -18,6 +18,7 @@ type decoderOptions struct {
|
|||||||
lowMem bool
|
lowMem bool
|
||||||
concurrent int
|
concurrent int
|
||||||
maxDecodedSize uint64
|
maxDecodedSize uint64
|
||||||
|
dicts []dict
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *decoderOptions) setDefault() {
|
func (o *decoderOptions) setDefault() {
|
||||||
@ -66,3 +67,18 @@ func WithDecoderMaxMemory(n uint64) DOption {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithDecoderDicts allows to register one or more dictionaries for the decoder.
|
||||||
|
// If several dictionaries with the same ID is provided the last one will be used.
|
||||||
|
func WithDecoderDicts(dicts ...[]byte) DOption {
|
||||||
|
return func(o *decoderOptions) error {
|
||||||
|
for _, b := range dicts {
|
||||||
|
d, err := loadDict(b)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
o.dicts = append(o.dicts, *d)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
vendor/github.com/klauspost/compress/zstd/encoder.go
generated
vendored
6
vendor/github.com/klauspost/compress/zstd/encoder.go
generated
vendored
@ -280,7 +280,7 @@ func (e *Encoder) nextBlock(final bool) error {
|
|||||||
// If we got the exact same number of literals as input,
|
// If we got the exact same number of literals as input,
|
||||||
// assume the literals cannot be compressed.
|
// assume the literals cannot be compressed.
|
||||||
if len(src) != len(blk.literals) || len(src) != e.o.blockSize {
|
if len(src) != len(blk.literals) || len(src) != e.o.blockSize {
|
||||||
err = blk.encode(e.o.noEntropy)
|
err = blk.encode(e.o.noEntropy, !e.o.allLitEntropy)
|
||||||
}
|
}
|
||||||
switch err {
|
switch err {
|
||||||
case errIncompressible:
|
case errIncompressible:
|
||||||
@ -491,7 +491,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
|||||||
if len(blk.literals) != len(src) || len(src) != e.o.blockSize {
|
if len(blk.literals) != len(src) || len(src) != e.o.blockSize {
|
||||||
// Output directly to dst
|
// Output directly to dst
|
||||||
blk.output = dst
|
blk.output = dst
|
||||||
err = blk.encode(e.o.noEntropy)
|
err = blk.encode(e.o.noEntropy, !e.o.allLitEntropy)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
@ -528,7 +528,7 @@ func (e *Encoder) EncodeAll(src, dst []byte) []byte {
|
|||||||
// If we got the exact same number of literals as input,
|
// If we got the exact same number of literals as input,
|
||||||
// assume the literals cannot be compressed.
|
// assume the literals cannot be compressed.
|
||||||
if len(blk.literals) != len(todo) || len(todo) != e.o.blockSize {
|
if len(blk.literals) != len(todo) || len(todo) != e.o.blockSize {
|
||||||
err = blk.encode(e.o.noEntropy)
|
err = blk.encode(e.o.noEntropy, !e.o.allLitEntropy)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch err {
|
switch err {
|
||||||
|
38
vendor/github.com/klauspost/compress/zstd/encoder_options.go
generated
vendored
38
vendor/github.com/klauspost/compress/zstd/encoder_options.go
generated
vendored
@ -12,16 +12,18 @@ type EOption func(*encoderOptions) error
|
|||||||
|
|
||||||
// options retains accumulated state of multiple options.
|
// options retains accumulated state of multiple options.
|
||||||
type encoderOptions struct {
|
type encoderOptions struct {
|
||||||
concurrent int
|
concurrent int
|
||||||
level EncoderLevel
|
level EncoderLevel
|
||||||
single *bool
|
single *bool
|
||||||
pad int
|
pad int
|
||||||
blockSize int
|
blockSize int
|
||||||
windowSize int
|
windowSize int
|
||||||
crc bool
|
crc bool
|
||||||
fullZero bool
|
fullZero bool
|
||||||
noEntropy bool
|
noEntropy bool
|
||||||
customWindow bool
|
allLitEntropy bool
|
||||||
|
customWindow bool
|
||||||
|
customALEntropy bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *encoderOptions) setDefault() {
|
func (o *encoderOptions) setDefault() {
|
||||||
@ -207,6 +209,10 @@ func WithEncoderLevel(l EncoderLevel) EOption {
|
|||||||
o.windowSize = 16 << 20
|
o.windowSize = 16 << 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if !o.customALEntropy {
|
||||||
|
o.allLitEntropy = l > SpeedFastest
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -221,6 +227,18 @@ func WithZeroFrames(b bool) EOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithAllLitEntropyCompression will apply entropy compression if no matches are found.
|
||||||
|
// Disabling this will skip incompressible data faster, but in cases with no matches but
|
||||||
|
// skewed character distribution compression is lost.
|
||||||
|
// Default value depends on the compression level selected.
|
||||||
|
func WithAllLitEntropyCompression(b bool) EOption {
|
||||||
|
return func(o *encoderOptions) error {
|
||||||
|
o.customALEntropy = true
|
||||||
|
o.allLitEntropy = b
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithNoEntropyCompression will always skip entropy compression of literals.
|
// WithNoEntropyCompression will always skip entropy compression of literals.
|
||||||
// This can be useful if content has matches, but unlikely to benefit from entropy
|
// This can be useful if content has matches, but unlikely to benefit from entropy
|
||||||
// compression. Usually the slight speed improvement is not worth enabling this.
|
// compression. Usually the slight speed improvement is not worth enabling this.
|
||||||
|
2
vendor/github.com/klauspost/compress/zstd/snappy.go
generated
vendored
2
vendor/github.com/klauspost/compress/zstd/snappy.go
generated
vendored
@ -178,7 +178,7 @@ func (r *SnappyConverter) Convert(in io.Reader, w io.Writer) (int64, error) {
|
|||||||
r.err = ErrSnappyCorrupt
|
r.err = ErrSnappyCorrupt
|
||||||
return written, r.err
|
return written, r.err
|
||||||
}
|
}
|
||||||
err = r.block.encode(false)
|
err = r.block.encode(false, false)
|
||||||
switch err {
|
switch err {
|
||||||
case errIncompressible:
|
case errIncompressible:
|
||||||
r.block.popOffsets()
|
r.block.popOffsets()
|
||||||
|
21
vendor/github.com/opencontainers/selinux/go-selinux/doc.go
generated
vendored
Normal file
21
vendor/github.com/opencontainers/selinux/go-selinux/doc.go
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
Package selinux provides a high-level interface for interacting with selinux.
|
||||||
|
|
||||||
|
This package uses a selinux build tag to enable the selinux functionality. This
|
||||||
|
allows non-linux and linux users who do not have selinux support to still use
|
||||||
|
tools that rely on this library.
|
||||||
|
|
||||||
|
To compile with full selinux support use the -tags=selinux option in your build
|
||||||
|
and test commands.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
import "github.com/opencontainers/selinux/go-selinux"
|
||||||
|
|
||||||
|
// Ensure that selinux is enforcing mode.
|
||||||
|
if selinux.EnforceMode() != selinux.Enforcing {
|
||||||
|
selinux.SetEnforceMode(selinux.Enforcing)
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
package selinux
|
2
vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
generated
vendored
2
vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
generated
vendored
@ -73,9 +73,9 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
|
|||||||
selinux.ReleaseLabel(processLabel)
|
selinux.ReleaseLabel(processLabel)
|
||||||
}
|
}
|
||||||
processLabel = pcon.Get()
|
processLabel = pcon.Get()
|
||||||
mountLabel = mcon.Get()
|
|
||||||
selinux.ReserveLabel(processLabel)
|
selinux.ReserveLabel(processLabel)
|
||||||
}
|
}
|
||||||
|
mountLabel = mcon.Get()
|
||||||
}
|
}
|
||||||
return processLabel, mountLabel, nil
|
return processLabel, mountLabel, nil
|
||||||
}
|
}
|
||||||
|
1
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
1
vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
generated
vendored
@ -30,7 +30,6 @@ func Relabel(path string, fileLabel string, shared bool) error {
|
|||||||
// DisableSecOpt returns a security opt that can disable labeling
|
// DisableSecOpt returns a security opt that can disable labeling
|
||||||
// support for future container processes
|
// support for future container processes
|
||||||
func DisableSecOpt() []string {
|
func DisableSecOpt() []string {
|
||||||
// TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil"
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
249
vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
generated
vendored
Normal file
249
vendor/github.com/opencontainers/selinux/go-selinux/selinux.go
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
|||||||
|
package selinux
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Enforcing constant indicate SELinux is in enforcing mode
|
||||||
|
Enforcing = 1
|
||||||
|
// Permissive constant to indicate SELinux is in permissive mode
|
||||||
|
Permissive = 0
|
||||||
|
// Disabled constant to indicate SELinux is disabled
|
||||||
|
Disabled = -1
|
||||||
|
|
||||||
|
// DefaultCategoryRange is the upper bound on the category range
|
||||||
|
DefaultCategoryRange = uint32(1024)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
||||||
|
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
||||||
|
// ErrEmptyPath is returned when an empty path has been specified.
|
||||||
|
ErrEmptyPath = errors.New("empty path")
|
||||||
|
|
||||||
|
// InvalidLabel is returned when an invalid label is specified.
|
||||||
|
InvalidLabel = errors.New("Invalid Label")
|
||||||
|
|
||||||
|
// ErrIncomparable is returned two levels are not comparable
|
||||||
|
ErrIncomparable = errors.New("incomparable levels")
|
||||||
|
// ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level
|
||||||
|
ErrLevelSyntax = errors.New("invalid level syntax")
|
||||||
|
|
||||||
|
// CategoryRange allows the upper bound on the category range to be adjusted
|
||||||
|
CategoryRange = DefaultCategoryRange
|
||||||
|
)
|
||||||
|
|
||||||
|
// Context is a representation of the SELinux label broken into 4 parts
|
||||||
|
type Context map[string]string
|
||||||
|
|
||||||
|
// SetDisabled disables SELinux support for the package
|
||||||
|
func SetDisabled() {
|
||||||
|
setDisabled()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetEnabled returns whether SELinux is currently enabled.
|
||||||
|
func GetEnabled() bool {
|
||||||
|
return getEnabled()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClassIndex returns the int index for an object class in the loaded policy,
|
||||||
|
// or -1 and an error
|
||||||
|
func ClassIndex(class string) (int, error) {
|
||||||
|
return classIndex(class)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFileLabel sets the SELinux label for this path or returns an error.
|
||||||
|
func SetFileLabel(fpath string, label string) error {
|
||||||
|
return setFileLabel(fpath, label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileLabel returns the SELinux label for this path or returns an error.
|
||||||
|
func FileLabel(fpath string) (string, error) {
|
||||||
|
return fileLabel(fpath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFSCreateLabel tells kernel the label to create all file system objects
|
||||||
|
// created by this task. Setting label="" to return to default.
|
||||||
|
func SetFSCreateLabel(label string) error {
|
||||||
|
return setFSCreateLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FSCreateLabel returns the default label the kernel which the kernel is using
|
||||||
|
// for file system objects created by this task. "" indicates default.
|
||||||
|
func FSCreateLabel() (string, error) {
|
||||||
|
return fsCreateLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
||||||
|
func CurrentLabel() (string, error) {
|
||||||
|
return currentLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PidLabel returns the SELinux label of the given pid, or an error.
|
||||||
|
func PidLabel(pid int) (string, error) {
|
||||||
|
return pidLabel(pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||||
|
// that are executed by the current process thread, or an error.
|
||||||
|
func ExecLabel() (string, error) {
|
||||||
|
return execLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// CanonicalizeContext takes a context string and writes it to the kernel
|
||||||
|
// the function then returns the context that the kernel will use. Use this
|
||||||
|
// function to check if two contexts are equivalent
|
||||||
|
func CanonicalizeContext(val string) (string, error) {
|
||||||
|
return canonicalizeContext(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ComputeCreateContext requests the type transition from source to target for
|
||||||
|
// class from the kernel.
|
||||||
|
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
||||||
|
return computeCreateContext(source, target, class)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CalculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
|
||||||
|
// of a source and target range.
|
||||||
|
// The glblub is calculated as the greater of the low sensitivities and
|
||||||
|
// the lower of the high sensitivities and the and of each category bitset.
|
||||||
|
func CalculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||||
|
return calculateGlbLub(sourceRange, targetRange)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetExecLabel sets the SELinux label that the kernel will use for any programs
|
||||||
|
// that are executed by the current process thread, or an error.
|
||||||
|
func SetExecLabel(label string) error {
|
||||||
|
return setExecLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTaskLabel sets the SELinux label for the current thread, or an error.
|
||||||
|
// This requires the dyntransition permission.
|
||||||
|
func SetTaskLabel(label string) error {
|
||||||
|
return setTaskLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSocketLabel takes a process label and tells the kernel to assign the
|
||||||
|
// label to the next socket that gets created
|
||||||
|
func SetSocketLabel(label string) error {
|
||||||
|
return setSocketLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SocketLabel retrieves the current socket label setting
|
||||||
|
func SocketLabel() (string, error) {
|
||||||
|
return socketLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// PeerLabel retrieves the label of the client on the other side of a socket
|
||||||
|
func PeerLabel(fd uintptr) (string, error) {
|
||||||
|
return peerLabel(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetKeyLabel takes a process label and tells the kernel to assign the
|
||||||
|
// label to the next kernel keyring that gets created
|
||||||
|
func SetKeyLabel(label string) error {
|
||||||
|
return setKeyLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KeyLabel retrieves the current kernel keyring label setting
|
||||||
|
func KeyLabel() (string, error) {
|
||||||
|
return keyLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get returns the Context as a string
|
||||||
|
func (c Context) Get() string {
|
||||||
|
return c.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContext creates a new Context struct from the specified label
|
||||||
|
func NewContext(label string) (Context, error) {
|
||||||
|
return newContext(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearLabels clears all reserved labels
|
||||||
|
func ClearLabels() {
|
||||||
|
clearLabels()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
||||||
|
func ReserveLabel(label string) {
|
||||||
|
reserveLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||||
|
func EnforceMode() int {
|
||||||
|
return enforceMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||||
|
// Disabled is not valid, since this needs to be set at boot time.
|
||||||
|
func SetEnforceMode(mode int) error {
|
||||||
|
return setEnforceMode(mode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||||
|
// Permissive or Disabled. Note this is is just the default at boot time.
|
||||||
|
// EnforceMode tells you the systems current mode.
|
||||||
|
func DefaultEnforceMode() int {
|
||||||
|
return defaultEnforceMode()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReleaseLabel un-reserves the MLS/MCS Level field of the specified label,
|
||||||
|
// allowing it to be used by another process.
|
||||||
|
func ReleaseLabel(label string) {
|
||||||
|
releaseLabel(label)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROFileLabel returns the specified SELinux readonly file label
|
||||||
|
func ROFileLabel() string {
|
||||||
|
return roFileLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
// KVMContainerLabels returns the default processLabel and mountLabel to be used
|
||||||
|
// for kvm containers by the calling process.
|
||||||
|
func KVMContainerLabels() (string, string) {
|
||||||
|
return kvmContainerLabels()
|
||||||
|
}
|
||||||
|
|
||||||
|
// InitContainerLabels returns the default processLabel and file labels to be
|
||||||
|
// used for containers running an init system like systemd by the calling process.
|
||||||
|
func InitContainerLabels() (string, string) {
|
||||||
|
return initContainerLabels()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
||||||
|
// container labeling by the calling process.
|
||||||
|
func ContainerLabels() (processLabel string, fileLabel string) {
|
||||||
|
return containerLabels()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
||||||
|
func SecurityCheckContext(val string) error {
|
||||||
|
return securityCheckContext(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||||
|
// the dest label.
|
||||||
|
func CopyLevel(src, dest string) (string, error) {
|
||||||
|
return copyLevel(src, dest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chcon changes the fpath file object to the SELinux label label.
|
||||||
|
// If fpath is a directory and recurse is true, then Chcon walks the
|
||||||
|
// directory tree setting the label.
|
||||||
|
func Chcon(fpath string, label string, recurse bool) error {
|
||||||
|
return chcon(fpath, label, recurse)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DupSecOpt takes an SELinux process label and returns security options that
|
||||||
|
// can be used to set the SELinux Type and Level for future container processes.
|
||||||
|
func DupSecOpt(src string) ([]string, error) {
|
||||||
|
return dupSecOpt(src)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
||||||
|
// labeling support for future container processes.
|
||||||
|
func DisableSecOpt() []string {
|
||||||
|
return disableSecOpt()
|
||||||
|
}
|
481
vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
generated
vendored
481
vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
generated
vendored
@ -20,17 +20,12 @@ import (
|
|||||||
|
|
||||||
"github.com/opencontainers/selinux/pkg/pwalk"
|
"github.com/opencontainers/selinux/pkg/pwalk"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
"github.com/willf/bitset"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Enforcing constant indicate SELinux is in enforcing mode
|
minSensLen = 2
|
||||||
Enforcing = 1
|
|
||||||
// Permissive constant to indicate SELinux is in permissive mode
|
|
||||||
Permissive = 0
|
|
||||||
// Disabled constant to indicate SELinux is disabled
|
|
||||||
Disabled = -1
|
|
||||||
|
|
||||||
contextFile = "/usr/share/containers/selinux/contexts"
|
contextFile = "/usr/share/containers/selinux/contexts"
|
||||||
selinuxDir = "/etc/selinux/"
|
selinuxDir = "/etc/selinux/"
|
||||||
selinuxConfig = selinuxDir + "config"
|
selinuxConfig = selinuxDir + "config"
|
||||||
@ -49,17 +44,27 @@ type selinuxState struct {
|
|||||||
sync.Mutex
|
sync.Mutex
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
type level struct {
|
||||||
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
sens uint
|
||||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
cats *bitset.BitSet
|
||||||
// ErrEmptyPath is returned when an empty path has been specified.
|
}
|
||||||
ErrEmptyPath = errors.New("empty path")
|
|
||||||
// InvalidLabel is returned when an invalid label is specified.
|
|
||||||
InvalidLabel = errors.New("Invalid Label")
|
|
||||||
|
|
||||||
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
type mlsRange struct {
|
||||||
roFileLabel string
|
low *level
|
||||||
state = selinuxState{
|
high *level
|
||||||
|
}
|
||||||
|
|
||||||
|
type levelItem byte
|
||||||
|
|
||||||
|
const (
|
||||||
|
sensitivity levelItem = 's'
|
||||||
|
category levelItem = 'c'
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
|
||||||
|
readOnlyFileLabel string
|
||||||
|
state = selinuxState{
|
||||||
mcsList: make(map[string]bool),
|
mcsList: make(map[string]bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,9 +73,6 @@ var (
|
|||||||
haveThreadSelf bool
|
haveThreadSelf bool
|
||||||
)
|
)
|
||||||
|
|
||||||
// Context is a representation of the SELinux label broken into 4 parts
|
|
||||||
type Context map[string]string
|
|
||||||
|
|
||||||
func (s *selinuxState) setEnable(enabled bool) bool {
|
func (s *selinuxState) setEnable(enabled bool) bool {
|
||||||
s.Lock()
|
s.Lock()
|
||||||
defer s.Unlock()
|
defer s.Unlock()
|
||||||
@ -97,8 +99,8 @@ func (s *selinuxState) getEnabled() bool {
|
|||||||
return s.setEnable(enabled)
|
return s.setEnable(enabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDisabled disables selinux support for the package
|
// setDisabled disables SELinux support for the package
|
||||||
func SetDisabled() {
|
func setDisabled() {
|
||||||
state.setEnable(false)
|
state.setEnable(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,15 +192,15 @@ func (s *selinuxState) getSELinuxfs() string {
|
|||||||
|
|
||||||
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
|
||||||
// filesystem or an empty string if no mountpoint is found. Selinuxfs is
|
// filesystem or an empty string if no mountpoint is found. Selinuxfs is
|
||||||
// a proc-like pseudo-filesystem that exposes the selinux policy API to
|
// a proc-like pseudo-filesystem that exposes the SELinux policy API to
|
||||||
// processes. The existence of an selinuxfs mount is used to determine
|
// processes. The existence of an selinuxfs mount is used to determine
|
||||||
// whether selinux is currently enabled or not.
|
// whether SELinux is currently enabled or not.
|
||||||
func getSelinuxMountPoint() string {
|
func getSelinuxMountPoint() string {
|
||||||
return state.getSELinuxfs()
|
return state.getSELinuxfs()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEnabled returns whether selinux is currently enabled.
|
// getEnabled returns whether SELinux is currently enabled.
|
||||||
func GetEnabled() bool {
|
func getEnabled() bool {
|
||||||
return state.getEnabled()
|
return state.getEnabled()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,8 +284,9 @@ func readCon(fpath string) (string, error) {
|
|||||||
return strings.Trim(retval, "\x00"), nil
|
return strings.Trim(retval, "\x00"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
// classIndex returns the int index for an object class in the loaded policy,
|
||||||
func ClassIndex(class string) (int, error) {
|
// or -1 and an error
|
||||||
|
func classIndex(class string) (int, error) {
|
||||||
permpath := fmt.Sprintf("class/%s/index", class)
|
permpath := fmt.Sprintf("class/%s/index", class)
|
||||||
indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
|
indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
|
||||||
|
|
||||||
@ -299,8 +302,8 @@ func ClassIndex(class string) (int, error) {
|
|||||||
return index, nil
|
return index, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
// setFileLabel sets the SELinux label for this path or returns an error.
|
||||||
func SetFileLabel(fpath string, label string) error {
|
func setFileLabel(fpath string, label string) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
}
|
}
|
||||||
@ -310,8 +313,8 @@ func SetFileLabel(fpath string, label string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileLabel returns the SELinux label for this path or returns an error.
|
// fileLabel returns the SELinux label for this path or returns an error.
|
||||||
func FileLabel(fpath string) (string, error) {
|
func fileLabel(fpath string) (string, error) {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return "", ErrEmptyPath
|
return "", ErrEmptyPath
|
||||||
}
|
}
|
||||||
@ -327,37 +330,31 @@ func FileLabel(fpath string) (string, error) {
|
|||||||
return string(label), nil
|
return string(label), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// setFSCreateLabel tells kernel the label to create all file system objects
|
||||||
SetFSCreateLabel tells kernel the label to create all file system objects
|
// created by this task. Setting label="" to return to default.
|
||||||
created by this task. Setting label="" to return to default.
|
func setFSCreateLabel(label string) error {
|
||||||
*/
|
|
||||||
func SetFSCreateLabel(label string) error {
|
|
||||||
return writeAttr("fscreate", label)
|
return writeAttr("fscreate", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// fsCreateLabel returns the default label the kernel which the kernel is using
|
||||||
FSCreateLabel returns the default label the kernel which the kernel is using
|
// for file system objects created by this task. "" indicates default.
|
||||||
for file system objects created by this task. "" indicates default.
|
func fsCreateLabel() (string, error) {
|
||||||
*/
|
|
||||||
func FSCreateLabel() (string, error) {
|
|
||||||
return readAttr("fscreate")
|
return readAttr("fscreate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
// currentLabel returns the SELinux label of the current process thread, or an error.
|
||||||
func CurrentLabel() (string, error) {
|
func currentLabel() (string, error) {
|
||||||
return readAttr("current")
|
return readAttr("current")
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
// pidLabel returns the SELinux label of the given pid, or an error.
|
||||||
func PidLabel(pid int) (string, error) {
|
func pidLabel(pid int) (string, error) {
|
||||||
return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
|
return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// ExecLabel returns the SELinux label that the kernel will use for any programs
|
||||||
ExecLabel returns the SELinux label that the kernel will use for any programs
|
// that are executed by the current process thread, or an error.
|
||||||
that are executed by the current process thread, or an error.
|
func execLabel() (string, error) {
|
||||||
*/
|
|
||||||
func ExecLabel() (string, error) {
|
|
||||||
return readAttr("exec")
|
return readAttr("exec")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,7 +363,7 @@ func writeCon(fpath, val string) error {
|
|||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
}
|
}
|
||||||
if val == "" {
|
if val == "" {
|
||||||
if !GetEnabled() {
|
if !getEnabled() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -418,20 +415,17 @@ func writeAttr(attr, val string) error {
|
|||||||
return writeCon(attrPath(attr), val)
|
return writeCon(attrPath(attr), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// canonicalizeContext takes a context string and writes it to the kernel
|
||||||
CanonicalizeContext takes a context string and writes it to the kernel
|
// the function then returns the context that the kernel will use. Use this
|
||||||
the function then returns the context that the kernel will use. This function
|
// function to check if two contexts are equivalent
|
||||||
can be used to see if two contexts are equivalent
|
func canonicalizeContext(val string) (string, error) {
|
||||||
*/
|
|
||||||
func CanonicalizeContext(val string) (string, error) {
|
|
||||||
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
|
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// computeCreateContext requests the type transition from source to target for
|
||||||
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
// class from the kernel.
|
||||||
*/
|
func computeCreateContext(source string, target string, class string) (string, error) {
|
||||||
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
classidx, err := classIndex(class)
|
||||||
classidx, err := ClassIndex(class)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -439,6 +433,217 @@ func ComputeCreateContext(source string, target string, class string) (string, e
|
|||||||
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
|
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// catsToBitset stores categories in a bitset.
|
||||||
|
func catsToBitset(cats string) (*bitset.BitSet, error) {
|
||||||
|
bitset := &bitset.BitSet{}
|
||||||
|
|
||||||
|
catlist := strings.Split(cats, ",")
|
||||||
|
for _, r := range catlist {
|
||||||
|
ranges := strings.SplitN(r, ".", 2)
|
||||||
|
if len(ranges) > 1 {
|
||||||
|
catstart, err := parseLevelItem(ranges[0], category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
catend, err := parseLevelItem(ranges[1], category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for i := catstart; i <= catend; i++ {
|
||||||
|
bitset.Set(i)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cat, err := parseLevelItem(ranges[0], category)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
bitset.Set(cat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bitset, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseLevelItem parses and verifies that a sensitivity or category are valid
|
||||||
|
func parseLevelItem(s string, sep levelItem) (uint, error) {
|
||||||
|
if len(s) < minSensLen || levelItem(s[0]) != sep {
|
||||||
|
return 0, ErrLevelSyntax
|
||||||
|
}
|
||||||
|
val, err := strconv.ParseUint(s[1:], 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint(val), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// parseLevel fills a level from a string that contains
|
||||||
|
// a sensitivity and categories
|
||||||
|
func (l *level) parseLevel(levelStr string) error {
|
||||||
|
lvl := strings.SplitN(levelStr, ":", 2)
|
||||||
|
sens, err := parseLevelItem(lvl[0], sensitivity)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to parse sensitivity")
|
||||||
|
}
|
||||||
|
l.sens = sens
|
||||||
|
if len(lvl) > 1 {
|
||||||
|
cats, err := catsToBitset(lvl[1])
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to parse categories")
|
||||||
|
}
|
||||||
|
l.cats = cats
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// rangeStrToMLSRange marshals a string representation of a range.
|
||||||
|
func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) {
|
||||||
|
mlsRange := &mlsRange{}
|
||||||
|
levelSlice := strings.SplitN(rangeStr, "-", 2)
|
||||||
|
|
||||||
|
switch len(levelSlice) {
|
||||||
|
// rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023
|
||||||
|
case 2:
|
||||||
|
mlsRange.high = &level{}
|
||||||
|
if err := mlsRange.high.parseLevel(levelSlice[1]); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to parse high level %q", levelSlice[1])
|
||||||
|
}
|
||||||
|
fallthrough
|
||||||
|
// rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023
|
||||||
|
case 1:
|
||||||
|
mlsRange.low = &level{}
|
||||||
|
if err := mlsRange.low.parseLevel(levelSlice[0]); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "failed to parse low level %q", levelSlice[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if mlsRange.high == nil {
|
||||||
|
mlsRange.high = mlsRange.low
|
||||||
|
}
|
||||||
|
|
||||||
|
return mlsRange, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// bitsetToStr takes a category bitset and returns it in the
|
||||||
|
// canonical selinux syntax
|
||||||
|
func bitsetToStr(c *bitset.BitSet) string {
|
||||||
|
var str string
|
||||||
|
i, e := c.NextSet(0)
|
||||||
|
len := 0
|
||||||
|
for e {
|
||||||
|
if len == 0 {
|
||||||
|
if str != "" {
|
||||||
|
str += ","
|
||||||
|
}
|
||||||
|
str += "c" + strconv.Itoa(int(i))
|
||||||
|
}
|
||||||
|
|
||||||
|
next, e := c.NextSet(i + 1)
|
||||||
|
if e {
|
||||||
|
// consecutive cats
|
||||||
|
if next == i+1 {
|
||||||
|
len++
|
||||||
|
i = next
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len == 1 {
|
||||||
|
str += ",c" + strconv.Itoa(int(i))
|
||||||
|
} else if len > 1 {
|
||||||
|
str += ".c" + strconv.Itoa(int(i))
|
||||||
|
}
|
||||||
|
if !e {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
len = 0
|
||||||
|
i = next
|
||||||
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l1 *level) equal(l2 *level) bool {
|
||||||
|
if l2 == nil || l1 == nil {
|
||||||
|
return l1 == l2
|
||||||
|
}
|
||||||
|
if l1.sens != l2.sens {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return l1.cats.Equal(l2.cats)
|
||||||
|
}
|
||||||
|
|
||||||
|
// String returns an mlsRange as a string.
|
||||||
|
func (m mlsRange) String() string {
|
||||||
|
low := "s" + strconv.Itoa(int(m.low.sens))
|
||||||
|
if m.low.cats != nil && m.low.cats.Count() > 0 {
|
||||||
|
low += ":" + bitsetToStr(m.low.cats)
|
||||||
|
}
|
||||||
|
|
||||||
|
if m.low.equal(m.high) {
|
||||||
|
return low
|
||||||
|
}
|
||||||
|
|
||||||
|
high := "s" + strconv.Itoa(int(m.high.sens))
|
||||||
|
if m.high.cats != nil && m.high.cats.Count() > 0 {
|
||||||
|
high += ":" + bitsetToStr(m.high.cats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return low + "-" + high
|
||||||
|
}
|
||||||
|
|
||||||
|
func max(a, b uint) uint {
|
||||||
|
if a > b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
func min(a, b uint) uint {
|
||||||
|
if a < b {
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
|
||||||
|
// of a source and target range.
|
||||||
|
// The glblub is calculated as the greater of the low sensitivities and
|
||||||
|
// the lower of the high sensitivities and the and of each category bitset.
|
||||||
|
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||||
|
s, err := rangeStrToMLSRange(sourceRange)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
t, err := rangeStrToMLSRange(targetRange)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.high.sens < t.low.sens || t.high.sens < s.low.sens {
|
||||||
|
/* these ranges have no common sensitivities */
|
||||||
|
return "", ErrIncomparable
|
||||||
|
}
|
||||||
|
|
||||||
|
outrange := &mlsRange{low: &level{}, high: &level{}}
|
||||||
|
|
||||||
|
/* take the greatest of the low */
|
||||||
|
outrange.low.sens = max(s.low.sens, t.low.sens)
|
||||||
|
|
||||||
|
/* take the least of the high */
|
||||||
|
outrange.high.sens = min(s.high.sens, t.high.sens)
|
||||||
|
|
||||||
|
/* find the intersecting categories */
|
||||||
|
if s.low.cats != nil && t.low.cats != nil {
|
||||||
|
outrange.low.cats = s.low.cats.Intersection(t.low.cats)
|
||||||
|
}
|
||||||
|
if s.high.cats != nil && t.high.cats != nil {
|
||||||
|
outrange.high.cats = s.high.cats.Intersection(t.high.cats)
|
||||||
|
}
|
||||||
|
|
||||||
|
return outrange.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
func readWriteCon(fpath string, val string) (string, error) {
|
func readWriteCon(fpath string, val string) (string, error) {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return "", ErrEmptyPath
|
return "", ErrEmptyPath
|
||||||
@ -461,41 +666,37 @@ func readWriteCon(fpath string, val string) (string, error) {
|
|||||||
return strings.Trim(retval, "\x00"), nil
|
return strings.Trim(retval, "\x00"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// setExecLabel sets the SELinux label that the kernel will use for any programs
|
||||||
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
// that are executed by the current process thread, or an error.
|
||||||
that are executed by the current process thread, or an error.
|
func setExecLabel(label string) error {
|
||||||
*/
|
|
||||||
func SetExecLabel(label string) error {
|
|
||||||
return writeAttr("exec", label)
|
return writeAttr("exec", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// setTaskLabel sets the SELinux label for the current thread, or an error.
|
||||||
SetTaskLabel sets the SELinux label for the current thread, or an error.
|
// This requires the dyntransition permission.
|
||||||
This requires the dyntransition permission.
|
func setTaskLabel(label string) error {
|
||||||
*/
|
|
||||||
func SetTaskLabel(label string) error {
|
|
||||||
return writeAttr("current", label)
|
return writeAttr("current", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSocketLabel takes a process label and tells the kernel to assign the
|
// setSocketLabel takes a process label and tells the kernel to assign the
|
||||||
// label to the next socket that gets created
|
// label to the next socket that gets created
|
||||||
func SetSocketLabel(label string) error {
|
func setSocketLabel(label string) error {
|
||||||
return writeAttr("sockcreate", label)
|
return writeAttr("sockcreate", label)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketLabel retrieves the current socket label setting
|
// socketLabel retrieves the current socket label setting
|
||||||
func SocketLabel() (string, error) {
|
func socketLabel() (string, error) {
|
||||||
return readAttr("sockcreate")
|
return readAttr("sockcreate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
// peerLabel retrieves the label of the client on the other side of a socket
|
||||||
func PeerLabel(fd uintptr) (string, error) {
|
func peerLabel(fd uintptr) (string, error) {
|
||||||
return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
|
return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
// setKeyLabel takes a process label and tells the kernel to assign the
|
||||||
// label to the next kernel keyring that gets created
|
// label to the next kernel keyring that gets created
|
||||||
func SetKeyLabel(label string) error {
|
func setKeyLabel(label string) error {
|
||||||
err := writeCon("/proc/self/attr/keycreate", label)
|
err := writeCon("/proc/self/attr/keycreate", label)
|
||||||
if os.IsNotExist(errors.Cause(err)) {
|
if os.IsNotExist(errors.Cause(err)) {
|
||||||
return nil
|
return nil
|
||||||
@ -506,21 +707,21 @@ func SetKeyLabel(label string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyLabel retrieves the current kernel keyring label setting
|
// keyLabel retrieves the current kernel keyring label setting
|
||||||
func KeyLabel() (string, error) {
|
func keyLabel() (string, error) {
|
||||||
return readCon("/proc/self/attr/keycreate")
|
return readCon("/proc/self/attr/keycreate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the Context as a string
|
// get returns the Context as a string
|
||||||
func (c Context) Get() string {
|
func (c Context) get() string {
|
||||||
if c["level"] != "" {
|
if c["level"] != "" {
|
||||||
return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"])
|
return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"])
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s:%s:%s", c["user"], c["role"], c["type"])
|
return fmt.Sprintf("%s:%s:%s", c["user"], c["role"], c["type"])
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext creates a new Context struct from the specified label
|
// newContext creates a new Context struct from the specified label
|
||||||
func NewContext(label string) (Context, error) {
|
func newContext(label string) (Context, error) {
|
||||||
c := make(Context)
|
c := make(Context)
|
||||||
|
|
||||||
if len(label) != 0 {
|
if len(label) != 0 {
|
||||||
@ -538,15 +739,15 @@ func NewContext(label string) (Context, error) {
|
|||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearLabels clears all reserved labels
|
// clearLabels clears all reserved labels
|
||||||
func ClearLabels() {
|
func clearLabels() {
|
||||||
state.Lock()
|
state.Lock()
|
||||||
state.mcsList = make(map[string]bool)
|
state.mcsList = make(map[string]bool)
|
||||||
state.Unlock()
|
state.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
// reserveLabel reserves the MLS/MCS level component of the specified label
|
||||||
func ReserveLabel(label string) {
|
func reserveLabel(label string) {
|
||||||
if len(label) != 0 {
|
if len(label) != 0 {
|
||||||
con := strings.SplitN(label, ":", 4)
|
con := strings.SplitN(label, ":", 4)
|
||||||
if len(con) > 3 {
|
if len(con) > 3 {
|
||||||
@ -559,8 +760,8 @@ func selinuxEnforcePath() string {
|
|||||||
return path.Join(getSelinuxMountPoint(), "enforce")
|
return path.Join(getSelinuxMountPoint(), "enforce")
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
// enforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
||||||
func EnforceMode() int {
|
func enforceMode() int {
|
||||||
var enforce int
|
var enforce int
|
||||||
|
|
||||||
enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
|
enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
|
||||||
@ -574,20 +775,16 @@ func EnforceMode() int {
|
|||||||
return enforce
|
return enforce
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// setEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
||||||
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
// Disabled is not valid, since this needs to be set at boot time.
|
||||||
Disabled is not valid, since this needs to be set at boot time.
|
func setEnforceMode(mode int) error {
|
||||||
*/
|
|
||||||
func SetEnforceMode(mode int) error {
|
|
||||||
return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
|
return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// defaultEnforceMode returns the systems default SELinux mode Enforcing,
|
||||||
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
// Permissive or Disabled. Note this is is just the default at boot time.
|
||||||
Permissive or Disabled. Note this is is just the default at boot time.
|
// EnforceMode tells you the systems current mode.
|
||||||
EnforceMode tells you the systems current mode.
|
func defaultEnforceMode() int {
|
||||||
*/
|
|
||||||
func DefaultEnforceMode() int {
|
|
||||||
switch readConfig(selinuxTag) {
|
switch readConfig(selinuxTag) {
|
||||||
case "enforcing":
|
case "enforcing":
|
||||||
return Enforcing
|
return Enforcing
|
||||||
@ -667,11 +864,9 @@ func uniqMcs(catRange uint32) string {
|
|||||||
return mcs
|
return mcs
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// releaseLabel un-reserves the MLS/MCS Level field of the specified label,
|
||||||
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
|
// allowing it to be used by another process.
|
||||||
Allowing it to be used by another process.
|
func releaseLabel(label string) {
|
||||||
*/
|
|
||||||
func ReleaseLabel(label string) {
|
|
||||||
if len(label) != 0 {
|
if len(label) != 0 {
|
||||||
con := strings.SplitN(label, ":", 4)
|
con := strings.SplitN(label, ":", 4)
|
||||||
if len(con) > 3 {
|
if len(con) > 3 {
|
||||||
@ -680,9 +875,9 @@ func ReleaseLabel(label string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROFileLabel returns the specified SELinux readonly file label
|
// roFileLabel returns the specified SELinux readonly file label
|
||||||
func ROFileLabel() string {
|
func roFileLabel() string {
|
||||||
return roFileLabel
|
return readOnlyFileLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
func openContextFile() (*os.File, error) {
|
func openContextFile() (*os.File, error) {
|
||||||
@ -737,11 +932,9 @@ func loadLabels() map[string]string {
|
|||||||
return labels
|
return labels
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// kvmContainerLabels returns the default processLabel and mountLabel to be used
|
||||||
KVMContainerLabels returns the default processLabel and mountLabel to be used
|
// for kvm containers by the calling process.
|
||||||
for kvm containers by the calling process.
|
func kvmContainerLabels() (string, string) {
|
||||||
*/
|
|
||||||
func KVMContainerLabels() (string, string) {
|
|
||||||
processLabel := labels["kvm_process"]
|
processLabel := labels["kvm_process"]
|
||||||
if processLabel == "" {
|
if processLabel == "" {
|
||||||
processLabel = labels["process"]
|
processLabel = labels["process"]
|
||||||
@ -750,11 +943,9 @@ func KVMContainerLabels() (string, string) {
|
|||||||
return addMcs(processLabel, labels["file"])
|
return addMcs(processLabel, labels["file"])
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// initContainerLabels returns the default processLabel and file labels to be
|
||||||
InitContainerLabels returns the default processLabel and file labels to be
|
// used for containers running an init system like systemd by the calling process.
|
||||||
used for containers running an init system like systemd by the calling process.
|
func initContainerLabels() (string, string) {
|
||||||
*/
|
|
||||||
func InitContainerLabels() (string, string) {
|
|
||||||
processLabel := labels["init_process"]
|
processLabel := labels["init_process"]
|
||||||
if processLabel == "" {
|
if processLabel == "" {
|
||||||
processLabel = labels["process"]
|
processLabel = labels["process"]
|
||||||
@ -763,25 +954,23 @@ func InitContainerLabels() (string, string) {
|
|||||||
return addMcs(processLabel, labels["file"])
|
return addMcs(processLabel, labels["file"])
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// containerLabels returns an allocated processLabel and fileLabel to be used for
|
||||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
// container labeling by the calling process.
|
||||||
container labeling by the calling process.
|
func containerLabels() (processLabel string, fileLabel string) {
|
||||||
*/
|
if !getEnabled() {
|
||||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
|
||||||
if !GetEnabled() {
|
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
processLabel = labels["process"]
|
processLabel = labels["process"]
|
||||||
fileLabel = labels["file"]
|
fileLabel = labels["file"]
|
||||||
roFileLabel = labels["ro_file"]
|
readOnlyFileLabel = labels["ro_file"]
|
||||||
|
|
||||||
if processLabel == "" || fileLabel == "" {
|
if processLabel == "" || fileLabel == "" {
|
||||||
return "", fileLabel
|
return "", fileLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
if roFileLabel == "" {
|
if readOnlyFileLabel == "" {
|
||||||
roFileLabel = fileLabel
|
readOnlyFileLabel = fileLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
return addMcs(processLabel, fileLabel)
|
return addMcs(processLabel, fileLabel)
|
||||||
@ -790,7 +979,7 @@ func ContainerLabels() (processLabel string, fileLabel string) {
|
|||||||
func addMcs(processLabel, fileLabel string) (string, string) {
|
func addMcs(processLabel, fileLabel string) (string, string) {
|
||||||
scon, _ := NewContext(processLabel)
|
scon, _ := NewContext(processLabel)
|
||||||
if scon["level"] != "" {
|
if scon["level"] != "" {
|
||||||
mcs := uniqMcs(1024)
|
mcs := uniqMcs(CategoryRange)
|
||||||
scon["level"] = mcs
|
scon["level"] = mcs
|
||||||
processLabel = scon.Get()
|
processLabel = scon.Get()
|
||||||
scon, _ = NewContext(fileLabel)
|
scon, _ = NewContext(fileLabel)
|
||||||
@ -800,16 +989,14 @@ func addMcs(processLabel, fileLabel string) (string, string) {
|
|||||||
return processLabel, fileLabel
|
return processLabel, fileLabel
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
// securityCheckContext validates that the SELinux label is understood by the kernel
|
||||||
func SecurityCheckContext(val string) error {
|
func securityCheckContext(val string) error {
|
||||||
return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
|
return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// copyLevel returns a label with the MLS/MCS level from src label replaced on
|
||||||
CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
// the dest label.
|
||||||
the dest label.
|
func copyLevel(src, dest string) (string, error) {
|
||||||
*/
|
|
||||||
func CopyLevel(src, dest string) (string, error) {
|
|
||||||
if src == "" {
|
if src == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
@ -833,7 +1020,7 @@ func CopyLevel(src, dest string) (string, error) {
|
|||||||
return tcon.Get(), nil
|
return tcon.Get(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent users from relabing system files
|
// Prevent users from relabeling system files
|
||||||
func badPrefix(fpath string) error {
|
func badPrefix(fpath string) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
@ -848,10 +1035,10 @@ func badPrefix(fpath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chcon changes the fpath file object to the SELinux label label.
|
// chcon changes the fpath file object to the SELinux label label.
|
||||||
// If fpath is a directory and recurse is true, Chcon will walk the
|
// If fpath is a directory and recurse is true, then chcon walks the
|
||||||
// directory tree setting the label.
|
// directory tree setting the label.
|
||||||
func Chcon(fpath string, label string, recurse bool) error {
|
func chcon(fpath string, label string, recurse bool) error {
|
||||||
if fpath == "" {
|
if fpath == "" {
|
||||||
return ErrEmptyPath
|
return ErrEmptyPath
|
||||||
}
|
}
|
||||||
@ -876,9 +1063,9 @@ func Chcon(fpath string, label string, recurse bool) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// DupSecOpt takes an SELinux process label and returns security options that
|
// dupSecOpt takes an SELinux process label and returns security options that
|
||||||
// can be used to set the SELinux Type and Level for future container processes.
|
// can be used to set the SELinux Type and Level for future container processes.
|
||||||
func DupSecOpt(src string) ([]string, error) {
|
func dupSecOpt(src string) ([]string, error) {
|
||||||
if src == "" {
|
if src == "" {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@ -903,8 +1090,8 @@ func DupSecOpt(src string) ([]string, error) {
|
|||||||
return dup, nil
|
return dup, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
// disableSecOpt returns a security opt that can be used to disable SELinux
|
||||||
// labeling support for future container processes.
|
// labeling support for future container processes.
|
||||||
func DisableSecOpt() []string {
|
func disableSecOpt() []string {
|
||||||
return []string{"disable"}
|
return []string{"disable"}
|
||||||
}
|
}
|
||||||
|
186
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
186
vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
generated
vendored
@ -2,253 +2,147 @@
|
|||||||
|
|
||||||
package selinux
|
package selinux
|
||||||
|
|
||||||
import (
|
func setDisabled() {
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
// Enforcing constant indicate SELinux is in enforcing mode
|
|
||||||
Enforcing = 1
|
|
||||||
// Permissive constant to indicate SELinux is in permissive mode
|
|
||||||
Permissive = 0
|
|
||||||
// Disabled constant to indicate SELinux is disabled
|
|
||||||
Disabled = -1
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
|
|
||||||
ErrMCSAlreadyExists = errors.New("MCS label already exists")
|
|
||||||
// ErrEmptyPath is returned when an empty path has been specified.
|
|
||||||
ErrEmptyPath = errors.New("empty path")
|
|
||||||
)
|
|
||||||
|
|
||||||
// Context is a representation of the SELinux label broken into 4 parts
|
|
||||||
type Context map[string]string
|
|
||||||
|
|
||||||
// SetDisabled disables selinux support for the package
|
|
||||||
func SetDisabled() {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEnabled returns whether selinux is currently enabled.
|
func getEnabled() bool {
|
||||||
func GetEnabled() bool {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
|
func classIndex(class string) (int, error) {
|
||||||
func ClassIndex(class string) (int, error) {
|
|
||||||
return -1, nil
|
return -1, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetFileLabel sets the SELinux label for this path or returns an error.
|
func setFileLabel(fpath string, label string) error {
|
||||||
func SetFileLabel(fpath string, label string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileLabel returns the SELinux label for this path or returns an error.
|
func fileLabel(fpath string) (string, error) {
|
||||||
func FileLabel(fpath string) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func setFSCreateLabel(label string) error {
|
||||||
SetFSCreateLabel tells kernel the label to create all file system objects
|
|
||||||
created by this task. Setting label="" to return to default.
|
|
||||||
*/
|
|
||||||
func SetFSCreateLabel(label string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func fsCreateLabel() (string, error) {
|
||||||
FSCreateLabel returns the default label the kernel which the kernel is using
|
|
||||||
for file system objects created by this task. "" indicates default.
|
|
||||||
*/
|
|
||||||
func FSCreateLabel() (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CurrentLabel returns the SELinux label of the current process thread, or an error.
|
func currentLabel() (string, error) {
|
||||||
func CurrentLabel() (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PidLabel returns the SELinux label of the given pid, or an error.
|
func pidLabel(pid int) (string, error) {
|
||||||
func PidLabel(pid int) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func execLabel() (string, error) {
|
||||||
ExecLabel returns the SELinux label that the kernel will use for any programs
|
|
||||||
that are executed by the current process thread, or an error.
|
|
||||||
*/
|
|
||||||
func ExecLabel() (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func canonicalizeContext(val string) (string, error) {
|
||||||
CanonicalizeContext takes a context string and writes it to the kernel
|
|
||||||
the function then returns the context that the kernel will use. This function
|
|
||||||
can be used to see if two contexts are equivalent
|
|
||||||
*/
|
|
||||||
func CanonicalizeContext(val string) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func computeCreateContext(source string, target string, class string) (string, error) {
|
||||||
ComputeCreateContext requests the type transition from source to target for class from the kernel.
|
|
||||||
*/
|
|
||||||
func ComputeCreateContext(source string, target string, class string) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
|
||||||
SetExecLabel sets the SELinux label that the kernel will use for any programs
|
return "", nil
|
||||||
that are executed by the current process thread, or an error.
|
}
|
||||||
*/
|
|
||||||
func SetExecLabel(label string) error {
|
func setExecLabel(label string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func setTaskLabel(label string) error {
|
||||||
SetTaskLabel sets the SELinux label for the current thread, or an error.
|
|
||||||
This requires the dyntransition permission.
|
|
||||||
*/
|
|
||||||
func SetTaskLabel(label string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func setSocketLabel(label string) error {
|
||||||
SetSocketLabel sets the SELinux label that the kernel will use for any programs
|
|
||||||
that are executed by the current process thread, or an error.
|
|
||||||
*/
|
|
||||||
func SetSocketLabel(label string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SocketLabel retrieves the current socket label setting
|
func socketLabel() (string, error) {
|
||||||
func SocketLabel() (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerLabel retrieves the label of the client on the other side of a socket
|
func peerLabel(fd uintptr) (string, error) {
|
||||||
func PeerLabel(fd uintptr) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetKeyLabel takes a process label and tells the kernel to assign the
|
func setKeyLabel(label string) error {
|
||||||
// label to the next kernel keyring that gets created
|
|
||||||
func SetKeyLabel(label string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KeyLabel retrieves the current kernel keyring label setting
|
func keyLabel() (string, error) {
|
||||||
func KeyLabel() (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the Context as a string
|
func (c Context) get() string {
|
||||||
func (c Context) Get() string {
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewContext creates a new Context struct from the specified label
|
func newContext(label string) (Context, error) {
|
||||||
func NewContext(label string) (Context, error) {
|
|
||||||
c := make(Context)
|
c := make(Context)
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClearLabels clears all reserved MLS/MCS levels
|
func clearLabels() {
|
||||||
func ClearLabels() {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReserveLabel reserves the MLS/MCS level component of the specified label
|
func reserveLabel(label string) {
|
||||||
func ReserveLabel(label string) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
|
func enforceMode() int {
|
||||||
func EnforceMode() int {
|
|
||||||
return Disabled
|
return Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func setEnforceMode(mode int) error {
|
||||||
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
|
|
||||||
Disabled is not valid, since this needs to be set at boot time.
|
|
||||||
*/
|
|
||||||
func SetEnforceMode(mode int) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func defaultEnforceMode() int {
|
||||||
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
|
|
||||||
Permissive or Disabled. Note this is is just the default at boot time.
|
|
||||||
EnforceMode tells you the systems current mode.
|
|
||||||
*/
|
|
||||||
func DefaultEnforceMode() int {
|
|
||||||
return Disabled
|
return Disabled
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func releaseLabel(label string) {
|
||||||
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
|
|
||||||
Allowing it to be used by another process.
|
|
||||||
*/
|
|
||||||
func ReleaseLabel(label string) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ROFileLabel returns the specified SELinux readonly file label
|
func roFileLabel() string {
|
||||||
func ROFileLabel() string {
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// KVMContainerLabels returns the default processLabel and mountLabel to be used
|
func kvmContainerLabels() (string, string) {
|
||||||
// for kvm containers by the calling process.
|
|
||||||
func KVMContainerLabels() (string, string) {
|
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// InitContainerLabels returns the default processLabel and file labels to be
|
func initContainerLabels() (string, string) {
|
||||||
// used for containers running an init system like systemd by the calling
|
|
||||||
func InitContainerLabels() (string, string) {
|
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func containerLabels() (processLabel string, fileLabel string) {
|
||||||
ContainerLabels returns an allocated processLabel and fileLabel to be used for
|
|
||||||
container labeling by the calling process.
|
|
||||||
*/
|
|
||||||
func ContainerLabels() (processLabel string, fileLabel string) {
|
|
||||||
return "", ""
|
return "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// SecurityCheckContext validates that the SELinux label is understood by the kernel
|
func securityCheckContext(val string) error {
|
||||||
func SecurityCheckContext(val string) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func copyLevel(src, dest string) (string, error) {
|
||||||
CopyLevel returns a label with the MLS/MCS level from src label replaced on
|
|
||||||
the dest label.
|
|
||||||
*/
|
|
||||||
func CopyLevel(src, dest string) (string, error) {
|
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Chcon changes the `fpath` file object to the SELinux label `label`.
|
func chcon(fpath string, label string, recurse bool) error {
|
||||||
// If `fpath` is a directory and `recurse`` is true, Chcon will walk the
|
|
||||||
// directory tree setting the label.
|
|
||||||
func Chcon(fpath string, label string, recurse bool) error {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DupSecOpt takes an SELinux process label and returns security options that
|
func dupSecOpt(src string) ([]string, error) {
|
||||||
// can be used to set the SELinux Type and Level for future container processes.
|
|
||||||
func DupSecOpt(src string) ([]string, error) {
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DisableSecOpt returns a security opt that can be used to disable SELinux
|
func disableSecOpt() []string {
|
||||||
// labeling support for future container processes.
|
|
||||||
func DisableSecOpt() []string {
|
|
||||||
return []string{"disable"}
|
return []string{"disable"}
|
||||||
}
|
}
|
||||||
|
8
vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
generated
vendored
8
vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
generated
vendored
@ -48,7 +48,11 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
|
|||||||
errCh := make(chan error, 1) // get the first error, ignore others
|
errCh := make(chan error, 1) // get the first error, ignore others
|
||||||
|
|
||||||
// Start walking a tree asap
|
// Start walking a tree asap
|
||||||
var err error
|
var (
|
||||||
|
err error
|
||||||
|
wg sync.WaitGroup
|
||||||
|
)
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
|
err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -68,9 +72,9 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
close(files)
|
close(files)
|
||||||
}
|
}
|
||||||
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
|
||||||
wg.Add(num)
|
wg.Add(num)
|
||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
go func() {
|
go func() {
|
||||||
|
26
vendor/github.com/willf/bitset/.gitignore
generated
vendored
Normal file
26
vendor/github.com/willf/bitset/.gitignore
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||||
|
*.o
|
||||||
|
*.a
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Folders
|
||||||
|
_obj
|
||||||
|
_test
|
||||||
|
|
||||||
|
# Architecture specific extensions/prefixes
|
||||||
|
*.[568vq]
|
||||||
|
[568vq].out
|
||||||
|
|
||||||
|
*.cgo1.go
|
||||||
|
*.cgo2.c
|
||||||
|
_cgo_defun.c
|
||||||
|
_cgo_gotypes.go
|
||||||
|
_cgo_export.*
|
||||||
|
|
||||||
|
_testmain.go
|
||||||
|
|
||||||
|
*.exe
|
||||||
|
*.test
|
||||||
|
*.prof
|
||||||
|
|
||||||
|
target
|
37
vendor/github.com/willf/bitset/.travis.yml
generated
vendored
Normal file
37
vendor/github.com/willf/bitset/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
language: go
|
||||||
|
|
||||||
|
sudo: false
|
||||||
|
|
||||||
|
branches:
|
||||||
|
except:
|
||||||
|
- release
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- travis
|
||||||
|
|
||||||
|
go:
|
||||||
|
- "1.11.x"
|
||||||
|
- tip
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
allow_failures:
|
||||||
|
- go: tip
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi;
|
||||||
|
- if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi;
|
||||||
|
- go get github.com/mattn/goveralls
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- make deps
|
||||||
|
|
||||||
|
script:
|
||||||
|
- make qa
|
||||||
|
|
||||||
|
after_failure:
|
||||||
|
- cat ./target/test/report.xml
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- if [ "$TRAVIS_GO_VERSION" = "1.11.1" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi;
|
27
vendor/github.com/willf/bitset/LICENSE
generated
vendored
Normal file
27
vendor/github.com/willf/bitset/LICENSE
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Copyright (c) 2014 Will Fitzgerald. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following disclaimer
|
||||||
|
in the documentation and/or other materials provided with the
|
||||||
|
distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
191
vendor/github.com/willf/bitset/Makefile
generated
vendored
Normal file
191
vendor/github.com/willf/bitset/Makefile
generated
vendored
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
# MAKEFILE
|
||||||
|
#
|
||||||
|
# @author Nicola Asuni <info@tecnick.com>
|
||||||
|
# @link https://github.com/willf/bitset
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# List special make targets that are not associated with files
|
||||||
|
.PHONY: help all test format fmtcheck vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan qa deps clean nuke
|
||||||
|
|
||||||
|
# Use bash as shell (Note: Ubuntu now uses dash which doesn't support PIPESTATUS).
|
||||||
|
SHELL=/bin/bash
|
||||||
|
|
||||||
|
# CVS path (path to the parent dir containing the project)
|
||||||
|
CVSPATH=github.com/willf
|
||||||
|
|
||||||
|
# Project owner
|
||||||
|
OWNER=willf
|
||||||
|
|
||||||
|
# Project vendor
|
||||||
|
VENDOR=willf
|
||||||
|
|
||||||
|
# Project name
|
||||||
|
PROJECT=bitset
|
||||||
|
|
||||||
|
# Project version
|
||||||
|
VERSION=$(shell cat VERSION)
|
||||||
|
|
||||||
|
# Name of RPM or DEB package
|
||||||
|
PKGNAME=${VENDOR}-${PROJECT}
|
||||||
|
|
||||||
|
# Current directory
|
||||||
|
CURRENTDIR=$(shell pwd)
|
||||||
|
|
||||||
|
# GO lang path
|
||||||
|
ifneq ($(GOPATH),)
|
||||||
|
ifeq ($(findstring $(GOPATH),$(CURRENTDIR)),)
|
||||||
|
# the defined GOPATH is not valid
|
||||||
|
GOPATH=
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
ifeq ($(GOPATH),)
|
||||||
|
# extract the GOPATH
|
||||||
|
GOPATH=$(firstword $(subst /src/, ,$(CURRENTDIR)))
|
||||||
|
endif
|
||||||
|
|
||||||
|
# --- MAKE TARGETS ---
|
||||||
|
|
||||||
|
# Display general help about this command
|
||||||
|
help:
|
||||||
|
@echo ""
|
||||||
|
@echo "$(PROJECT) Makefile."
|
||||||
|
@echo "GOPATH=$(GOPATH)"
|
||||||
|
@echo "The following commands are available:"
|
||||||
|
@echo ""
|
||||||
|
@echo " make qa : Run all the tests"
|
||||||
|
@echo " make test : Run the unit tests"
|
||||||
|
@echo ""
|
||||||
|
@echo " make format : Format the source code"
|
||||||
|
@echo " make fmtcheck : Check if the source code has been formatted"
|
||||||
|
@echo " make vet : Check for suspicious constructs"
|
||||||
|
@echo " make lint : Check for style errors"
|
||||||
|
@echo " make coverage : Generate the coverage report"
|
||||||
|
@echo " make cyclo : Generate the cyclomatic complexity report"
|
||||||
|
@echo " make ineffassign : Detect ineffectual assignments"
|
||||||
|
@echo " make misspell : Detect commonly misspelled words in source files"
|
||||||
|
@echo " make structcheck : Find unused struct fields"
|
||||||
|
@echo " make varcheck : Find unused global variables and constants"
|
||||||
|
@echo " make errcheck : Check that error return values are used"
|
||||||
|
@echo " make gosimple : Suggest code simplifications"
|
||||||
|
@echo " make astscan : GO AST scanner"
|
||||||
|
@echo ""
|
||||||
|
@echo " make docs : Generate source code documentation"
|
||||||
|
@echo ""
|
||||||
|
@echo " make deps : Get the dependencies"
|
||||||
|
@echo " make clean : Remove any build artifact"
|
||||||
|
@echo " make nuke : Deletes any intermediate file"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
# Alias for help target
|
||||||
|
all: help
|
||||||
|
|
||||||
|
# Run the unit tests
|
||||||
|
test:
|
||||||
|
@mkdir -p target/test
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) \
|
||||||
|
go test \
|
||||||
|
-covermode=atomic \
|
||||||
|
-bench=. \
|
||||||
|
-race \
|
||||||
|
-cpuprofile=target/report/cpu.out \
|
||||||
|
-memprofile=target/report/mem.out \
|
||||||
|
-mutexprofile=target/report/mutex.out \
|
||||||
|
-coverprofile=target/report/coverage.out \
|
||||||
|
-v ./... | \
|
||||||
|
tee >(PATH=$(GOPATH)/bin:$(PATH) go-junit-report > target/test/report.xml); \
|
||||||
|
test $${PIPESTATUS[0]} -eq 0
|
||||||
|
|
||||||
|
# Format the source code
|
||||||
|
format:
|
||||||
|
@find . -type f -name "*.go" -exec gofmt -s -w {} \;
|
||||||
|
|
||||||
|
# Check if the source code has been formatted
|
||||||
|
fmtcheck:
|
||||||
|
@mkdir -p target
|
||||||
|
@find . -type f -name "*.go" -exec gofmt -s -d {} \; | tee target/format.diff
|
||||||
|
@test ! -s target/format.diff || { echo "ERROR: the source code has not been formatted - please use 'make format' or 'gofmt'"; exit 1; }
|
||||||
|
|
||||||
|
# Check for syntax errors
|
||||||
|
vet:
|
||||||
|
GOPATH=$(GOPATH) go vet .
|
||||||
|
|
||||||
|
# Check for style errors
|
||||||
|
lint:
|
||||||
|
GOPATH=$(GOPATH) PATH=$(GOPATH)/bin:$(PATH) golint .
|
||||||
|
|
||||||
|
# Generate the coverage report
|
||||||
|
coverage:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) \
|
||||||
|
go tool cover -html=target/report/coverage.out -o target/report/coverage.html
|
||||||
|
|
||||||
|
# Report cyclomatic complexity
|
||||||
|
cyclo:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) gocyclo -avg ./ | tee target/report/cyclo.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||||
|
|
||||||
|
# Detect ineffectual assignments
|
||||||
|
ineffassign:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) ineffassign ./ | tee target/report/ineffassign.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||||
|
|
||||||
|
# Detect commonly misspelled words in source files
|
||||||
|
misspell:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) misspell -error ./ | tee target/report/misspell.txt ; test $${PIPESTATUS[0]} -eq 0
|
||||||
|
|
||||||
|
# Find unused struct fields
|
||||||
|
structcheck:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) structcheck -a ./ | tee target/report/structcheck.txt
|
||||||
|
|
||||||
|
# Find unused global variables and constants
|
||||||
|
varcheck:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) varcheck -e ./ | tee target/report/varcheck.txt
|
||||||
|
|
||||||
|
# Check that error return values are used
|
||||||
|
errcheck:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) errcheck ./ | tee target/report/errcheck.txt
|
||||||
|
|
||||||
|
# AST scanner
|
||||||
|
astscan:
|
||||||
|
@mkdir -p target/report
|
||||||
|
GOPATH=$(GOPATH) gosec . | tee target/report/astscan.txt ; test $${PIPESTATUS[0]} -eq 0 || true
|
||||||
|
|
||||||
|
# Generate source docs
|
||||||
|
docs:
|
||||||
|
@mkdir -p target/docs
|
||||||
|
nohup sh -c 'GOPATH=$(GOPATH) godoc -http=127.0.0.1:6060' > target/godoc_server.log 2>&1 &
|
||||||
|
wget --directory-prefix=target/docs/ --execute robots=off --retry-connrefused --recursive --no-parent --adjust-extension --page-requisites --convert-links http://127.0.0.1:6060/pkg/github.com/${VENDOR}/${PROJECT}/ ; kill -9 `lsof -ti :6060`
|
||||||
|
@echo '<html><head><meta http-equiv="refresh" content="0;./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html"/></head><a href="./127.0.0.1:6060/pkg/'${CVSPATH}'/'${PROJECT}'/index.html">'${PKGNAME}' Documentation ...</a></html>' > target/docs/index.html
|
||||||
|
|
||||||
|
# Alias to run all quality-assurance checks
|
||||||
|
qa: fmtcheck test vet lint coverage cyclo ineffassign misspell structcheck varcheck errcheck gosimple astscan
|
||||||
|
|
||||||
|
# --- INSTALL ---
|
||||||
|
|
||||||
|
# Get the dependencies
|
||||||
|
deps:
|
||||||
|
GOPATH=$(GOPATH) go get ./...
|
||||||
|
GOPATH=$(GOPATH) go get golang.org/x/lint/golint
|
||||||
|
GOPATH=$(GOPATH) go get github.com/jstemmer/go-junit-report
|
||||||
|
GOPATH=$(GOPATH) go get github.com/axw/gocov/gocov
|
||||||
|
GOPATH=$(GOPATH) go get github.com/fzipp/gocyclo
|
||||||
|
GOPATH=$(GOPATH) go get github.com/gordonklaus/ineffassign
|
||||||
|
GOPATH=$(GOPATH) go get github.com/client9/misspell/cmd/misspell
|
||||||
|
GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/structcheck
|
||||||
|
GOPATH=$(GOPATH) go get github.com/opennota/check/cmd/varcheck
|
||||||
|
GOPATH=$(GOPATH) go get github.com/kisielk/errcheck
|
||||||
|
GOPATH=$(GOPATH) go get github.com/securego/gosec/cmd/gosec/...
|
||||||
|
|
||||||
|
# Remove any build artifact
|
||||||
|
clean:
|
||||||
|
GOPATH=$(GOPATH) go clean ./...
|
||||||
|
|
||||||
|
# Deletes any intermediate file
|
||||||
|
nuke:
|
||||||
|
rm -rf ./target
|
||||||
|
GOPATH=$(GOPATH) go clean -i ./...
|
96
vendor/github.com/willf/bitset/README.md
generated
vendored
Normal file
96
vendor/github.com/willf/bitset/README.md
generated
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
# bitset
|
||||||
|
|
||||||
|
*Go language library to map between non-negative integers and boolean values*
|
||||||
|
|
||||||
|
[](https://travis-ci.org/willf/bitset?branch=master)
|
||||||
|
[](https://coveralls.io/github/willf/bitset?branch=master)
|
||||||
|
[](https://goreportcard.com/report/github.com/willf/bitset)
|
||||||
|
[](http://godoc.org/github.com/willf/bitset)
|
||||||
|
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
Package bitset implements bitsets, a mapping between non-negative integers and boolean values.
|
||||||
|
It should be more efficient than map[uint] bool.
|
||||||
|
|
||||||
|
It provides methods for setting, clearing, flipping, and testing individual integers.
|
||||||
|
|
||||||
|
But it also provides set intersection, union, difference, complement, and symmetric operations, as well as tests to check whether any, all, or no bits are set, and querying a bitset's current length and number of positive bits.
|
||||||
|
|
||||||
|
BitSets are expanded to the size of the largest set bit; the memory allocation is approximately Max bits, where Max is the largest set bit. BitSets are never shrunk. On creation, a hint can be given for the number of bits that will be used.
|
||||||
|
|
||||||
|
Many of the methods, including Set, Clear, and Flip, return a BitSet pointer, which allows for chaining.
|
||||||
|
|
||||||
|
### Example use:
|
||||||
|
|
||||||
|
```go
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"github.com/willf/bitset"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Printf("Hello from BitSet!\n")
|
||||||
|
var b bitset.BitSet
|
||||||
|
// play some Go Fish
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
card1 := uint(rand.Intn(52))
|
||||||
|
card2 := uint(rand.Intn(52))
|
||||||
|
b.Set(card1)
|
||||||
|
if b.Test(card2) {
|
||||||
|
fmt.Println("Go Fish!")
|
||||||
|
}
|
||||||
|
b.Clear(card1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chaining
|
||||||
|
b.Set(10).Set(11)
|
||||||
|
|
||||||
|
for i, e := b.NextSet(0); e; i, e = b.NextSet(i + 1) {
|
||||||
|
fmt.Println("The following bit is set:", i)
|
||||||
|
}
|
||||||
|
if b.Intersection(bitset.New(100).Set(10)).Count() == 1 {
|
||||||
|
fmt.Println("Intersection works.")
|
||||||
|
} else {
|
||||||
|
fmt.Println("Intersection doesn't work???")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
As an alternative to BitSets, one should check out the 'big' package, which provides a (less set-theoretical) view of bitsets.
|
||||||
|
|
||||||
|
Godoc documentation is at: https://godoc.org/github.com/willf/bitset
|
||||||
|
|
||||||
|
|
||||||
|
## Implementation Note
|
||||||
|
|
||||||
|
Go 1.9 introduced a native `math/bits` library. We provide backward compatibility to Go 1.7, which might be removed.
|
||||||
|
|
||||||
|
It is possible that a later version will match the `math/bits` return signature for counts (which is `int`, rather than our library's `unit64`). If so, the version will be bumped.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go get github.com/willf/bitset
|
||||||
|
```
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you wish to contribute to this project, please branch and issue a pull request against master ("[GitHub Flow](https://guides.github.com/introduction/flow/)")
|
||||||
|
|
||||||
|
This project include a Makefile that allows you to test and build the project with simple commands.
|
||||||
|
To see all available options:
|
||||||
|
```bash
|
||||||
|
make help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running all tests
|
||||||
|
|
||||||
|
Before committing the code, please check if it passes all tests using (note: this will install some dependencies):
|
||||||
|
```bash
|
||||||
|
make qa
|
||||||
|
```
|
39
vendor/github.com/willf/bitset/azure-pipelines.yml
generated
vendored
Normal file
39
vendor/github.com/willf/bitset/azure-pipelines.yml
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Go
|
||||||
|
# Build your Go project.
|
||||||
|
# Add steps that test, save build artifacts, deploy, and more:
|
||||||
|
# https://docs.microsoft.com/azure/devops/pipelines/languages/go
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: 'Ubuntu-16.04'
|
||||||
|
|
||||||
|
variables:
|
||||||
|
GOBIN: '$(GOPATH)/bin' # Go binaries path
|
||||||
|
GOROOT: '/usr/local/go1.11' # Go installation path
|
||||||
|
GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path
|
||||||
|
modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- script: |
|
||||||
|
mkdir -p '$(GOBIN)'
|
||||||
|
mkdir -p '$(GOPATH)/pkg'
|
||||||
|
mkdir -p '$(modulePath)'
|
||||||
|
shopt -s extglob
|
||||||
|
shopt -s dotglob
|
||||||
|
mv !(gopath) '$(modulePath)'
|
||||||
|
echo '##vso[task.prependpath]$(GOBIN)'
|
||||||
|
echo '##vso[task.prependpath]$(GOROOT)/bin'
|
||||||
|
displayName: 'Set up the Go workspace'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
go version
|
||||||
|
go get -v -t -d ./...
|
||||||
|
if [ -f Gopkg.toml ]; then
|
||||||
|
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
|
||||||
|
dep ensure
|
||||||
|
fi
|
||||||
|
go build -v .
|
||||||
|
workingDirectory: '$(modulePath)'
|
||||||
|
displayName: 'Get dependencies, then build'
|
879
vendor/github.com/willf/bitset/bitset.go
generated
vendored
Normal file
879
vendor/github.com/willf/bitset/bitset.go
generated
vendored
Normal file
@ -0,0 +1,879 @@
|
|||||||
|
/*
|
||||||
|
Package bitset implements bitsets, a mapping
|
||||||
|
between non-negative integers and boolean values. It should be more
|
||||||
|
efficient than map[uint] bool.
|
||||||
|
|
||||||
|
It provides methods for setting, clearing, flipping, and testing
|
||||||
|
individual integers.
|
||||||
|
|
||||||
|
But it also provides set intersection, union, difference,
|
||||||
|
complement, and symmetric operations, as well as tests to
|
||||||
|
check whether any, all, or no bits are set, and querying a
|
||||||
|
bitset's current length and number of positive bits.
|
||||||
|
|
||||||
|
BitSets are expanded to the size of the largest set bit; the
|
||||||
|
memory allocation is approximately Max bits, where Max is
|
||||||
|
the largest set bit. BitSets are never shrunk. On creation,
|
||||||
|
a hint can be given for the number of bits that will be used.
|
||||||
|
|
||||||
|
Many of the methods, including Set,Clear, and Flip, return
|
||||||
|
a BitSet pointer, which allows for chaining.
|
||||||
|
|
||||||
|
Example use:
|
||||||
|
|
||||||
|
import "bitset"
|
||||||
|
var b BitSet
|
||||||
|
b.Set(10).Set(11)
|
||||||
|
if b.Test(1000) {
|
||||||
|
b.Clear(1000)
|
||||||
|
}
|
||||||
|
if B.Intersection(bitset.New(100).Set(10)).Count() > 1 {
|
||||||
|
fmt.Println("Intersection works.")
|
||||||
|
}
|
||||||
|
|
||||||
|
As an alternative to BitSets, one should check out the 'big' package,
|
||||||
|
which provides a (less set-theoretical) view of bitsets.
|
||||||
|
|
||||||
|
*/
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/binary"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
// the wordSize of a bit set
|
||||||
|
const wordSize = uint(64)
|
||||||
|
|
||||||
|
// log2WordSize is lg(wordSize)
|
||||||
|
const log2WordSize = uint(6)
|
||||||
|
|
||||||
|
// allBits has every bit set
|
||||||
|
const allBits uint64 = 0xffffffffffffffff
|
||||||
|
|
||||||
|
// default binary BigEndian
|
||||||
|
var binaryOrder binary.ByteOrder = binary.BigEndian
|
||||||
|
|
||||||
|
// default json encoding base64.URLEncoding
|
||||||
|
var base64Encoding = base64.URLEncoding
|
||||||
|
|
||||||
|
// Base64StdEncoding Marshal/Unmarshal BitSet with base64.StdEncoding(Default: base64.URLEncoding)
|
||||||
|
func Base64StdEncoding() { base64Encoding = base64.StdEncoding }
|
||||||
|
|
||||||
|
// LittleEndian Marshal/Unmarshal Binary as Little Endian(Default: binary.BigEndian)
|
||||||
|
func LittleEndian() { binaryOrder = binary.LittleEndian }
|
||||||
|
|
||||||
|
// A BitSet is a set of bits. The zero value of a BitSet is an empty set of length 0.
|
||||||
|
type BitSet struct {
|
||||||
|
length uint
|
||||||
|
set []uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error is used to distinguish errors (panics) generated in this package.
|
||||||
|
type Error string
|
||||||
|
|
||||||
|
// safeSet will fixup b.set to be non-nil and return the field value
|
||||||
|
func (b *BitSet) safeSet() []uint64 {
|
||||||
|
if b.set == nil {
|
||||||
|
b.set = make([]uint64, wordsNeeded(0))
|
||||||
|
}
|
||||||
|
return b.set
|
||||||
|
}
|
||||||
|
|
||||||
|
// From is a constructor used to create a BitSet from an array of integers
|
||||||
|
func From(buf []uint64) *BitSet {
|
||||||
|
return &BitSet{uint(len(buf)) * 64, buf}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bytes returns the bitset as array of integers
|
||||||
|
func (b *BitSet) Bytes() []uint64 {
|
||||||
|
return b.set
|
||||||
|
}
|
||||||
|
|
||||||
|
// wordsNeeded calculates the number of words needed for i bits
|
||||||
|
func wordsNeeded(i uint) int {
|
||||||
|
if i > (Cap() - wordSize + 1) {
|
||||||
|
return int(Cap() >> log2WordSize)
|
||||||
|
}
|
||||||
|
return int((i + (wordSize - 1)) >> log2WordSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new BitSet with a hint that length bits will be required
|
||||||
|
func New(length uint) (bset *BitSet) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
bset = &BitSet{
|
||||||
|
0,
|
||||||
|
make([]uint64, 0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
bset = &BitSet{
|
||||||
|
length,
|
||||||
|
make([]uint64, wordsNeeded(length)),
|
||||||
|
}
|
||||||
|
|
||||||
|
return bset
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cap returns the total possible capacity, or number of bits
|
||||||
|
func Cap() uint {
|
||||||
|
return ^uint(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Len returns the number of bits in the BitSet.
|
||||||
|
// Note the difference to method Count, see example.
|
||||||
|
func (b *BitSet) Len() uint {
|
||||||
|
return b.length
|
||||||
|
}
|
||||||
|
|
||||||
|
// extendSetMaybe adds additional words to incorporate new bits if needed
|
||||||
|
func (b *BitSet) extendSetMaybe(i uint) {
|
||||||
|
if i >= b.length { // if we need more bits, make 'em
|
||||||
|
nsize := wordsNeeded(i + 1)
|
||||||
|
if b.set == nil {
|
||||||
|
b.set = make([]uint64, nsize)
|
||||||
|
} else if cap(b.set) >= nsize {
|
||||||
|
b.set = b.set[:nsize] // fast resize
|
||||||
|
} else if len(b.set) < nsize {
|
||||||
|
newset := make([]uint64, nsize, 2*nsize) // increase capacity 2x
|
||||||
|
copy(newset, b.set)
|
||||||
|
b.set = newset
|
||||||
|
}
|
||||||
|
b.length = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test whether bit i is set.
|
||||||
|
func (b *BitSet) Test(i uint) bool {
|
||||||
|
if i >= b.length {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return b.set[i>>log2WordSize]&(1<<(i&(wordSize-1))) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set bit i to 1
|
||||||
|
func (b *BitSet) Set(i uint) *BitSet {
|
||||||
|
b.extendSetMaybe(i)
|
||||||
|
b.set[i>>log2WordSize] |= 1 << (i & (wordSize - 1))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear bit i to 0
|
||||||
|
func (b *BitSet) Clear(i uint) *BitSet {
|
||||||
|
if i >= b.length {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
b.set[i>>log2WordSize] &^= 1 << (i & (wordSize - 1))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetTo sets bit i to value
|
||||||
|
func (b *BitSet) SetTo(i uint, value bool) *BitSet {
|
||||||
|
if value {
|
||||||
|
return b.Set(i)
|
||||||
|
}
|
||||||
|
return b.Clear(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flip bit at i
|
||||||
|
func (b *BitSet) Flip(i uint) *BitSet {
|
||||||
|
if i >= b.length {
|
||||||
|
return b.Set(i)
|
||||||
|
}
|
||||||
|
b.set[i>>log2WordSize] ^= 1 << (i & (wordSize - 1))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shrink shrinks BitSet to desired length in bits. It clears all bits > length
|
||||||
|
// and reduces the size and length of the set.
|
||||||
|
//
|
||||||
|
// A new slice is allocated to store the new bits, so you may see an increase in
|
||||||
|
// memory usage until the GC runs. Normally this should not be a problem, but if you
|
||||||
|
// have an extremely large BitSet its important to understand that the old BitSet will
|
||||||
|
// remain in memory until the GC frees it.
|
||||||
|
func (b *BitSet) Shrink(length uint) *BitSet {
|
||||||
|
idx := wordsNeeded(length + 1)
|
||||||
|
if idx > len(b.set) {
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
shrunk := make([]uint64, idx)
|
||||||
|
copy(shrunk, b.set[:idx])
|
||||||
|
b.set = shrunk
|
||||||
|
b.length = length + 1
|
||||||
|
b.set[idx-1] &= (allBits >> (uint64(64) - uint64(length&(wordSize-1)) - 1))
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// InsertAt takes an index which indicates where a bit should be
|
||||||
|
// inserted. Then it shifts all the bits in the set to the left by 1, starting
|
||||||
|
// from the given index position, and sets the index position to 0.
|
||||||
|
//
|
||||||
|
// Depending on the size of your BitSet, and where you are inserting the new entry,
|
||||||
|
// this method could be extremely slow and in some cases might cause the entire BitSet
|
||||||
|
// to be recopied.
|
||||||
|
func (b *BitSet) InsertAt(idx uint) *BitSet {
|
||||||
|
insertAtElement := (idx >> log2WordSize)
|
||||||
|
|
||||||
|
// if length of set is a multiple of wordSize we need to allocate more space first
|
||||||
|
if b.isLenExactMultiple() {
|
||||||
|
b.set = append(b.set, uint64(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
var i uint
|
||||||
|
for i = uint(len(b.set) - 1); i > insertAtElement; i-- {
|
||||||
|
// all elements above the position where we want to insert can simply by shifted
|
||||||
|
b.set[i] <<= 1
|
||||||
|
|
||||||
|
// we take the most significant bit of the previous element and set it as
|
||||||
|
// the least significant bit of the current element
|
||||||
|
b.set[i] |= (b.set[i-1] & 0x8000000000000000) >> 63
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate a mask to extract the data that we need to shift left
|
||||||
|
// within the element where we insert a bit
|
||||||
|
dataMask := ^(uint64(1)<<uint64(idx&(wordSize-1)) - 1)
|
||||||
|
|
||||||
|
// extract that data that we'll shift
|
||||||
|
data := b.set[i] & dataMask
|
||||||
|
|
||||||
|
// set the positions of the data mask to 0 in the element where we insert
|
||||||
|
b.set[i] &= ^dataMask
|
||||||
|
|
||||||
|
// shift data mask to the left and insert its data to the slice element
|
||||||
|
b.set[i] |= data << 1
|
||||||
|
|
||||||
|
// add 1 to length of BitSet
|
||||||
|
b.length++
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// String creates a string representation of the Bitmap
|
||||||
|
func (b *BitSet) String() string {
|
||||||
|
// follows code from https://github.com/RoaringBitmap/roaring
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
start := []byte("{")
|
||||||
|
buffer.Write(start)
|
||||||
|
counter := 0
|
||||||
|
i, e := b.NextSet(0)
|
||||||
|
for e {
|
||||||
|
counter = counter + 1
|
||||||
|
// to avoid exhausting the memory
|
||||||
|
if counter > 0x40000 {
|
||||||
|
buffer.WriteString("...")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
buffer.WriteString(strconv.FormatInt(int64(i), 10))
|
||||||
|
i, e = b.NextSet(i + 1)
|
||||||
|
if e {
|
||||||
|
buffer.WriteString(",")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.WriteString("}")
|
||||||
|
return buffer.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAt deletes the bit at the given index position from
|
||||||
|
// within the bitset
|
||||||
|
// All the bits residing on the left of the deleted bit get
|
||||||
|
// shifted right by 1
|
||||||
|
// The running time of this operation may potentially be
|
||||||
|
// relatively slow, O(length)
|
||||||
|
func (b *BitSet) DeleteAt(i uint) *BitSet {
|
||||||
|
// the index of the slice element where we'll delete a bit
|
||||||
|
deleteAtElement := i >> log2WordSize
|
||||||
|
|
||||||
|
// generate a mask for the data that needs to be shifted right
|
||||||
|
// within that slice element that gets modified
|
||||||
|
dataMask := ^((uint64(1) << (i & (wordSize - 1))) - 1)
|
||||||
|
|
||||||
|
// extract the data that we'll shift right from the slice element
|
||||||
|
data := b.set[deleteAtElement] & dataMask
|
||||||
|
|
||||||
|
// set the masked area to 0 while leaving the rest as it is
|
||||||
|
b.set[deleteAtElement] &= ^dataMask
|
||||||
|
|
||||||
|
// shift the previously extracted data to the right and then
|
||||||
|
// set it in the previously masked area
|
||||||
|
b.set[deleteAtElement] |= (data >> 1) & dataMask
|
||||||
|
|
||||||
|
// loop over all the consecutive slice elements to copy each
|
||||||
|
// lowest bit into the highest position of the previous element,
|
||||||
|
// then shift the entire content to the right by 1
|
||||||
|
for i := int(deleteAtElement) + 1; i < len(b.set); i++ {
|
||||||
|
b.set[i-1] |= (b.set[i] & 1) << 63
|
||||||
|
b.set[i] >>= 1
|
||||||
|
}
|
||||||
|
|
||||||
|
b.length = b.length - 1
|
||||||
|
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextSet returns the next bit set from the specified index,
|
||||||
|
// including possibly the current index
|
||||||
|
// along with an error code (true = valid, false = no set bit found)
|
||||||
|
// for i,e := v.NextSet(0); e; i,e = v.NextSet(i + 1) {...}
|
||||||
|
func (b *BitSet) NextSet(i uint) (uint, bool) {
|
||||||
|
x := int(i >> log2WordSize)
|
||||||
|
if x >= len(b.set) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
w := b.set[x]
|
||||||
|
w = w >> (i & (wordSize - 1))
|
||||||
|
if w != 0 {
|
||||||
|
return i + trailingZeroes64(w), true
|
||||||
|
}
|
||||||
|
x = x + 1
|
||||||
|
for x < len(b.set) {
|
||||||
|
if b.set[x] != 0 {
|
||||||
|
return uint(x)*wordSize + trailingZeroes64(b.set[x]), true
|
||||||
|
}
|
||||||
|
x = x + 1
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextSetMany returns many next bit sets from the specified index,
|
||||||
|
// including possibly the current index and up to cap(buffer).
|
||||||
|
// If the returned slice has len zero, then no more set bits were found
|
||||||
|
//
|
||||||
|
// buffer := make([]uint, 256) // this should be reused
|
||||||
|
// j := uint(0)
|
||||||
|
// j, buffer = bitmap.NextSetMany(j, buffer)
|
||||||
|
// for ; len(buffer) > 0; j, buffer = bitmap.NextSetMany(j,buffer) {
|
||||||
|
// for k := range buffer {
|
||||||
|
// do something with buffer[k]
|
||||||
|
// }
|
||||||
|
// j += 1
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
func (b *BitSet) NextSetMany(i uint, buffer []uint) (uint, []uint) {
|
||||||
|
myanswer := buffer
|
||||||
|
capacity := cap(buffer)
|
||||||
|
x := int(i >> log2WordSize)
|
||||||
|
if x >= len(b.set) || capacity == 0 {
|
||||||
|
return 0, myanswer[:0]
|
||||||
|
}
|
||||||
|
skip := i & (wordSize - 1)
|
||||||
|
word := b.set[x] >> skip
|
||||||
|
myanswer = myanswer[:capacity]
|
||||||
|
size := int(0)
|
||||||
|
for word != 0 {
|
||||||
|
r := trailingZeroes64(word)
|
||||||
|
t := word & ((^word) + 1)
|
||||||
|
myanswer[size] = r + i
|
||||||
|
size++
|
||||||
|
if size == capacity {
|
||||||
|
goto End
|
||||||
|
}
|
||||||
|
word = word ^ t
|
||||||
|
}
|
||||||
|
x++
|
||||||
|
for idx, word := range b.set[x:] {
|
||||||
|
for word != 0 {
|
||||||
|
r := trailingZeroes64(word)
|
||||||
|
t := word & ((^word) + 1)
|
||||||
|
myanswer[size] = r + (uint(x+idx) << 6)
|
||||||
|
size++
|
||||||
|
if size == capacity {
|
||||||
|
goto End
|
||||||
|
}
|
||||||
|
word = word ^ t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
End:
|
||||||
|
if size > 0 {
|
||||||
|
return myanswer[size-1], myanswer[:size]
|
||||||
|
}
|
||||||
|
return 0, myanswer[:0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NextClear returns the next clear bit from the specified index,
|
||||||
|
// including possibly the current index
|
||||||
|
// along with an error code (true = valid, false = no bit found i.e. all bits are set)
|
||||||
|
func (b *BitSet) NextClear(i uint) (uint, bool) {
|
||||||
|
x := int(i >> log2WordSize)
|
||||||
|
if x >= len(b.set) {
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
w := b.set[x]
|
||||||
|
w = w >> (i & (wordSize - 1))
|
||||||
|
wA := allBits >> (i & (wordSize - 1))
|
||||||
|
index := i + trailingZeroes64(^w)
|
||||||
|
if w != wA && index < b.length {
|
||||||
|
return index, true
|
||||||
|
}
|
||||||
|
x++
|
||||||
|
for x < len(b.set) {
|
||||||
|
index = uint(x)*wordSize + trailingZeroes64(^b.set[x])
|
||||||
|
if b.set[x] != allBits && index < b.length {
|
||||||
|
return index, true
|
||||||
|
}
|
||||||
|
x++
|
||||||
|
}
|
||||||
|
return 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClearAll clears the entire BitSet
|
||||||
|
func (b *BitSet) ClearAll() *BitSet {
|
||||||
|
if b != nil && b.set != nil {
|
||||||
|
for i := range b.set {
|
||||||
|
b.set[i] = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
|
|
||||||
|
// wordCount returns the number of words used in a bit set
|
||||||
|
func (b *BitSet) wordCount() int {
|
||||||
|
return len(b.set)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone this BitSet
|
||||||
|
func (b *BitSet) Clone() *BitSet {
|
||||||
|
c := New(b.length)
|
||||||
|
if b.set != nil { // Clone should not modify current object
|
||||||
|
copy(c.set, b.set)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy into a destination BitSet
|
||||||
|
// Returning the size of the destination BitSet
|
||||||
|
// like array copy
|
||||||
|
func (b *BitSet) Copy(c *BitSet) (count uint) {
|
||||||
|
if c == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if b.set != nil { // Copy should not modify current object
|
||||||
|
copy(c.set, b.set)
|
||||||
|
}
|
||||||
|
count = c.length
|
||||||
|
if b.length < c.length {
|
||||||
|
count = b.length
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count (number of set bits).
|
||||||
|
// Also known as "popcount" or "popularity count".
|
||||||
|
func (b *BitSet) Count() uint {
|
||||||
|
if b != nil && b.set != nil {
|
||||||
|
return uint(popcntSlice(b.set))
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equal tests the equivalence of two BitSets.
|
||||||
|
// False if they are of different sizes, otherwise true
|
||||||
|
// only if all the same bits are set
|
||||||
|
func (b *BitSet) Equal(c *BitSet) bool {
|
||||||
|
if c == nil || b == nil {
|
||||||
|
return c == b
|
||||||
|
}
|
||||||
|
if b.length != c.length {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if b.length == 0 { // if they have both length == 0, then could have nil set
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// testing for equality shoud not transform the bitset (no call to safeSet)
|
||||||
|
|
||||||
|
for p, v := range b.set {
|
||||||
|
if c.set[p] != v {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func panicIfNull(b *BitSet) {
|
||||||
|
if b == nil {
|
||||||
|
panic(Error("BitSet must not be null"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Difference of base set and other set
|
||||||
|
// This is the BitSet equivalent of &^ (and not)
|
||||||
|
func (b *BitSet) Difference(compare *BitSet) (result *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
result = b.Clone() // clone b (in case b is bigger than compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
result.set[i] = b.set[i] &^ compare.set[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DifferenceCardinality computes the cardinality of the differnce
|
||||||
|
func (b *BitSet) DifferenceCardinality(compare *BitSet) uint {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
cnt := uint64(0)
|
||||||
|
cnt += popcntMaskSlice(b.set[:l], compare.set[:l])
|
||||||
|
cnt += popcntSlice(b.set[l:])
|
||||||
|
return uint(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InPlaceDifference computes the difference of base set and other set
|
||||||
|
// This is the BitSet equivalent of &^ (and not)
|
||||||
|
func (b *BitSet) InPlaceDifference(compare *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
b.set[i] &^= compare.set[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience function: return two bitsets ordered by
|
||||||
|
// increasing length. Note: neither can be nil
|
||||||
|
func sortByLength(a *BitSet, b *BitSet) (ap *BitSet, bp *BitSet) {
|
||||||
|
if a.length <= b.length {
|
||||||
|
ap, bp = a, b
|
||||||
|
} else {
|
||||||
|
ap, bp = b, a
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersection of base set and other set
|
||||||
|
// This is the BitSet equivalent of & (and)
|
||||||
|
func (b *BitSet) Intersection(compare *BitSet) (result *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
result = New(b.length)
|
||||||
|
for i, word := range b.set {
|
||||||
|
result.set[i] = word & compare.set[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// IntersectionCardinality computes the cardinality of the union
|
||||||
|
func (b *BitSet) IntersectionCardinality(compare *BitSet) uint {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
cnt := popcntAndSlice(b.set, compare.set)
|
||||||
|
return uint(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InPlaceIntersection destructively computes the intersection of
|
||||||
|
// base set and the compare set.
|
||||||
|
// This is the BitSet equivalent of & (and)
|
||||||
|
func (b *BitSet) InPlaceIntersection(compare *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
b.set[i] &= compare.set[i]
|
||||||
|
}
|
||||||
|
for i := l; i < len(b.set); i++ {
|
||||||
|
b.set[i] = 0
|
||||||
|
}
|
||||||
|
if compare.length > 0 {
|
||||||
|
b.extendSetMaybe(compare.length - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Union of base set and other set
|
||||||
|
// This is the BitSet equivalent of | (or)
|
||||||
|
func (b *BitSet) Union(compare *BitSet) (result *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
result = compare.Clone()
|
||||||
|
for i, word := range b.set {
|
||||||
|
result.set[i] = word | compare.set[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnionCardinality computes the cardinality of the uniton of the base set
|
||||||
|
// and the compare set.
|
||||||
|
func (b *BitSet) UnionCardinality(compare *BitSet) uint {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
cnt := popcntOrSlice(b.set, compare.set)
|
||||||
|
if len(compare.set) > len(b.set) {
|
||||||
|
cnt += popcntSlice(compare.set[len(b.set):])
|
||||||
|
}
|
||||||
|
return uint(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InPlaceUnion creates the destructive union of base set and compare set.
|
||||||
|
// This is the BitSet equivalent of | (or).
|
||||||
|
func (b *BitSet) InPlaceUnion(compare *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
if compare.length > 0 {
|
||||||
|
b.extendSetMaybe(compare.length - 1)
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
b.set[i] |= compare.set[i]
|
||||||
|
}
|
||||||
|
if len(compare.set) > l {
|
||||||
|
for i := l; i < len(compare.set); i++ {
|
||||||
|
b.set[i] = compare.set[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SymmetricDifference of base set and other set
|
||||||
|
// This is the BitSet equivalent of ^ (xor)
|
||||||
|
func (b *BitSet) SymmetricDifference(compare *BitSet) (result *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
// compare is bigger, so clone it
|
||||||
|
result = compare.Clone()
|
||||||
|
for i, word := range b.set {
|
||||||
|
result.set[i] = word ^ compare.set[i]
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// SymmetricDifferenceCardinality computes the cardinality of the symmetric difference
|
||||||
|
func (b *BitSet) SymmetricDifferenceCardinality(compare *BitSet) uint {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
b, compare = sortByLength(b, compare)
|
||||||
|
cnt := popcntXorSlice(b.set, compare.set)
|
||||||
|
if len(compare.set) > len(b.set) {
|
||||||
|
cnt += popcntSlice(compare.set[len(b.set):])
|
||||||
|
}
|
||||||
|
return uint(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// InPlaceSymmetricDifference creates the destructive SymmetricDifference of base set and other set
|
||||||
|
// This is the BitSet equivalent of ^ (xor)
|
||||||
|
func (b *BitSet) InPlaceSymmetricDifference(compare *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
panicIfNull(compare)
|
||||||
|
l := int(compare.wordCount())
|
||||||
|
if l > int(b.wordCount()) {
|
||||||
|
l = int(b.wordCount())
|
||||||
|
}
|
||||||
|
if compare.length > 0 {
|
||||||
|
b.extendSetMaybe(compare.length - 1)
|
||||||
|
}
|
||||||
|
for i := 0; i < l; i++ {
|
||||||
|
b.set[i] ^= compare.set[i]
|
||||||
|
}
|
||||||
|
if len(compare.set) > l {
|
||||||
|
for i := l; i < len(compare.set); i++ {
|
||||||
|
b.set[i] = compare.set[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the length an exact multiple of word sizes?
|
||||||
|
func (b *BitSet) isLenExactMultiple() bool {
|
||||||
|
return b.length%wordSize == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean last word by setting unused bits to 0
|
||||||
|
func (b *BitSet) cleanLastWord() {
|
||||||
|
if !b.isLenExactMultiple() {
|
||||||
|
b.set[len(b.set)-1] &= allBits >> (wordSize - b.length%wordSize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complement computes the (local) complement of a biset (up to length bits)
|
||||||
|
func (b *BitSet) Complement() (result *BitSet) {
|
||||||
|
panicIfNull(b)
|
||||||
|
result = New(b.length)
|
||||||
|
for i, word := range b.set {
|
||||||
|
result.set[i] = ^word
|
||||||
|
}
|
||||||
|
result.cleanLastWord()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// All returns true if all bits are set, false otherwise. Returns true for
|
||||||
|
// empty sets.
|
||||||
|
func (b *BitSet) All() bool {
|
||||||
|
panicIfNull(b)
|
||||||
|
return b.Count() == b.length
|
||||||
|
}
|
||||||
|
|
||||||
|
// None returns true if no bit is set, false otherwise. Returns true for
|
||||||
|
// empty sets.
|
||||||
|
func (b *BitSet) None() bool {
|
||||||
|
panicIfNull(b)
|
||||||
|
if b != nil && b.set != nil {
|
||||||
|
for _, word := range b.set {
|
||||||
|
if word > 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any returns true if any bit is set, false otherwise
|
||||||
|
func (b *BitSet) Any() bool {
|
||||||
|
panicIfNull(b)
|
||||||
|
return !b.None()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSuperSet returns true if this is a superset of the other set
|
||||||
|
func (b *BitSet) IsSuperSet(other *BitSet) bool {
|
||||||
|
for i, e := other.NextSet(0); e; i, e = other.NextSet(i + 1) {
|
||||||
|
if !b.Test(i) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsStrictSuperSet returns true if this is a strict superset of the other set
|
||||||
|
func (b *BitSet) IsStrictSuperSet(other *BitSet) bool {
|
||||||
|
return b.Count() > other.Count() && b.IsSuperSet(other)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DumpAsBits dumps a bit set as a string of bits
|
||||||
|
func (b *BitSet) DumpAsBits() string {
|
||||||
|
if b.set == nil {
|
||||||
|
return "."
|
||||||
|
}
|
||||||
|
buffer := bytes.NewBufferString("")
|
||||||
|
i := len(b.set) - 1
|
||||||
|
for ; i >= 0; i-- {
|
||||||
|
fmt.Fprintf(buffer, "%064b.", b.set[i])
|
||||||
|
}
|
||||||
|
return buffer.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// BinaryStorageSize returns the binary storage requirements
|
||||||
|
func (b *BitSet) BinaryStorageSize() int {
|
||||||
|
return binary.Size(uint64(0)) + binary.Size(b.set)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteTo writes a BitSet to a stream
|
||||||
|
func (b *BitSet) WriteTo(stream io.Writer) (int64, error) {
|
||||||
|
length := uint64(b.length)
|
||||||
|
|
||||||
|
// Write length
|
||||||
|
err := binary.Write(stream, binaryOrder, length)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write set
|
||||||
|
err = binary.Write(stream, binaryOrder, b.set)
|
||||||
|
return int64(b.BinaryStorageSize()), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadFrom reads a BitSet from a stream written using WriteTo
|
||||||
|
func (b *BitSet) ReadFrom(stream io.Reader) (int64, error) {
|
||||||
|
var length uint64
|
||||||
|
|
||||||
|
// Read length first
|
||||||
|
err := binary.Read(stream, binaryOrder, &length)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
newset := New(uint(length))
|
||||||
|
|
||||||
|
if uint64(newset.length) != length {
|
||||||
|
return 0, errors.New("Unmarshalling error: type mismatch")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read remaining bytes as set
|
||||||
|
err = binary.Read(stream, binaryOrder, newset.set)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
*b = *newset
|
||||||
|
return int64(b.BinaryStorageSize()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalBinary encodes a BitSet into a binary form and returns the result.
|
||||||
|
func (b *BitSet) MarshalBinary() ([]byte, error) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
writer := bufio.NewWriter(&buf)
|
||||||
|
|
||||||
|
_, err := b.WriteTo(writer)
|
||||||
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = writer.Flush()
|
||||||
|
|
||||||
|
return buf.Bytes(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalBinary decodes the binary form generated by MarshalBinary.
|
||||||
|
func (b *BitSet) UnmarshalBinary(data []byte) error {
|
||||||
|
buf := bytes.NewReader(data)
|
||||||
|
reader := bufio.NewReader(buf)
|
||||||
|
|
||||||
|
_, err := b.ReadFrom(reader)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals a BitSet as a JSON structure
|
||||||
|
func (b *BitSet) MarshalJSON() ([]byte, error) {
|
||||||
|
buffer := bytes.NewBuffer(make([]byte, 0, b.BinaryStorageSize()))
|
||||||
|
_, err := b.WriteTo(buffer)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLEncode all bytes
|
||||||
|
return json.Marshal(base64Encoding.EncodeToString(buffer.Bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON unmarshals a BitSet from JSON created using MarshalJSON
|
||||||
|
func (b *BitSet) UnmarshalJSON(data []byte) error {
|
||||||
|
// Unmarshal as string
|
||||||
|
var s string
|
||||||
|
err := json.Unmarshal(data, &s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLDecode string
|
||||||
|
buf, err := base64Encoding.DecodeString(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = b.ReadFrom(bytes.NewReader(buf))
|
||||||
|
return err
|
||||||
|
}
|
53
vendor/github.com/willf/bitset/popcnt.go
generated
vendored
Normal file
53
vendor/github.com/willf/bitset/popcnt.go
generated
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package bitset
|
||||||
|
|
||||||
|
// bit population count, take from
|
||||||
|
// https://code.google.com/p/go/issues/detail?id=4988#c11
|
||||||
|
// credit: https://code.google.com/u/arnehormann/
|
||||||
|
func popcount(x uint64) (n uint64) {
|
||||||
|
x -= (x >> 1) & 0x5555555555555555
|
||||||
|
x = (x>>2)&0x3333333333333333 + x&0x3333333333333333
|
||||||
|
x += x >> 4
|
||||||
|
x &= 0x0f0f0f0f0f0f0f0f
|
||||||
|
x *= 0x0101010101010101
|
||||||
|
return x >> 56
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntSliceGo(s []uint64) uint64 {
|
||||||
|
cnt := uint64(0)
|
||||||
|
for _, x := range s {
|
||||||
|
cnt += popcount(x)
|
||||||
|
}
|
||||||
|
return cnt
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntMaskSliceGo(s, m []uint64) uint64 {
|
||||||
|
cnt := uint64(0)
|
||||||
|
for i := range s {
|
||||||
|
cnt += popcount(s[i] &^ m[i])
|
||||||
|
}
|
||||||
|
return cnt
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntAndSliceGo(s, m []uint64) uint64 {
|
||||||
|
cnt := uint64(0)
|
||||||
|
for i := range s {
|
||||||
|
cnt += popcount(s[i] & m[i])
|
||||||
|
}
|
||||||
|
return cnt
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntOrSliceGo(s, m []uint64) uint64 {
|
||||||
|
cnt := uint64(0)
|
||||||
|
for i := range s {
|
||||||
|
cnt += popcount(s[i] | m[i])
|
||||||
|
}
|
||||||
|
return cnt
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntXorSliceGo(s, m []uint64) uint64 {
|
||||||
|
cnt := uint64(0)
|
||||||
|
for i := range s {
|
||||||
|
cnt += popcount(s[i] ^ m[i])
|
||||||
|
}
|
||||||
|
return cnt
|
||||||
|
}
|
45
vendor/github.com/willf/bitset/popcnt_19.go
generated
vendored
Normal file
45
vendor/github.com/willf/bitset/popcnt_19.go
generated
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
|
func popcntSlice(s []uint64) uint64 {
|
||||||
|
var cnt int
|
||||||
|
for _, x := range s {
|
||||||
|
cnt += bits.OnesCount64(x)
|
||||||
|
}
|
||||||
|
return uint64(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||||
|
var cnt int
|
||||||
|
for i := range s {
|
||||||
|
cnt += bits.OnesCount64(s[i] &^ m[i])
|
||||||
|
}
|
||||||
|
return uint64(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntAndSlice(s, m []uint64) uint64 {
|
||||||
|
var cnt int
|
||||||
|
for i := range s {
|
||||||
|
cnt += bits.OnesCount64(s[i] & m[i])
|
||||||
|
}
|
||||||
|
return uint64(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntOrSlice(s, m []uint64) uint64 {
|
||||||
|
var cnt int
|
||||||
|
for i := range s {
|
||||||
|
cnt += bits.OnesCount64(s[i] | m[i])
|
||||||
|
}
|
||||||
|
return uint64(cnt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntXorSlice(s, m []uint64) uint64 {
|
||||||
|
var cnt int
|
||||||
|
for i := range s {
|
||||||
|
cnt += bits.OnesCount64(s[i] ^ m[i])
|
||||||
|
}
|
||||||
|
return uint64(cnt)
|
||||||
|
}
|
68
vendor/github.com/willf/bitset/popcnt_amd64.go
generated
vendored
Normal file
68
vendor/github.com/willf/bitset/popcnt_amd64.go
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// +build !go1.9
|
||||||
|
// +build amd64,!appengine
|
||||||
|
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
// *** the following functions are defined in popcnt_amd64.s
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func hasAsm() bool
|
||||||
|
|
||||||
|
// useAsm is a flag used to select the GO or ASM implementation of the popcnt function
|
||||||
|
var useAsm = hasAsm()
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func popcntSliceAsm(s []uint64) uint64
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func popcntMaskSliceAsm(s, m []uint64) uint64
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func popcntAndSliceAsm(s, m []uint64) uint64
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func popcntOrSliceAsm(s, m []uint64) uint64
|
||||||
|
|
||||||
|
//go:noescape
|
||||||
|
|
||||||
|
func popcntXorSliceAsm(s, m []uint64) uint64
|
||||||
|
|
||||||
|
func popcntSlice(s []uint64) uint64 {
|
||||||
|
if useAsm {
|
||||||
|
return popcntSliceAsm(s)
|
||||||
|
}
|
||||||
|
return popcntSliceGo(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||||
|
if useAsm {
|
||||||
|
return popcntMaskSliceAsm(s, m)
|
||||||
|
}
|
||||||
|
return popcntMaskSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntAndSlice(s, m []uint64) uint64 {
|
||||||
|
if useAsm {
|
||||||
|
return popcntAndSliceAsm(s, m)
|
||||||
|
}
|
||||||
|
return popcntAndSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntOrSlice(s, m []uint64) uint64 {
|
||||||
|
if useAsm {
|
||||||
|
return popcntOrSliceAsm(s, m)
|
||||||
|
}
|
||||||
|
return popcntOrSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntXorSlice(s, m []uint64) uint64 {
|
||||||
|
if useAsm {
|
||||||
|
return popcntXorSliceAsm(s, m)
|
||||||
|
}
|
||||||
|
return popcntXorSliceGo(s, m)
|
||||||
|
}
|
104
vendor/github.com/willf/bitset/popcnt_amd64.s
generated
vendored
Normal file
104
vendor/github.com/willf/bitset/popcnt_amd64.s
generated
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// +build !go1.9
|
||||||
|
// +build amd64,!appengine
|
||||||
|
|
||||||
|
TEXT ·hasAsm(SB),4,$0-1
|
||||||
|
MOVQ $1, AX
|
||||||
|
CPUID
|
||||||
|
SHRQ $23, CX
|
||||||
|
ANDQ $1, CX
|
||||||
|
MOVB CX, ret+0(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
#define POPCNTQ_DX_DX BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0xd2
|
||||||
|
|
||||||
|
TEXT ·popcntSliceAsm(SB),4,$0-32
|
||||||
|
XORQ AX, AX
|
||||||
|
MOVQ s+0(FP), SI
|
||||||
|
MOVQ s_len+8(FP), CX
|
||||||
|
TESTQ CX, CX
|
||||||
|
JZ popcntSliceEnd
|
||||||
|
popcntSliceLoop:
|
||||||
|
BYTE $0xf3; BYTE $0x48; BYTE $0x0f; BYTE $0xb8; BYTE $0x16 // POPCNTQ (SI), DX
|
||||||
|
ADDQ DX, AX
|
||||||
|
ADDQ $8, SI
|
||||||
|
LOOP popcntSliceLoop
|
||||||
|
popcntSliceEnd:
|
||||||
|
MOVQ AX, ret+24(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·popcntMaskSliceAsm(SB),4,$0-56
|
||||||
|
XORQ AX, AX
|
||||||
|
MOVQ s+0(FP), SI
|
||||||
|
MOVQ s_len+8(FP), CX
|
||||||
|
TESTQ CX, CX
|
||||||
|
JZ popcntMaskSliceEnd
|
||||||
|
MOVQ m+24(FP), DI
|
||||||
|
popcntMaskSliceLoop:
|
||||||
|
MOVQ (DI), DX
|
||||||
|
NOTQ DX
|
||||||
|
ANDQ (SI), DX
|
||||||
|
POPCNTQ_DX_DX
|
||||||
|
ADDQ DX, AX
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
LOOP popcntMaskSliceLoop
|
||||||
|
popcntMaskSliceEnd:
|
||||||
|
MOVQ AX, ret+48(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·popcntAndSliceAsm(SB),4,$0-56
|
||||||
|
XORQ AX, AX
|
||||||
|
MOVQ s+0(FP), SI
|
||||||
|
MOVQ s_len+8(FP), CX
|
||||||
|
TESTQ CX, CX
|
||||||
|
JZ popcntAndSliceEnd
|
||||||
|
MOVQ m+24(FP), DI
|
||||||
|
popcntAndSliceLoop:
|
||||||
|
MOVQ (DI), DX
|
||||||
|
ANDQ (SI), DX
|
||||||
|
POPCNTQ_DX_DX
|
||||||
|
ADDQ DX, AX
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
LOOP popcntAndSliceLoop
|
||||||
|
popcntAndSliceEnd:
|
||||||
|
MOVQ AX, ret+48(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·popcntOrSliceAsm(SB),4,$0-56
|
||||||
|
XORQ AX, AX
|
||||||
|
MOVQ s+0(FP), SI
|
||||||
|
MOVQ s_len+8(FP), CX
|
||||||
|
TESTQ CX, CX
|
||||||
|
JZ popcntOrSliceEnd
|
||||||
|
MOVQ m+24(FP), DI
|
||||||
|
popcntOrSliceLoop:
|
||||||
|
MOVQ (DI), DX
|
||||||
|
ORQ (SI), DX
|
||||||
|
POPCNTQ_DX_DX
|
||||||
|
ADDQ DX, AX
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
LOOP popcntOrSliceLoop
|
||||||
|
popcntOrSliceEnd:
|
||||||
|
MOVQ AX, ret+48(FP)
|
||||||
|
RET
|
||||||
|
|
||||||
|
TEXT ·popcntXorSliceAsm(SB),4,$0-56
|
||||||
|
XORQ AX, AX
|
||||||
|
MOVQ s+0(FP), SI
|
||||||
|
MOVQ s_len+8(FP), CX
|
||||||
|
TESTQ CX, CX
|
||||||
|
JZ popcntXorSliceEnd
|
||||||
|
MOVQ m+24(FP), DI
|
||||||
|
popcntXorSliceLoop:
|
||||||
|
MOVQ (DI), DX
|
||||||
|
XORQ (SI), DX
|
||||||
|
POPCNTQ_DX_DX
|
||||||
|
ADDQ DX, AX
|
||||||
|
ADDQ $8, SI
|
||||||
|
ADDQ $8, DI
|
||||||
|
LOOP popcntXorSliceLoop
|
||||||
|
popcntXorSliceEnd:
|
||||||
|
MOVQ AX, ret+48(FP)
|
||||||
|
RET
|
24
vendor/github.com/willf/bitset/popcnt_generic.go
generated
vendored
Normal file
24
vendor/github.com/willf/bitset/popcnt_generic.go
generated
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// +build !go1.9
|
||||||
|
// +build !amd64 appengine
|
||||||
|
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
func popcntSlice(s []uint64) uint64 {
|
||||||
|
return popcntSliceGo(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntMaskSlice(s, m []uint64) uint64 {
|
||||||
|
return popcntMaskSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntAndSlice(s, m []uint64) uint64 {
|
||||||
|
return popcntAndSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntOrSlice(s, m []uint64) uint64 {
|
||||||
|
return popcntOrSliceGo(s, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func popcntXorSlice(s, m []uint64) uint64 {
|
||||||
|
return popcntXorSliceGo(s, m)
|
||||||
|
}
|
14
vendor/github.com/willf/bitset/trailing_zeros_18.go
generated
vendored
Normal file
14
vendor/github.com/willf/bitset/trailing_zeros_18.go
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// +build !go1.9
|
||||||
|
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
var deBruijn = [...]byte{
|
||||||
|
0, 1, 56, 2, 57, 49, 28, 3, 61, 58, 42, 50, 38, 29, 17, 4,
|
||||||
|
62, 47, 59, 36, 45, 43, 51, 22, 53, 39, 33, 30, 24, 18, 12, 5,
|
||||||
|
63, 55, 48, 27, 60, 41, 37, 16, 46, 35, 44, 21, 52, 32, 23, 11,
|
||||||
|
54, 26, 40, 15, 34, 20, 31, 10, 25, 14, 19, 9, 13, 8, 7, 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
func trailingZeroes64(v uint64) uint {
|
||||||
|
return uint(deBruijn[((v&-v)*0x03f79d71b4ca8b09)>>58])
|
||||||
|
}
|
9
vendor/github.com/willf/bitset/trailing_zeros_19.go
generated
vendored
Normal file
9
vendor/github.com/willf/bitset/trailing_zeros_19.go
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// +build go1.9
|
||||||
|
|
||||||
|
package bitset
|
||||||
|
|
||||||
|
import "math/bits"
|
||||||
|
|
||||||
|
func trailingZeroes64(v uint64) uint {
|
||||||
|
return uint(bits.TrailingZeros64(v))
|
||||||
|
}
|
10
vendor/modules.txt
vendored
10
vendor/modules.txt
vendored
@ -155,7 +155,7 @@ github.com/containers/psgo/internal/dev
|
|||||||
github.com/containers/psgo/internal/host
|
github.com/containers/psgo/internal/host
|
||||||
github.com/containers/psgo/internal/proc
|
github.com/containers/psgo/internal/proc
|
||||||
github.com/containers/psgo/internal/process
|
github.com/containers/psgo/internal/process
|
||||||
# github.com/containers/storage v1.20.2
|
# github.com/containers/storage v1.21.0
|
||||||
github.com/containers/storage
|
github.com/containers/storage
|
||||||
github.com/containers/storage/drivers
|
github.com/containers/storage/drivers
|
||||||
github.com/containers/storage/drivers/aufs
|
github.com/containers/storage/drivers/aufs
|
||||||
@ -308,7 +308,7 @@ github.com/gorilla/mux
|
|||||||
github.com/gorilla/schema
|
github.com/gorilla/schema
|
||||||
# github.com/hashicorp/errwrap v1.0.0
|
# github.com/hashicorp/errwrap v1.0.0
|
||||||
github.com/hashicorp/errwrap
|
github.com/hashicorp/errwrap
|
||||||
# github.com/hashicorp/go-multierror v1.0.0
|
# github.com/hashicorp/go-multierror v1.1.0
|
||||||
github.com/hashicorp/go-multierror
|
github.com/hashicorp/go-multierror
|
||||||
# github.com/hashicorp/golang-lru v0.5.1
|
# github.com/hashicorp/golang-lru v0.5.1
|
||||||
github.com/hashicorp/golang-lru/simplelru
|
github.com/hashicorp/golang-lru/simplelru
|
||||||
@ -326,7 +326,7 @@ github.com/inconshreveable/mousetrap
|
|||||||
github.com/ishidawataru/sctp
|
github.com/ishidawataru/sctp
|
||||||
# github.com/json-iterator/go v1.1.10
|
# github.com/json-iterator/go v1.1.10
|
||||||
github.com/json-iterator/go
|
github.com/json-iterator/go
|
||||||
# github.com/klauspost/compress v1.10.8
|
# github.com/klauspost/compress v1.10.10
|
||||||
github.com/klauspost/compress/flate
|
github.com/klauspost/compress/flate
|
||||||
github.com/klauspost/compress/fse
|
github.com/klauspost/compress/fse
|
||||||
github.com/klauspost/compress/huff0
|
github.com/klauspost/compress/huff0
|
||||||
@ -428,7 +428,7 @@ github.com/opencontainers/runtime-tools/generate
|
|||||||
github.com/opencontainers/runtime-tools/generate/seccomp
|
github.com/opencontainers/runtime-tools/generate/seccomp
|
||||||
github.com/opencontainers/runtime-tools/specerror
|
github.com/opencontainers/runtime-tools/specerror
|
||||||
github.com/opencontainers/runtime-tools/validate
|
github.com/opencontainers/runtime-tools/validate
|
||||||
# github.com/opencontainers/selinux v1.5.2
|
# github.com/opencontainers/selinux v1.6.0
|
||||||
github.com/opencontainers/selinux/go-selinux
|
github.com/opencontainers/selinux/go-selinux
|
||||||
github.com/opencontainers/selinux/go-selinux/label
|
github.com/opencontainers/selinux/go-selinux/label
|
||||||
github.com/opencontainers/selinux/pkg/pwalk
|
github.com/opencontainers/selinux/pkg/pwalk
|
||||||
@ -544,6 +544,8 @@ github.com/vishvananda/netlink
|
|||||||
github.com/vishvananda/netlink/nl
|
github.com/vishvananda/netlink/nl
|
||||||
# github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
|
# github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df
|
||||||
github.com/vishvananda/netns
|
github.com/vishvananda/netns
|
||||||
|
# github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243
|
||||||
|
github.com/willf/bitset
|
||||||
# github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b
|
# github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b
|
||||||
github.com/xeipuuv/gojsonpointer
|
github.com/xeipuuv/gojsonpointer
|
||||||
# github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
|
# github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415
|
||||||
|
Reference in New Issue
Block a user