diff --git a/go.mod b/go.mod index e9b03ab5..60ca3c41 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,8 @@ require ( k8s.io/apimachinery v0.32.2 k8s.io/client-go v0.32.2 k8s.io/kubelet v0.32.2 - tags.cncf.io/container-device-interface v1.1.0 - tags.cncf.io/container-device-interface/specs-go v1.1.0 + tags.cncf.io/container-device-interface v1.1.1 + tags.cncf.io/container-device-interface/specs-go v1.1.1 ) require ( @@ -137,7 +137,6 @@ require ( github.com/mgechev/revive v1.7.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/moby/sys/capability v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/moricho/tparallel v0.3.2 // indirect @@ -148,11 +147,9 @@ require ( github.com/nunnatsa/ginkgolinter v0.19.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/opencontainers/runtime-spec v1.3.0 // indirect - github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polyfloyd/go-errorlint v1.7.1 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect @@ -186,8 +183,8 @@ require ( github.com/spf13/viper v1.12.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect - github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.11.1 // indirect + github.com/stretchr/objx v0.5.3 // indirect + github.com/stretchr/testify v1.12.1 // indirect github.com/subosito/gotenv v1.4.1 // indirect github.com/tdakkota/asciicheck v0.4.1 // indirect github.com/tetafro/godot v1.5.0 // indirect @@ -211,7 +208,7 @@ require ( go.uber.org/automaxprocs v1.6.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.24.0 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac // indirect golang.org/x/mod v0.40.0 // indirect golang.org/x/net v0.58.0 // indirect diff --git a/go.sum b/go.sum index cae77a43..5698ac2d 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo= -github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= -github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v4 v4.5.0 h1:iZRsEvDdyhd2La0FVi5k6tYehpOR/R7qIUjmKk7N74A= @@ -215,12 +213,8 @@ github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= github.com/gostaticanalysis/testutil v0.5.0 h1:Dq4wT1DdTwTGCQQv3rl3IvD5Ld0E6HiY+3Zh0sUGqw8= github.com/gostaticanalysis/testutil v0.5.0/go.mod h1:OLQSbuM6zw2EvCcXTz1lVq5unyoNft372msDY0nY5Hs= -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/go-immutable-radix/v2 v2.1.0 h1:CUW5RYIcysz+D3B+l1mDeXrQ7fUvGGCwJfdASSzbrfo= github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw= -github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= @@ -314,8 +308,6 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= -github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -341,10 +333,6 @@ github.com/onsi/gomega v1.41.0 h1:OwKp4pXNgVxf6sCplzYo794OFNuoL2q2SBMU5NSWOjA= github.com/onsi/gomega v1.41.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A= github.com/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg= github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 h1:tAKu3NkKWZYpqBSOJKwTxT1wIGueiF7gcmcNgr5pNTY= -github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116/go.mod h1:DKDEfzxvRkoQ6n9TGhxQgg2IM1lY4aM0eaQP4e3oElw= -github.com/opencontainers/selinux v1.10.0 h1:rAiKF8hTcgLI3w0DHm6i0ylVVcOrlgR1kK99DRLDhyU= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= @@ -437,8 +425,8 @@ github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -448,8 +436,8 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tdakkota/asciicheck v0.4.1 h1:bm0tbcmi0jezRA2b5kg4ozmMuGAFotKI3RZfrhfovg8= @@ -486,12 +474,6 @@ github.com/uudashr/iface v1.3.1 h1:bA51vmVx1UIhiIsQFSNq6GZ6VPTk3WNMZgRiCe9R29U= github.com/uudashr/iface v1.3.1/go.mod h1:4QvspiRd3JLPAEXBQ9AiZpLbJlrWWgRChOKDJEuQTdg= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= @@ -537,8 +519,8 @@ go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -720,7 +702,7 @@ sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aN sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= -tags.cncf.io/container-device-interface v1.1.0 h1:RnxNhxF1JOu6CJUVpetTYvrXHdxw9j9jFYgZpI+anSY= -tags.cncf.io/container-device-interface v1.1.0/go.mod h1:76Oj0Yqp9FwTx/pySDc8Bxjpg+VqXfDb50cKAXVJ34Q= -tags.cncf.io/container-device-interface/specs-go v1.1.0 h1:QRZVeAceQM+zTZe12eyfuJuuzp524EKYwhmvLd+h+yQ= -tags.cncf.io/container-device-interface/specs-go v1.1.0/go.mod h1:u86hoFWqnh3hWz3esofRFKbI261bUlvUfLKGrDhJkgQ= +tags.cncf.io/container-device-interface v1.1.1 h1:YPwQz4xg8PlQ0yT/baR0BtLpTQROe4l6M1yuRgAu1vc= +tags.cncf.io/container-device-interface v1.1.1/go.mod h1:S1PSJWYPD4Iom0/39mvr/VVFCfG0Yt14j20d0OYrY2M= +tags.cncf.io/container-device-interface/specs-go v1.1.1 h1:3xjaytilFeCBVFJsJTaT9uOFahoqJMVuYG7gYqi2+NY= +tags.cncf.io/container-device-interface/specs-go v1.1.1/go.mod h1:BhJIkjjPh4qpys+qm4DAYtUyryaTDg9zris+AczXyws= diff --git a/vendor/github.com/moby/sys/capability/CHANGELOG.md b/vendor/github.com/moby/sys/capability/CHANGELOG.md deleted file mode 100644 index 299b36d9..00000000 --- a/vendor/github.com/moby/sys/capability/CHANGELOG.md +++ /dev/null @@ -1,124 +0,0 @@ -# Changelog -This file documents all notable changes made to this project since the initial fork -from https://github.com/syndtr/gocapability/commit/42c35b4376354fd5. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [0.4.0] - 2024-11-11 - -### Added -* New separate API for ambient ([GetAmbient], [SetAmbient], [ResetAmbient]) - and bound ([GetBound], [DropBound]) capabilities, modelled after libcap. (#176) - -### Fixed -* [Apply] now returns an error if called for non-zero `pid`. Before this change, - it could silently change some capabilities of the current process, instead of - the one identified by the `pid`. (#168, #174) -* Fixed tests that change capabilities to be run in a separate process. (#173) -* Other improvements in tests. (#169, #170) - -### Changed -* Use raw syscalls (which are slightly faster). (#176) -* Most tests are now limited to testing the public API of the package. (#162) -* Simplify parsing /proc/*pid*/status, add a test case. (#162) -* Optimize the number of syscall to set ambient capabilities in Apply - by clearing them first; add a test case. (#163, #164) -* Better documentation for [Apply], [NewFile], [NewFile2], [NewPid], [NewPid2]. (#175) - -### Removed -* `.golangci.yml` and `.codespellrc` are no longer part of the package. (#158) - -## [0.3.0] - 2024-09-25 - -### Added -* Added [ListKnown] and [ListSupported] functions. (#153) -* [LastCap] is now available on non-Linux platforms (where it returns an error). (#152) - -### Changed -* [List] is now deprecated in favor of [ListKnown] and [ListSupported]. (#153) - -### Fixed -* Various documentation improvements. (#151) -* Fix "generated code" comment. (#153) - -## [0.2.0] - 2024-09-16 - -This is the first release after the move to a new home in -github.com/moby/sys/capability. - -### Fixed - * Fixed URLs in documentation to reflect the new home. - -## [0.1.1] - 2024-08-01 - -This is a maintenance release, fixing a few minor issues. - -### Fixed - * Fixed future kernel compatibility, for real this time. [#11] - * Fixed [LastCap] to be a function. [#12] - -## [0.1.0] - 2024-07-31 - -This is an initial release since the fork. - -### Breaking changes - - * The `CAP_LAST_CAP` variable is removed; users need to modify the code to - use [LastCap] to get the value. [#6] - * The code now requires Go >= 1.21. - -### Added - * `go.mod` and `go.sum` files. [#2] - * New [LastCap] function. [#6] - * Basic CI using GHA infra. [#8], [#9] - * README and CHANGELOG. [#10] - -### Fixed - * Fixed ambient capabilities error handling in [Apply]. [#3] - * Fixed future kernel compatibility. [#1] - * Fixed various linter warnings. [#4], [#7] - -### Changed - * Go build tags changed from old-style (`+build`) to new Go 1.17+ style (`go:build`). [#2] - -### Removed - * Removed support for capabilities v1 and v2. [#1] - * Removed init function so programs that use this package start faster. [#6] - * Removed `CAP_LAST_CAP` (use [LastCap] instead). [#6] - - -[Apply]: https://pkg.go.dev/github.com/moby/sys/capability#Capabilities.Apply -[DropBound]: https://pkg.go.dev/github.com/moby/sys/capability#DropBound -[GetAmbient]: https://pkg.go.dev/github.com/moby/sys/capability#GetAmbient -[GetBound]: https://pkg.go.dev/github.com/moby/sys/capability#GetBound -[LastCap]: https://pkg.go.dev/github.com/moby/sys/capability#LastCap -[ListKnown]: https://pkg.go.dev/github.com/moby/sys/capability#ListKnown -[ListSupported]: https://pkg.go.dev/github.com/moby/sys/capability#ListSupported -[List]: https://pkg.go.dev/github.com/moby/sys/capability#List -[NewFile2]: https://pkg.go.dev/github.com/moby/sys/capability#NewFile2 -[NewFile]: https://pkg.go.dev/github.com/moby/sys/capability#NewFile -[NewPid2]: https://pkg.go.dev/github.com/moby/sys/capability#NewPid2 -[NewPid]: https://pkg.go.dev/github.com/moby/sys/capability#NewPid -[ResetAmbient]: https://pkg.go.dev/github.com/moby/sys/capability#ResetAmbient -[SetAmbient]: https://pkg.go.dev/github.com/moby/sys/capability#SetAmbient - - -[0.4.0]: https://github.com/moby/sys/releases/tag/capability%2Fv0.4.0 -[0.3.0]: https://github.com/moby/sys/releases/tag/capability%2Fv0.3.0 -[0.2.0]: https://github.com/moby/sys/releases/tag/capability%2Fv0.2.0 -[0.1.1]: https://github.com/kolyshkin/capability/compare/v0.1.0...v0.1.1 -[0.1.0]: https://github.com/kolyshkin/capability/compare/42c35b4376354fd5...v0.1.0 - - -[#1]: https://github.com/kolyshkin/capability/pull/1 -[#2]: https://github.com/kolyshkin/capability/pull/2 -[#3]: https://github.com/kolyshkin/capability/pull/3 -[#4]: https://github.com/kolyshkin/capability/pull/4 -[#6]: https://github.com/kolyshkin/capability/pull/6 -[#7]: https://github.com/kolyshkin/capability/pull/7 -[#8]: https://github.com/kolyshkin/capability/pull/8 -[#9]: https://github.com/kolyshkin/capability/pull/9 -[#10]: https://github.com/kolyshkin/capability/pull/10 -[#11]: https://github.com/kolyshkin/capability/pull/11 -[#12]: https://github.com/kolyshkin/capability/pull/12 diff --git a/vendor/github.com/moby/sys/capability/LICENSE b/vendor/github.com/moby/sys/capability/LICENSE deleted file mode 100644 index 08adcd6e..00000000 --- a/vendor/github.com/moby/sys/capability/LICENSE +++ /dev/null @@ -1,25 +0,0 @@ -Copyright 2023 The Capability Authors. -Copyright 2013 Suryandaru Triandana -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. - -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 -HOLDER 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. diff --git a/vendor/github.com/moby/sys/capability/README.md b/vendor/github.com/moby/sys/capability/README.md deleted file mode 100644 index 84b74871..00000000 --- a/vendor/github.com/moby/sys/capability/README.md +++ /dev/null @@ -1,13 +0,0 @@ -This is a fork of (apparently no longer maintained) -https://github.com/syndtr/gocapability package. It provides basic primitives to -work with [Linux capabilities][capabilities(7)]. - -For changes, see [CHANGELOG.md](./CHANGELOG.md). - -[![Go Reference](https://pkg.go.dev/badge/github.com/moby/sys/capability/capability.svg)](https://pkg.go.dev/github.com/moby/sys/capability) - -## Alternatives - - * https://pkg.go.dev/kernel.org/pub/linux/libs/security/libcap/cap - -[capabilities(7)]: https://man7.org/linux/man-pages/man7/capabilities.7.html diff --git a/vendor/github.com/moby/sys/capability/capability.go b/vendor/github.com/moby/sys/capability/capability.go deleted file mode 100644 index 11e47bed..00000000 --- a/vendor/github.com/moby/sys/capability/capability.go +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright 2023 The Capability Authors. -// Copyright 2013 Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package capability provides utilities for manipulating POSIX capabilities. -package capability - -type Capabilities interface { - // Get check whether a capability present in the given - // capabilities set. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Get(which CapType, what Cap) bool - - // Empty check whether all capability bits of the given capabilities - // set are zero. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Empty(which CapType) bool - - // Full check whether all capability bits of the given capabilities - // set are one. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Full(which CapType) bool - - // Set sets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Set(which CapType, caps ...Cap) - - // Unset unsets capabilities of the given capabilities sets. The - // 'which' value should be one or combination (OR'ed) of EFFECTIVE, - // PERMITTED, INHERITABLE, BOUNDING or AMBIENT. - Unset(which CapType, caps ...Cap) - - // Fill sets all bits of the given capabilities kind to one. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Fill(kind CapType) - - // Clear sets all bits of the given capabilities kind to zero. The - // 'kind' value should be one or combination (OR'ed) of CAPS, - // BOUNDS or AMBS. - Clear(kind CapType) - - // String return current capabilities state of the given capabilities - // set as string. The 'which' value should be one of EFFECTIVE, - // PERMITTED, INHERITABLE BOUNDING or AMBIENT - StringCap(which CapType) string - - // String return current capabilities state as string. - String() string - - // Load load actual capabilities value. This will overwrite all - // outstanding changes. - Load() error - - // Apply apply the capabilities settings, so all changes made by - // [Set], [Unset], [Fill], or [Clear] will take effect. - Apply(kind CapType) error -} - -// NewPid initializes a new [Capabilities] object for given pid when -// it is nonzero, or for the current process if pid is 0. -// -// Deprecated: replace with [NewPid2] followed by optional [Capabilities.Load] -// (only if needed). For example, replace: -// -// c, err := NewPid(0) -// if err != nil { -// return err -// } -// -// with: -// -// c, err := NewPid2(0) -// if err != nil { -// return err -// } -// err = c.Load() -// if err != nil { -// return err -// } -func NewPid(pid int) (Capabilities, error) { - c, err := newPid(pid) - if err != nil { - return c, err - } - err = c.Load() - return c, err -} - -// NewPid2 initializes a new [Capabilities] object for given pid when -// it is nonzero, or for the current process if pid is 0. This -// does not load the process's current capabilities; if needed, -// call [Capabilities.Load]. -func NewPid2(pid int) (Capabilities, error) { - return newPid(pid) -} - -// NewFile initializes a new Capabilities object for given file path. -// -// Deprecated: replace with [NewFile2] followed by optional [Capabilities.Load] -// (only if needed). For example, replace: -// -// c, err := NewFile(path) -// if err != nil { -// return err -// } -// -// with: -// -// c, err := NewFile2(path) -// if err != nil { -// return err -// } -// err = c.Load() -// if err != nil { -// return err -// } -func NewFile(path string) (Capabilities, error) { - c, err := newFile(path) - if err != nil { - return c, err - } - err = c.Load() - return c, err -} - -// NewFile2 creates a new initialized [Capabilities] object for given -// file path. This does not load the process's current capabilities; -// if needed, call [Capabilities.Load]. -func NewFile2(path string) (Capabilities, error) { - return newFile(path) -} - -// LastCap returns highest valid capability of the running kernel, -// or an error if it can not be obtained. -// -// See also: [ListSupported]. -func LastCap() (Cap, error) { - return lastCap() -} - -// GetAmbient determines if a specific ambient capability is raised in the -// calling thread. -func GetAmbient(c Cap) (bool, error) { - return getAmbient(c) -} - -// SetAmbient raises or lowers specified ambient capabilities for the calling -// thread. To complete successfully, the prevailing effective capability set -// must have a raised CAP_SETPCAP. Further, to raise a specific ambient -// capability the inheritable and permitted sets of the calling thread must -// already contain the specified capability. -func SetAmbient(raise bool, caps ...Cap) error { - return setAmbient(raise, caps...) -} - -// ResetAmbient resets all of the ambient capabilities for the calling thread -// to their lowered value. -func ResetAmbient() error { - return resetAmbient() -} - -// GetBound determines if a specific bounding capability is raised in the -// calling thread. -func GetBound(c Cap) (bool, error) { - return getBound(c) -} - -// DropBound lowers the specified bounding set capability. -func DropBound(caps ...Cap) error { - return dropBound(caps...) -} diff --git a/vendor/github.com/moby/sys/capability/capability_linux.go b/vendor/github.com/moby/sys/capability/capability_linux.go deleted file mode 100644 index 234b1efb..00000000 --- a/vendor/github.com/moby/sys/capability/capability_linux.go +++ /dev/null @@ -1,591 +0,0 @@ -// Copyright 2023 The Capability Authors. -// Copyright 2013 Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package capability - -import ( - "bufio" - "errors" - "fmt" - "io" - "os" - "strconv" - "strings" - "sync" - "syscall" -) - -const ( - linuxCapVer1 = 0x19980330 // No longer supported. - linuxCapVer2 = 0x20071026 // No longer supported. - linuxCapVer3 = 0x20080522 -) - -var lastCap = sync.OnceValues(func() (Cap, error) { - f, err := os.Open("/proc/sys/kernel/cap_last_cap") - if err != nil { - return 0, err - } - - buf := make([]byte, 11) - l, err := f.Read(buf) - f.Close() - if err != nil { - return 0, err - } - buf = buf[:l] - - last, err := strconv.Atoi(strings.TrimSpace(string(buf))) - if err != nil { - return 0, err - } - return Cap(last), nil -}) - -func capUpperMask() uint32 { - last, err := lastCap() - if err != nil || last < 32 { - return 0 - } - return (uint32(1) << (uint(last) - 31)) - 1 -} - -func mkStringCap(c Capabilities, which CapType) (ret string) { - last, err := lastCap() - if err != nil { - return "" - } - for i, first := Cap(0), true; i <= last; i++ { - if !c.Get(which, i) { - continue - } - if first { - first = false - } else { - ret += ", " - } - ret += i.String() - } - return -} - -func mkString(c Capabilities, max CapType) (ret string) { - ret = "{" - for i := CapType(1); i <= max; i <<= 1 { - ret += " " + i.String() + "=\"" - if c.Empty(i) { - ret += "empty" - } else if c.Full(i) { - ret += "full" - } else { - ret += c.StringCap(i) - } - ret += "\"" - } - ret += " }" - return -} - -var capVersion = sync.OnceValues(func() (uint32, error) { - var hdr capHeader - err := capget(&hdr, nil) - return hdr.version, err -}) - -func newPid(pid int) (c Capabilities, retErr error) { - ver, err := capVersion() - if err != nil { - retErr = fmt.Errorf("unable to get capability version from the kernel: %w", err) - return - } - switch ver { - case linuxCapVer1, linuxCapVer2: - retErr = errors.New("old/unsupported capability version (kernel older than 2.6.26?)") - default: - // Either linuxCapVer3, or an unknown/future version (such as v4). - // In the latter case, we fall back to v3 as the latest version known - // to this package, as kernel should be backward-compatible to v3. - p := new(capsV3) - p.hdr.version = linuxCapVer3 - p.hdr.pid = int32(pid) - c = p - } - return -} - -func ignoreEINVAL(err error) error { - if errors.Is(err, syscall.EINVAL) { - err = nil - } - return err -} - -type capsV3 struct { - hdr capHeader - data [2]capData - bounds [2]uint32 - ambient [2]uint32 -} - -func (c *capsV3) Get(which CapType, what Cap) bool { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable |= 1 << uint(what) - } - if which&BOUNDING != 0 { - c.bounds[i] |= 1 << uint(what) - } - if which&AMBIENT != 0 { - c.ambient[i] |= 1 << uint(what) - } - } -} - -func (c *capsV3) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data[i].effective &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data[i].inheritable &= ^(1 << uint(what)) - } - if which&BOUNDING != 0 { - c.bounds[i] &= ^(1 << uint(what)) - } - if which&AMBIENT != 0 { - c.ambient[i] &= ^(1 << uint(what)) - } - } -} - -func (c *capsV3) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0xffffffff - c.data[0].permitted = 0xffffffff - c.data[0].inheritable = 0 - c.data[1].effective = 0xffffffff - c.data[1].permitted = 0xffffffff - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0xffffffff - c.bounds[1] = 0xffffffff - } - if kind&AMBS == AMBS { - c.ambient[0] = 0xffffffff - c.ambient[1] = 0xffffffff - } -} - -func (c *capsV3) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data[0].effective = 0 - c.data[0].permitted = 0 - c.data[0].inheritable = 0 - c.data[1].effective = 0 - c.data[1].permitted = 0 - c.data[1].inheritable = 0 - } - - if kind&BOUNDS == BOUNDS { - c.bounds[0] = 0 - c.bounds[1] = 0 - } - if kind&AMBS == AMBS { - c.ambient[0] = 0 - c.ambient[1] = 0 - } -} - -func (c *capsV3) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsV3) String() (ret string) { - return mkString(c, BOUNDING) -} - -func (c *capsV3) Load() (err error) { - err = capget(&c.hdr, &c.data[0]) - if err != nil { - return - } - - path := "/proc/self/status" - if c.hdr.pid != 0 { - path = fmt.Sprintf("/proc/%d/status", c.hdr.pid) - } - - f, err := os.Open(path) - if err != nil { - return - } - b := bufio.NewReader(f) - for { - line, e := b.ReadString('\n') - if e != nil { - if e != io.EOF { - err = e - } - break - } - if val, ok := strings.CutPrefix(line, "CapBnd:\t"); ok { - _, err = fmt.Sscanf(val, "%08x%08x", &c.bounds[1], &c.bounds[0]) - if err != nil { - break - } - continue - } - if val, ok := strings.CutPrefix(line, "CapAmb:\t"); ok { - _, err = fmt.Sscanf(val, "%08x%08x", &c.ambient[1], &c.ambient[0]) - if err != nil { - break - } - continue - } - } - f.Close() - - return -} - -func (c *capsV3) Apply(kind CapType) error { - if c.hdr.pid != 0 { - return errors.New("unable to modify capabilities of another process") - } - last, err := LastCap() - if err != nil { - return err - } - if kind&BOUNDS == BOUNDS { - var data [2]capData - err = capget(&c.hdr, &data[0]) - if err != nil { - return err - } - if (1< 0, nil -} - -func setAmbient(raise bool, caps ...Cap) error { - op := pr_CAP_AMBIENT_RAISE - if !raise { - op = pr_CAP_AMBIENT_LOWER - } - for _, val := range caps { - err := prctl(pr_CAP_AMBIENT, op, uintptr(val)) - if err != nil { - return err - } - } - return nil -} - -func resetAmbient() error { - return prctl(pr_CAP_AMBIENT, pr_CAP_AMBIENT_CLEAR_ALL, 0) -} - -func getBound(c Cap) (bool, error) { - res, err := prctlRetInt(syscall.PR_CAPBSET_READ, uintptr(c), 0) - if err != nil { - return false, err - } - return res > 0, nil -} - -func dropBound(caps ...Cap) error { - for _, val := range caps { - err := prctl(syscall.PR_CAPBSET_DROP, uintptr(val), 0) - if err != nil { - return err - } - } - return nil -} - -func newFile(path string) (c Capabilities, err error) { - c = &capsFile{path: path} - return -} - -type capsFile struct { - path string - data vfscapData -} - -func (c *capsFile) Get(which CapType, what Cap) bool { - var i uint - if what > 31 { - if c.data.version == 1 { - return false - } - i = uint(what) >> 5 - what %= 32 - } - - switch which { - case EFFECTIVE: - return (1< 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] |= 1 << uint(what) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted |= 1 << uint(what) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable |= 1 << uint(what) - } - } -} - -func (c *capsFile) Unset(which CapType, caps ...Cap) { - for _, what := range caps { - var i uint - if what > 31 { - if c.data.version == 1 { - continue - } - i = uint(what) >> 5 - what %= 32 - } - - if which&EFFECTIVE != 0 { - c.data.effective[i] &= ^(1 << uint(what)) - } - if which&PERMITTED != 0 { - c.data.data[i].permitted &= ^(1 << uint(what)) - } - if which&INHERITABLE != 0 { - c.data.data[i].inheritable &= ^(1 << uint(what)) - } - } -} - -func (c *capsFile) Fill(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0xffffffff - c.data.data[0].permitted = 0xffffffff - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0xffffffff - c.data.data[1].permitted = 0xffffffff - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) Clear(kind CapType) { - if kind&CAPS == CAPS { - c.data.effective[0] = 0 - c.data.data[0].permitted = 0 - c.data.data[0].inheritable = 0 - if c.data.version == 2 { - c.data.effective[1] = 0 - c.data.data[1].permitted = 0 - c.data.data[1].inheritable = 0 - } - } -} - -func (c *capsFile) StringCap(which CapType) (ret string) { - return mkStringCap(c, which) -} - -func (c *capsFile) String() (ret string) { - return mkString(c, INHERITABLE) -} - -func (c *capsFile) Load() (err error) { - return getVfsCap(c.path, &c.data) -} - -func (c *capsFile) Apply(kind CapType) (err error) { - if kind&CAPS == CAPS { - return setVfsCap(c.path, &c.data) - } - return -} diff --git a/vendor/github.com/moby/sys/capability/capability_noop.go b/vendor/github.com/moby/sys/capability/capability_noop.go deleted file mode 100644 index b766e444..00000000 --- a/vendor/github.com/moby/sys/capability/capability_noop.go +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2023 The Capability Authors. -// Copyright 2013 Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !linux - -package capability - -import "errors" - -var errNotSup = errors.New("not supported") - -func newPid(_ int) (Capabilities, error) { - return nil, errNotSup -} - -func newFile(_ string) (Capabilities, error) { - return nil, errNotSup -} - -func lastCap() (Cap, error) { - return -1, errNotSup -} - -func getAmbient(_ Cap) (bool, error) { - return false, errNotSup -} - -func setAmbient(_ bool, _ ...Cap) error { - return errNotSup -} - -func resetAmbient() error { - return errNotSup -} - -func getBound(_ Cap) (bool, error) { - return false, errNotSup -} - -func dropBound(_ ...Cap) error { - return errNotSup -} diff --git a/vendor/github.com/moby/sys/capability/enum.go b/vendor/github.com/moby/sys/capability/enum.go deleted file mode 100644 index f8859331..00000000 --- a/vendor/github.com/moby/sys/capability/enum.go +++ /dev/null @@ -1,330 +0,0 @@ -// Copyright 2024 The Capability Authors. -// Copyright 2013 Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package capability - -import "slices" - -type CapType uint - -func (c CapType) String() string { - switch c { - case EFFECTIVE: - return "effective" - case PERMITTED: - return "permitted" - case INHERITABLE: - return "inheritable" - case BOUNDING: - return "bounding" - case CAPS: - return "caps" - case AMBIENT: - return "ambient" - } - return "unknown" -} - -const ( - EFFECTIVE CapType = 1 << iota - PERMITTED - INHERITABLE - BOUNDING - AMBIENT - - CAPS = EFFECTIVE | PERMITTED | INHERITABLE - BOUNDS = BOUNDING - AMBS = AMBIENT -) - -//go:generate go run enumgen/gen.go -type Cap int - -// POSIX-draft defined capabilities and Linux extensions. -// -// Defined in https://github.com/torvalds/linux/blob/master/include/uapi/linux/capability.h -const ( - // In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this - // overrides the restriction of changing file ownership and group - // ownership. - CAP_CHOWN = Cap(0) - - // Override all DAC access, including ACL execute access if - // [_POSIX_ACL] is defined. Excluding DAC access covered by - // CAP_LINUX_IMMUTABLE. - CAP_DAC_OVERRIDE = Cap(1) - - // Overrides all DAC restrictions regarding read and search on files - // and directories, including ACL restrictions if [_POSIX_ACL] is - // defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. - CAP_DAC_READ_SEARCH = Cap(2) - - // Overrides all restrictions about allowed operations on files, where - // file owner ID must be equal to the user ID, except where CAP_FSETID - // is applicable. It doesn't override MAC and DAC restrictions. - CAP_FOWNER = Cap(3) - - // Overrides the following restrictions that the effective user ID - // shall match the file owner ID when setting the S_ISUID and S_ISGID - // bits on that file; that the effective group ID (or one of the - // supplementary group IDs) shall match the file owner ID when setting - // the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are - // cleared on successful return from chown(2) (not implemented). - CAP_FSETID = Cap(4) - - // Overrides the restriction that the real or effective user ID of a - // process sending a signal must match the real or effective user ID - // of the process receiving the signal. - CAP_KILL = Cap(5) - - // Allows setgid(2) manipulation - // Allows setgroups(2) - // Allows forged gids on socket credentials passing. - CAP_SETGID = Cap(6) - - // Allows set*uid(2) manipulation (including fsuid). - // Allows forged pids on socket credentials passing. - CAP_SETUID = Cap(7) - - // Linux-specific capabilities - - // Without VFS support for capabilities: - // Transfer any capability in your permitted set to any pid, - // remove any capability in your permitted set from any pid - // With VFS support for capabilities (neither of above, but) - // Add any capability from current's capability bounding set - // to the current process' inheritable set - // Allow taking bits out of capability bounding set - // Allow modification of the securebits for a process - CAP_SETPCAP = Cap(8) - - // Allow modification of S_IMMUTABLE and S_APPEND file attributes - CAP_LINUX_IMMUTABLE = Cap(9) - - // Allows binding to TCP/UDP sockets below 1024 - // Allows binding to ATM VCIs below 32 - CAP_NET_BIND_SERVICE = Cap(10) - - // Allow broadcasting, listen to multicast - CAP_NET_BROADCAST = Cap(11) - - // Allow interface configuration - // Allow administration of IP firewall, masquerading and accounting - // Allow setting debug option on sockets - // Allow modification of routing tables - // Allow setting arbitrary process / process group ownership on - // sockets - // Allow binding to any address for transparent proxying (also via NET_RAW) - // Allow setting TOS (type of service) - // Allow setting promiscuous mode - // Allow clearing driver statistics - // Allow multicasting - // Allow read/write of device-specific registers - // Allow activation of ATM control sockets - CAP_NET_ADMIN = Cap(12) - - // Allow use of RAW sockets - // Allow use of PACKET sockets - // Allow binding to any address for transparent proxying (also via NET_ADMIN) - CAP_NET_RAW = Cap(13) - - // Allow locking of shared memory segments - // Allow mlock and mlockall (which doesn't really have anything to do - // with IPC) - CAP_IPC_LOCK = Cap(14) - - // Override IPC ownership checks - CAP_IPC_OWNER = Cap(15) - - // Insert and remove kernel modules - modify kernel without limit - CAP_SYS_MODULE = Cap(16) - - // Allow ioperm/iopl access - // Allow sending USB messages to any device via /proc/bus/usb - CAP_SYS_RAWIO = Cap(17) - - // Allow use of chroot() - CAP_SYS_CHROOT = Cap(18) - - // Allow ptrace() of any process - CAP_SYS_PTRACE = Cap(19) - - // Allow configuration of process accounting - CAP_SYS_PACCT = Cap(20) - - // Allow configuration of the secure attention key - // Allow administration of the random device - // Allow examination and configuration of disk quotas - // Allow setting the domainname - // Allow setting the hostname - // Allow calling bdflush() - // Allow mount() and umount(), setting up new smb connection - // Allow some autofs root ioctls - // Allow nfsservctl - // Allow VM86_REQUEST_IRQ - // Allow to read/write pci config on alpha - // Allow irix_prctl on mips (setstacksize) - // Allow flushing all cache on m68k (sys_cacheflush) - // Allow removing semaphores - // Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores - // and shared memory - // Allow locking/unlocking of shared memory segment - // Allow turning swap on/off - // Allow forged pids on socket credentials passing - // Allow setting readahead and flushing buffers on block devices - // Allow setting geometry in floppy driver - // Allow turning DMA on/off in xd driver - // Allow administration of md devices (mostly the above, but some - // extra ioctls) - // Allow tuning the ide driver - // Allow access to the nvram device - // Allow administration of apm_bios, serial and bttv (TV) device - // Allow manufacturer commands in isdn CAPI support driver - // Allow reading non-standardized portions of pci configuration space - // Allow DDI debug ioctl on sbpcd driver - // Allow setting up serial ports - // Allow sending raw qic-117 commands - // Allow enabling/disabling tagged queuing on SCSI controllers and sending - // arbitrary SCSI commands - // Allow setting encryption key on loopback filesystem - // Allow setting zone reclaim policy - // Allow everything under CAP_BPF and CAP_PERFMON for backward compatibility - CAP_SYS_ADMIN = Cap(21) - - // Allow use of reboot() - CAP_SYS_BOOT = Cap(22) - - // Allow raising priority and setting priority on other (different - // UID) processes - // Allow use of FIFO and round-robin (realtime) scheduling on own - // processes and setting the scheduling algorithm used by another - // process. - // Allow setting cpu affinity on other processes - CAP_SYS_NICE = Cap(23) - - // Override resource limits. Set resource limits. - // Override quota limits. - // Override reserved space on ext2 filesystem - // Modify data journaling mode on ext3 filesystem (uses journaling - // resources) - // NOTE: ext2 honors fsuid when checking for resource overrides, so - // you can override using fsuid too - // Override size restrictions on IPC message queues - // Allow more than 64hz interrupts from the real-time clock - // Override max number of consoles on console allocation - // Override max number of keymaps - // Control memory reclaim behavior - CAP_SYS_RESOURCE = Cap(24) - - // Allow manipulation of system clock - // Allow irix_stime on mips - // Allow setting the real-time clock - CAP_SYS_TIME = Cap(25) - - // Allow configuration of tty devices - // Allow vhangup() of tty - CAP_SYS_TTY_CONFIG = Cap(26) - - // Allow the privileged aspects of mknod() - CAP_MKNOD = Cap(27) - - // Allow taking of leases on files - CAP_LEASE = Cap(28) - - CAP_AUDIT_WRITE = Cap(29) - CAP_AUDIT_CONTROL = Cap(30) - CAP_SETFCAP = Cap(31) - - // Override MAC access. - // The base kernel enforces no MAC policy. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based overrides of that policy, this is - // the capability it should use to do so. - CAP_MAC_OVERRIDE = Cap(32) - - // Allow MAC configuration or state changes. - // The base kernel requires no MAC configuration. - // An LSM may enforce a MAC policy, and if it does and it chooses - // to implement capability based checks on modifications to that - // policy or the data required to maintain it, this is the - // capability it should use to do so. - CAP_MAC_ADMIN = Cap(33) - - // Allow configuring the kernel's syslog (printk behaviour) - CAP_SYSLOG = Cap(34) - - // Allow triggering something that will wake the system - CAP_WAKE_ALARM = Cap(35) - - // Allow preventing system suspends - CAP_BLOCK_SUSPEND = Cap(36) - - // Allow reading the audit log via multicast netlink socket - CAP_AUDIT_READ = Cap(37) - - // Allow system performance and observability privileged operations - // using perf_events, i915_perf and other kernel subsystems - CAP_PERFMON = Cap(38) - - // CAP_BPF allows the following BPF operations: - // - Creating all types of BPF maps - // - Advanced verifier features - // - Indirect variable access - // - Bounded loops - // - BPF to BPF function calls - // - Scalar precision tracking - // - Larger complexity limits - // - Dead code elimination - // - And potentially other features - // - Loading BPF Type Format (BTF) data - // - Retrieve xlated and JITed code of BPF programs - // - Use bpf_spin_lock() helper - // - // CAP_PERFMON relaxes the verifier checks further: - // - BPF progs can use of pointer-to-integer conversions - // - speculation attack hardening measures are bypassed - // - bpf_probe_read to read arbitrary kernel memory is allowed - // - bpf_trace_printk to print kernel memory is allowed - // - // CAP_SYS_ADMIN is required to use bpf_probe_write_user. - // - // CAP_SYS_ADMIN is required to iterate system wide loaded - // programs, maps, links, BTFs and convert their IDs to file descriptors. - // - // CAP_PERFMON and CAP_BPF are required to load tracing programs. - // CAP_NET_ADMIN and CAP_BPF are required to load networking programs. - CAP_BPF = Cap(39) - - // Allow checkpoint/restore related operations. - // Introduced in kernel 5.9 - CAP_CHECKPOINT_RESTORE = Cap(40) -) - -// List returns the list of all capabilities known to the package. -// -// Deprecated: use [ListKnown] or [ListSupported] instead. -func List() []Cap { - return ListKnown() -} - -// ListKnown returns the list of all capabilities known to the package. -func ListKnown() []Cap { - return list() -} - -// ListSupported returns the list of all capabilities known to the package, -// except those that are not supported by the currently running Linux kernel. -func ListSupported() ([]Cap, error) { - last, err := LastCap() - if err != nil { - return nil, err - } - return slices.DeleteFunc(list(), func(c Cap) bool { - // Remove caps not supported by the kernel. - return c > last - }), nil -} diff --git a/vendor/github.com/moby/sys/capability/enum_gen.go b/vendor/github.com/moby/sys/capability/enum_gen.go deleted file mode 100644 index f72cd43a..00000000 --- a/vendor/github.com/moby/sys/capability/enum_gen.go +++ /dev/null @@ -1,137 +0,0 @@ -// Code generated by go generate; DO NOT EDIT. - -package capability - -func (c Cap) String() string { - switch c { - case CAP_CHOWN: - return "chown" - case CAP_DAC_OVERRIDE: - return "dac_override" - case CAP_DAC_READ_SEARCH: - return "dac_read_search" - case CAP_FOWNER: - return "fowner" - case CAP_FSETID: - return "fsetid" - case CAP_KILL: - return "kill" - case CAP_SETGID: - return "setgid" - case CAP_SETUID: - return "setuid" - case CAP_SETPCAP: - return "setpcap" - case CAP_LINUX_IMMUTABLE: - return "linux_immutable" - case CAP_NET_BIND_SERVICE: - return "net_bind_service" - case CAP_NET_BROADCAST: - return "net_broadcast" - case CAP_NET_ADMIN: - return "net_admin" - case CAP_NET_RAW: - return "net_raw" - case CAP_IPC_LOCK: - return "ipc_lock" - case CAP_IPC_OWNER: - return "ipc_owner" - case CAP_SYS_MODULE: - return "sys_module" - case CAP_SYS_RAWIO: - return "sys_rawio" - case CAP_SYS_CHROOT: - return "sys_chroot" - case CAP_SYS_PTRACE: - return "sys_ptrace" - case CAP_SYS_PACCT: - return "sys_pacct" - case CAP_SYS_ADMIN: - return "sys_admin" - case CAP_SYS_BOOT: - return "sys_boot" - case CAP_SYS_NICE: - return "sys_nice" - case CAP_SYS_RESOURCE: - return "sys_resource" - case CAP_SYS_TIME: - return "sys_time" - case CAP_SYS_TTY_CONFIG: - return "sys_tty_config" - case CAP_MKNOD: - return "mknod" - case CAP_LEASE: - return "lease" - case CAP_AUDIT_WRITE: - return "audit_write" - case CAP_AUDIT_CONTROL: - return "audit_control" - case CAP_SETFCAP: - return "setfcap" - case CAP_MAC_OVERRIDE: - return "mac_override" - case CAP_MAC_ADMIN: - return "mac_admin" - case CAP_SYSLOG: - return "syslog" - case CAP_WAKE_ALARM: - return "wake_alarm" - case CAP_BLOCK_SUSPEND: - return "block_suspend" - case CAP_AUDIT_READ: - return "audit_read" - case CAP_PERFMON: - return "perfmon" - case CAP_BPF: - return "bpf" - case CAP_CHECKPOINT_RESTORE: - return "checkpoint_restore" - } - return "unknown" -} - -func list() []Cap { - return []Cap{ - CAP_CHOWN, - CAP_DAC_OVERRIDE, - CAP_DAC_READ_SEARCH, - CAP_FOWNER, - CAP_FSETID, - CAP_KILL, - CAP_SETGID, - CAP_SETUID, - CAP_SETPCAP, - CAP_LINUX_IMMUTABLE, - CAP_NET_BIND_SERVICE, - CAP_NET_BROADCAST, - CAP_NET_ADMIN, - CAP_NET_RAW, - CAP_IPC_LOCK, - CAP_IPC_OWNER, - CAP_SYS_MODULE, - CAP_SYS_RAWIO, - CAP_SYS_CHROOT, - CAP_SYS_PTRACE, - CAP_SYS_PACCT, - CAP_SYS_ADMIN, - CAP_SYS_BOOT, - CAP_SYS_NICE, - CAP_SYS_RESOURCE, - CAP_SYS_TIME, - CAP_SYS_TTY_CONFIG, - CAP_MKNOD, - CAP_LEASE, - CAP_AUDIT_WRITE, - CAP_AUDIT_CONTROL, - CAP_SETFCAP, - CAP_MAC_OVERRIDE, - CAP_MAC_ADMIN, - CAP_SYSLOG, - CAP_WAKE_ALARM, - CAP_BLOCK_SUSPEND, - CAP_AUDIT_READ, - CAP_PERFMON, - CAP_BPF, - CAP_CHECKPOINT_RESTORE, - } -} diff --git a/vendor/github.com/moby/sys/capability/syscall_linux.go b/vendor/github.com/moby/sys/capability/syscall_linux.go deleted file mode 100644 index 2d8faa85..00000000 --- a/vendor/github.com/moby/sys/capability/syscall_linux.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2024 The Capability Authors. -// Copyright 2013 Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package capability - -import ( - "syscall" - "unsafe" -) - -type capHeader struct { - version uint32 - pid int32 -} - -type capData struct { - effective uint32 - permitted uint32 - inheritable uint32 -} - -func capget(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_CAPGET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -func capset(hdr *capHeader, data *capData) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_CAPSET, uintptr(unsafe.Pointer(hdr)), uintptr(unsafe.Pointer(data)), 0) - if e1 != 0 { - err = e1 - } - return -} - -// not yet in syscall -const ( - pr_CAP_AMBIENT = 47 - pr_CAP_AMBIENT_IS_SET = uintptr(1) - pr_CAP_AMBIENT_RAISE = uintptr(2) - pr_CAP_AMBIENT_LOWER = uintptr(3) - pr_CAP_AMBIENT_CLEAR_ALL = uintptr(4) -) - -func prctl(option int, arg2, arg3 uintptr) (err error) { - _, _, e1 := syscall.RawSyscall(syscall.SYS_PRCTL, uintptr(option), arg2, arg3) - if e1 != 0 { - err = e1 - } - return -} - -func prctlRetInt(option int, arg2, arg3 uintptr) (int, error) { - ret, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, uintptr(option), arg2, arg3) - if err != 0 { - return 0, err - } - return int(ret), nil -} - -const ( - vfsXattrName = "security.capability" - - vfsCapVerMask = 0xff000000 - vfsCapVer1 = 0x01000000 - vfsCapVer2 = 0x02000000 - - vfsCapFlagMask = ^vfsCapVerMask - vfsCapFlageffective = 0x000001 - - vfscapDataSizeV1 = 4 * (1 + 2*1) - vfscapDataSizeV2 = 4 * (1 + 2*2) -) - -type vfscapData struct { - magic uint32 - data [2]struct { - permitted uint32 - inheritable uint32 - } - effective [2]uint32 - version int8 -} - -var _vfsXattrName *byte - -func init() { - _vfsXattrName, _ = syscall.BytePtrFromString(vfsXattrName) -} - -func getVfsCap(path string, dest *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - r0, _, e1 := syscall.RawSyscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(dest)), vfscapDataSizeV2, 0, 0) - if e1 != 0 { - if e1 == syscall.ENODATA { - dest.version = 2 - return - } - err = e1 - } - switch dest.magic & vfsCapVerMask { - case vfsCapVer1: - dest.version = 1 - if r0 != vfscapDataSizeV1 { - return syscall.EINVAL - } - dest.data[1].permitted = 0 - dest.data[1].inheritable = 0 - case vfsCapVer2: - dest.version = 2 - if r0 != vfscapDataSizeV2 { - return syscall.EINVAL - } - default: - return syscall.EINVAL - } - if dest.magic&vfsCapFlageffective != 0 { - dest.effective[0] = dest.data[0].permitted | dest.data[0].inheritable - dest.effective[1] = dest.data[1].permitted | dest.data[1].inheritable - } else { - dest.effective[0] = 0 - dest.effective[1] = 0 - } - return -} - -func setVfsCap(path string, data *vfscapData) (err error) { - var _p0 *byte - _p0, err = syscall.BytePtrFromString(path) - if err != nil { - return - } - var size uintptr - if data.version == 1 { - data.magic = vfsCapVer1 - size = vfscapDataSizeV1 - } else if data.version == 2 { - data.magic = vfsCapVer2 - if data.effective[0] != 0 || data.effective[1] != 0 { - data.magic |= vfsCapFlageffective - } - size = vfscapDataSizeV2 - } else { - return syscall.EINVAL - } - _, _, e1 := syscall.RawSyscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_vfsXattrName)), uintptr(unsafe.Pointer(data)), size, 0, 0) - if e1 != 0 { - err = e1 - } - return -} diff --git a/vendor/github.com/opencontainers/runtime-tools/LICENSE b/vendor/github.com/opencontainers/runtime-tools/LICENSE deleted file mode 100644 index bdc40365..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 The Linux Foundation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/config.go b/vendor/github.com/opencontainers/runtime-tools/generate/config.go deleted file mode 100644 index 48f281d2..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/config.go +++ /dev/null @@ -1,194 +0,0 @@ -package generate - -import ( - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -func (g *Generator) initConfig() { - if g.Config == nil { - g.Config = &rspec.Spec{} - } -} - -func (g *Generator) initConfigProcess() { - g.initConfig() - if g.Config.Process == nil { - g.Config.Process = &rspec.Process{} - } -} - -func (g *Generator) initConfigProcessConsoleSize() { - g.initConfigProcess() - if g.Config.Process.ConsoleSize == nil { - g.Config.Process.ConsoleSize = &rspec.Box{} - } -} - -func (g *Generator) initConfigProcessCapabilities() { - g.initConfigProcess() - if g.Config.Process.Capabilities == nil { - g.Config.Process.Capabilities = &rspec.LinuxCapabilities{} - } -} - -func (g *Generator) initConfigRoot() { - g.initConfig() - if g.Config.Root == nil { - g.Config.Root = &rspec.Root{} - } -} - -func (g *Generator) initConfigAnnotations() { - g.initConfig() - if g.Config.Annotations == nil { - g.Config.Annotations = make(map[string]string) - } -} - -func (g *Generator) initConfigHooks() { - g.initConfig() - if g.Config.Hooks == nil { - g.Config.Hooks = &rspec.Hooks{} - } -} - -func (g *Generator) initConfigLinux() { - g.initConfig() - if g.Config.Linux == nil { - g.Config.Linux = &rspec.Linux{} - } -} - -func (g *Generator) initConfigLinuxIntelRdt() { - g.initConfigLinux() - if g.Config.Linux.IntelRdt == nil { - g.Config.Linux.IntelRdt = &rspec.LinuxIntelRdt{} - } -} - -func (g *Generator) initConfigLinuxSysctl() { - g.initConfigLinux() - if g.Config.Linux.Sysctl == nil { - g.Config.Linux.Sysctl = make(map[string]string) - } -} - -func (g *Generator) initConfigLinuxSeccomp() { - g.initConfigLinux() - if g.Config.Linux.Seccomp == nil { - g.Config.Linux.Seccomp = &rspec.LinuxSeccomp{} - } -} - -func (g *Generator) initConfigLinuxResources() { - g.initConfigLinux() - if g.Config.Linux.Resources == nil { - g.Config.Linux.Resources = &rspec.LinuxResources{} - } -} - -func (g *Generator) initConfigLinuxResourcesBlockIO() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.BlockIO == nil { - g.Config.Linux.Resources.BlockIO = &rspec.LinuxBlockIO{} - } -} - -// InitConfigLinuxResourcesCPU initializes CPU of Linux resources -func (g *Generator) InitConfigLinuxResourcesCPU() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.CPU == nil { - g.Config.Linux.Resources.CPU = &rspec.LinuxCPU{} - } -} - -func (g *Generator) initConfigLinuxResourcesMemory() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.Memory == nil { - g.Config.Linux.Resources.Memory = &rspec.LinuxMemory{} - } -} - -func (g *Generator) initConfigLinuxResourcesNetwork() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.Network == nil { - g.Config.Linux.Resources.Network = &rspec.LinuxNetwork{} - } -} - -func (g *Generator) initConfigLinuxResourcesPids() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.Pids == nil { - g.Config.Linux.Resources.Pids = &rspec.LinuxPids{} - } -} - -func (g *Generator) initConfigLinuxResourcesUnified() { - g.initConfigLinuxResources() - if g.Config.Linux.Resources.Unified == nil { - g.Config.Linux.Resources.Unified = map[string]string{} - } -} - -func (g *Generator) initConfigSolaris() { - g.initConfig() - if g.Config.Solaris == nil { - g.Config.Solaris = &rspec.Solaris{} - } -} - -func (g *Generator) initConfigSolarisCappedCPU() { - g.initConfigSolaris() - if g.Config.Solaris.CappedCPU == nil { - g.Config.Solaris.CappedCPU = &rspec.SolarisCappedCPU{} - } -} - -func (g *Generator) initConfigSolarisCappedMemory() { - g.initConfigSolaris() - if g.Config.Solaris.CappedMemory == nil { - g.Config.Solaris.CappedMemory = &rspec.SolarisCappedMemory{} - } -} - -func (g *Generator) initConfigWindows() { - g.initConfig() - if g.Config.Windows == nil { - g.Config.Windows = &rspec.Windows{} - } -} - -func (g *Generator) initConfigWindowsNetwork() { - g.initConfigWindows() - if g.Config.Windows.Network == nil { - g.Config.Windows.Network = &rspec.WindowsNetwork{} - } -} - -func (g *Generator) initConfigWindowsHyperV() { - g.initConfigWindows() - if g.Config.Windows.HyperV == nil { - g.Config.Windows.HyperV = &rspec.WindowsHyperV{} - } -} - -func (g *Generator) initConfigWindowsResources() { - g.initConfigWindows() - if g.Config.Windows.Resources == nil { - g.Config.Windows.Resources = &rspec.WindowsResources{} - } -} - -func (g *Generator) initConfigWindowsResourcesMemory() { - g.initConfigWindowsResources() - if g.Config.Windows.Resources.Memory == nil { - g.Config.Windows.Resources.Memory = &rspec.WindowsMemoryResources{} - } -} - -func (g *Generator) initConfigVM() { - g.initConfig() - if g.Config.VM == nil { - g.Config.VM = &rspec.VM{} - } -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go b/vendor/github.com/opencontainers/runtime-tools/generate/generate.go deleted file mode 100644 index 44c199e1..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/generate.go +++ /dev/null @@ -1,1881 +0,0 @@ -// Package generate implements functions generating container config files. -package generate - -import ( - "encoding/json" - "fmt" - "io" - "os" - "slices" - "strings" - - "github.com/moby/sys/capability" - rspec "github.com/opencontainers/runtime-spec/specs-go" - "github.com/opencontainers/runtime-tools/generate/seccomp" - capsCheck "github.com/opencontainers/runtime-tools/validate/capabilities" -) - -var ( - // Namespaces include the names of supported namespaces. - Namespaces = []string{"network", "pid", "mount", "ipc", "uts", "user", "cgroup"} - - // we don't care about order...and this is way faster... - removeFunc = func(s []string, i int) []string { - s[i] = s[len(s)-1] - return s[:len(s)-1] - } -) - -const ( - // UnlimitedPidsLimit can be passed to SetLinuxResourcesPidsLimit to - // request unlimited PIDs. - UnlimitedPidsLimit int64 = -1 -) - -// Generator represents a generator for a container config. -type Generator struct { - Config *rspec.Spec - HostSpecific bool - // This is used to keep a cache of the ENVs added to improve - // performance when adding a huge number of ENV variables - envMap map[string]int -} - -// ExportOptions have toggles for exporting only certain parts of the specification -type ExportOptions struct { - Seccomp bool // seccomp toggles if only seccomp should be exported -} - -// New creates a configuration Generator with the default -// configuration for the target operating system. -func New(os string) (generator Generator, err error) { - if os != "linux" && os != "solaris" && os != "windows" && os != "freebsd" { - return generator, fmt.Errorf("no defaults configured for %s", os) - } - - config := rspec.Spec{ - Version: rspec.Version, - Hostname: "mrsdalloway", - } - - if os == "windows" { - config.Process = &rspec.Process{ - Args: []string{ - "cmd", - }, - Cwd: `C:\`, - } - config.Windows = &rspec.Windows{} - } else { - config.Root = &rspec.Root{ - Path: "rootfs", - Readonly: false, - } - config.Process = &rspec.Process{ - Terminal: false, - Args: []string{ - "sh", - }, - } - } - - if os == "linux" || os == "solaris" || os == "freebsd" { - config.Process.User = rspec.User{} - config.Process.Env = []string{ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM=xterm", - } - config.Process.Cwd = "/" - config.Process.Rlimits = []rspec.POSIXRlimit{ - { - Type: "RLIMIT_NOFILE", - Hard: uint64(1024), - Soft: uint64(1024), - }, - } - } - - switch os { - case "linux": - config.Process.Capabilities = &rspec.LinuxCapabilities{ - Bounding: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Permitted: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Inheritable: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Effective: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Ambient: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - } - config.Mounts = []rspec.Mount{ - { - Destination: "/proc", - Type: "proc", - Source: "proc", - Options: []string{"nosuid", "noexec", "nodev"}, - }, - { - Destination: "/dev", - Type: "tmpfs", - Source: "tmpfs", - Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, - }, - { - Destination: "/dev/pts", - Type: "devpts", - Source: "devpts", - Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620", "gid=5"}, - }, - { - Destination: "/dev/shm", - Type: "tmpfs", - Source: "shm", - Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, - }, - { - Destination: "/dev/mqueue", - Type: "mqueue", - Source: "mqueue", - Options: []string{"nosuid", "noexec", "nodev"}, - }, - { - Destination: "/sys", - Type: "sysfs", - Source: "sysfs", - Options: []string{"nosuid", "noexec", "nodev", "ro"}, - }, - } - config.Linux = &rspec.Linux{ - Resources: &rspec.LinuxResources{ - Devices: []rspec.LinuxDeviceCgroup{ - { - Allow: false, - Access: "rwm", - }, - }, - }, - Namespaces: []rspec.LinuxNamespace{ - { - Type: "pid", - }, - { - Type: "network", - }, - { - Type: "ipc", - }, - { - Type: "uts", - }, - { - Type: "mount", - }, - }, - Seccomp: seccomp.DefaultProfile(&config), - } - case "freebsd": - config.Mounts = []rspec.Mount{ - { - Destination: "/dev", - Type: "devfs", - Source: "devfs", - Options: []string{"ruleset=4"}, - }, - { - Destination: "/dev/fd", - Type: "fdescfs", - Source: "fdesc", - Options: []string{}, - }, - } - } - - envCache := map[string]int{} - if config.Process != nil { - envCache = createEnvCacheMap(config.Process.Env) - } - - return Generator{Config: &config, envMap: envCache}, nil -} - -// NewFromSpec creates a configuration Generator from a given -// configuration. -func NewFromSpec(config *rspec.Spec) Generator { - envCache := map[string]int{} - if config != nil && config.Process != nil { - envCache = createEnvCacheMap(config.Process.Env) - } - - return Generator{ - Config: config, - envMap: envCache, - } -} - -// NewFromFile loads the template specified in a file into a -// configuration Generator. -func NewFromFile(path string) (Generator, error) { - cf, err := os.Open(path) - if err != nil { - if os.IsNotExist(err) { - return Generator{}, fmt.Errorf("template configuration at %s not found", path) - } - return Generator{}, err - } - defer cf.Close() - - return NewFromTemplate(cf) -} - -// NewFromTemplate loads the template from io.Reader into a -// configuration Generator. -func NewFromTemplate(r io.Reader) (Generator, error) { - var config rspec.Spec - if err := json.NewDecoder(r).Decode(&config); err != nil { - return Generator{}, err - } - - envCache := map[string]int{} - if config.Process != nil { - envCache = createEnvCacheMap(config.Process.Env) - } - - return Generator{ - Config: &config, - envMap: envCache, - }, nil -} - -// createEnvCacheMap creates a hash map with the ENV variables given by the config -func createEnvCacheMap(env []string) map[string]int { - envMap := make(map[string]int, len(env)) - for i, val := range env { - envMap[val] = i - } - return envMap -} - -// SetSpec sets the configuration in the Generator g. -// -// Deprecated: Replace with: -// -// Use generator.Config = config -func (g *Generator) SetSpec(config *rspec.Spec) { - g.Config = config -} - -// Spec gets the configuration from the Generator g. -// -// Deprecated: Replace with generator.Config. -func (g *Generator) Spec() *rspec.Spec { - return g.Config -} - -// Save writes the configuration into w. -func (g *Generator) Save(w io.Writer, exportOpts ExportOptions) (err error) { - var data []byte - - if g.Config.Linux != nil { - buf, err := json.Marshal(g.Config.Linux) - if err != nil { - return err - } - if string(buf) == "{}" { - g.Config.Linux = nil - } - } - - if exportOpts.Seccomp { - data, err = json.MarshalIndent(g.Config.Linux.Seccomp, "", "\t") - } else { - data, err = json.MarshalIndent(g.Config, "", "\t") - } - if err != nil { - return err - } - - _, err = w.Write(data) - if err != nil { - return err - } - - return nil -} - -// SaveToFile writes the configuration into a file. -func (g *Generator) SaveToFile(path string, exportOpts ExportOptions) error { - f, err := os.Create(path) - if err != nil { - return err - } - defer f.Close() - return g.Save(f, exportOpts) -} - -// SetVersion sets g.Config.Version. -func (g *Generator) SetVersion(version string) { - g.initConfig() - g.Config.Version = version -} - -// SetRootPath sets g.Config.Root.Path. -func (g *Generator) SetRootPath(path string) { - g.initConfigRoot() - g.Config.Root.Path = path -} - -// SetRootReadonly sets g.Config.Root.Readonly. -func (g *Generator) SetRootReadonly(b bool) { - g.initConfigRoot() - g.Config.Root.Readonly = b -} - -// SetHostname sets g.Config.Hostname. -func (g *Generator) SetHostname(s string) { - g.initConfig() - g.Config.Hostname = s -} - -// SetOCIVersion sets g.Config.Version. -func (g *Generator) SetOCIVersion(s string) { - g.initConfig() - g.Config.Version = s -} - -// ClearAnnotations clears g.Config.Annotations. -func (g *Generator) ClearAnnotations() { - if g.Config == nil { - return - } - g.Config.Annotations = make(map[string]string) -} - -// AddAnnotation adds an annotation into g.Config.Annotations. -func (g *Generator) AddAnnotation(key, value string) { - g.initConfigAnnotations() - g.Config.Annotations[key] = value -} - -// RemoveAnnotation remove an annotation from g.Config.Annotations. -func (g *Generator) RemoveAnnotation(key string) { - if g.Config == nil || g.Config.Annotations == nil { - return - } - delete(g.Config.Annotations, key) -} - -// RemoveHostname removes g.Config.Hostname, setting it to an empty string. -func (g *Generator) RemoveHostname() { - if g.Config == nil { - return - } - g.Config.Hostname = "" -} - -// SetProcessConsoleSize sets g.Config.Process.ConsoleSize. -func (g *Generator) SetProcessConsoleSize(width, height uint) { - g.initConfigProcessConsoleSize() - g.Config.Process.ConsoleSize.Width = width - g.Config.Process.ConsoleSize.Height = height -} - -// SetProcessUID sets g.Config.Process.User.UID. -func (g *Generator) SetProcessUID(uid uint32) { - g.initConfigProcess() - g.Config.Process.User.UID = uid -} - -// SetProcessUsername sets g.Config.Process.User.Username. -func (g *Generator) SetProcessUsername(username string) { - g.initConfigProcess() - g.Config.Process.User.Username = username -} - -// SetProcessUmask sets g.Config.Process.User.Umask. -func (g *Generator) SetProcessUmask(umask uint32) { - g.initConfigProcess() - u := umask - g.Config.Process.User.Umask = &u -} - -// SetProcessGID sets g.Config.Process.User.GID. -func (g *Generator) SetProcessGID(gid uint32) { - g.initConfigProcess() - g.Config.Process.User.GID = gid -} - -// SetProcessCwd sets g.Config.Process.Cwd. -func (g *Generator) SetProcessCwd(cwd string) { - g.initConfigProcess() - g.Config.Process.Cwd = cwd -} - -// SetProcessNoNewPrivileges sets g.Config.Process.NoNewPrivileges. -func (g *Generator) SetProcessNoNewPrivileges(b bool) { - g.initConfigProcess() - g.Config.Process.NoNewPrivileges = b -} - -// SetProcessTerminal sets g.Config.Process.Terminal. -func (g *Generator) SetProcessTerminal(b bool) { - g.initConfigProcess() - g.Config.Process.Terminal = b -} - -// SetProcessApparmorProfile sets g.Config.Process.ApparmorProfile. -func (g *Generator) SetProcessApparmorProfile(prof string) { - g.initConfigProcess() - g.Config.Process.ApparmorProfile = prof -} - -// SetProcessArgs sets g.Config.Process.Args. -func (g *Generator) SetProcessArgs(args []string) { - g.initConfigProcess() - g.Config.Process.Args = args -} - -// ClearProcessEnv clears g.Config.Process.Env. -func (g *Generator) ClearProcessEnv() { - if g.Config == nil || g.Config.Process == nil { - return - } - g.Config.Process.Env = []string{} - // Clear out the env cache map as well - g.envMap = map[string]int{} -} - -// AddProcessEnv adds name=value into g.Config.Process.Env, or replaces an -// existing entry with the given name. -func (g *Generator) AddProcessEnv(name, value string) { - if name == "" { - return - } - - g.initConfigProcess() - g.addEnv(fmt.Sprintf("%s=%s", name, value), name) -} - -// AddMultipleProcessEnv adds multiple name=value into g.Config.Process.Env, or replaces -// existing entries with the given name. -func (g *Generator) AddMultipleProcessEnv(envs []string) { - g.initConfigProcess() - - for _, val := range envs { - split := strings.SplitN(val, "=", 2) - g.addEnv(val, split[0]) - } -} - -// addEnv looks through adds ENV to the Process and checks envMap for -// any duplicates -// This is called by both AddMultipleProcessEnv and AddProcessEnv -func (g *Generator) addEnv(env, key string) { - if idx, ok := g.envMap[key]; ok { - // The ENV exists in the cache, so change its value in g.Config.Process.Env - g.Config.Process.Env[idx] = env - } else { - // else the env doesn't exist, so add it and add it's index to g.envMap - g.Config.Process.Env = append(g.Config.Process.Env, env) - g.envMap[key] = len(g.Config.Process.Env) - 1 - } -} - -// AddProcessRlimits adds rlimit into g.Config.Process.Rlimits. -func (g *Generator) AddProcessRlimits(rType string, rHard uint64, rSoft uint64) { - g.initConfigProcess() - for i, rlimit := range g.Config.Process.Rlimits { - if rlimit.Type == rType { - g.Config.Process.Rlimits[i].Hard = rHard - g.Config.Process.Rlimits[i].Soft = rSoft - return - } - } - - newRlimit := rspec.POSIXRlimit{ - Type: rType, - Hard: rHard, - Soft: rSoft, - } - g.Config.Process.Rlimits = append(g.Config.Process.Rlimits, newRlimit) -} - -// RemoveProcessRlimits removes a rlimit from g.Config.Process.Rlimits. -func (g *Generator) RemoveProcessRlimits(rType string) { - if g.Config == nil || g.Config.Process == nil { - return - } - for i, rlimit := range g.Config.Process.Rlimits { - if rlimit.Type == rType { - g.Config.Process.Rlimits = append(g.Config.Process.Rlimits[:i], g.Config.Process.Rlimits[i+1:]...) - return - } - } -} - -// ClearProcessRlimits clear g.Config.Process.Rlimits. -func (g *Generator) ClearProcessRlimits() { - if g.Config == nil || g.Config.Process == nil { - return - } - g.Config.Process.Rlimits = []rspec.POSIXRlimit{} -} - -// ClearProcessAdditionalGids clear g.Config.Process.AdditionalGids. -func (g *Generator) ClearProcessAdditionalGids() { - if g.Config == nil || g.Config.Process == nil { - return - } - g.Config.Process.User.AdditionalGids = []uint32{} -} - -// AddProcessAdditionalGid adds an additional gid into g.Config.Process.AdditionalGids. -func (g *Generator) AddProcessAdditionalGid(gid uint32) { //nolint:staticcheck // Ignore ST1003: method AddProcessAdditionalGid should be AddProcessAdditionalGID - g.initConfigProcess() - if slices.Contains(g.Config.Process.User.AdditionalGids, gid) { - return - } - g.Config.Process.User.AdditionalGids = append(g.Config.Process.User.AdditionalGids, gid) -} - -// SetProcessSelinuxLabel sets g.Config.Process.SelinuxLabel. -func (g *Generator) SetProcessSelinuxLabel(label string) { - g.initConfigProcess() - g.Config.Process.SelinuxLabel = label -} - -// SetLinuxCgroupsPath sets g.Config.Linux.CgroupsPath. -func (g *Generator) SetLinuxCgroupsPath(path string) { - g.initConfigLinux() - g.Config.Linux.CgroupsPath = path -} - -// SetLinuxIntelRdtClosID sets g.Config.Linux.IntelRdt.ClosID -func (g *Generator) SetLinuxIntelRdtClosID(clos string) { - g.initConfigLinuxIntelRdt() - g.Config.Linux.IntelRdt.ClosID = clos -} - -// SetLinuxIntelRdtL3CacheSchema sets g.Config.Linux.IntelRdt.L3CacheSchema -func (g *Generator) SetLinuxIntelRdtL3CacheSchema(schema string) { - g.initConfigLinuxIntelRdt() - g.Config.Linux.IntelRdt.L3CacheSchema = schema -} - -// SetLinuxMountLabel sets g.Config.Linux.MountLabel. -func (g *Generator) SetLinuxMountLabel(label string) { - g.initConfigLinux() - g.Config.Linux.MountLabel = label -} - -// SetProcessOOMScoreAdj sets g.Config.Process.OOMScoreAdj. -func (g *Generator) SetProcessOOMScoreAdj(adj int) { - g.initConfigProcess() - g.Config.Process.OOMScoreAdj = &adj -} - -// SetLinuxResourcesBlockIOLeafWeight sets g.Config.Linux.Resources.BlockIO.LeafWeight. -func (g *Generator) SetLinuxResourcesBlockIOLeafWeight(weight uint16) { - g.initConfigLinuxResourcesBlockIO() - g.Config.Linux.Resources.BlockIO.LeafWeight = &weight -} - -// AddLinuxResourcesBlockIOLeafWeightDevice adds or sets g.Config.Linux.Resources.BlockIO.WeightDevice.LeafWeight. -func (g *Generator) AddLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64, weight uint16) { - g.initConfigLinuxResourcesBlockIO() - for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice { - if weightDevice.Major == major && weightDevice.Minor == minor { - g.Config.Linux.Resources.BlockIO.WeightDevice[i].LeafWeight = &weight - return - } - } - weightDevice := new(rspec.LinuxWeightDevice) - weightDevice.Major = major - weightDevice.Minor = minor - weightDevice.LeafWeight = &weight - g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice, *weightDevice) -} - -// DropLinuxResourcesBlockIOLeafWeightDevice drops a item form g.Config.Linux.Resources.BlockIO.WeightDevice.LeafWeight -func (g *Generator) DropLinuxResourcesBlockIOLeafWeightDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice { - if weightDevice.Major == major && weightDevice.Minor == minor { - if weightDevice.Weight != nil { - newWeightDevice := new(rspec.LinuxWeightDevice) - newWeightDevice.Major = major - newWeightDevice.Minor = minor - newWeightDevice.Weight = weightDevice.Weight - g.Config.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice - } else { - g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice[:i], g.Config.Linux.Resources.BlockIO.WeightDevice[i+1:]...) - } - return - } - } -} - -// SetLinuxResourcesBlockIOWeight sets g.Config.Linux.Resources.BlockIO.Weight. -func (g *Generator) SetLinuxResourcesBlockIOWeight(weight uint16) { - g.initConfigLinuxResourcesBlockIO() - g.Config.Linux.Resources.BlockIO.Weight = &weight -} - -// AddLinuxResourcesBlockIOWeightDevice adds or sets g.Config.Linux.Resources.BlockIO.WeightDevice.Weight. -func (g *Generator) AddLinuxResourcesBlockIOWeightDevice(major int64, minor int64, weight uint16) { - g.initConfigLinuxResourcesBlockIO() - for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice { - if weightDevice.Major == major && weightDevice.Minor == minor { - g.Config.Linux.Resources.BlockIO.WeightDevice[i].Weight = &weight - return - } - } - weightDevice := new(rspec.LinuxWeightDevice) - weightDevice.Major = major - weightDevice.Minor = minor - weightDevice.Weight = &weight - g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice, *weightDevice) -} - -// DropLinuxResourcesBlockIOWeightDevice drops a item form g.Config.Linux.Resources.BlockIO.WeightDevice.Weight -func (g *Generator) DropLinuxResourcesBlockIOWeightDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - for i, weightDevice := range g.Config.Linux.Resources.BlockIO.WeightDevice { - if weightDevice.Major == major && weightDevice.Minor == minor { - if weightDevice.LeafWeight != nil { - newWeightDevice := new(rspec.LinuxWeightDevice) - newWeightDevice.Major = major - newWeightDevice.Minor = minor - newWeightDevice.LeafWeight = weightDevice.LeafWeight - g.Config.Linux.Resources.BlockIO.WeightDevice[i] = *newWeightDevice - } else { - g.Config.Linux.Resources.BlockIO.WeightDevice = append(g.Config.Linux.Resources.BlockIO.WeightDevice[:i], g.Config.Linux.Resources.BlockIO.WeightDevice[i+1:]...) - } - return - } - } -} - -// AddLinuxResourcesBlockIOThrottleReadBpsDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice. -func (g *Generator) AddLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64, rate uint64) { - g.initConfigLinuxResourcesBlockIO() - throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor, rate) - g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices -} - -// DropLinuxResourcesBlockIOThrottleReadBpsDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice. -func (g *Generator) DropLinuxResourcesBlockIOThrottleReadBpsDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice, major, minor) - g.Config.Linux.Resources.BlockIO.ThrottleReadBpsDevice = throttleDevices -} - -// AddLinuxResourcesBlockIOThrottleReadIOPSDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice. -func (g *Generator) AddLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64, rate uint64) { - g.initConfigLinuxResourcesBlockIO() - throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor, rate) - g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices -} - -// DropLinuxResourcesBlockIOThrottleReadIOPSDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice. -func (g *Generator) DropLinuxResourcesBlockIOThrottleReadIOPSDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice, major, minor) - g.Config.Linux.Resources.BlockIO.ThrottleReadIOPSDevice = throttleDevices -} - -// AddLinuxResourcesBlockIOThrottleWriteBpsDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice. -func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64, rate uint64) { - g.initConfigLinuxResourcesBlockIO() - throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor, rate) - g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices -} - -// DropLinuxResourcesBlockIOThrottleWriteBpsDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice. -func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteBpsDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice, major, minor) - g.Config.Linux.Resources.BlockIO.ThrottleWriteBpsDevice = throttleDevices -} - -// AddLinuxResourcesBlockIOThrottleWriteIOPSDevice adds or sets g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice. -func (g *Generator) AddLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64, rate uint64) { - g.initConfigLinuxResourcesBlockIO() - throttleDevices := addOrReplaceBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor, rate) - g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices -} - -// DropLinuxResourcesBlockIOThrottleWriteIOPSDevice drops a item from g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice. -func (g *Generator) DropLinuxResourcesBlockIOThrottleWriteIOPSDevice(major int64, minor int64) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.BlockIO == nil { - return - } - - throttleDevices := dropBlockIOThrottleDevice(g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice, major, minor) - g.Config.Linux.Resources.BlockIO.ThrottleWriteIOPSDevice = throttleDevices -} - -// SetLinuxResourcesCPUShares sets g.Config.Linux.Resources.CPU.Shares. -func (g *Generator) SetLinuxResourcesCPUShares(shares uint64) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.Shares = &shares -} - -// SetLinuxResourcesCPUQuota sets g.Config.Linux.Resources.CPU.Quota. -func (g *Generator) SetLinuxResourcesCPUQuota(quota int64) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.Quota = "a -} - -// SetLinuxResourcesCPUPeriod sets g.Config.Linux.Resources.CPU.Period. -func (g *Generator) SetLinuxResourcesCPUPeriod(period uint64) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.Period = &period -} - -// SetLinuxResourcesCPURealtimeRuntime sets g.Config.Linux.Resources.CPU.RealtimeRuntime. -func (g *Generator) SetLinuxResourcesCPURealtimeRuntime(time int64) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.RealtimeRuntime = &time -} - -// SetLinuxResourcesCPURealtimePeriod sets g.Config.Linux.Resources.CPU.RealtimePeriod. -func (g *Generator) SetLinuxResourcesCPURealtimePeriod(period uint64) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.RealtimePeriod = &period -} - -// SetLinuxResourcesCPUCpus sets g.Config.Linux.Resources.CPU.Cpus. -func (g *Generator) SetLinuxResourcesCPUCpus(cpus string) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.Cpus = cpus -} - -// SetLinuxResourcesCPUMems sets g.Config.Linux.Resources.CPU.Mems. -func (g *Generator) SetLinuxResourcesCPUMems(mems string) { - g.InitConfigLinuxResourcesCPU() - g.Config.Linux.Resources.CPU.Mems = mems -} - -// AddLinuxResourcesHugepageLimit adds or sets g.Config.Linux.Resources.HugepageLimits. -func (g *Generator) AddLinuxResourcesHugepageLimit(pageSize string, limit uint64) { - hugepageLimit := rspec.LinuxHugepageLimit{ - Pagesize: pageSize, - Limit: limit, - } - - g.initConfigLinuxResources() - for i, pageLimit := range g.Config.Linux.Resources.HugepageLimits { - if pageLimit.Pagesize == pageSize { - g.Config.Linux.Resources.HugepageLimits[i].Limit = limit - return - } - } - g.Config.Linux.Resources.HugepageLimits = append(g.Config.Linux.Resources.HugepageLimits, hugepageLimit) -} - -// DropLinuxResourcesHugepageLimit drops a hugepage limit from g.Config.Linux.Resources.HugepageLimits. -func (g *Generator) DropLinuxResourcesHugepageLimit(pageSize string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil { - return - } - - for i, pageLimit := range g.Config.Linux.Resources.HugepageLimits { - if pageLimit.Pagesize == pageSize { - g.Config.Linux.Resources.HugepageLimits = append(g.Config.Linux.Resources.HugepageLimits[:i], g.Config.Linux.Resources.HugepageLimits[i+1:]...) - return - } - } -} - -// SetLinuxResourcesUnified sets the g.Config.Linux.Resources.Unified. -func (g *Generator) SetLinuxResourcesUnified(unified map[string]string) { - g.initConfigLinuxResourcesUnified() - for k, v := range unified { - g.Config.Linux.Resources.Unified[k] = v - } -} - -// AddLinuxResourcesUnified adds or updates the key-value pair from g.Config.Linux.Resources.Unified -func (g *Generator) AddLinuxResourcesUnified(key, val string) { - g.initConfigLinuxResourcesUnified() - g.Config.Linux.Resources.Unified[key] = val -} - -// DropLinuxResourcesUnified drops a key-value pair from g.Config.Linux.Resources.Unified -func (g *Generator) DropLinuxResourcesUnified(key string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.Unified == nil { - return - } - delete(g.Config.Linux.Resources.Unified, key) -} - -// SetLinuxResourcesMemoryLimit sets g.Config.Linux.Resources.Memory.Limit. -func (g *Generator) SetLinuxResourcesMemoryLimit(limit int64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.Limit = &limit -} - -// SetLinuxResourcesMemoryReservation sets g.Config.Linux.Resources.Memory.Reservation. -func (g *Generator) SetLinuxResourcesMemoryReservation(reservation int64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.Reservation = &reservation -} - -// SetLinuxResourcesMemorySwap sets g.Config.Linux.Resources.Memory.Swap. -func (g *Generator) SetLinuxResourcesMemorySwap(swap int64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.Swap = &swap -} - -// SetLinuxResourcesMemoryKernel sets g.Config.Linux.Resources.Memory.Kernel. -func (g *Generator) SetLinuxResourcesMemoryKernel(kernel int64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.Kernel = &kernel //nolint:staticcheck // Ignore SA1019: g.Config.Linux.Resources.Memory.Kernel is deprecated -} - -// SetLinuxResourcesMemoryKernelTCP sets g.Config.Linux.Resources.Memory.KernelTCP. -func (g *Generator) SetLinuxResourcesMemoryKernelTCP(kernelTCP int64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.KernelTCP = &kernelTCP -} - -// SetLinuxResourcesMemorySwappiness sets g.Config.Linux.Resources.Memory.Swappiness. -func (g *Generator) SetLinuxResourcesMemorySwappiness(swappiness uint64) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.Swappiness = &swappiness -} - -// SetLinuxResourcesMemoryDisableOOMKiller sets g.Config.Linux.Resources.Memory.DisableOOMKiller. -func (g *Generator) SetLinuxResourcesMemoryDisableOOMKiller(disable bool) { - g.initConfigLinuxResourcesMemory() - g.Config.Linux.Resources.Memory.DisableOOMKiller = &disable -} - -// SetLinuxResourcesNetworkClassID sets g.Config.Linux.Resources.Network.ClassID. -func (g *Generator) SetLinuxResourcesNetworkClassID(classid uint32) { - g.initConfigLinuxResourcesNetwork() - g.Config.Linux.Resources.Network.ClassID = &classid -} - -// AddLinuxResourcesNetworkPriorities adds or sets g.Config.Linux.Resources.Network.Priorities. -func (g *Generator) AddLinuxResourcesNetworkPriorities(name string, prio uint32) { - g.initConfigLinuxResourcesNetwork() - for i, netPriority := range g.Config.Linux.Resources.Network.Priorities { - if netPriority.Name == name { - g.Config.Linux.Resources.Network.Priorities[i].Priority = prio - return - } - } - interfacePrio := new(rspec.LinuxInterfacePriority) - interfacePrio.Name = name - interfacePrio.Priority = prio - g.Config.Linux.Resources.Network.Priorities = append(g.Config.Linux.Resources.Network.Priorities, *interfacePrio) -} - -// DropLinuxResourcesNetworkPriorities drops one item from g.Config.Linux.Resources.Network.Priorities. -func (g *Generator) DropLinuxResourcesNetworkPriorities(name string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil || g.Config.Linux.Resources.Network == nil { - return - } - - for i, netPriority := range g.Config.Linux.Resources.Network.Priorities { - if netPriority.Name == name { - g.Config.Linux.Resources.Network.Priorities = append(g.Config.Linux.Resources.Network.Priorities[:i], g.Config.Linux.Resources.Network.Priorities[i+1:]...) - return - } - } -} - -// SetLinuxResourcesPidsLimit sets g.Config.Linux.Resources.Pids.Limit. -func (g *Generator) SetLinuxResourcesPidsLimit(limit int64) { - g.initConfigLinuxResourcesPids() - g.Config.Linux.Resources.Pids.Limit = &limit -} - -// ClearLinuxSysctl clears g.Config.Linux.Sysctl. -func (g *Generator) ClearLinuxSysctl() { - if g.Config == nil || g.Config.Linux == nil { - return - } - g.Config.Linux.Sysctl = make(map[string]string) -} - -// AddLinuxSysctl adds a new sysctl config into g.Config.Linux.Sysctl. -func (g *Generator) AddLinuxSysctl(key, value string) { - g.initConfigLinuxSysctl() - g.Config.Linux.Sysctl[key] = value -} - -// RemoveLinuxSysctl removes a sysctl config from g.Config.Linux.Sysctl. -func (g *Generator) RemoveLinuxSysctl(key string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Sysctl == nil { - return - } - delete(g.Config.Linux.Sysctl, key) -} - -// ClearLinuxUIDMappings clear g.Config.Linux.UIDMappings. -func (g *Generator) ClearLinuxUIDMappings() { - if g.Config == nil || g.Config.Linux == nil { - return - } - g.Config.Linux.UIDMappings = []rspec.LinuxIDMapping{} -} - -// AddLinuxUIDMapping adds uidMap into g.Config.Linux.UIDMappings. -func (g *Generator) AddLinuxUIDMapping(hid, cid, size uint32) { - idMapping := rspec.LinuxIDMapping{ - HostID: hid, - ContainerID: cid, - Size: size, - } - - g.initConfigLinux() - g.Config.Linux.UIDMappings = append(g.Config.Linux.UIDMappings, idMapping) -} - -// ClearLinuxGIDMappings clear g.Config.Linux.GIDMappings. -func (g *Generator) ClearLinuxGIDMappings() { - if g.Config == nil || g.Config.Linux == nil { - return - } - g.Config.Linux.GIDMappings = []rspec.LinuxIDMapping{} -} - -// AddLinuxGIDMapping adds gidMap into g.Config.Linux.GIDMappings. -func (g *Generator) AddLinuxGIDMapping(hid, cid, size uint32) { - idMapping := rspec.LinuxIDMapping{ - HostID: hid, - ContainerID: cid, - Size: size, - } - - g.initConfigLinux() - g.Config.Linux.GIDMappings = append(g.Config.Linux.GIDMappings, idMapping) -} - -// SetLinuxRootPropagation sets g.Config.Linux.RootfsPropagation. -func (g *Generator) SetLinuxRootPropagation(rp string) error { - switch rp { - case "": - case "private": - case "rprivate": - case "slave": - case "rslave": - case "shared": - case "rshared": - case "unbindable": - case "runbindable": - default: - return fmt.Errorf("rootfs-propagation %q must be empty or one of (r)private|(r)slave|(r)shared|(r)unbindable", rp) - } - g.initConfigLinux() - g.Config.Linux.RootfsPropagation = rp - return nil -} - -// ClearPreStartHooks clear g.Config.Hooks.Prestart. -func (g *Generator) ClearPreStartHooks() { - if g.Config == nil || g.Config.Hooks == nil { - return - } - g.Config.Hooks.Prestart = []rspec.Hook{} //nolint:staticcheck // Ignore SA1019: g.Config.Hooks.Prestart is deprecated -} - -// AddPreStartHook add a prestart hook into g.Config.Hooks.Prestart. -func (g *Generator) AddPreStartHook(preStartHook rspec.Hook) { - g.initConfigHooks() - g.Config.Hooks.Prestart = append(g.Config.Hooks.Prestart, preStartHook) //nolint:staticcheck // Ignore SA1019: g.Config.Hooks.Prestart is deprecated -} - -// ClearPostStopHooks clear g.Config.Hooks.Poststop. -func (g *Generator) ClearPostStopHooks() { - if g.Config == nil || g.Config.Hooks == nil { - return - } - g.Config.Hooks.Poststop = []rspec.Hook{} -} - -// AddPostStopHook adds a poststop hook into g.Config.Hooks.Poststop. -func (g *Generator) AddPostStopHook(postStopHook rspec.Hook) { - g.initConfigHooks() - g.Config.Hooks.Poststop = append(g.Config.Hooks.Poststop, postStopHook) -} - -// ClearPostStartHooks clear g.Config.Hooks.Poststart. -func (g *Generator) ClearPostStartHooks() { - if g.Config == nil || g.Config.Hooks == nil { - return - } - g.Config.Hooks.Poststart = []rspec.Hook{} -} - -// AddPostStartHook adds a poststart hook into g.Config.Hooks.Poststart. -func (g *Generator) AddPostStartHook(postStartHook rspec.Hook) { - g.initConfigHooks() - g.Config.Hooks.Poststart = append(g.Config.Hooks.Poststart, postStartHook) -} - -// AddMount adds a mount into g.Config.Mounts. -func (g *Generator) AddMount(mnt rspec.Mount) { - g.initConfig() - - g.Config.Mounts = append(g.Config.Mounts, mnt) -} - -// RemoveMount removes a mount point on the dest directory -func (g *Generator) RemoveMount(dest string) { - g.initConfig() - - for index, mount := range g.Config.Mounts { - if mount.Destination == dest { - g.Config.Mounts = append(g.Config.Mounts[:index], g.Config.Mounts[index+1:]...) - return - } - } -} - -// Mounts returns the list of mounts -func (g *Generator) Mounts() []rspec.Mount { - g.initConfig() - - return g.Config.Mounts -} - -// ClearMounts clear g.Config.Mounts -func (g *Generator) ClearMounts() { - if g.Config == nil { - return - } - g.Config.Mounts = []rspec.Mount{} -} - -// SetupPrivileged sets up the privilege-related fields inside g.Config. -func (g *Generator) SetupPrivileged(privileged bool) { - if privileged { // Add all capabilities in privileged mode. - var finalCapList []string - capList := capability.ListKnown() - if g.HostSpecific { - capList, _ = capability.ListSupported() - } - for _, cap := range capList { - finalCapList = append(finalCapList, fmt.Sprintf("CAP_%s", strings.ToUpper(cap.String()))) - } - g.initConfigLinux() - g.initConfigProcessCapabilities() - g.ClearProcessCapabilities() - g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, finalCapList...) - g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, finalCapList...) - g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, finalCapList...) - g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, finalCapList...) - g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, finalCapList...) - g.Config.Process.SelinuxLabel = "" - g.Config.Process.ApparmorProfile = "" - g.Config.Linux.Seccomp = nil - } -} - -// ClearProcessCapabilities clear g.Config.Process.Capabilities. -func (g *Generator) ClearProcessCapabilities() { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return - } - g.Config.Process.Capabilities.Bounding = []string{} - g.Config.Process.Capabilities.Effective = []string{} - g.Config.Process.Capabilities.Inheritable = []string{} - g.Config.Process.Capabilities.Permitted = []string{} - g.Config.Process.Capabilities.Ambient = []string{} -} - -// AddProcessCapability adds a process capability into all 5 capability sets. -func (g *Generator) AddProcessCapability(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundAmbient, foundBounding, foundEffective, foundInheritable, foundPermitted bool - for _, cap := range g.Config.Process.Capabilities.Ambient { - if strings.ToUpper(cap) == cp { - foundAmbient = true - break - } - } - if !foundAmbient { - g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, cp) - } - - for _, cap := range g.Config.Process.Capabilities.Bounding { - if strings.ToUpper(cap) == cp { - foundBounding = true - break - } - } - if !foundBounding { - g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, cp) - } - - for _, cap := range g.Config.Process.Capabilities.Effective { - if strings.ToUpper(cap) == cp { - foundEffective = true - break - } - } - if !foundEffective { - g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, cp) - } - - for _, cap := range g.Config.Process.Capabilities.Inheritable { - if strings.ToUpper(cap) == cp { - foundInheritable = true - break - } - } - if !foundInheritable { - g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, cp) - } - - for _, cap := range g.Config.Process.Capabilities.Permitted { - if strings.ToUpper(cap) == cp { - foundPermitted = true - break - } - } - if !foundPermitted { - g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, cp) - } - - return nil -} - -// AddProcessCapabilityAmbient adds a process capability into g.Config.Process.Capabilities.Ambient. -func (g *Generator) AddProcessCapabilityAmbient(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundAmbient bool - for _, cap := range g.Config.Process.Capabilities.Ambient { - if strings.ToUpper(cap) == cp { - foundAmbient = true - break - } - } - - if !foundAmbient { - g.Config.Process.Capabilities.Ambient = append(g.Config.Process.Capabilities.Ambient, cp) - } - - return nil -} - -// AddProcessCapabilityBounding adds a process capability into g.Config.Process.Capabilities.Bounding. -func (g *Generator) AddProcessCapabilityBounding(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundBounding bool - for _, cap := range g.Config.Process.Capabilities.Bounding { - if strings.ToUpper(cap) == cp { - foundBounding = true - break - } - } - if !foundBounding { - g.Config.Process.Capabilities.Bounding = append(g.Config.Process.Capabilities.Bounding, cp) - } - - return nil -} - -// AddProcessCapabilityEffective adds a process capability into g.Config.Process.Capabilities.Effective. -func (g *Generator) AddProcessCapabilityEffective(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundEffective bool - for _, cap := range g.Config.Process.Capabilities.Effective { - if strings.ToUpper(cap) == cp { - foundEffective = true - break - } - } - if !foundEffective { - g.Config.Process.Capabilities.Effective = append(g.Config.Process.Capabilities.Effective, cp) - } - - return nil -} - -// AddProcessCapabilityInheritable adds a process capability into g.Config.Process.Capabilities.Inheritable. -func (g *Generator) AddProcessCapabilityInheritable(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundInheritable bool - for _, cap := range g.Config.Process.Capabilities.Inheritable { - if strings.ToUpper(cap) == cp { - foundInheritable = true - break - } - } - if !foundInheritable { - g.Config.Process.Capabilities.Inheritable = append(g.Config.Process.Capabilities.Inheritable, cp) - } - - return nil -} - -// AddProcessCapabilityPermitted adds a process capability into g.Config.Process.Capabilities.Permitted. -func (g *Generator) AddProcessCapabilityPermitted(c string) error { - cp := strings.ToUpper(c) - if err := capsCheck.CapValid(cp, g.HostSpecific); err != nil { - return err - } - - g.initConfigProcessCapabilities() - - var foundPermitted bool - for _, cap := range g.Config.Process.Capabilities.Permitted { - if strings.ToUpper(cap) == cp { - foundPermitted = true - break - } - } - if !foundPermitted { - g.Config.Process.Capabilities.Permitted = append(g.Config.Process.Capabilities.Permitted, cp) - } - - return nil -} - -// DropProcessCapability drops a process capability from all 5 capability sets. -func (g *Generator) DropProcessCapability(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Ambient { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Ambient = removeFunc(g.Config.Process.Capabilities.Ambient, i) - } - } - for i, cap := range g.Config.Process.Capabilities.Bounding { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Bounding = removeFunc(g.Config.Process.Capabilities.Bounding, i) - } - } - for i, cap := range g.Config.Process.Capabilities.Effective { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Effective = removeFunc(g.Config.Process.Capabilities.Effective, i) - } - } - for i, cap := range g.Config.Process.Capabilities.Inheritable { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Inheritable = removeFunc(g.Config.Process.Capabilities.Inheritable, i) - } - } - for i, cap := range g.Config.Process.Capabilities.Permitted { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Permitted = removeFunc(g.Config.Process.Capabilities.Permitted, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -// DropProcessCapabilityAmbient drops a process capability from g.Config.Process.Capabilities.Ambient. -func (g *Generator) DropProcessCapabilityAmbient(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Ambient { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Ambient = removeFunc(g.Config.Process.Capabilities.Ambient, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -// DropProcessCapabilityBounding drops a process capability from g.Config.Process.Capabilities.Bounding. -func (g *Generator) DropProcessCapabilityBounding(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Bounding { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Bounding = removeFunc(g.Config.Process.Capabilities.Bounding, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -// DropProcessCapabilityEffective drops a process capability from g.Config.Process.Capabilities.Effective. -func (g *Generator) DropProcessCapabilityEffective(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Effective { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Effective = removeFunc(g.Config.Process.Capabilities.Effective, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -// DropProcessCapabilityInheritable drops a process capability from g.Config.Process.Capabilities.Inheritable. -func (g *Generator) DropProcessCapabilityInheritable(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Inheritable { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Inheritable = removeFunc(g.Config.Process.Capabilities.Inheritable, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -// DropProcessCapabilityPermitted drops a process capability from g.Config.Process.Capabilities.Permitted. -func (g *Generator) DropProcessCapabilityPermitted(c string) error { - if g.Config == nil || g.Config.Process == nil || g.Config.Process.Capabilities == nil { - return nil - } - - cp := strings.ToUpper(c) - for i, cap := range g.Config.Process.Capabilities.Permitted { - if strings.ToUpper(cap) == cp { - g.Config.Process.Capabilities.Permitted = removeFunc(g.Config.Process.Capabilities.Permitted, i) - } - } - - return capsCheck.CapValid(cp, false) -} - -func mapStrToNamespace(ns string, path string) (rspec.LinuxNamespace, error) { - switch ns { - case "network": - return rspec.LinuxNamespace{Type: rspec.NetworkNamespace, Path: path}, nil - case "pid": - return rspec.LinuxNamespace{Type: rspec.PIDNamespace, Path: path}, nil - case "mount": - return rspec.LinuxNamespace{Type: rspec.MountNamespace, Path: path}, nil - case "ipc": - return rspec.LinuxNamespace{Type: rspec.IPCNamespace, Path: path}, nil - case "uts": - return rspec.LinuxNamespace{Type: rspec.UTSNamespace, Path: path}, nil - case "user": - return rspec.LinuxNamespace{Type: rspec.UserNamespace, Path: path}, nil - case "cgroup": - return rspec.LinuxNamespace{Type: rspec.CgroupNamespace, Path: path}, nil - default: - return rspec.LinuxNamespace{}, fmt.Errorf("unrecognized namespace %q", ns) - } -} - -// ClearLinuxNamespaces clear g.Config.Linux.Namespaces. -func (g *Generator) ClearLinuxNamespaces() { - if g.Config == nil || g.Config.Linux == nil { - return - } - g.Config.Linux.Namespaces = []rspec.LinuxNamespace{} -} - -// AddOrReplaceLinuxNamespace adds or replaces a namespace inside -// g.Config.Linux.Namespaces. -func (g *Generator) AddOrReplaceLinuxNamespace(ns string, path string) error { - namespace, err := mapStrToNamespace(ns, path) - if err != nil { - return err - } - - g.initConfigLinux() - for i, ns := range g.Config.Linux.Namespaces { - if ns.Type == namespace.Type { - g.Config.Linux.Namespaces[i] = namespace - return nil - } - } - g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces, namespace) - return nil -} - -// RemoveLinuxNamespace removes a namespace from g.Config.Linux.Namespaces. -func (g *Generator) RemoveLinuxNamespace(ns string) error { - namespace, err := mapStrToNamespace(ns, "") - if err != nil { - return err - } - - if g.Config == nil || g.Config.Linux == nil { - return nil - } - for i, ns := range g.Config.Linux.Namespaces { - if ns.Type == namespace.Type { - g.Config.Linux.Namespaces = append(g.Config.Linux.Namespaces[:i], g.Config.Linux.Namespaces[i+1:]...) - return nil - } - } - return nil -} - -// AddDevice - add a device into g.Config.Linux.Devices -func (g *Generator) AddDevice(device rspec.LinuxDevice) { - g.initConfigLinux() - - for i, dev := range g.Config.Linux.Devices { - if dev.Path == device.Path { - g.Config.Linux.Devices[i] = device - return - } - } - - g.Config.Linux.Devices = append(g.Config.Linux.Devices, device) -} - -// RemoveDevice remove a device from g.Config.Linux.Devices -func (g *Generator) RemoveDevice(path string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Devices == nil { - return - } - - for i, device := range g.Config.Linux.Devices { - if device.Path == path { - g.Config.Linux.Devices = append(g.Config.Linux.Devices[:i], g.Config.Linux.Devices[i+1:]...) - return - } - } -} - -// ClearLinuxDevices clears g.Config.Linux.Devices -func (g *Generator) ClearLinuxDevices() { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Devices == nil { - return - } - - g.Config.Linux.Devices = []rspec.LinuxDevice{} -} - -// AddLinuxResourcesDevice - add a device into g.Config.Linux.Resources.Devices -func (g *Generator) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) { - g.initConfigLinuxResources() - - device := rspec.LinuxDeviceCgroup{ - Allow: allow, - Type: devType, - Access: access, - Major: major, - Minor: minor, - } - g.Config.Linux.Resources.Devices = append(g.Config.Linux.Resources.Devices, device) -} - -// RemoveLinuxResourcesDevice - remove a device from g.Config.Linux.Resources.Devices -func (g *Generator) RemoveLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) { - if g.Config == nil || g.Config.Linux == nil || g.Config.Linux.Resources == nil { - return - } - for i, device := range g.Config.Linux.Resources.Devices { - if device.Allow == allow && - (devType == device.Type || (devType != "" && device.Type != "" && devType == device.Type)) && - (access == device.Access || (access != "" && device.Access != "" && access == device.Access)) && - (major == device.Major || (major != nil && device.Major != nil && *major == *device.Major)) && - (minor == device.Minor || (minor != nil && device.Minor != nil && *minor == *device.Minor)) { - - g.Config.Linux.Resources.Devices = append(g.Config.Linux.Resources.Devices[:i], g.Config.Linux.Resources.Devices[i+1:]...) - return - } - } -} - -// SetSyscallAction adds rules for syscalls with the specified action -func (g *Generator) SetSyscallAction(arguments seccomp.SyscallOpts) error { - g.initConfigLinuxSeccomp() - return seccomp.ParseSyscallFlag(arguments, g.Config.Linux.Seccomp) -} - -// SetDefaultSeccompAction sets the default action for all syscalls not defined -// and then removes any syscall rules with this action already specified. -func (g *Generator) SetDefaultSeccompAction(action string) error { - g.initConfigLinuxSeccomp() - return seccomp.ParseDefaultAction(action, g.Config.Linux.Seccomp) -} - -// SetDefaultSeccompActionForce only sets the default action for all syscalls not defined -func (g *Generator) SetDefaultSeccompActionForce(action string) error { - g.initConfigLinuxSeccomp() - return seccomp.ParseDefaultActionForce(action, g.Config.Linux.Seccomp) -} - -// SetDomainName sets g.Config.Domainname -func (g *Generator) SetDomainName(domain string) { - g.initConfig() - g.Config.Domainname = domain -} - -// SetSeccompArchitecture sets the supported seccomp architectures -func (g *Generator) SetSeccompArchitecture(architecture string) error { - g.initConfigLinuxSeccomp() - return seccomp.ParseArchitectureFlag(architecture, g.Config.Linux.Seccomp) -} - -// RemoveSeccompRule removes rules for any specified syscalls -func (g *Generator) RemoveSeccompRule(arguments string) error { - g.initConfigLinuxSeccomp() - return seccomp.RemoveAction(arguments, g.Config.Linux.Seccomp) -} - -// RemoveAllSeccompRules removes all syscall rules -func (g *Generator) RemoveAllSeccompRules() error { - g.initConfigLinuxSeccomp() - return seccomp.RemoveAllSeccompRules(g.Config.Linux.Seccomp) -} - -// AddLinuxMaskedPaths adds masked paths into g.Config.Linux.MaskedPaths. -func (g *Generator) AddLinuxMaskedPaths(path string) { - g.initConfigLinux() - g.Config.Linux.MaskedPaths = append(g.Config.Linux.MaskedPaths, path) -} - -// AddLinuxReadonlyPaths adds readonly paths into g.Config.Linux.MaskedPaths. -func (g *Generator) AddLinuxReadonlyPaths(path string) { - g.initConfigLinux() - g.Config.Linux.ReadonlyPaths = append(g.Config.Linux.ReadonlyPaths, path) -} - -func addOrReplaceBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64, rate uint64) []rspec.LinuxThrottleDevice { - throttleDevices := tmpList - for i, throttleDevice := range throttleDevices { - if throttleDevice.Major == major && throttleDevice.Minor == minor { - throttleDevices[i].Rate = rate - return throttleDevices - } - } - throttleDevice := new(rspec.LinuxThrottleDevice) - throttleDevice.Major = major - throttleDevice.Minor = minor - throttleDevice.Rate = rate - throttleDevices = append(throttleDevices, *throttleDevice) - - return throttleDevices -} - -func dropBlockIOThrottleDevice(tmpList []rspec.LinuxThrottleDevice, major int64, minor int64) []rspec.LinuxThrottleDevice { - throttleDevices := tmpList - for i, throttleDevice := range throttleDevices { - if throttleDevice.Major == major && throttleDevice.Minor == minor { - throttleDevices = append(throttleDevices[:i], throttleDevices[i+1:]...) - return throttleDevices - } - } - - return throttleDevices -} - -// AddSolarisAnet adds network into g.Config.Solaris.Anet -func (g *Generator) AddSolarisAnet(anet rspec.SolarisAnet) { - g.initConfigSolaris() - g.Config.Solaris.Anet = append(g.Config.Solaris.Anet, anet) -} - -// SetSolarisCappedCPUNcpus sets g.Config.Solaris.CappedCPU.Ncpus -func (g *Generator) SetSolarisCappedCPUNcpus(ncpus string) { - g.initConfigSolarisCappedCPU() - g.Config.Solaris.CappedCPU.Ncpus = ncpus -} - -// SetSolarisCappedMemoryPhysical sets g.Config.Solaris.CappedMemory.Physical -func (g *Generator) SetSolarisCappedMemoryPhysical(physical string) { - g.initConfigSolarisCappedMemory() - g.Config.Solaris.CappedMemory.Physical = physical -} - -// SetSolarisCappedMemorySwap sets g.Config.Solaris.CappedMemory.Swap -func (g *Generator) SetSolarisCappedMemorySwap(swap string) { - g.initConfigSolarisCappedMemory() - g.Config.Solaris.CappedMemory.Swap = swap -} - -// SetSolarisLimitPriv sets g.Config.Solaris.LimitPriv -func (g *Generator) SetSolarisLimitPriv(limitPriv string) { - g.initConfigSolaris() - g.Config.Solaris.LimitPriv = limitPriv -} - -// SetSolarisMaxShmMemory sets g.Config.Solaris.MaxShmMemory -func (g *Generator) SetSolarisMaxShmMemory(memory string) { - g.initConfigSolaris() - g.Config.Solaris.MaxShmMemory = memory -} - -// SetSolarisMilestone sets g.Config.Solaris.Milestone -func (g *Generator) SetSolarisMilestone(milestone string) { - g.initConfigSolaris() - g.Config.Solaris.Milestone = milestone -} - -// SetVMHypervisorPath sets g.Config.VM.Hypervisor.Path -func (g *Generator) SetVMHypervisorPath(path string) error { - if !strings.HasPrefix(path, "/") { - return fmt.Errorf("hypervisorPath %v is not an absolute path", path) - } - g.initConfigVM() - g.Config.VM.Hypervisor.Path = path - return nil -} - -// SetVMHypervisorParameters sets g.Config.VM.Hypervisor.Parameters -func (g *Generator) SetVMHypervisorParameters(parameters []string) { - g.initConfigVM() - g.Config.VM.Hypervisor.Parameters = parameters -} - -// SetVMKernelPath sets g.Config.VM.Kernel.Path -func (g *Generator) SetVMKernelPath(path string) error { - if !strings.HasPrefix(path, "/") { - return fmt.Errorf("kernelPath %v is not an absolute path", path) - } - g.initConfigVM() - g.Config.VM.Kernel.Path = path - return nil -} - -// SetVMKernelParameters sets g.Config.VM.Kernel.Parameters -func (g *Generator) SetVMKernelParameters(parameters []string) { - g.initConfigVM() - g.Config.VM.Kernel.Parameters = parameters -} - -// SetVMKernelInitRD sets g.Config.VM.Kernel.InitRD -func (g *Generator) SetVMKernelInitRD(initrd string) error { - if !strings.HasPrefix(initrd, "/") { - return fmt.Errorf("kernelInitrd %v is not an absolute path", initrd) - } - g.initConfigVM() - g.Config.VM.Kernel.InitRD = initrd - return nil -} - -// SetVMImagePath sets g.Config.VM.Image.Path -func (g *Generator) SetVMImagePath(path string) error { - if !strings.HasPrefix(path, "/") { - return fmt.Errorf("imagePath %v is not an absolute path", path) - } - g.initConfigVM() - g.Config.VM.Image.Path = path - return nil -} - -// SetVMImageFormat sets g.Config.VM.Image.Format -func (g *Generator) SetVMImageFormat(format string) error { - switch format { - case "raw": - case "qcow2": - case "vdi": - case "vmdk": - case "vhd": - default: - return fmt.Errorf("Commonly supported formats are: raw, qcow2, vdi, vmdk, vhd") - } - g.initConfigVM() - g.Config.VM.Image.Format = format - return nil -} - -// SetWindowsHypervUntilityVMPath sets g.Config.Windows.HyperV.UtilityVMPath. -func (g *Generator) SetWindowsHypervUntilityVMPath(path string) { - g.initConfigWindowsHyperV() - g.Config.Windows.HyperV.UtilityVMPath = path -} - -// SetWindowsIgnoreFlushesDuringBoot sets g.Config.Windows.IgnoreFlushesDuringBoot. -func (g *Generator) SetWindowsIgnoreFlushesDuringBoot(ignore bool) { - g.initConfigWindows() - g.Config.Windows.IgnoreFlushesDuringBoot = ignore -} - -// AddWindowsLayerFolders adds layer folders into g.Config.Windows.LayerFolders. -func (g *Generator) AddWindowsLayerFolders(folder string) { - g.initConfigWindows() - g.Config.Windows.LayerFolders = append(g.Config.Windows.LayerFolders, folder) -} - -// AddWindowsDevices adds or sets g.Config.Windwos.Devices -func (g *Generator) AddWindowsDevices(id, idType string) error { - if idType != "class" { - return fmt.Errorf("Invalid idType value: %s. Windows only supports a value of class", idType) - } - device := rspec.WindowsDevice{ - ID: id, - IDType: idType, - } - - g.initConfigWindows() - for i, device := range g.Config.Windows.Devices { - if device.ID == id { - g.Config.Windows.Devices[i].IDType = idType - return nil - } - } - g.Config.Windows.Devices = append(g.Config.Windows.Devices, device) - return nil -} - -// SetWindowsNetwork sets g.Config.Windows.Network. -func (g *Generator) SetWindowsNetwork(network rspec.WindowsNetwork) { - g.initConfigWindows() - g.Config.Windows.Network = &network -} - -// SetWindowsNetworkAllowUnqualifiedDNSQuery sets g.Config.Windows.Network.AllowUnqualifiedDNSQuery -func (g *Generator) SetWindowsNetworkAllowUnqualifiedDNSQuery(setting bool) { - g.initConfigWindowsNetwork() - g.Config.Windows.Network.AllowUnqualifiedDNSQuery = setting -} - -// SetWindowsNetworkNamespace sets g.Config.Windows.Network.NetworkNamespace -func (g *Generator) SetWindowsNetworkNamespace(path string) { - g.initConfigWindowsNetwork() - g.Config.Windows.Network.NetworkNamespace = path -} - -// SetWindowsResourcesCPU sets g.Config.Windows.Resources.CPU. -func (g *Generator) SetWindowsResourcesCPU(cpu rspec.WindowsCPUResources) { - g.initConfigWindowsResources() - g.Config.Windows.Resources.CPU = &cpu -} - -// SetWindowsResourcesMemoryLimit sets g.Config.Windows.Resources.Memory.Limit. -func (g *Generator) SetWindowsResourcesMemoryLimit(limit uint64) { - g.initConfigWindowsResourcesMemory() - g.Config.Windows.Resources.Memory.Limit = &limit -} - -// SetWindowsResourcesStorage sets g.Config.Windows.Resources.Storage. -func (g *Generator) SetWindowsResourcesStorage(storage rspec.WindowsStorageResources) { - g.initConfigWindowsResources() - g.Config.Windows.Resources.Storage = &storage -} - -// SetWindowsServicing sets g.Config.Windows.Servicing. -func (g *Generator) SetWindowsServicing(servicing bool) { - g.initConfigWindows() - g.Config.Windows.Servicing = servicing -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go deleted file mode 100644 index f28d8f58..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/consts.go +++ /dev/null @@ -1,7 +0,0 @@ -package seccomp - -const ( - seccompOverwrite = "overwrite" - seccompAppend = "append" - nothing = "nothing" -) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go deleted file mode 100644 index a845af51..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_action.go +++ /dev/null @@ -1,137 +0,0 @@ -package seccomp - -import ( - "fmt" - "strconv" - "strings" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -// SyscallOpts contain options for parsing syscall rules -type SyscallOpts struct { - Action string - Syscall string - Index string - Value string - ValueTwo string - Operator string -} - -// ParseSyscallFlag takes a SyscallOpts struct and the seccomp configuration -// and sets the new syscall rule accordingly -func ParseSyscallFlag(args SyscallOpts, config *rspec.LinuxSeccomp) error { - var arguments []string - if args.Index != "" && args.Value != "" && args.ValueTwo != "" && args.Operator != "" { - arguments = []string{ - args.Action, args.Syscall, args.Index, args.Value, - args.ValueTwo, args.Operator, - } - } else { - arguments = []string{args.Action, args.Syscall} - } - - action, _ := parseAction(arguments[0]) - if action == config.DefaultAction && args.argsAreEmpty() { - // default already set, no need to make changes - return nil - } - - var newSyscall rspec.LinuxSyscall - numOfArgs := len(arguments) - if numOfArgs == 6 || numOfArgs == 2 { - argStruct, err := parseArguments(arguments[1:]) - if err != nil { - return err - } - newSyscall = newSyscallStruct(arguments[1], action, argStruct) - } else { - return fmt.Errorf("incorrect number of arguments to ParseSyscall: %d", numOfArgs) - } - - descison, err := decideCourseOfAction(&newSyscall, config.Syscalls) - if err != nil { - return err - } - delimDescison := strings.Split(descison, ":") - - if delimDescison[0] == seccompAppend { - config.Syscalls = append(config.Syscalls, newSyscall) - } - - if delimDescison[0] == seccompOverwrite { - indexForOverwrite, err := strconv.ParseInt(delimDescison[1], 10, 32) - if err != nil { - return err - } - config.Syscalls[indexForOverwrite] = newSyscall - } - - return nil -} - -var actions = map[string]rspec.LinuxSeccompAction{ - "allow": rspec.ActAllow, - "errno": rspec.ActErrno, - "kill": rspec.ActKill, - "trace": rspec.ActTrace, - "trap": rspec.ActTrap, -} - -// Take passed action, return the SCMP_ACT_ version of it -func parseAction(action string) (rspec.LinuxSeccompAction, error) { - a, ok := actions[action] - if !ok { - return "", fmt.Errorf("unrecognized action: %s", action) - } - return a, nil -} - -// ParseDefaultAction sets the default action of the seccomp configuration -// and then removes any rules that were already specified with this action -func ParseDefaultAction(action string, config *rspec.LinuxSeccomp) error { - if action == "" { - return nil - } - - defaultAction, err := parseAction(action) - if err != nil { - return err - } - config.DefaultAction = defaultAction - err = RemoveAllMatchingRules(config, defaultAction) - if err != nil { - return err - } - return nil -} - -// ParseDefaultActionForce simply sets the default action of the seccomp configuration -func ParseDefaultActionForce(action string, config *rspec.LinuxSeccomp) error { - if action == "" { - return nil - } - - defaultAction, err := parseAction(action) - if err != nil { - return err - } - config.DefaultAction = defaultAction - return nil -} - -func newSyscallStruct(name string, action rspec.LinuxSeccompAction, args []rspec.LinuxSeccompArg) rspec.LinuxSyscall { - syscallStruct := rspec.LinuxSyscall{ - Names: []string{name}, - Action: action, - Args: args, - } - return syscallStruct -} - -func (s SyscallOpts) argsAreEmpty() bool { - return (s.Index == "" && - s.Value == "" && - s.ValueTwo == "" && - s.Operator == "") -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go deleted file mode 100644 index 9b2bdfd2..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_architecture.go +++ /dev/null @@ -1,55 +0,0 @@ -package seccomp - -import ( - "fmt" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -// ParseArchitectureFlag takes the raw string passed with the --arch flag, parses it -// and updates the Seccomp config accordingly -func ParseArchitectureFlag(architectureArg string, config *rspec.LinuxSeccomp) error { - correctedArch, err := parseArch(architectureArg) - if err != nil { - return err - } - - shouldAppend := true - for _, alreadySpecified := range config.Architectures { - if correctedArch == alreadySpecified { - shouldAppend = false - } - } - if shouldAppend { - config.Architectures = append(config.Architectures, correctedArch) - } - return nil -} - -func parseArch(arch string) (rspec.Arch, error) { - arches := map[string]rspec.Arch{ - "x86": rspec.ArchX86, - "amd64": rspec.ArchX86_64, - "x32": rspec.ArchX32, - "arm": rspec.ArchARM, - "arm64": rspec.ArchAARCH64, - "mips": rspec.ArchMIPS, - "mips64": rspec.ArchMIPS64, - "mips64n32": rspec.ArchMIPS64N32, - "mipsel": rspec.ArchMIPSEL, - "mipsel64": rspec.ArchMIPSEL64, - "mipsel64n32": rspec.ArchMIPSEL64N32, - "parisc": rspec.ArchPARISC, - "parisc64": rspec.ArchPARISC64, - "ppc": rspec.ArchPPC, - "ppc64": rspec.ArchPPC64, - "ppc64le": rspec.ArchPPC64LE, - "s390": rspec.ArchS390, - "s390x": rspec.ArchS390X, - } - a, ok := arches[arch] - if !ok { - return "", fmt.Errorf("unrecognized architecture: %s", arch) - } - return a, nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go deleted file mode 100644 index 2b4c394e..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_arguments.go +++ /dev/null @@ -1,73 +0,0 @@ -package seccomp - -import ( - "fmt" - "strconv" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -// parseArguments takes a list of arguments (delimArgs). It parses and fills out -// the argument information and returns a slice of arg structs -func parseArguments(delimArgs []string) ([]rspec.LinuxSeccompArg, error) { - nilArgSlice := []rspec.LinuxSeccompArg{} - numberOfArgs := len(delimArgs) - - // No parameters passed with syscall - if numberOfArgs == 1 { - return nilArgSlice, nil - } - - // Correct number of parameters passed with syscall - if numberOfArgs == 5 { - syscallIndex, err := strconv.ParseUint(delimArgs[1], 10, 0) - if err != nil { - return nilArgSlice, err - } - - syscallValue, err := strconv.ParseUint(delimArgs[2], 10, 64) - if err != nil { - return nilArgSlice, err - } - - syscallValueTwo, err := strconv.ParseUint(delimArgs[3], 10, 64) - if err != nil { - return nilArgSlice, err - } - - syscallOp, err := parseOperator(delimArgs[4]) - if err != nil { - return nilArgSlice, err - } - - argStruct := rspec.LinuxSeccompArg{ - Index: uint(syscallIndex), - Value: syscallValue, - ValueTwo: syscallValueTwo, - Op: syscallOp, - } - - argSlice := []rspec.LinuxSeccompArg{} - argSlice = append(argSlice, argStruct) - return argSlice, nil - } - - return nilArgSlice, fmt.Errorf("incorrect number of arguments passed with syscall: %d", numberOfArgs) -} - -func parseOperator(operator string) (rspec.LinuxSeccompOperator, error) { - operators := map[string]rspec.LinuxSeccompOperator{ - "NE": rspec.OpNotEqual, - "LT": rspec.OpLessThan, - "LE": rspec.OpLessEqual, - "EQ": rspec.OpEqualTo, - "GE": rspec.OpGreaterEqual, - "GT": rspec.OpGreaterThan, - "ME": rspec.OpMaskedEqual, - } - o, ok := operators[operator] - if !ok { - return "", fmt.Errorf("unrecognized operator: %s", operator) - } - return o, nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go deleted file mode 100644 index 59537d49..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/parse_remove.go +++ /dev/null @@ -1,52 +0,0 @@ -package seccomp - -import ( - "fmt" - "reflect" - "strings" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -// RemoveAction takes the argument string that was passed with the --remove flag, -// parses it, and updates the Seccomp config accordingly -func RemoveAction(arguments string, config *rspec.LinuxSeccomp) error { - if config == nil { - return fmt.Errorf("Cannot remove action from nil Seccomp pointer") - } - - syscallsToRemove := strings.Split(arguments, ",") - - for counter, syscallStruct := range config.Syscalls { - if reflect.DeepEqual(syscallsToRemove, syscallStruct.Names) { - config.Syscalls = append(config.Syscalls[:counter], config.Syscalls[counter+1:]...) - } - } - - return nil -} - -// RemoveAllSeccompRules removes all seccomp syscall rules -func RemoveAllSeccompRules(config *rspec.LinuxSeccomp) error { - if config == nil { - return fmt.Errorf("Cannot remove action from nil Seccomp pointer") - } - newSyscallSlice := []rspec.LinuxSyscall{} - config.Syscalls = newSyscallSlice - return nil -} - -// RemoveAllMatchingRules will remove any syscall rules that match the specified action -func RemoveAllMatchingRules(config *rspec.LinuxSeccomp, seccompAction rspec.LinuxSeccompAction) error { - if config == nil { - return fmt.Errorf("Cannot remove action from nil Seccomp pointer") - } - - for _, syscall := range config.Syscalls { - if reflect.DeepEqual(syscall.Action, seccompAction) { - RemoveAction(strings.Join(syscall.Names, ","), config) - } - } - - return nil -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go deleted file mode 100644 index 64ec8a1f..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default.go +++ /dev/null @@ -1,603 +0,0 @@ -package seccomp - -import ( - "runtime" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -func arches() []rspec.Arch { - native := runtime.GOARCH - - switch native { - case "amd64": - return []rspec.Arch{rspec.ArchX86_64, rspec.ArchX86, rspec.ArchX32} - case "arm64": - return []rspec.Arch{rspec.ArchARM, rspec.ArchAARCH64} - case "mips64": - return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32} - case "mips64n32": - return []rspec.Arch{rspec.ArchMIPS, rspec.ArchMIPS64, rspec.ArchMIPS64N32} - case "mipsel64": - return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32} - case "mipsel64n32": - return []rspec.Arch{rspec.ArchMIPSEL, rspec.ArchMIPSEL64, rspec.ArchMIPSEL64N32} - case "s390x": - return []rspec.Arch{rspec.ArchS390, rspec.ArchS390X} - default: - return []rspec.Arch{} - } -} - -// DefaultProfile defines the whitelist for the default seccomp profile. -func DefaultProfile(rs *rspec.Spec) *rspec.LinuxSeccomp { - syscalls := []rspec.LinuxSyscall{ - { - Names: []string{ - "accept", - "accept4", - "access", - "alarm", - "bind", - "brk", - "capget", - "capset", - "chdir", - "chmod", - "chown", - "chown32", - "clock_getres", - "clock_gettime", - "clock_nanosleep", - "close", - "connect", - "copy_file_range", - "creat", - "dup", - "dup2", - "dup3", - "epoll_create", - "epoll_create1", - "epoll_ctl", - "epoll_ctl_old", - "epoll_pwait", - "epoll_wait", - "epoll_wait_old", - "eventfd", - "eventfd2", - "execve", - "execveat", - "exit", - "exit_group", - "faccessat", - "fadvise64", - "fadvise64_64", - "fallocate", - "fanotify_mark", - "fchdir", - "fchmod", - "fchmodat", - "fchown", - "fchown32", - "fchownat", - "fcntl", - "fcntl64", - "fdatasync", - "fgetxattr", - "flistxattr", - "flock", - "fork", - "fremovexattr", - "fsetxattr", - "fstat", - "fstat64", - "fstatat64", - "fstatfs", - "fstatfs64", - "fsync", - "ftruncate", - "ftruncate64", - "futex", - "futimesat", - "getcpu", - "getcwd", - "getdents", - "getdents64", - "getegid", - "getegid32", - "geteuid", - "geteuid32", - "getgid", - "getgid32", - "getgroups", - "getgroups32", - "getitimer", - "getpeername", - "getpgid", - "getpgrp", - "getpid", - "getppid", - "getpriority", - "getrandom", - "getresgid", - "getresgid32", - "getresuid", - "getresuid32", - "getrlimit", - "get_robust_list", - "getrusage", - "getsid", - "getsockname", - "getsockopt", - "get_thread_area", - "gettid", - "gettimeofday", - "getuid", - "getuid32", - "getxattr", - "inotify_add_watch", - "inotify_init", - "inotify_init1", - "inotify_rm_watch", - "io_cancel", - "ioctl", - "io_destroy", - "io_getevents", - "ioprio_get", - "ioprio_set", - "io_setup", - "io_submit", - "ipc", - "kill", - "landlock_add_rule", - "landlock_create_ruleset", - "landlock_restrict_self", - "lchown", - "lchown32", - "lgetxattr", - "link", - "linkat", - "listen", - "listxattr", - "llistxattr", - "_llseek", - "lremovexattr", - "lseek", - "lsetxattr", - "lstat", - "lstat64", - "madvise", - "memfd_create", - "mincore", - "mkdir", - "mkdirat", - "mknod", - "mknodat", - "mlock", - "mlock2", - "mlockall", - "mmap", - "mmap2", - "mprotect", - "mq_getsetattr", - "mq_notify", - "mq_open", - "mq_timedreceive", - "mq_timedsend", - "mq_unlink", - "mremap", - "msgctl", - "msgget", - "msgrcv", - "msgsnd", - "msync", - "munlock", - "munlockall", - "munmap", - "nanosleep", - "newfstatat", - "_newselect", - "open", - "openat", - "pause", - "pipe", - "pipe2", - "poll", - "ppoll", - "prctl", - "pread64", - "preadv", - "prlimit64", - "pselect6", - "pwrite64", - "pwritev", - "read", - "readahead", - "readlink", - "readlinkat", - "readv", - "recv", - "recvfrom", - "recvmmsg", - "recvmsg", - "remap_file_pages", - "removexattr", - "rename", - "renameat", - "renameat2", - "restart_syscall", - "rmdir", - "rt_sigaction", - "rt_sigpending", - "rt_sigprocmask", - "rt_sigqueueinfo", - "rt_sigreturn", - "rt_sigsuspend", - "rt_sigtimedwait", - "rt_tgsigqueueinfo", - "sched_getaffinity", - "sched_getattr", - "sched_getparam", - "sched_get_priority_max", - "sched_get_priority_min", - "sched_getscheduler", - "sched_rr_get_interval", - "sched_setaffinity", - "sched_setattr", - "sched_setparam", - "sched_setscheduler", - "sched_yield", - "seccomp", - "select", - "semctl", - "semget", - "semop", - "semtimedop", - "send", - "sendfile", - "sendfile64", - "sendmmsg", - "sendmsg", - "sendto", - "setfsgid", - "setfsgid32", - "setfsuid", - "setfsuid32", - "setgid", - "setgid32", - "setgroups", - "setgroups32", - "setitimer", - "setpgid", - "setpriority", - "setregid", - "setregid32", - "setresgid", - "setresgid32", - "setresuid", - "setresuid32", - "setreuid", - "setreuid32", - "setrlimit", - "set_robust_list", - "setsid", - "setsockopt", - "set_thread_area", - "set_tid_address", - "setuid", - "setuid32", - "setxattr", - "shmat", - "shmctl", - "shmdt", - "shmget", - "shutdown", - "sigaltstack", - "signalfd", - "signalfd4", - "sigreturn", - "socket", - "socketcall", - "socketpair", - "splice", - "stat", - "stat64", - "statfs", - "statfs64", - "statx", - "symlink", - "symlinkat", - "sync", - "sync_file_range", - "syncfs", - "sysinfo", - "syslog", - "tee", - "tgkill", - "time", - "timer_create", - "timer_delete", - "timerfd_create", - "timerfd_gettime", - "timerfd_settime", - "timer_getoverrun", - "timer_gettime", - "timer_settime", - "times", - "tkill", - "truncate", - "truncate64", - "ugetrlimit", - "umask", - "uname", - "unlink", - "unlinkat", - "utime", - "utimensat", - "utimes", - "vfork", - "vmsplice", - "wait4", - "waitid", - "waitpid", - "write", - "writev", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - { - Names: []string{"personality"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{ - { - Index: 0, - Value: 0x0, - Op: rspec.OpEqualTo, - }, - }, - }, - { - Names: []string{"personality"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{ - { - Index: 0, - Value: 0x0008, - Op: rspec.OpEqualTo, - }, - }, - }, - { - Names: []string{"personality"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{ - { - Index: 0, - Value: 0xffffffff, - Op: rspec.OpEqualTo, - }, - }, - }, - } - var sysCloneFlagsIndex uint - - capSysAdmin := false - caps := make(map[string]bool) - - for _, cap := range rs.Process.Capabilities.Bounding { - caps[cap] = true - } - for _, cap := range rs.Process.Capabilities.Effective { - caps[cap] = true - } - for _, cap := range rs.Process.Capabilities.Inheritable { - caps[cap] = true - } - for _, cap := range rs.Process.Capabilities.Permitted { - caps[cap] = true - } - for _, cap := range rs.Process.Capabilities.Ambient { - caps[cap] = true - } - - for cap := range caps { - switch cap { - case "CAP_DAC_READ_SEARCH": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"open_by_handle_at"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_ADMIN": - capSysAdmin = true - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "bpf", - "clone", - "fanotify_init", - "lookup_dcookie", - "mount", - "name_to_handle_at", - "perf_event_open", - "setdomainname", - "sethostname", - "setns", - "umount", - "umount2", - "unshare", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_BOOT": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"reboot"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_CHROOT": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"chroot"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_MODULE": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "delete_module", - "init_module", - "finit_module", - "query_module", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_PACCT": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"acct"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_PTRACE": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "kcmp", - "process_vm_readv", - "process_vm_writev", - "ptrace", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_RAWIO": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "iopl", - "ioperm", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_TIME": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "settimeofday", - "stime", - "adjtimex", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "CAP_SYS_TTY_CONFIG": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"vhangup"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - } - } - - if !capSysAdmin { - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"clone"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{ - { - Index: sysCloneFlagsIndex, - Value: CloneNewNS | CloneNewUTS | CloneNewIPC | CloneNewUser | CloneNewPID | CloneNewNet | CloneNewCgroup, - ValueTwo: 0, - Op: rspec.OpMaskedEqual, - }, - }, - }, - }...) - } - - arch := runtime.GOARCH - switch arch { - case "arm", "arm64": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "breakpoint", - "cacheflush", - "set_tls", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "amd64", "x32": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"arch_prctl"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - fallthrough - case "x86": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"modify_ldt"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - case "s390", "s390x": - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{ - "s390_pci_mmio_read", - "s390_pci_mmio_write", - "s390_runtime_instr", - }, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{}, - }, - }...) - /* Flags parameter of the clone syscall is the 2nd on s390 */ - syscalls = append(syscalls, []rspec.LinuxSyscall{ - { - Names: []string{"clone"}, - Action: rspec.ActAllow, - Args: []rspec.LinuxSeccompArg{ - { - Index: 1, - Value: 2080505856, - ValueTwo: 0, - Op: rspec.OpMaskedEqual, - }, - }, - }, - }...) - } - - return &rspec.LinuxSeccomp{ - DefaultAction: rspec.ActErrno, - Architectures: arches(), - Syscalls: syscalls, - } -} diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go deleted file mode 100644 index aac5c2bb..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_linux.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build linux - -package seccomp - -import "golang.org/x/sys/unix" - -// System values passed through on linux -const ( - CloneNewIPC = unix.CLONE_NEWIPC - CloneNewNet = unix.CLONE_NEWNET - CloneNewNS = unix.CLONE_NEWNS - CloneNewPID = unix.CLONE_NEWPID - CloneNewUser = unix.CLONE_NEWUSER - CloneNewUTS = unix.CLONE_NEWUTS - CloneNewCgroup = unix.CLONE_NEWCGROUP -) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go deleted file mode 100644 index a8d58267..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/seccomp_default_unsupported.go +++ /dev/null @@ -1,15 +0,0 @@ -//go:build !linux - -package seccomp - -// These are copied from linux/amd64 syscall values, as a reference for other -// platforms to have access to -const ( - CloneNewIPC = 0x8000000 - CloneNewNet = 0x40000000 - CloneNewNS = 0x20000 - CloneNewPID = 0x20000000 - CloneNewUser = 0x10000000 - CloneNewUTS = 0x4000000 - CloneNewCgroup = 0x02000000 -) diff --git a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go b/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go deleted file mode 100644 index 5e84653a..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/generate/seccomp/syscall_compare.go +++ /dev/null @@ -1,124 +0,0 @@ -package seccomp - -import ( - "fmt" - "reflect" - "strconv" - "strings" - - rspec "github.com/opencontainers/runtime-spec/specs-go" -) - -// Determine if a new syscall rule should be appended, overwrite an existing rule -// or if no action should be taken at all -func decideCourseOfAction(newSyscall *rspec.LinuxSyscall, syscalls []rspec.LinuxSyscall) (string, error) { - ruleForSyscallAlreadyExists := false - - var sliceOfDeterminedActions []string - for i, syscall := range syscalls { - if sameName(&syscall, newSyscall) { - ruleForSyscallAlreadyExists = true - - if identical(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing) - } - - if sameAction(newSyscall, &syscall) { - if bothHaveArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) - } - if onlyOneHasArgs(newSyscall, &syscall) { - if firstParamOnlyHasArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) - } else { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, nothing) - } - } - } - - if !sameAction(newSyscall, &syscall) { - if bothHaveArgs(newSyscall, &syscall) { - if sameArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) - } - if !sameArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) - } - } - if onlyOneHasArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) - } - if neitherHasArgs(newSyscall, &syscall) { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, "overwrite:"+strconv.Itoa(i)) - } - } - } - } - - if !ruleForSyscallAlreadyExists { - sliceOfDeterminedActions = append(sliceOfDeterminedActions, seccompAppend) - } - - // Nothing has highest priority - for _, determinedAction := range sliceOfDeterminedActions { - if determinedAction == nothing { - return determinedAction, nil - } - } - - // Overwrite has second highest priority - for _, determinedAction := range sliceOfDeterminedActions { - if strings.Contains(determinedAction, seccompOverwrite) { - return determinedAction, nil - } - } - - // Append has the lowest priority - for _, determinedAction := range sliceOfDeterminedActions { - if determinedAction == seccompAppend { - return determinedAction, nil - } - } - - return "", fmt.Errorf("Trouble determining action: %s", sliceOfDeterminedActions) -} - -func hasArguments(config *rspec.LinuxSyscall) bool { - nilSyscall := new(rspec.LinuxSyscall) - return !sameArgs(nilSyscall, config) -} - -func identical(config1, config2 *rspec.LinuxSyscall) bool { - return reflect.DeepEqual(config1, config2) -} - -func sameName(config1, config2 *rspec.LinuxSyscall) bool { - return reflect.DeepEqual(config1.Names, config2.Names) -} - -func sameAction(config1, config2 *rspec.LinuxSyscall) bool { - return config1.Action == config2.Action -} - -func sameArgs(config1, config2 *rspec.LinuxSyscall) bool { - return reflect.DeepEqual(config1.Args, config2.Args) -} - -func bothHaveArgs(config1, config2 *rspec.LinuxSyscall) bool { - return hasArguments(config1) && hasArguments(config2) -} - -func onlyOneHasArgs(config1, config2 *rspec.LinuxSyscall) bool { - conf1 := hasArguments(config1) - conf2 := hasArguments(config2) - - return (conf1 && !conf2) || (!conf1 && conf2) -} - -func neitherHasArgs(config1, config2 *rspec.LinuxSyscall) bool { - return !hasArguments(config1) && !hasArguments(config2) -} - -func firstParamOnlyHasArgs(config1, config2 *rspec.LinuxSyscall) bool { - return !hasArguments(config1) && hasArguments(config2) -} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/lastcap.go b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/lastcap.go deleted file mode 100644 index 09279572..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/lastcap.go +++ /dev/null @@ -1,16 +0,0 @@ -package capabilities - -import ( - "github.com/moby/sys/capability" -) - -// LastCap returns last cap of system. -// -// Deprecated: use github.com/moby/sys/capability.LastCap instead. -func LastCap() capability.Cap { - last, err := capability.LastCap() - if err != nil { - return -1 - } - return last -} diff --git a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go b/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go deleted file mode 100644 index 572e7081..00000000 --- a/vendor/github.com/opencontainers/runtime-tools/validate/capabilities/validate.go +++ /dev/null @@ -1,45 +0,0 @@ -package capabilities - -import ( - "fmt" - "strings" - "sync" - - "github.com/moby/sys/capability" -) - -// CapValid checks whether a capability is valid. If hostSpecific is set, -// it also checks that the capability is supported on the current host. -func CapValid(c string, hostSpecific bool) error { - if !strings.HasPrefix(c, "CAP_") { - return fmt.Errorf("capability %s must start with CAP_", c) - } - - if _, ok := knownCaps()[c]; !ok { - return fmt.Errorf("invalid capability: %s", c) - } - if !hostSpecific { - return nil - } - if _, ok := supportedCaps()[c]; !ok { - return fmt.Errorf("%s is not supported on the current host", c) - } - return nil -} - -func capSet(list []capability.Cap) map[string]struct{} { - m := make(map[string]struct{}, len(list)) - for _, c := range list { - m["CAP_"+strings.ToUpper(c.String())] = struct{}{} - } - return m -} - -var knownCaps = sync.OnceValue(func() map[string]struct{} { - return capSet(capability.ListKnown()) -}) - -var supportedCaps = sync.OnceValue(func() map[string]struct{} { - list, _ := capability.ListSupported() - return capSet(list) -}) diff --git a/vendor/github.com/stretchr/objx/README.md b/vendor/github.com/stretchr/objx/README.md index 78dc1f8b..e9ba8307 100644 --- a/vendor/github.com/stretchr/objx/README.md +++ b/vendor/github.com/stretchr/objx/README.md @@ -1,8 +1,6 @@ # Objx [![Build Status](https://travis-ci.org/stretchr/objx.svg?branch=master)](https://travis-ci.org/stretchr/objx) [![Go Report Card](https://goreportcard.com/badge/github.com/stretchr/objx)](https://goreportcard.com/report/github.com/stretchr/objx) -[![Maintainability](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/maintainability)](https://codeclimate.com/github/stretchr/objx/maintainability) -[![Test Coverage](https://api.codeclimate.com/v1/badges/1d64bc6c8474c2074f2b/test_coverage)](https://codeclimate.com/github/stretchr/objx/test_coverage) [![Sourcegraph](https://sourcegraph.com/github.com/stretchr/objx/-/badge.svg)](https://sourcegraph.com/github.com/stretchr/objx) [![GoDoc](https://pkg.go.dev/badge/github.com/stretchr/objx?utm_source=godoc)](https://pkg.go.dev/github.com/stretchr/objx) @@ -19,49 +17,62 @@ Objx provides the `objx.Map` type, which is a `map[string]interface{}` that expo ### Pattern Objx uses a predictable pattern to make access data from within `map[string]interface{}` easy. Call one of the `objx.` functions to create your `objx.Map` to get going: - m, err := objx.FromJSON(json) +```go +m, err := objx.FromJSON(json) +``` NOTE: Any methods or functions with the `Must` prefix will panic if something goes wrong, the rest will be optimistic and try to figure things out without panicking. Use `Get` to access the value you're interested in. You can use dot and array notation too: - m.Get("places[0].latlng") +```go +m.Get("places[0].latlng") +``` Once you have sought the `Value` you're interested in, you can use the `Is*` methods to determine its type. - if m.Get("code").IsStr() { // Your code... } +```go +if m.Get("code").IsStr() { // Your code... } +``` Or you can just assume the type, and use one of the strong type methods to extract the real value: - m.Get("code").Int() +```go +m.Get("code").Int() +``` If there's no value there (or if it's the wrong type) then a default value will be returned, or you can be explicit about the default value. - Get("code").Int(-1) - +```go +Get("code").Int(-1) +``` If you're dealing with a slice of data as a value, Objx provides many useful methods for iterating, manipulating and selecting that data. You can find out more by exploring the index below. ### Reading data A simple example of how to use Objx: - // Use MustFromJSON to make an objx.Map from some JSON - m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) +```go +// Use MustFromJSON to make an objx.Map from some JSON +m := objx.MustFromJSON(`{"name": "Mat", "age": 30}`) - // Get the details - name := m.Get("name").Str() - age := m.Get("age").Int() +// Get the details +name := m.Get("name").Str() +age := m.Get("age").Int() - // Get their nickname (or use their name if they don't have one) - nickname := m.Get("nickname").Str(name) +// Get their nickname (or use their name if they don't have one) +nickname := m.Get("nickname").Str(name) +``` ### Ranging Since `objx.Map` is a `map[string]interface{}` you can treat it as such. For example, to `range` the data, do what you would expect: - m := objx.MustFromJSON(json) - for key, value := range m { - // Your code... - } +```go +m := objx.MustFromJSON(json) +for key, value := range m { + // Your code... +} +``` ## Installation To install Objx, use go get: diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go index c592f6ad..a19a8927 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_format.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -84,7 +84,7 @@ func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, ar return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -124,7 +124,7 @@ func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg stri return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Errorf(t, err, "error message %s", "formatted") @@ -144,8 +144,8 @@ func ErrorAsf(t TestingT, err error, target interface{}, msg string, args ...int return ErrorAs(t, err, target, append([]interface{}{msg}, args...)...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContainsf(t, err, expectedErrorSubString, "error message %s", "formatted") @@ -190,10 +190,10 @@ func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick // time.Sleep(8*time.Second) // externalValue = true // }() -// assert.EventuallyWithTf(t, func(c *assert.CollectT, "error message %s", "formatted") { +// assert.EventuallyWithTf(t, func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func EventuallyWithTf(t TestingT, condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -552,7 +552,7 @@ func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool return NoDirExists(t, path, append([]interface{}{msg}, args...)...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoErrorf(t, err, "error message %s", "formatted") { @@ -849,7 +849,19 @@ func WithinRangef(t TestingT, actual time.Time, start time.Time, end time.Time, return WithinRange(t, actual, start, end, append([]interface{}{msg}, args...)...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEqf(t, expected, actual, "error message %s", "formatted") func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go index 58db9284..cd2a8606 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_forward.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -146,7 +146,7 @@ func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs return Equal(a.t, expected, actual, msgAndArgs...) } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -158,7 +158,7 @@ func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ... return EqualError(a.t, theError, errString, msgAndArgs...) } -// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// EqualErrorf asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -240,7 +240,7 @@ func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string return Equalf(a.t, expected, actual, msg, args...) } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Error(err) @@ -269,8 +269,8 @@ func (a *Assertions) ErrorAsf(err error, target interface{}, msg string, args .. return ErrorAsf(a.t, err, target, msg, args...) } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContains(err, expectedErrorSubString) @@ -281,8 +281,8 @@ func (a *Assertions) ErrorContains(theError error, contains string, msgAndArgs . return ErrorContains(a.t, theError, contains, msgAndArgs...) } -// ErrorContainsf asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContainsf asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // a.ErrorContainsf(err, expectedErrorSubString, "error message %s", "formatted") @@ -311,7 +311,7 @@ func (a *Assertions) ErrorIsf(err error, target error, msg string, args ...inter return ErrorIsf(a.t, err, target, msg, args...) } -// Errorf asserts that a function returned an error (i.e. not `nil`). +// Errorf asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // a.Errorf(err, "error message %s", "formatted") @@ -372,10 +372,10 @@ func (a *Assertions) EventuallyWithT(condition func(collect *CollectT), waitFor // time.Sleep(8*time.Second) // externalValue = true // }() -// a.EventuallyWithTf(func(c *assert.CollectT, "error message %s", "formatted") { +// a.EventuallyWithTf(func(c *assert.CollectT) { // // add assertions as needed; any assertion failure will fail the current tick // assert.True(c, externalValue, "expected 'externalValue' to be true") -// }, 10*time.Second, 1*time.Second, "external state has not changed to 'true'; still false") +// }, 10*time.Second, 1*time.Second, "error message %s", "formatted") func (a *Assertions) EventuallyWithTf(condition func(collect *CollectT), waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1096,7 +1096,7 @@ func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) return NoDirExistsf(a.t, path, msg, args...) } -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoError(err) { @@ -1109,7 +1109,7 @@ func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { return NoError(a.t, err, msgAndArgs...) } -// NoErrorf asserts that a function returned no error (i.e. `nil`). +// NoErrorf asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if a.NoErrorf(err, "error message %s", "formatted") { @@ -1690,7 +1690,19 @@ func (a *Assertions) WithinRangef(actual time.Time, start time.Time, end time.Ti return WithinRangef(a.t, actual, start, end, msg, args...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEq(expected, actual) func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() @@ -1698,7 +1710,19 @@ func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interf return YAMLEq(a.t, expected, actual, msgAndArgs...) } -// YAMLEqf asserts that two YAML strings are equivalent. +// YAMLEqf asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// a.YAMLEqf(expected, actual, "error message %s", "formatted") func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { if h, ok := a.t.(tHelper); ok { h.Helper() diff --git a/vendor/github.com/stretchr/testify/assert/assertion_order.go b/vendor/github.com/stretchr/testify/assert/assertion_order.go index 2fdf80fd..a44b40ed 100644 --- a/vendor/github.com/stretchr/testify/assert/assertion_order.go +++ b/vendor/github.com/stretchr/testify/assert/assertion_order.go @@ -9,7 +9,7 @@ import ( func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareResult, failMessage string, msgAndArgs ...interface{}) bool { objKind := reflect.TypeOf(object).Kind() if objKind != reflect.Slice && objKind != reflect.Array { - return false + return Fail(t, fmt.Sprintf("object %T is not an ordered collection", object), msgAndArgs...) } objValue := reflect.ValueOf(object) @@ -50,6 +50,9 @@ func isOrdered(t TestingT, object interface{}, allowedComparesResults []compareR // assert.IsIncreasing(t, []float{1, 2}) // assert.IsIncreasing(t, []string{"a", "b"}) func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs...) } @@ -59,6 +62,9 @@ func IsIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonIncreasing(t, []float{2, 1}) // assert.IsNonIncreasing(t, []string{"b", "a"}) func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareEqual, compareGreater}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs...) } @@ -68,6 +74,9 @@ func IsNonIncreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) // assert.IsDecreasing(t, []float{2, 1}) // assert.IsDecreasing(t, []string{"b", "a"}) func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs...) } @@ -77,5 +86,8 @@ func IsDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) boo // assert.IsNonDecreasing(t, []float{1, 2}) // assert.IsNonDecreasing(t, []string{"a", "b"}) func IsNonDecreasing(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } return isOrdered(t, object, []compareResult{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index de8de0cb..166f6372 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -17,11 +17,10 @@ import ( "unicode" "unicode/utf8" - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" - - // Wrapper around gopkg.in/yaml.v3 + // Wrapper around go.yaml.in/yaml/v3 "github.com/stretchr/testify/assert/yaml" + "github.com/stretchr/testify/internal/difflib" + "github.com/stretchr/testify/internal/spew" ) //go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" @@ -33,19 +32,19 @@ type TestingT interface { // ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful // for table driven tests. -type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool +type ComparisonAssertionFunc = func(TestingT, interface{}, interface{}, ...interface{}) bool // ValueAssertionFunc is a common function prototype when validating a single value. Can be useful // for table driven tests. -type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool +type ValueAssertionFunc = func(TestingT, interface{}, ...interface{}) bool // BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful // for table driven tests. -type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool +type BoolAssertionFunc = func(TestingT, bool, ...interface{}) bool // ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful // for table driven tests. -type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool +type ErrorAssertionFunc = func(TestingT, error, ...interface{}) bool // PanicAssertionFunc is a common function prototype when validating a panic value. Can be useful // for table driven tests. @@ -325,13 +324,15 @@ func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { func indentMessageLines(message string, longestLabelLen int) string { outBuf := new(bytes.Buffer) - for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { - // no need to align first line because it starts at the correct location (after the label) - if i != 0 { - // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab - outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + scanner := bufio.NewScanner(strings.NewReader(message)) + for firstLine := true; scanner.Scan(); firstLine = false { + if !firstLine { + fmt.Fprint(outBuf, "\n\t"+strings.Repeat(" ", longestLabelLen+1)+"\t") } - outBuf.WriteString(scanner.Text()) + fmt.Fprint(outBuf, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return fmt.Sprintf("cannot display message: %s", err) } return outBuf.String() @@ -544,9 +545,8 @@ func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) b if !same { // both are pointers but not the same type & pointing to the same address return Fail(t, fmt.Sprintf("Not same: \n"+ - "expected: %p %#[1]v\n"+ - "actual : %p %#[2]v", - expected, actual), msgAndArgs...) + "expected: %[2]s (%[1]T)(%[1]p)\n"+ + "actual : %[4]s (%[3]T)(%[3]p)", expected, truncatingFormat("%#v", expected), actual, truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -571,8 +571,8 @@ func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{} if same { return Fail(t, fmt.Sprintf( - "Expected and actual point to the same object: %p %#[1]v", - expected), msgAndArgs...) + "Expected and actual point to the same object: %p %s", + expected, truncatingFormat("%#v", expected)), msgAndArgs...) } return true } @@ -604,25 +604,26 @@ func samePointers(first, second interface{}) (same bool, ok bool) { // to a type conversion in the Go grammar. func formatUnequalValues(expected, actual interface{}) (e string, a string) { if reflect.TypeOf(expected) != reflect.TypeOf(actual) { - return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), - fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) + return fmt.Sprintf("%T(%s)", expected, truncatingFormat("%#v", expected)), + fmt.Sprintf("%T(%s)", actual, truncatingFormat("%#v", actual)) } switch expected.(type) { case time.Duration: return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) } - return truncatingFormat(expected), truncatingFormat(actual) + return truncatingFormat("%#v", expected), truncatingFormat("%#v", actual) } // truncatingFormat formats the data and truncates it if it's too long. // // This helps keep formatted error messages lines from exceeding the // bufio.MaxScanTokenSize max line length that the go testing framework imposes. -func truncatingFormat(data interface{}) string { - value := fmt.Sprintf("%#v", data) - max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. - if len(value) > max { - value = value[0:max] + "<... truncated>" +func truncatingFormat(format string, data interface{}) string { + value := fmt.Sprintf(format, data) + // Give us space for two truncated objects and the surrounding sentence. + maxMessageSize := bufio.MaxScanTokenSize/2 - 100 + if len(value) > maxMessageSize { + value = value[0:maxMessageSize] + "<... truncated>" } return value } @@ -743,7 +744,7 @@ func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("Expected nil, but got: %s", truncatingFormat("%#v", object)), msgAndArgs...) } // isEmpty gets whether the specified object is considered empty or not. @@ -793,7 +794,7 @@ func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + Fail(t, fmt.Sprintf("Should be empty, but was %s", truncatingFormat("%v", object)), msgAndArgs...) } return pass @@ -836,11 +837,11 @@ func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) } l, ok := getLen(object) if !ok { - return Fail(t, fmt.Sprintf("\"%v\" could not be applied builtin len()", object), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", truncatingFormat("%v", object)), msgAndArgs...) } if l != length { - return Fail(t, fmt.Sprintf("\"%v\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + return Fail(t, fmt.Sprintf("%q should have %d item(s), but has %d", truncatingFormat("%v", object), length, l), msgAndArgs...) } return true } @@ -889,7 +890,7 @@ func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{ } if ObjectsAreEqual(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -904,7 +905,7 @@ func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...inte } if ObjectsAreEqualValues(expected, actual) { - return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should not be: %s\n", truncatingFormat("%#v", actual)), msgAndArgs...) } return true @@ -964,10 +965,10 @@ func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bo ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -986,10 +987,10 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) ok, found := containsElement(s, contains) if !ok { - return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s could not be applied builtin len()", truncatingFormat("%#v", s)), msgAndArgs...) } if found { - return Fail(t, fmt.Sprintf("%#v should not contain %#v", s, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s should not contain %#v", truncatingFormat("%#v", s), contains), msgAndArgs...) } return true @@ -1031,10 +1032,10 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok av := actualMap.MapIndex(k) if !av.IsValid() { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } if !ObjectsAreEqual(ev.Interface(), av.Interface()) { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, subset), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %s", truncatingFormat("%#v", list), truncatingFormat("%#v", subset)), msgAndArgs...) } } @@ -1056,7 +1057,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { - return Fail(t, fmt.Sprintf("%#v does not contain %#v", list, element), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s does not contain %#v", truncatingFormat("%#v", list), element), msgAndArgs...) } } @@ -1082,12 +1083,12 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) listKind := reflect.TypeOf(list).Kind() if listKind != reflect.Array && listKind != reflect.Slice && listKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", list, listKind), msgAndArgs...) } subsetKind := reflect.TypeOf(subset).Kind() if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map { - return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v has an unsupported type %s", subset, subsetKind), msgAndArgs...) } if subsetKind == reflect.Map && listKind == reflect.Map { @@ -1106,7 +1107,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } subsetList := reflect.ValueOf(subset) @@ -1121,14 +1122,14 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) element := subsetList.Index(i).Interface() ok, found := containsElement(list, element) if !ok { - return Fail(t, fmt.Sprintf("%q could not be applied builtin len()", list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", list), msgAndArgs...) } if !found { return true } } - return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) + return Fail(t, fmt.Sprintf("%s is a subset of %s", truncatingFormat("%#v", subset), truncatingFormat("%#v", list)), msgAndArgs...) } // ElementsMatch asserts that the specified listA(array, slice...) is equal to specified @@ -1343,9 +1344,15 @@ func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs . if !funcDidPanic { return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) } - panicErr, ok := panicValue.(error) - if !ok || panicErr.Error() != errString { - return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) + panicErr, isError := panicValue.(error) + if !isError || panicErr.Error() != errString { + msg := fmt.Sprintf("func %#v should panic with error message:\t%#v\n", f, errString) + if isError { + msg += fmt.Sprintf("\tError message:\t%#v\n", panicErr.Error()) + } + msg += fmt.Sprintf("\tPanic value:\t%#v\n", panicValue) + msg += fmt.Sprintf("\tPanic stack:\t%s\n", panickedStack) + return Fail(t, msg, msgAndArgs...) } return true @@ -1624,7 +1631,7 @@ func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, m Errors */ -// NoError asserts that a function returned no error (i.e. `nil`). +// NoError asserts that a function returned a nil error (ie. no error). // // actualObj, err := SomeFunction() // if assert.NoError(t, err) { @@ -1635,13 +1642,13 @@ func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() } - return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + return Fail(t, fmt.Sprintf("Received unexpected error:\n%s", truncatingFormat("%+v", err)), msgAndArgs...) } return true } -// Error asserts that a function returned an error (i.e. not `nil`). +// Error asserts that a function returned a non-nil error (ie. an error). // // actualObj, err := SomeFunction() // assert.Error(t, err) @@ -1656,7 +1663,7 @@ func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { return true } -// EqualError asserts that a function returned an error (i.e. not `nil`) +// EqualError asserts that a function returned a non-nil error (i.e. an error) // and that it is equal to the provided error. // // actualObj, err := SomeFunction() @@ -1674,13 +1681,13 @@ func EqualError(t TestingT, theError error, errString string, msgAndArgs ...inte if expected != actual { return Fail(t, fmt.Sprintf("Error message not equal:\n"+ "expected: %q\n"+ - "actual : %q", expected, actual), msgAndArgs...) + "actual : %s", expected, truncatingFormat("%q", actual)), msgAndArgs...) } return true } -// ErrorContains asserts that a function returned an error (i.e. not `nil`) -// and that the error contains the specified substring. +// ErrorContains asserts that a function returned a non-nil error (i.e. an +// error) and that the error contains the specified substring. // // actualObj, err := SomeFunction() // assert.ErrorContains(t, err, expectedErrorSubString) @@ -1694,7 +1701,7 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in actual := theError.Error() if !strings.Contains(actual, contains) { - return Fail(t, fmt.Sprintf("Error %#v does not contain %#v", actual, contains), msgAndArgs...) + return Fail(t, fmt.Sprintf("Error %s does not contain %#v", truncatingFormat("%#v", actual), contains), msgAndArgs...) } return true @@ -1760,7 +1767,7 @@ func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { h.Helper() } if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { - return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + return Fail(t, fmt.Sprintf("Should be zero, but was %s", truncatingFormat("%v", i)), msgAndArgs...) } return true } @@ -1874,7 +1881,19 @@ func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{ return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) } -// YAMLEq asserts that two YAML strings are equivalent. +// YAMLEq asserts that the first documents in the two YAML strings are equivalent. +// +// expected := `--- +// key: value +// --- +// key: this is a second document, it is not evaluated +// ` +// actual := `--- +// key: value +// --- +// key: this is a subsequent document, it is not evaluated +// ` +// assert.YAMLEq(t, expected, actual) func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -2188,8 +2207,8 @@ func ErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should be in err chain:\n"+ - "expected: %q\n"+ - "in chain: %s", expectedText, chain, + "expected: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2211,8 +2230,8 @@ func NotErrorIs(t TestingT, err, target error, msgAndArgs ...interface{}) bool { chain := buildErrorChainString(err, false) return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ - "found: %q\n"+ - "in chain: %s", expectedText, chain, + "found: %s\n"+ + "in chain: %s", truncatingFormat("%q", expectedText), truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2236,7 +2255,7 @@ func ErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interface{ return Fail(t, fmt.Sprintf("Should be in error chain:\n"+ "expected: %s\n"+ - "in chain: %s", expectedType, chain, + "in chain: %s", expectedType, truncatingFormat("%s", chain), ), msgAndArgs...) } @@ -2254,7 +2273,7 @@ func NotErrorAs(t TestingT, err error, target interface{}, msgAndArgs ...interfa return Fail(t, fmt.Sprintf("Target error should not be in err chain:\n"+ "found: %s\n"+ - "in chain: %s", reflect.TypeOf(target).Elem().String(), chain, + "in chain: %s", reflect.TypeOf(target).Elem().String(), truncatingFormat("%s", chain), ), msgAndArgs...) } diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go index a0b953aa..c111589c 100644 --- a/vendor/github.com/stretchr/testify/assert/doc.go +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -40,8 +40,8 @@ // // # Assertions // -// Assertions allow you to easily write test code, and are global funcs in the `assert` package. -// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// Assertions allow you to easily write test code, and are global funcs in the assert package. +// All assertion functions take, as the first argument, the [*testing.T] object provided by the // testing framework. This allows the assertion funcs to write the failings and other details to // the correct place. // diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go index 5a74c4f4..956227ca 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_custom.go @@ -7,7 +7,7 @@ // go test -tags testify_yaml_custom // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]. +// to avoid linking with [go.yaml.in/yaml/v3]. // // In your test package: // diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go index 0bae80e3..dd89ac03 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_default.go @@ -6,7 +6,7 @@ // indirection with an alternative implementation of this package that uses // another implementation of YAML deserialization. This allows to not either not // use YAML deserialization at all, or to use another implementation than -// [gopkg.in/yaml.v3] (for example for license compatibility reasons, see [PR #1120]). +// [go.yaml.in/yaml/v3] (for example for license compatibility reasons, see [PR #1120]). // // Alternative implementations are selected using build tags: // @@ -28,9 +28,9 @@ // [PR #1120]: https://github.com/stretchr/testify/pull/1120 package yaml -import goyaml "gopkg.in/yaml.v3" +import goyaml "go.yaml.in/yaml/v3" -// Unmarshal is just a wrapper of [gopkg.in/yaml.v3.Unmarshal]. +// Unmarshal is just a wrapper of [go.yaml.in/yaml/v3.Unmarshal]. func Unmarshal(in []byte, out interface{}) error { return goyaml.Unmarshal(in, out) } diff --git a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go index 8041803f..a51d2792 100644 --- a/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go +++ b/vendor/github.com/stretchr/testify/assert/yaml/yaml_fail.go @@ -3,7 +3,7 @@ // Package yaml is an implementation of YAML functions that always fail. // // This implementation can be used at build time to replace the default implementation -// to avoid linking with [gopkg.in/yaml.v3]: +// to avoid linking with [go.yaml.in/yaml/v3]: // // go test -tags testify_yaml_fail package yaml diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE similarity index 95% rename from vendor/github.com/pmezard/go-difflib/LICENSE rename to vendor/github.com/stretchr/testify/internal/difflib/LICENSE index c67dad61..485be13c 100644 --- a/vendor/github.com/pmezard/go-difflib/LICENSE +++ b/vendor/github.com/stretchr/testify/internal/difflib/LICENSE @@ -24,4 +24,4 @@ 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. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go similarity index 77% rename from vendor/github.com/pmezard/go-difflib/difflib/difflib.go rename to vendor/github.com/stretchr/testify/internal/difflib/difflib.go index 003e99fa..9984599b 100644 --- a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go +++ b/vendor/github.com/stretchr/testify/internal/difflib/difflib.go @@ -8,11 +8,14 @@ // // - unified_diff // -// - context_diff -// // Getting unified diffs was the main goal of the port. Keep in mind this code // is mostly suitable to output text differences in a human friendly way, there // are no guarantees generated diffs are consumable by patch(1). +// +// This package was adopted from [github.com/pmezard/go-difflib] which +// is no longer maintained. +// +// [github.com/pmezard/go-difflib]: https://github.com/pmezard/go-difflib package difflib import ( @@ -37,13 +40,6 @@ func max(a, b int) int { return b } -func calculateRatio(matches, length int) float64 { - if length > 0 { - return 2.0 * float64(matches) / float64(length) - } - return 1.0 -} - type Match struct { A int B int @@ -103,14 +99,6 @@ func NewMatcher(a, b []string) *SequenceMatcher { return &m } -func NewMatcherWithJunk(a, b []string, autoJunk bool, - isJunk func(string) bool) *SequenceMatcher { - - m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} - m.SetSeqs(a, b) - return &m -} - // Set two sequences to be compared. func (m *SequenceMatcher) SetSeqs(a, b []string) { m.SetSeq1(a) @@ -199,12 +187,15 @@ func (m *SequenceMatcher) isBJunk(s string) bool { // If IsJunk is not defined: // // Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where -// alo <= i <= i+k <= ahi -// blo <= j <= j+k <= bhi +// +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// // and for all (i',j',k') meeting those conditions, -// k >= k' -// i <= i' -// and if i == i', j <= j' +// +// k >= k' +// i <= i' +// and if i == i', j <= j' // // In other words, of all maximal matching blocks, return one that // starts earliest in a, and of all those maximal matching blocks that @@ -451,66 +442,6 @@ func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { return groups } -// Return a measure of the sequences' similarity (float in [0,1]). -// -// Where T is the total number of elements in both sequences, and -// M is the number of matches, this is 2.0*M / T. -// Note that this is 1 if the sequences are identical, and 0 if -// they have nothing in common. -// -// .Ratio() is expensive to compute if you haven't already computed -// .GetMatchingBlocks() or .GetOpCodes(), in which case you may -// want to try .QuickRatio() or .RealQuickRation() first to get an -// upper bound. -func (m *SequenceMatcher) Ratio() float64 { - matches := 0 - for _, m := range m.GetMatchingBlocks() { - matches += m.Size - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() relatively quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute. -func (m *SequenceMatcher) QuickRatio() float64 { - // viewing a and b as multisets, set matches to the cardinality - // of their intersection; this counts the number of matches - // without regard to order, so is clearly an upper bound - if m.fullBCount == nil { - m.fullBCount = map[string]int{} - for _, s := range m.b { - m.fullBCount[s] = m.fullBCount[s] + 1 - } - } - - // avail[x] is the number of times x appears in 'b' less the - // number of times we've seen it in 'a' so far ... kinda - avail := map[string]int{} - matches := 0 - for _, s := range m.a { - n, ok := avail[s] - if !ok { - n = m.fullBCount[s] - } - avail[s] = n - 1 - if n > 0 { - matches += 1 - } - } - return calculateRatio(matches, len(m.a)+len(m.b)) -} - -// Return an upper bound on ratio() very quickly. -// -// This isn't defined beyond that it is an upper bound on .Ratio(), and -// is faster to compute than either .Ratio() or .QuickRatio(). -func (m *SequenceMatcher) RealQuickRatio() float64 { - la, lb := len(m.a), len(m.b) - return calculateRatio(min(la, lb), la+lb) -} - // Convert range to the "ed" format func formatRangeUnified(start, stop int) string { // Per the diff spec at http://www.unix.org/single_unix_specification/ @@ -652,117 +583,6 @@ func formatRangeContext(start, stop int) string { return fmt.Sprintf("%d,%d", beginning, beginning+length-1) } -type ContextDiff UnifiedDiff - -// Compare two sequences of lines; generate the delta as a context diff. -// -// Context diffs are a compact way of showing line changes and a few -// lines of context. The number of context lines is set by diff.Context -// which defaults to three. -// -// By default, the diff control lines (those with *** or ---) are -// created with a trailing newline. -// -// For inputs that do not have trailing newlines, set the diff.Eol -// argument to "" so that the output will be uniformly newline free. -// -// The context diff format normally has a header for filenames and -// modification times. Any or all of these may be specified using -// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. -// The modification times are normally expressed in the ISO 8601 format. -// If not specified, the strings default to blanks. -func WriteContextDiff(writer io.Writer, diff ContextDiff) error { - buf := bufio.NewWriter(writer) - defer buf.Flush() - var diffErr error - wf := func(format string, args ...interface{}) { - _, err := buf.WriteString(fmt.Sprintf(format, args...)) - if diffErr == nil && err != nil { - diffErr = err - } - } - ws := func(s string) { - _, err := buf.WriteString(s) - if diffErr == nil && err != nil { - diffErr = err - } - } - - if len(diff.Eol) == 0 { - diff.Eol = "\n" - } - - prefix := map[byte]string{ - 'i': "+ ", - 'd': "- ", - 'r': "! ", - 'e': " ", - } - - started := false - m := NewMatcher(diff.A, diff.B) - for _, g := range m.GetGroupedOpCodes(diff.Context) { - if !started { - started = true - fromDate := "" - if len(diff.FromDate) > 0 { - fromDate = "\t" + diff.FromDate - } - toDate := "" - if len(diff.ToDate) > 0 { - toDate = "\t" + diff.ToDate - } - if diff.FromFile != "" || diff.ToFile != "" { - wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) - wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) - } - } - - first, last := g[0], g[len(g)-1] - ws("***************" + diff.Eol) - - range1 := formatRangeContext(first.I1, last.I2) - wf("*** %s ****%s", range1, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'd' { - for _, cc := range g { - if cc.Tag == 'i' { - continue - } - for _, line := range diff.A[cc.I1:cc.I2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - - range2 := formatRangeContext(first.J1, last.J2) - wf("--- %s ----%s", range2, diff.Eol) - for _, c := range g { - if c.Tag == 'r' || c.Tag == 'i' { - for _, cc := range g { - if cc.Tag == 'd' { - continue - } - for _, line := range diff.B[cc.J1:cc.J2] { - ws(prefix[cc.Tag] + line) - } - } - break - } - } - } - return diffErr -} - -// Like WriteContextDiff but returns the diff a string. -func GetContextDiffString(diff ContextDiff) (string, error) { - w := &bytes.Buffer{} - err := WriteContextDiff(w, diff) - return string(w.Bytes()), err -} - // Split a string on "\n" while preserving them. The output can be used // as input for UnifiedDiff and ContextDiff structures. func SplitLines(s string) []string { diff --git a/vendor/github.com/stretchr/testify/internal/spew/LICENSE b/vendor/github.com/stretchr/testify/internal/spew/LICENSE new file mode 100644 index 00000000..bc52e96f --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/LICENSE @@ -0,0 +1,15 @@ +ISC License + +Copyright (c) 2012-2016 Dave Collins + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/internal/spew/README.md b/vendor/github.com/stretchr/testify/internal/spew/README.md new file mode 100644 index 00000000..51a909e2 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/README.md @@ -0,0 +1,12 @@ +go-spew +======= + +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) + +Go-spew implements a deep pretty printer for Go data structures to aid in +debugging. A comprehensive suite of tests with 100% test coverage is provided +to ensure proper functionality. + +## License + +Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License. diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypass.go b/vendor/github.com/stretchr/testify/internal/spew/bypass.go new file mode 100644 index 00000000..70ddeaad --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypass.go @@ -0,0 +1,146 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is not running on Google App Engine, compiled by GopherJS, and +// "-tags safe" is not added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +// Go versions prior to 1.4 are disabled because they use a different layout +// for interfaces which make the implementation of unsafeReflectValue more complex. +//go:build !js && !appengine && !safe && !disableunsafe && go1.4 +// +build !js,!appengine,!safe,!disableunsafe,go1.4 + +package spew + +import ( + "reflect" + "unsafe" +) + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = false + + // ptrSize is the size of a pointer on the current arch. + ptrSize = unsafe.Sizeof((*byte)(nil)) +) + +type flag uintptr + +var ( + // flagRO indicates whether the value field of a reflect.Value + // is read-only. + flagRO flag + + // flagAddr indicates whether the address of the reflect.Value's + // value may be taken. + flagAddr flag +) + +// flagKindMask holds the bits that make up the kind +// part of the flags field. In all the supported versions, +// it is in the lower 5 bits. +const flagKindMask = flag(0x1f) + +// Different versions of Go have used different +// bit layouts for the flags type. This table +// records the known combinations. +var okFlags = []struct { + ro, addr flag +}{{ + // From Go 1.4 to 1.5 + ro: 1 << 5, + addr: 1 << 7, +}, { + // Up to Go tip. + ro: 1<<5 | 1<<6, + addr: 1 << 8, +}} + +var flagValOffset = func() uintptr { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + return field.Offset +}() + +// flagField returns a pointer to the flag field of a reflect.Value. +func flagField(v *reflect.Value) *flag { + return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset)) +} + +// unsafeReflectValue converts the passed reflect.Value into a one that bypasses +// the typical safety restrictions preventing access to unaddressable and +// unexported data. It works by digging the raw pointer to the underlying +// value out of the protected value and generating a new unprotected (unsafe) +// reflect.Value to it. +// +// This allows us to check for implementations of the Stringer and error +// interfaces to be used for pretty printing ordinarily unaddressable and +// inaccessible values such as unexported struct fields. +func unsafeReflectValue(v reflect.Value) reflect.Value { + if !v.IsValid() || (v.CanInterface() && v.CanAddr()) { + return v + } + flagFieldPtr := flagField(&v) + *flagFieldPtr &^= flagRO + *flagFieldPtr |= flagAddr + return v +} + +// Sanity checks against future reflect package changes +// to the type or semantics of the Value.flag field. +func init() { + field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag") + if !ok { + panic("reflect.Value has no flag field") + } + if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() { + panic("reflect.Value flag field has changed kind") + } + type t0 int + var t struct { + A t0 + // t0 will have flagEmbedRO set. + t0 + // a will have flagStickyRO set + a t0 + } + vA := reflect.ValueOf(t).FieldByName("A") + va := reflect.ValueOf(t).FieldByName("a") + vt0 := reflect.ValueOf(t).FieldByName("t0") + + // Infer flagRO from the difference between the flags + // for the (otherwise identical) fields in t. + flagPublic := *flagField(&vA) + flagWithRO := *flagField(&va) | *flagField(&vt0) + flagRO = flagPublic ^ flagWithRO + + // Infer flagAddr from the difference between a value + // taken from a pointer and not. + vPtrA := reflect.ValueOf(&t).Elem().FieldByName("A") + flagNoPtr := *flagField(&vA) + flagPtr := *flagField(&vPtrA) + flagAddr = flagNoPtr ^ flagPtr + + // Check that the inferred flags tally with one of the known versions. + for _, f := range okFlags { + if flagRO == f.ro && flagAddr == f.addr { + return + } + } + panic("reflect.Value read-only flag has changed semantics") +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go new file mode 100644 index 00000000..5e2d890d --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/bypasssafe.go @@ -0,0 +1,39 @@ +// Copyright (c) 2015-2016 Dave Collins +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +// NOTE: Due to the following build constraints, this file will only be compiled +// when the code is running on Google App Engine, compiled by GopherJS, or +// "-tags safe" is added to the go build command line. The "disableunsafe" +// tag is deprecated and thus should not be used. +//go:build js || appengine || safe || disableunsafe || !go1.4 +// +build js appengine safe disableunsafe !go1.4 + +package spew + +import "reflect" + +const ( + // UnsafeDisabled is a build-time constant which specifies whether or + // not access to the unsafe package is available. + UnsafeDisabled = true +) + +// unsafeReflectValue typically converts the passed reflect.Value into a one +// that bypasses the typical safety restrictions preventing access to +// unaddressable and unexported data. However, doing this relies on access to +// the unsafe package. This is a stub version which simply returns the passed +// reflect.Value when the unsafe package is not available. +func unsafeReflectValue(v reflect.Value) reflect.Value { + return v +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/common.go b/vendor/github.com/stretchr/testify/internal/spew/common.go new file mode 100644 index 00000000..1be8ce94 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/common.go @@ -0,0 +1,341 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "reflect" + "sort" + "strconv" +) + +// Some constants in the form of bytes to avoid string overhead. This mirrors +// the technique used in the fmt package. +var ( + panicBytes = []byte("(PANIC=") + plusBytes = []byte("+") + iBytes = []byte("i") + trueBytes = []byte("true") + falseBytes = []byte("false") + interfaceBytes = []byte("(interface {})") + commaNewlineBytes = []byte(",\n") + newlineBytes = []byte("\n") + openBraceBytes = []byte("{") + openBraceNewlineBytes = []byte("{\n") + closeBraceBytes = []byte("}") + asteriskBytes = []byte("*") + colonBytes = []byte(":") + colonSpaceBytes = []byte(": ") + openParenBytes = []byte("(") + closeParenBytes = []byte(")") + spaceBytes = []byte(" ") + pointerChainBytes = []byte("->") + nilAngleBytes = []byte("") + maxNewlineBytes = []byte("\n") + maxShortBytes = []byte("") + circularBytes = []byte("") + circularShortBytes = []byte("") + invalidAngleBytes = []byte("") + openBracketBytes = []byte("[") + closeBracketBytes = []byte("]") + percentBytes = []byte("%") + precisionBytes = []byte(".") + openAngleBytes = []byte("<") + closeAngleBytes = []byte(">") + openMapBytes = []byte("map[") + closeMapBytes = []byte("]") + lenEqualsBytes = []byte("len=") + capEqualsBytes = []byte("cap=") +) + +// hexDigits is used to map a decimal value to a hex digit. +var hexDigits = "0123456789abcdef" + +// catchPanic handles any panics that might occur during the handleMethods +// calls. +func catchPanic(w io.Writer, v reflect.Value) { + if err := recover(); err != nil { + w.Write(panicBytes) + fmt.Fprintf(w, "%v", err) + w.Write(closeParenBytes) + } +} + +// handleMethods attempts to call the Error and String methods on the underlying +// type the passed reflect.Value represents and outputes the result to Writer w. +// +// It handles panics in any called methods by catching and displaying the error +// as the formatted value. +func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) { + // We need an interface to check if the type implements the error or + // Stringer interface. However, the reflect package won't give us an + // interface on certain things like unexported struct fields in order + // to enforce visibility rules. We use unsafe, when it's available, + // to bypass these restrictions since this package does not mutate the + // values. + if !v.CanInterface() { + if UnsafeDisabled { + return false + } + + v = unsafeReflectValue(v) + } + + // Choose whether or not to do error and Stringer interface lookups against + // the base type or a pointer to the base type depending on settings. + // Technically calling one of these methods with a pointer receiver can + // mutate the value, however, types which choose to satisify an error or + // Stringer interface with a pointer receiver should not be mutating their + // state inside these interface methods. + if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() { + v = unsafeReflectValue(v) + } + if v.CanAddr() { + v = v.Addr() + } + + // Is it an error or Stringer? + switch iface := v.Interface().(type) { + case error: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.Error())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + + w.Write([]byte(iface.Error())) + return true + + case fmt.Stringer: + defer catchPanic(w, v) + if cs.ContinueOnMethod { + w.Write(openParenBytes) + w.Write([]byte(iface.String())) + w.Write(closeParenBytes) + w.Write(spaceBytes) + return false + } + w.Write([]byte(iface.String())) + return true + } + return false +} + +// printBool outputs a boolean value as true or false to Writer w. +func printBool(w io.Writer, val bool) { + if val { + w.Write(trueBytes) + } else { + w.Write(falseBytes) + } +} + +// printInt outputs a signed integer value to Writer w. +func printInt(w io.Writer, val int64, base int) { + w.Write([]byte(strconv.FormatInt(val, base))) +} + +// printUint outputs an unsigned integer value to Writer w. +func printUint(w io.Writer, val uint64, base int) { + w.Write([]byte(strconv.FormatUint(val, base))) +} + +// printFloat outputs a floating point value using the specified precision, +// which is expected to be 32 or 64bit, to Writer w. +func printFloat(w io.Writer, val float64, precision int) { + w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision))) +} + +// printComplex outputs a complex value using the specified float precision +// for the real and imaginary parts to Writer w. +func printComplex(w io.Writer, c complex128, floatPrecision int) { + r := real(c) + w.Write(openParenBytes) + w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision))) + i := imag(c) + if i >= 0 { + w.Write(plusBytes) + } + w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision))) + w.Write(iBytes) + w.Write(closeParenBytes) +} + +// printHexPtr outputs a uintptr formatted as hexadecimal with a leading '0x' +// prefix to Writer w. +func printHexPtr(w io.Writer, p uintptr) { + // Null pointer. + num := uint64(p) + if num == 0 { + w.Write(nilAngleBytes) + return + } + + // Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix + buf := make([]byte, 18) + + // It's simpler to construct the hex string right to left. + base := uint64(16) + i := len(buf) - 1 + for num >= base { + buf[i] = hexDigits[num%base] + num /= base + i-- + } + buf[i] = hexDigits[num] + + // Add '0x' prefix. + i-- + buf[i] = 'x' + i-- + buf[i] = '0' + + // Strip unused leading bytes. + buf = buf[i:] + w.Write(buf) +} + +// valuesSorter implements sort.Interface to allow a slice of reflect.Value +// elements to be sorted. +type valuesSorter struct { + values []reflect.Value + strings []string // either nil or same len and values + cs *ConfigState +} + +// newValuesSorter initializes a valuesSorter instance, which holds a set of +// surrogate keys on which the data should be sorted. It uses flags in +// ConfigState to decide if and how to populate those surrogate keys. +func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface { + vs := &valuesSorter{values: values, cs: cs} + if canSortSimply(vs.values[0].Kind()) { + return vs + } + if !cs.DisableMethods { + vs.strings = make([]string, len(values)) + for i := range vs.values { + b := bytes.Buffer{} + if !handleMethods(cs, &b, vs.values[i]) { + vs.strings = nil + break + } + vs.strings[i] = b.String() + } + } + if vs.strings == nil && cs.SpewKeys { + vs.strings = make([]string, len(values)) + for i := range vs.values { + vs.strings[i] = Sprintf("%#v", vs.values[i].Interface()) + } + } + return vs +} + +// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted +// directly, or whether it should be considered for sorting by surrogate keys +// (if the ConfigState allows it). +func canSortSimply(kind reflect.Kind) bool { + // This switch parallels valueSortLess, except for the default case. + switch kind { + case reflect.Bool: + return true + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return true + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return true + case reflect.Float32, reflect.Float64: + return true + case reflect.String: + return true + case reflect.Uintptr: + return true + case reflect.Array: + return true + } + return false +} + +// Len returns the number of values in the slice. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Len() int { + return len(s.values) +} + +// Swap swaps the values at the passed indices. It is part of the +// sort.Interface implementation. +func (s *valuesSorter) Swap(i, j int) { + s.values[i], s.values[j] = s.values[j], s.values[i] + if s.strings != nil { + s.strings[i], s.strings[j] = s.strings[j], s.strings[i] + } +} + +// valueSortLess returns whether the first value should sort before the second +// value. It is used by valueSorter.Less as part of the sort.Interface +// implementation. +func valueSortLess(a, b reflect.Value) bool { + switch a.Kind() { + case reflect.Bool: + return !a.Bool() && b.Bool() + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + return a.Int() < b.Int() + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + return a.Uint() < b.Uint() + case reflect.Float32, reflect.Float64: + return a.Float() < b.Float() + case reflect.String: + return a.String() < b.String() + case reflect.Uintptr: + return a.Uint() < b.Uint() + case reflect.Array: + // Compare the contents of both arrays. + l := a.Len() + for i := 0; i < l; i++ { + av := a.Index(i) + bv := b.Index(i) + if av.Interface() == bv.Interface() { + continue + } + return valueSortLess(av, bv) + } + } + return a.String() < b.String() +} + +// Less returns whether the value at index i should sort before the +// value at index j. It is part of the sort.Interface implementation. +func (s *valuesSorter) Less(i, j int) bool { + if s.strings == nil { + return valueSortLess(s.values[i], s.values[j]) + } + return s.strings[i] < s.strings[j] +} + +// sortValues is a sort function that handles both native types and any type that +// can be converted to error or Stringer. Other inputs are sorted according to +// their Value.String() value to ensure display stability. +func sortValues(values []reflect.Value, cs *ConfigState) { + if len(values) == 0 { + return + } + sort.Sort(newValuesSorter(values, cs)) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/config.go b/vendor/github.com/stretchr/testify/internal/spew/config.go new file mode 100644 index 00000000..161895fc --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/config.go @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "io" + "os" +) + +// ConfigState houses the configuration options used by spew to format and +// display values. There is a global instance, Config, that is used to control +// all top-level Formatter and Dump functionality. Each ConfigState instance +// provides methods equivalent to the top-level functions. +// +// The zero value for ConfigState provides no indentation. You would typically +// want to set it to a space or a tab. +// +// Alternatively, you can use NewDefaultConfig to get a ConfigState instance +// with default settings. See the documentation of NewDefaultConfig for default +// values. +type ConfigState struct { + // Indent specifies the string to use for each indentation level. The + // global config instance that all top-level functions use set this to a + // single space by default. If you would like more indentation, you might + // set this to a tab with "\t" or perhaps two spaces with " ". + Indent string + + // MaxDepth controls the maximum number of levels to descend into nested + // data structures. The default, 0, means there is no limit. + // + // NOTE: Circular data structures are properly detected, so it is not + // necessary to set this value unless you specifically want to limit deeply + // nested data structures. + MaxDepth int + + // DisableMethods specifies whether or not error and Stringer interfaces are + // invoked for types that implement them. + DisableMethods bool + + // DisablePointerMethods specifies whether or not to check for and invoke + // error and Stringer interfaces on types which only accept a pointer + // receiver when the current type is not a pointer. + // + // NOTE: This might be an unsafe action since calling one of these methods + // with a pointer receiver could technically mutate the value, however, + // in practice, types which choose to satisify an error or Stringer + // interface with a pointer receiver should not be mutating their state + // inside these interface methods. As a result, this option relies on + // access to the unsafe package, so it will not have any effect when + // running in environments without access to the unsafe package such as + // Google App Engine or with the "safe" build tag specified. + DisablePointerMethods bool + + // DisablePointerAddresses specifies whether to disable the printing of + // pointer addresses. This is useful when diffing data structures in tests. + DisablePointerAddresses bool + + // DisableCapacities specifies whether to disable the printing of capacities + // for arrays, slices, maps and channels. This is useful when diffing + // data structures in tests. + DisableCapacities bool + + // ContinueOnMethod specifies whether or not recursion should continue once + // a custom error or Stringer interface is invoked. The default, false, + // means it will print the results of invoking the custom error or Stringer + // interface and return immediately instead of continuing to recurse into + // the internals of the data type. + // + // NOTE: This flag does not have any effect if method invocation is disabled + // via the DisableMethods or DisablePointerMethods options. + ContinueOnMethod bool + + // SortKeys specifies map keys should be sorted before being printed. Use + // this to have a more deterministic, diffable output. Note that only + // native types (bool, int, uint, floats, uintptr and string) and types + // that support the error or Stringer interfaces (if methods are + // enabled) are supported, with other types sorted according to the + // reflect.Value.String() output which guarantees display stability. + SortKeys bool + + // SpewKeys specifies that, as a last resort attempt, map keys should + // be spewed to strings and sorted by those strings. This is only + // considered if SortKeys is true. + SpewKeys bool +} + +// Config is the active configuration of the top-level functions. +// The configuration can be changed by modifying the contents of spew.Config. +var Config = ConfigState{Indent: " "} + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the formatted string as a value that satisfies error. See NewFormatter +// for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, c.convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, c.convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, c.convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a Formatter interface returned by c.NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, c.convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Print(a ...interface{}) (n int, err error) { + return fmt.Print(c.convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, c.convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Println(a ...interface{}) (n int, err error) { + return fmt.Println(c.convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprint(a ...interface{}) string { + return fmt.Sprint(c.convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a Formatter interface returned by c.NewFormatter. It returns +// the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, c.convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a Formatter interface returned by c.NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b)) +func (c *ConfigState) Sprintln(a ...interface{}) string { + return fmt.Sprintln(c.convertArgs(a)...) +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +c.Printf, c.Println, or c.Printf. +*/ +func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(c, v) +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) { + fdump(c, w, a...) +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by modifying the public members +of c. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func (c *ConfigState) Dump(a ...interface{}) { + fdump(c, os.Stdout, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func (c *ConfigState) Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(c, &buf, a...) + return buf.String() +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a spew Formatter interface using +// the ConfigState associated with s. +func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = newFormatter(c, arg) + } + return formatters +} + +// NewDefaultConfig returns a ConfigState with the following default settings. +// +// Indent: " " +// MaxDepth: 0 +// DisableMethods: false +// DisablePointerMethods: false +// ContinueOnMethod: false +// SortKeys: false +func NewDefaultConfig() *ConfigState { + return &ConfigState{Indent: " "} +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/doc.go b/vendor/github.com/stretchr/testify/internal/spew/doc.go new file mode 100644 index 00000000..722e9aa7 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/doc.go @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* +Package spew implements a deep pretty printer for Go data structures to aid in +debugging. + +A quick overview of the additional features spew provides over the built-in +printing facilities for Go data types are as follows: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output (only when using + Dump style) + +There are two different approaches spew allows for dumping Go data structures: + + - Dump style which prints with newlines, customizable indentation, + and additional debug information such as types and all pointer addresses + used to indirect to the final value + - A custom Formatter interface that integrates cleanly with the standard fmt + package and replaces %v, %+v, %#v, and %#+v to provide inline printing + similar to the default %v while providing the additional functionality + outlined above and passing unsupported format verbs such as %x and %q + along to fmt + +# Quick Start + +This section demonstrates how to quickly get started with spew. See the +sections below for further details on formatting and configuration options. + +To dump a variable with full newlines, indentation, type, and pointer +information use Dump, Fdump, or Sdump: + + spew.Dump(myVar1, myVar2, ...) + spew.Fdump(someWriter, myVar1, myVar2, ...) + str := spew.Sdump(myVar1, myVar2, ...) + +Alternatively, if you would prefer to use format strings with a compacted inline +printing style, use the convenience wrappers Printf, Fprintf, etc with +%v (most compact), %+v (adds pointer addresses), %#v (adds types), or +%#+v (adds types and pointer addresses): + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +# Configuration Options + +Configuration of spew is handled by fields in the ConfigState type. For +convenience, all of the top-level functions use a global state available +via the spew.Config global. + +It is also possible to create a ConfigState instance that provides methods +equivalent to the top-level functions. This allows concurrent configuration +options. See the ConfigState documentation for more details. + +The following configuration options are available: + + - Indent + String to use for each indentation level for Dump functions. + It is a single space by default. A popular alternative is "\t". + + - MaxDepth + Maximum number of levels to descend into nested data structures. + There is no limit by default. + + - DisableMethods + Disables invocation of error and Stringer interface methods. + Method invocation is enabled by default. + + - DisablePointerMethods + Disables invocation of error and Stringer interface methods on types + which only accept pointer receivers from non-pointer variables. + Pointer method invocation is enabled by default. + + - DisablePointerAddresses + DisablePointerAddresses specifies whether to disable the printing of + pointer addresses. This is useful when diffing data structures in tests. + + - DisableCapacities + DisableCapacities specifies whether to disable the printing of + capacities for arrays, slices, maps and channels. This is useful when + diffing data structures in tests. + + - ContinueOnMethod + Enables recursion into types after invoking error and Stringer interface + methods. Recursion after method invocation is disabled by default. + + - SortKeys + Specifies map keys should be sorted before being printed. Use + this to have a more deterministic, diffable output. Note that + only native types (bool, int, uint, floats, uintptr and string) + and types which implement error or Stringer interfaces are + supported with other types sorted according to the + reflect.Value.String() output which guarantees display + stability. Natural map order is used by default. + + - SpewKeys + Specifies that, as a last resort attempt, map keys should be + spewed to strings and sorted by those strings. This is only + considered if SortKeys is true. + +# Dump Usage + +Simply call spew.Dump with a list of variables you want to dump: + + spew.Dump(myVar1, myVar2, ...) + +You may also call spew.Fdump if you would prefer to output to an arbitrary +io.Writer. For example, to dump to standard error: + + spew.Fdump(os.Stderr, myVar1, myVar2, ...) + +A third option is to call spew.Sdump to get the formatted output as a string: + + str := spew.Sdump(myVar1, myVar2, ...) + +# Sample Dump Output + +See the Dump example for details on the setup of the types and variables being +shown here. + + (main.Foo) { + unexportedField: (*main.Bar)(0xf84002e210)({ + flag: (main.Flag) flagTwo, + data: (uintptr) + }), + ExportedField: (map[interface {}]interface {}) (len=1) { + (string) (len=3) "one": (bool) true + } + } + +Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C +command as shown. + + ([]uint8) (len=32 cap=32) { + 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... | + 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0| + 00000020 31 32 |12| + } + +# Custom Formatter + +Spew provides a custom formatter that implements the fmt.Formatter interface +so that it integrates cleanly with standard fmt package printing functions. The +formatter is useful for inline printing of smaller data types similar to the +standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +# Custom Formatter Usage + +The simplest way to make use of the spew custom formatter is to call one of the +convenience functions such as spew.Printf, spew.Println, or spew.Printf. The +functions have syntax you are most likely already familiar with: + + spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + spew.Println(myVar, myVar2) + spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2) + spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4) + +See the Index for the full list convenience functions. + +# Sample Formatter Output + +Double pointer to a uint8: + + %v: <**>5 + %+v: <**>(0xf8400420d0->0xf8400420c8)5 + %#v: (**uint8)5 + %#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5 + +Pointer to circular struct with a uint8 field and a pointer to itself: + + %v: <*>{1 <*>} + %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)} + %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)} + %#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)} + +See the Printf example for details on the setup of variables being shown +here. + +# Errors + +Since it is possible for custom Stringer/error interfaces to panic, spew +detects them and handles them internally by printing the panic information +inline with the output. Since spew is intended to provide deep pretty printing +capabilities on structures, it intentionally does not return any errors. +*/ +package spew diff --git a/vendor/github.com/stretchr/testify/internal/spew/dump.go b/vendor/github.com/stretchr/testify/internal/spew/dump.go new file mode 100644 index 00000000..8323041a --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/dump.go @@ -0,0 +1,509 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "reflect" + "regexp" + "strconv" + "strings" +) + +var ( + // uint8Type is a reflect.Type representing a uint8. It is used to + // convert cgo types to uint8 slices for hexdumping. + uint8Type = reflect.TypeOf(uint8(0)) + + // cCharRE is a regular expression that matches a cgo char. + // It is used to detect character arrays to hexdump them. + cCharRE = regexp.MustCompile(`^.*\._Ctype_char$`) + + // cUnsignedCharRE is a regular expression that matches a cgo unsigned + // char. It is used to detect unsigned character arrays to hexdump + // them. + cUnsignedCharRE = regexp.MustCompile(`^.*\._Ctype_unsignedchar$`) + + // cUint8tCharRE is a regular expression that matches a cgo uint8_t. + // It is used to detect uint8_t arrays to hexdump them. + cUint8tCharRE = regexp.MustCompile(`^.*\._Ctype_uint8_t$`) +) + +// dumpState contains information about the state of a dump operation. +type dumpState struct { + w io.Writer + depth int + pointers map[uintptr]int + ignoreNextType bool + ignoreNextIndent bool + cs *ConfigState +} + +// indent performs indentation according to the depth level and cs.Indent +// option. +func (d *dumpState) indent() { + if d.ignoreNextIndent { + d.ignoreNextIndent = false + return + } + d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth)) +} + +// unpackValue returns values inside of non-nil interfaces when possible. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (d *dumpState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface && !v.IsNil() { + v = v.Elem() + } + return v +} + +// dumpPtr handles formatting of pointers by indirecting them as necessary. +func (d *dumpState) dumpPtr(v reflect.Value) { + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range d.pointers { + if depth >= d.depth { + delete(d.pointers, k) + } + } + + // Keep list of all dereferenced pointers to show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by dereferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := d.pointers[addr]; ok && pd < d.depth { + cycleFound = true + indirects-- + break + } + d.pointers[addr] = d.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type information. + d.w.Write(openParenBytes) + d.w.Write(bytes.Repeat(asteriskBytes, indirects)) + d.w.Write([]byte(ve.Type().String())) + d.w.Write(closeParenBytes) + + // Display pointer information. + if !d.cs.DisablePointerAddresses && len(pointerChain) > 0 { + d.w.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + d.w.Write(pointerChainBytes) + } + printHexPtr(d.w, addr) + } + d.w.Write(closeParenBytes) + } + + // Display dereferenced value. + d.w.Write(openParenBytes) + switch { + case nilFound: + d.w.Write(nilAngleBytes) + + case cycleFound: + d.w.Write(circularBytes) + + default: + d.ignoreNextType = true + d.dump(ve) + } + d.w.Write(closeParenBytes) +} + +// dumpSlice handles formatting of arrays and slices. Byte (uint8 under +// reflection) arrays and slices are dumped in hexdump -C fashion. +func (d *dumpState) dumpSlice(v reflect.Value) { + // Determine whether this type should be hex dumped or not. Also, + // for types which should be hexdumped, try to use the underlying data + // first, then fall back to trying to convert them to a uint8 slice. + var buf []uint8 + doConvert := false + doHexDump := false + numEntries := v.Len() + if numEntries > 0 { + vt := v.Index(0).Type() + vts := vt.String() + switch { + // C types that need to be converted. + case cCharRE.MatchString(vts): + fallthrough + case cUnsignedCharRE.MatchString(vts): + fallthrough + case cUint8tCharRE.MatchString(vts): + doConvert = true + + // Try to use existing uint8 slices and fall back to converting + // and copying if that fails. + case vt.Kind() == reflect.Uint8: + // We need an addressable interface to convert the type + // to a byte slice. However, the reflect package won't + // give us an interface on certain things like + // unexported struct fields in order to enforce + // visibility rules. We use unsafe, when available, to + // bypass these restrictions since this package does not + // mutate the values. + vs := v + if !vs.CanInterface() || !vs.CanAddr() { + vs = unsafeReflectValue(vs) + } + if !UnsafeDisabled { + vs = vs.Slice(0, numEntries) + + // Use the existing uint8 slice if it can be + // type asserted. + iface := vs.Interface() + if slice, ok := iface.([]uint8); ok { + buf = slice + doHexDump = true + break + } + } + + // The underlying data needs to be converted if it can't + // be type asserted to a uint8 slice. + doConvert = true + } + + // Copy and convert the underlying type if needed. + if doConvert && vt.ConvertibleTo(uint8Type) { + // Convert and copy each element into a uint8 byte + // slice. + buf = make([]uint8, numEntries) + for i := 0; i < numEntries; i++ { + vv := v.Index(i) + buf[i] = uint8(vv.Convert(uint8Type).Uint()) + } + doHexDump = true + } + } + + // Hexdump the entire slice as needed. + if doHexDump { + indent := strings.Repeat(d.cs.Indent, d.depth) + str := indent + hex.Dump(buf) + str = strings.Replace(str, "\n", "\n"+indent, -1) + str = strings.TrimRight(str, d.cs.Indent) + d.w.Write([]byte(str)) + return + } + + // Recursively call dump for each item. + for i := 0; i < numEntries; i++ { + d.dump(d.unpackValue(v.Index(i))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } +} + +// dump is the main workhorse for dumping a value. It uses the passed reflect +// value to figure out what kind of object we are dealing with and formats it +// appropriately. It is a recursive function, however circular data structures +// are detected and handled properly. +func (d *dumpState) dump(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + d.w.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + d.indent() + d.dumpPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !d.ignoreNextType { + d.indent() + d.w.Write(openParenBytes) + d.w.Write([]byte(v.Type().String())) + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + d.ignoreNextType = false + + // Display length and capacity if the built-in len and cap functions + // work with the value's kind and the len/cap itself is non-zero. + valueLen, valueCap := 0, 0 + switch v.Kind() { + case reflect.Array, reflect.Slice, reflect.Chan: + valueLen, valueCap = v.Len(), v.Cap() + case reflect.Map, reflect.String: + valueLen = v.Len() + } + if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 { + d.w.Write(openParenBytes) + if valueLen != 0 { + d.w.Write(lenEqualsBytes) + printInt(d.w, int64(valueLen), 10) + } + if !d.cs.DisableCapacities && valueCap != 0 { + if valueLen != 0 { + d.w.Write(spaceBytes) + } + d.w.Write(capEqualsBytes) + printInt(d.w, int64(valueCap), 10) + } + d.w.Write(closeParenBytes) + d.w.Write(spaceBytes) + } + + // Call Stringer/error interfaces if they exist and the handle methods flag + // is enabled + if !d.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(d.cs, d.w, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(d.w, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(d.w, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(d.w, v.Uint(), 10) + + case reflect.Float32: + printFloat(d.w, v.Float(), 32) + + case reflect.Float64: + printFloat(d.w, v.Float(), 64) + + case reflect.Complex64: + printComplex(d.w, v.Complex(), 32) + + case reflect.Complex128: + printComplex(d.w, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + d.dumpSlice(v) + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.String: + d.w.Write([]byte(strconv.Quote(v.String()))) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + d.w.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + d.w.Write(nilAngleBytes) + break + } + + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + numEntries := v.Len() + keys := v.MapKeys() + if d.cs.SortKeys { + sortValues(keys, d.cs) + } + for i, key := range keys { + d.dump(d.unpackValue(key)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.MapIndex(key))) + if i < (numEntries - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Struct: + d.w.Write(openBraceNewlineBytes) + d.depth++ + if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) { + d.indent() + d.w.Write(maxNewlineBytes) + } else { + vt := v.Type() + numFields := v.NumField() + for i := 0; i < numFields; i++ { + d.indent() + vtf := vt.Field(i) + d.w.Write([]byte(vtf.Name)) + d.w.Write(colonSpaceBytes) + d.ignoreNextIndent = true + d.dump(d.unpackValue(v.Field(i))) + if i < (numFields - 1) { + d.w.Write(commaNewlineBytes) + } else { + d.w.Write(newlineBytes) + } + } + } + d.depth-- + d.indent() + d.w.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(d.w, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(d.w, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it in case any new + // types are added. + default: + if v.CanInterface() { + fmt.Fprintf(d.w, "%v", v.Interface()) + } else { + fmt.Fprintf(d.w, "%v", v.String()) + } + } +} + +// fdump is a helper function to consolidate the logic from the various public +// methods which take varying writers and config states. +func fdump(cs *ConfigState, w io.Writer, a ...interface{}) { + for _, arg := range a { + if arg == nil { + w.Write(interfaceBytes) + w.Write(spaceBytes) + w.Write(nilAngleBytes) + w.Write(newlineBytes) + continue + } + + d := dumpState{w: w, cs: cs} + d.pointers = make(map[uintptr]int) + d.dump(reflect.ValueOf(arg)) + d.w.Write(newlineBytes) + } +} + +// Fdump formats and displays the passed arguments to io.Writer w. It formats +// exactly the same as Dump. +func Fdump(w io.Writer, a ...interface{}) { + fdump(&Config, w, a...) +} + +// Sdump returns a string with the passed arguments formatted exactly the same +// as Dump. +func Sdump(a ...interface{}) string { + var buf bytes.Buffer + fdump(&Config, &buf, a...) + return buf.String() +} + +/* +Dump displays the passed parameters to standard out with newlines, customizable +indentation, and additional debug information such as complete types and all +pointer addresses used to indirect to the final value. It provides the +following features over the built-in printing facilities provided by the fmt +package: + + - Pointers are dereferenced and followed + - Circular data structures are detected and handled properly + - Custom Stringer/error interfaces are optionally invoked, including + on unexported types + - Custom types which only implement the Stringer/error interfaces via + a pointer receiver are optionally invoked when passing non-pointer + variables + - Byte arrays and slices are dumped like the hexdump -C command which + includes offsets, byte values in hex, and ASCII output + +The configuration options are controlled by an exported package global, +spew.Config. See ConfigState for options documentation. + +See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to +get the formatted result as a string. +*/ +func Dump(a ...interface{}) { + fdump(&Config, os.Stdout, a...) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/format.go b/vendor/github.com/stretchr/testify/internal/spew/format.go new file mode 100644 index 00000000..b04edb7d --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/format.go @@ -0,0 +1,419 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "bytes" + "fmt" + "reflect" + "strconv" + "strings" +) + +// supportedFlags is a list of all the character flags supported by fmt package. +const supportedFlags = "0-+# " + +// formatState implements the fmt.Formatter interface and contains information +// about the state of a formatting operation. The NewFormatter function can +// be used to get a new Formatter which can be used directly as arguments +// in standard fmt package printing calls. +type formatState struct { + value interface{} + fs fmt.State + depth int + pointers map[uintptr]int + ignoreNextType bool + cs *ConfigState +} + +// buildDefaultFormat recreates the original format string without precision +// and width information to pass in to fmt.Sprintf in the case of an +// unrecognized type. Unless new types are added to the language, this +// function won't ever be called. +func (f *formatState) buildDefaultFormat() (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + buf.WriteRune('v') + + format = buf.String() + return format +} + +// constructOrigFormat recreates the original format string including precision +// and width information to pass along to the standard fmt package. This allows +// automatic deferral of all format strings this package doesn't support. +func (f *formatState) constructOrigFormat(verb rune) (format string) { + buf := bytes.NewBuffer(percentBytes) + + for _, flag := range supportedFlags { + if f.fs.Flag(int(flag)) { + buf.WriteRune(flag) + } + } + + if width, ok := f.fs.Width(); ok { + buf.WriteString(strconv.Itoa(width)) + } + + if precision, ok := f.fs.Precision(); ok { + buf.Write(precisionBytes) + buf.WriteString(strconv.Itoa(precision)) + } + + buf.WriteRune(verb) + + format = buf.String() + return format +} + +// unpackValue returns values inside of non-nil interfaces when possible and +// ensures that types for values which have been unpacked from an interface +// are displayed when the show types flag is also set. +// This is useful for data types like structs, arrays, slices, and maps which +// can contain varying types packed inside an interface. +func (f *formatState) unpackValue(v reflect.Value) reflect.Value { + if v.Kind() == reflect.Interface { + f.ignoreNextType = false + if !v.IsNil() { + v = v.Elem() + } + } + return v +} + +// formatPtr handles formatting of pointers by indirecting them as necessary. +func (f *formatState) formatPtr(v reflect.Value) { + // Display nil if top level pointer is nil. + showTypes := f.fs.Flag('#') + if v.IsNil() && (!showTypes || f.ignoreNextType) { + f.fs.Write(nilAngleBytes) + return + } + + // Remove pointers at or below the current depth from map used to detect + // circular refs. + for k, depth := range f.pointers { + if depth >= f.depth { + delete(f.pointers, k) + } + } + + // Keep list of all dereferenced pointers to possibly show later. + pointerChain := make([]uintptr, 0) + + // Figure out how many levels of indirection there are by derferencing + // pointers and unpacking interfaces down the chain while detecting circular + // references. + nilFound := false + cycleFound := false + indirects := 0 + ve := v + for ve.Kind() == reflect.Ptr { + if ve.IsNil() { + nilFound = true + break + } + indirects++ + addr := ve.Pointer() + pointerChain = append(pointerChain, addr) + if pd, ok := f.pointers[addr]; ok && pd < f.depth { + cycleFound = true + indirects-- + break + } + f.pointers[addr] = f.depth + + ve = ve.Elem() + if ve.Kind() == reflect.Interface { + if ve.IsNil() { + nilFound = true + break + } + ve = ve.Elem() + } + } + + // Display type or indirection level depending on flags. + if showTypes && !f.ignoreNextType { + f.fs.Write(openParenBytes) + f.fs.Write(bytes.Repeat(asteriskBytes, indirects)) + f.fs.Write([]byte(ve.Type().String())) + f.fs.Write(closeParenBytes) + } else { + if nilFound || cycleFound { + indirects += strings.Count(ve.Type().String(), "*") + } + f.fs.Write(openAngleBytes) + f.fs.Write([]byte(strings.Repeat("*", indirects))) + f.fs.Write(closeAngleBytes) + } + + // Display pointer information depending on flags. + if f.fs.Flag('+') && (len(pointerChain) > 0) { + f.fs.Write(openParenBytes) + for i, addr := range pointerChain { + if i > 0 { + f.fs.Write(pointerChainBytes) + } + printHexPtr(f.fs, addr) + } + f.fs.Write(closeParenBytes) + } + + // Display dereferenced value. + switch { + case nilFound: + f.fs.Write(nilAngleBytes) + + case cycleFound: + f.fs.Write(circularShortBytes) + + default: + f.ignoreNextType = true + f.format(ve) + } +} + +// format is the main workhorse for providing the Formatter interface. It +// uses the passed reflect value to figure out what kind of object we are +// dealing with and formats it appropriately. It is a recursive function, +// however circular data structures are detected and handled properly. +func (f *formatState) format(v reflect.Value) { + // Handle invalid reflect values immediately. + kind := v.Kind() + if kind == reflect.Invalid { + f.fs.Write(invalidAngleBytes) + return + } + + // Handle pointers specially. + if kind == reflect.Ptr { + f.formatPtr(v) + return + } + + // Print type information unless already handled elsewhere. + if !f.ignoreNextType && f.fs.Flag('#') { + f.fs.Write(openParenBytes) + f.fs.Write([]byte(v.Type().String())) + f.fs.Write(closeParenBytes) + } + f.ignoreNextType = false + + // Call Stringer/error interfaces if they exist and the handle methods + // flag is enabled. + if !f.cs.DisableMethods { + if (kind != reflect.Invalid) && (kind != reflect.Interface) { + if handled := handleMethods(f.cs, f.fs, v); handled { + return + } + } + } + + switch kind { + case reflect.Invalid: + // Do nothing. We should never get here since invalid has already + // been handled above. + + case reflect.Bool: + printBool(f.fs, v.Bool()) + + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + printInt(f.fs, v.Int(), 10) + + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint: + printUint(f.fs, v.Uint(), 10) + + case reflect.Float32: + printFloat(f.fs, v.Float(), 32) + + case reflect.Float64: + printFloat(f.fs, v.Float(), 64) + + case reflect.Complex64: + printComplex(f.fs, v.Complex(), 32) + + case reflect.Complex128: + printComplex(f.fs, v.Complex(), 64) + + case reflect.Slice: + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + fallthrough + + case reflect.Array: + f.fs.Write(openBracketBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + numEntries := v.Len() + for i := 0; i < numEntries; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(v.Index(i))) + } + } + f.depth-- + f.fs.Write(closeBracketBytes) + + case reflect.String: + f.fs.Write([]byte(v.String())) + + case reflect.Interface: + // The only time we should get here is for nil interfaces due to + // unpackValue calls. + if v.IsNil() { + f.fs.Write(nilAngleBytes) + } + + case reflect.Ptr: + // Do nothing. We should never get here since pointers have already + // been handled above. + + case reflect.Map: + // nil maps should be indicated as different than empty maps + if v.IsNil() { + f.fs.Write(nilAngleBytes) + break + } + + f.fs.Write(openMapBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + keys := v.MapKeys() + if f.cs.SortKeys { + sortValues(keys, f.cs) + } + for i, key := range keys { + if i > 0 { + f.fs.Write(spaceBytes) + } + f.ignoreNextType = true + f.format(f.unpackValue(key)) + f.fs.Write(colonBytes) + f.ignoreNextType = true + f.format(f.unpackValue(v.MapIndex(key))) + } + } + f.depth-- + f.fs.Write(closeMapBytes) + + case reflect.Struct: + numFields := v.NumField() + f.fs.Write(openBraceBytes) + f.depth++ + if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) { + f.fs.Write(maxShortBytes) + } else { + vt := v.Type() + for i := 0; i < numFields; i++ { + if i > 0 { + f.fs.Write(spaceBytes) + } + vtf := vt.Field(i) + if f.fs.Flag('+') || f.fs.Flag('#') { + f.fs.Write([]byte(vtf.Name)) + f.fs.Write(colonBytes) + } + f.format(f.unpackValue(v.Field(i))) + } + } + f.depth-- + f.fs.Write(closeBraceBytes) + + case reflect.Uintptr: + printHexPtr(f.fs, uintptr(v.Uint())) + + case reflect.UnsafePointer, reflect.Chan, reflect.Func: + printHexPtr(f.fs, v.Pointer()) + + // There were not any other types at the time this code was written, but + // fall back to letting the default fmt package handle it if any get added. + default: + format := f.buildDefaultFormat() + if v.CanInterface() { + fmt.Fprintf(f.fs, format, v.Interface()) + } else { + fmt.Fprintf(f.fs, format, v.String()) + } + } +} + +// Format satisfies the fmt.Formatter interface. See NewFormatter for usage +// details. +func (f *formatState) Format(fs fmt.State, verb rune) { + f.fs = fs + + // Use standard formatting for verbs that are not v. + if verb != 'v' { + format := f.constructOrigFormat(verb) + fmt.Fprintf(fs, format, f.value) + return + } + + if f.value == nil { + if fs.Flag('#') { + fs.Write(interfaceBytes) + } + fs.Write(nilAngleBytes) + return + } + + f.format(reflect.ValueOf(f.value)) +} + +// newFormatter is a helper function to consolidate the logic from the various +// public methods which take varying config states. +func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter { + fs := &formatState{value: v, cs: cs} + fs.pointers = make(map[uintptr]int) + return fs +} + +/* +NewFormatter returns a custom formatter that satisfies the fmt.Formatter +interface. As a result, it integrates cleanly with standard fmt package +printing functions. The formatter is useful for inline printing of smaller data +types similar to the standard %v format specifier. + +The custom formatter only responds to the %v (most compact), %+v (adds pointer +addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb +combinations. Any other verbs such as %x and %q will be sent to the the +standard fmt package for formatting. In addition, the custom formatter ignores +the width and precision arguments (however they will still work on the format +specifiers not handled by the custom formatter). + +Typically this function shouldn't be called directly. It is much easier to make +use of the custom formatter by calling one of the convenience functions such as +Printf, Println, or Fprintf. +*/ +func NewFormatter(v interface{}) fmt.Formatter { + return newFormatter(&Config, v) +} diff --git a/vendor/github.com/stretchr/testify/internal/spew/spew.go b/vendor/github.com/stretchr/testify/internal/spew/spew.go new file mode 100644 index 00000000..32c0e338 --- /dev/null +++ b/vendor/github.com/stretchr/testify/internal/spew/spew.go @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2013-2016 Dave Collins + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package spew + +import ( + "fmt" + "io" +) + +// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the formatted string as a value that satisfies error. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Errorf(format string, a ...interface{}) (err error) { + return fmt.Errorf(format, convertArgs(a)...) +} + +// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprint(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprint(w, convertArgs(a)...) +} + +// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) { + return fmt.Fprintf(w, format, convertArgs(a)...) +} + +// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it +// passed with a default Formatter interface returned by NewFormatter. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b)) +func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { + return fmt.Fprintln(w, convertArgs(a)...) +} + +// Print is a wrapper for fmt.Print that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b)) +func Print(a ...interface{}) (n int, err error) { + return fmt.Print(convertArgs(a)...) +} + +// Printf is a wrapper for fmt.Printf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Printf(format string, a ...interface{}) (n int, err error) { + return fmt.Printf(format, convertArgs(a)...) +} + +// Println is a wrapper for fmt.Println that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the number of bytes written and any write error encountered. See +// NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b)) +func Println(a ...interface{}) (n int, err error) { + return fmt.Println(convertArgs(a)...) +} + +// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprint(a ...interface{}) string { + return fmt.Sprint(convertArgs(a)...) +} + +// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were +// passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintf(format string, a ...interface{}) string { + return fmt.Sprintf(format, convertArgs(a)...) +} + +// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it +// were passed with a default Formatter interface returned by NewFormatter. It +// returns the resulting string. See NewFormatter for formatting details. +// +// This function is shorthand for the following syntax: +// +// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b)) +func Sprintln(a ...interface{}) string { + return fmt.Sprintln(convertArgs(a)...) +} + +// convertArgs accepts a slice of arguments and returns a slice of the same +// length with each argument converted to a default spew Formatter interface. +func convertArgs(args []interface{}) (formatters []interface{}) { + formatters = make([]interface{}, len(args)) + for index, arg := range args { + formatters[index] = NewFormatter(arg) + } + return formatters +} diff --git a/vendor/github.com/stretchr/testify/mock/mock.go b/vendor/github.com/stretchr/testify/mock/mock.go index efc89def..7f4d28d5 100644 --- a/vendor/github.com/stretchr/testify/mock/mock.go +++ b/vendor/github.com/stretchr/testify/mock/mock.go @@ -11,11 +11,11 @@ import ( "sync" "time" - "github.com/davecgh/go-spew/spew" - "github.com/pmezard/go-difflib/difflib" "github.com/stretchr/objx" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/internal/difflib" + "github.com/stretchr/testify/internal/spew" ) // regex for GCCGO functions @@ -470,7 +470,7 @@ func callString(method string, arguments Arguments, includeArgumentValues bool) // Called tells the mock object that a method has been called, and gets an array // of arguments to return. Panics if the call is unexpected (i.e. not preceded by -// appropriate .On .Return() calls) +// appropriate [Mock.On] calls) // If Call.WaitFor is set, blocks until the channel is closed or receives a message. func (m *Mock) Called(arguments ...interface{}) Arguments { // get the calling function's name @@ -493,7 +493,7 @@ func (m *Mock) Called(arguments ...interface{}) Arguments { // MethodCalled tells the mock object that the given method has been called, and gets // an array of arguments to return. Panics if the call is unexpected (i.e. not preceded -// by appropriate .On .Return() calls) +// by appropriate [Mock.On] calls) // If Call.WaitFor is set, blocks until the channel is closed or receives a message. func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Arguments { m.mutex.Lock() @@ -510,8 +510,7 @@ func (m *Mock) MethodCalled(methodName string, arguments ...interface{}) Argumen // as the return arguments. This is because: // // a) this is a totally unexpected call to this method, - // b) the arguments are not what was expected, or - // c) the developer has forgotten to add an accompanying On...Return pair. + // b) the arguments are not what was expected closestCall, mismatch := m.findClosestCall(methodName, arguments...) m.mutex.Unlock() @@ -595,7 +594,7 @@ type assertExpectationiser interface { AssertExpectations(TestingT) bool } -// AssertExpectationsForObjects asserts that everything specified with On and Return +// AssertExpectationsForObjects asserts that everything specified with [Mock.On] // of the specified objects was in fact called as expected. // // Calls may have occurred in any order. @@ -604,11 +603,12 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { h.Helper() } for _, obj := range testObjects { - if m, ok := obj.(*Mock); ok { - t.Logf("Deprecated mock.AssertExpectationsForObjects(myMock.Mock) use mock.AssertExpectationsForObjects(myMock)") - obj = m + m, ok := obj.(assertExpectationiser) + if !ok { + t.Errorf("Invalid test object type %T. Expected reference to a mock.Mock, eg: 'AssertExpectationsForObjects(t, myMock)' or 'AssertExpectationsForObjects(t, &myMock.Mock)'", obj) + continue + } - m := obj.(assertExpectationiser) if !m.AssertExpectations(t) { t.Logf("Expectations didn't match for Mock: %+v", reflect.TypeOf(m)) return false @@ -617,7 +617,7 @@ func AssertExpectationsForObjects(t TestingT, testObjects ...interface{}) bool { return true } -// AssertExpectations asserts that everything specified with On and Return was +// AssertExpectations asserts that everything specified with [Mock.On] was // in fact called as expected. Calls may have occurred in any order. func (m *Mock) AssertExpectations(t TestingT) bool { if s, ok := t.(interface{ Skipped() bool }); ok && s.Skipped() { @@ -712,8 +712,8 @@ func (m *Mock) AssertNotCalled(t TestingT, methodName string, arguments ...inter return true } -// IsMethodCallable checking that the method can be called -// If the method was called more than `Repeatability` return false +// IsMethodCallable returns true if given methodName and arguments have an +// unsatisfied expected call registered in the Mock. func (m *Mock) IsMethodCallable(t TestingT, methodName string, arguments ...interface{}) bool { if h, ok := t.(tHelper); ok { h.Helper() @@ -833,6 +833,10 @@ type IsTypeArgument struct { // For example: // // args.Assert(t, IsType(""), IsType(0)) +// +// Mock cannot match interface types because the contained type will be passed +// to both IsType and Mock.Called, for the zero value of all interfaces this +// will be type. func IsType(t interface{}) *IsTypeArgument { return &IsTypeArgument{t: reflect.TypeOf(t)} } @@ -1012,7 +1016,7 @@ func (args Arguments) Diff(objects []interface{}) (string, int) { actualT := reflect.TypeOf(actual) if actualT != expected.t { differences++ - output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, expected.t.Name(), actualT.Name(), actualFmt) + output = fmt.Sprintf("%s\t%d: FAIL: type %s != type %s - %s\n", output, i, safeTypeName(expected.t), safeTypeName(actualT), actualFmt) } case *FunctionalOptionsArgument: var name string @@ -1141,6 +1145,15 @@ func (args Arguments) Bool(index int) bool { return s } +// safeTypeName returns the reflect.Type's name without causing a panic. +// If the provided reflect.Type is nil, it returns the placeholder string "" +func safeTypeName(t reflect.Type) string { + if t == nil { + return "" + } + return t.Name() +} + func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { t := reflect.TypeOf(v) k := t.Kind() diff --git a/vendor/go.yaml.in/yaml/v3/parserc.go b/vendor/go.yaml.in/yaml/v3/parserc.go index 25fe8236..f35829db 100644 --- a/vendor/go.yaml.in/yaml/v3/parserc.go +++ b/vendor/go.yaml.in/yaml/v3/parserc.go @@ -226,9 +226,9 @@ func yaml_parser_state_machine(parser *yaml_parser_t, event *yaml_event_t) bool } // Parse the production: -// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END // -// ************ +// stream ::= STREAM-START implicit_document? explicit_document* STREAM-END +// ************ func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -249,13 +249,11 @@ func yaml_parser_parse_stream_start(parser *yaml_parser_t, event *yaml_event_t) } // Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// -// * // -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* -// -// ************************* +// implicit_document ::= block_node DOCUMENT-END* +// * +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// ************************* func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t, implicit bool) bool { token := peek_token(parser) @@ -359,9 +357,9 @@ func yaml_parser_parse_document_start(parser *yaml_parser_t, event *yaml_event_t } // Parse the productions: -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* // -// *********** +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// *********** func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -382,11 +380,10 @@ func yaml_parser_parse_document_content(parser *yaml_parser_t, event *yaml_event } // Parse the productions: -// implicit_document ::= block_node DOCUMENT-END* -// -// ************* // -// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* +// implicit_document ::= block_node DOCUMENT-END* +// ************* +// explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END* func yaml_parser_parse_document_end(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -432,42 +429,32 @@ func yaml_parser_set_event_comments(parser *yaml_parser_t, event *yaml_event_t) } // Parse the productions: -// block_node_or_indentless_sequence ::= -// -// ALIAS -// ***** -// | properties (block_content | indentless_block_sequence)? -// ********** * -// | block_content | indentless_block_sequence -// * -// -// block_node ::= ALIAS -// -// ***** -// | properties block_content? -// ********** * -// | block_content -// * -// -// flow_node ::= ALIAS -// -// ***** -// | properties flow_content? -// ********** * -// | flow_content -// * -// -// properties ::= TAG ANCHOR? | ANCHOR TAG? -// -// ************************* -// -// block_content ::= block_collection | flow_collection | SCALAR -// -// ****** // -// flow_content ::= flow_collection | SCALAR -// -// ****** +// block_node_or_indentless_sequence ::= +// ALIAS +// ***** +// | properties (block_content | indentless_block_sequence)? +// ********** * +// | block_content | indentless_block_sequence +// * +// block_node ::= ALIAS +// ***** +// | properties block_content? +// ********** * +// | block_content +// * +// flow_node ::= ALIAS +// ***** +// | properties flow_content? +// ********** * +// | flow_content +// * +// properties ::= TAG ANCHOR? | ANCHOR TAG? +// ************************* +// block_content ::= block_collection | flow_collection | SCALAR +// ****** +// flow_content ::= flow_collection | SCALAR +// ****** func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, indentless_sequence bool) bool { //defer trace("yaml_parser_parse_node", "block:", block, "indentless_sequence:", indentless_sequence)() @@ -697,9 +684,9 @@ func yaml_parser_parse_node(parser *yaml_parser_t, event *yaml_event_t, block, i } // Parse the productions: -// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END // -// ******************** *********** * ********* +// block_sequence ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END +// ******************** *********** * ********* func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -755,9 +742,9 @@ func yaml_parser_parse_block_sequence_entry(parser *yaml_parser_t, event *yaml_e } // Parse the productions: -// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ // -// *********** * +// indentless_sequence ::= (BLOCK-ENTRY block_node?)+ +// *********** * func yaml_parser_parse_indentless_sequence_entry(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -821,15 +808,15 @@ func yaml_parser_split_stem_comment(parser *yaml_parser_t, stem_len int) { } // Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START // -// ******************* -// ((KEY block_node_or_indentless_sequence?)? -// *** * -// (VALUE block_node_or_indentless_sequence?)?)* +// block_mapping ::= BLOCK-MAPPING_START +// ******************* +// ((KEY block_node_or_indentless_sequence?)? +// *** * +// (VALUE block_node_or_indentless_sequence?)?)* // -// BLOCK-END -// ********* +// BLOCK-END +// ********* func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -896,13 +883,14 @@ func yaml_parser_parse_block_mapping_key(parser *yaml_parser_t, event *yaml_even } // Parse the productions: -// block_mapping ::= BLOCK-MAPPING_START // -// ((KEY block_node_or_indentless_sequence?)? +// block_mapping ::= BLOCK-MAPPING_START +// +// ((KEY block_node_or_indentless_sequence?)? // -// (VALUE block_node_or_indentless_sequence?)?)* -// ***** * -// BLOCK-END +// (VALUE block_node_or_indentless_sequence?)?)* +// ***** * +// BLOCK-END func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -929,19 +917,17 @@ func yaml_parser_parse_block_mapping_value(parser *yaml_parser_t, event *yaml_ev } // Parse the productions: -// flow_sequence ::= FLOW-SEQUENCE-START -// -// ******************* -// (flow_sequence_entry FLOW-ENTRY)* -// * ********** -// flow_sequence_entry? -// * -// FLOW-SEQUENCE-END -// ***************** // -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// -// * +// flow_sequence ::= FLOW-SEQUENCE-START +// ******************* +// (flow_sequence_entry FLOW-ENTRY)* +// * ********** +// flow_sequence_entry? +// * +// FLOW-SEQUENCE-END +// ***************** +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -1005,9 +991,9 @@ func yaml_parser_parse_flow_sequence_entry(parser *yaml_parser_t, event *yaml_ev } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// *** * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// *** * func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1026,9 +1012,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_key(parser *yaml_parser_t, ev } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// ***** * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// ***** * func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1050,9 +1036,9 @@ func yaml_parser_parse_flow_sequence_entry_mapping_value(parser *yaml_parser_t, } // Parse the productions: -// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? // -// * +// flow_sequence_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, event *yaml_event_t) bool { token := peek_token(parser) if token == nil { @@ -1068,18 +1054,17 @@ func yaml_parser_parse_flow_sequence_entry_mapping_end(parser *yaml_parser_t, ev } // Parse the productions: -// flow_mapping ::= FLOW-MAPPING-START -// -// ****************** -// (flow_mapping_entry FLOW-ENTRY)* -// * ********** -// flow_mapping_entry? -// ****************** -// FLOW-MAPPING-END -// **************** // -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// - *** * +// flow_mapping ::= FLOW-MAPPING-START +// ****************** +// (flow_mapping_entry FLOW-ENTRY)* +// * ********** +// flow_mapping_entry? +// ****************** +// FLOW-MAPPING-END +// **************** +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * *** * func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event_t, first bool) bool { if first { token := peek_token(parser) @@ -1144,8 +1129,9 @@ func yaml_parser_parse_flow_mapping_key(parser *yaml_parser_t, event *yaml_event } // Parse the productions: -// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? -// - ***** * +// +// flow_mapping_entry ::= flow_node | KEY flow_node? (VALUE flow_node?)? +// * ***** * func yaml_parser_parse_flow_mapping_value(parser *yaml_parser_t, event *yaml_event_t, empty bool) bool { token := peek_token(parser) if token == nil { diff --git a/vendor/go.yaml.in/yaml/v3/yamlh.go b/vendor/go.yaml.in/yaml/v3/yamlh.go index f59aa40f..07c44236 100644 --- a/vendor/go.yaml.in/yaml/v3/yamlh.go +++ b/vendor/go.yaml.in/yaml/v3/yamlh.go @@ -433,21 +433,19 @@ type yaml_document_t struct { // The prototype of a read handler. // -// The read handler is called when the parser needs to read more bytes from the -// source. The handler should write not more than size bytes to the buffer. -// The number of written bytes should be set to the size_read variable. +// The read handler is called when the parser needs to read more bytes from the +// source. The handler should write not more than size bytes to the buffer. +// The number of written bytes should be set to the size_read variable. // -// [in,out] data A pointer to an application data specified by +// [in,out] data A pointer to an application data specified by +// yaml_parser_set_input(). +// [out] buffer The buffer to write the data from the source. +// [in] size The size of the buffer. +// [out] size_read The actual number of bytes read from the source. // -// yaml_parser_set_input(). -// -// [out] buffer The buffer to write the data from the source. -// [in] size The size of the buffer. -// [out] size_read The actual number of bytes read from the source. -// -// On success, the handler should return 1. If the handler failed, -// the returned value should be 0. On EOF, the handler should set the -// size_read to 0 and return 1. +// On success, the handler should return 1. If the handler failed, +// the returned value should be 0. On EOF, the handler should set the +// size_read to 0 and return 1. type yaml_read_handler_t func(parser *yaml_parser_t, buffer []byte) (n int, err error) // This structure holds information about a potential simple key. @@ -655,19 +653,17 @@ type yaml_comment_t struct { // The prototype of a write handler. // -// The write handler is called when the emitter needs to flush the accumulated -// characters to the output. The handler should write @a size bytes of the -// @a buffer to the output. -// -// @param[in,out] data A pointer to an application data specified by -// -// yaml_emitter_set_output(). +// The write handler is called when the emitter needs to flush the accumulated +// characters to the output. The handler should write @a size bytes of the +// @a buffer to the output. // -// @param[in] buffer The buffer with bytes to be written. -// @param[in] size The size of the buffer. +// @param[in,out] data A pointer to an application data specified by +// yaml_emitter_set_output(). +// @param[in] buffer The buffer with bytes to be written. +// @param[in] size The size of the buffer. // -// @returns On success, the handler should return @c 1. If the handler failed, -// the returned value should be @c 0. +// @returns On success, the handler should return @c 1. If the handler failed, +// the returned value should be @c 0. type yaml_write_handler_t func(emitter *yaml_emitter_t, buffer []byte) error type yaml_emitter_state_t int diff --git a/vendor/modules.txt b/vendor/modules.txt index fb0287f0..204b5948 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -614,9 +614,6 @@ github.com/mitchellh/go-homedir # github.com/mitchellh/mapstructure v1.5.0 ## explicit; go 1.14 github.com/mitchellh/mapstructure -# github.com/moby/sys/capability v0.4.0 -## explicit; go 1.21 -github.com/moby/sys/capability # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent @@ -703,11 +700,6 @@ github.com/onsi/gomega/types # github.com/opencontainers/runtime-spec v1.3.0 ## explicit github.com/opencontainers/runtime-spec/specs-go -# github.com/opencontainers/runtime-tools v0.9.1-0.20251114084447-edf4cb3d2116 -## explicit; go 1.21 -github.com/opencontainers/runtime-tools/generate -github.com/opencontainers/runtime-tools/generate/seccomp -github.com/opencontainers/runtime-tools/validate/capabilities # github.com/pelletier/go-toml v1.9.5 ## explicit; go 1.12 github.com/pelletier/go-toml @@ -721,9 +713,6 @@ github.com/pelletier/go-toml/v2/unstable # github.com/pkg/errors v0.9.1 ## explicit github.com/pkg/errors -# github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 -## explicit -github.com/pmezard/go-difflib/difflib # github.com/polyfloyd/go-errorlint v1.7.1 ## explicit; go 1.22.0 github.com/polyfloyd/go-errorlint/errorlint @@ -868,13 +857,15 @@ github.com/ssgreg/nlreturn/v2/pkg/nlreturn # github.com/stbenjam/no-sprintf-host-port v0.2.0 ## explicit; go 1.18 github.com/stbenjam/no-sprintf-host-port/pkg/analyzer -# github.com/stretchr/objx v0.5.2 +# github.com/stretchr/objx v0.5.3 ## explicit; go 1.20 github.com/stretchr/objx -# github.com/stretchr/testify v1.11.1 +# github.com/stretchr/testify v1.12.1 ## explicit; go 1.17 github.com/stretchr/testify/assert github.com/stretchr/testify/assert/yaml +github.com/stretchr/testify/internal/difflib +github.com/stretchr/testify/internal/spew github.com/stretchr/testify/mock # github.com/subosito/gotenv v1.4.1 ## explicit; go 1.18 @@ -965,7 +956,7 @@ go.uber.org/zap/internal/bufferpool go.uber.org/zap/internal/color go.uber.org/zap/internal/exit go.uber.org/zap/zapcore -# go.yaml.in/yaml/v3 v3.0.4 +# go.yaml.in/yaml/v3 v3.0.5 ## explicit; go 1.16 go.yaml.in/yaml/v3 # golang.org/x/exp/typeparams v0.0.0-20250210185358-939b2ce775ac @@ -1737,12 +1728,13 @@ sigs.k8s.io/structured-merge-diff/v4/value ## explicit; go 1.12 sigs.k8s.io/yaml sigs.k8s.io/yaml/goyaml.v2 -# tags.cncf.io/container-device-interface v1.1.0 -## explicit; go 1.21 +# tags.cncf.io/container-device-interface v1.1.1 +## explicit; go 1.23 +tags.cncf.io/container-device-interface/internal/ociedit tags.cncf.io/container-device-interface/internal/validation tags.cncf.io/container-device-interface/internal/validation/k8s tags.cncf.io/container-device-interface/pkg/cdi tags.cncf.io/container-device-interface/pkg/parser -# tags.cncf.io/container-device-interface/specs-go v1.1.0 +# tags.cncf.io/container-device-interface/specs-go v1.1.1 ## explicit; go 1.19 tags.cncf.io/container-device-interface/specs-go diff --git a/vendor/tags.cncf.io/container-device-interface/internal/ociedit/spec_editor.go b/vendor/tags.cncf.io/container-device-interface/internal/ociedit/spec_editor.go new file mode 100644 index 00000000..28e97e5b --- /dev/null +++ b/vendor/tags.cncf.io/container-device-interface/internal/ociedit/spec_editor.go @@ -0,0 +1,247 @@ +/* + Copyright 2026 The CDI Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package ociedit + +import ( + "errors" + "slices" + "strings" + + oci "github.com/opencontainers/runtime-spec/specs-go" +) + +// SpecEditor is the internal boundary between CDI edits and OCI spec mutation. +// It deliberately models only the operations CDI needs, so a future external +// generator can be wired in without leaking that dependency elsewhere. +type SpecEditor interface { + AddMultipleProcessEnv([]string) + RemoveDevice(string) + AddDevice(oci.LinuxDevice) + AddLinuxResourcesDevice(bool, string, *int64, *int64, string) + SetLinuxNetDevice(string, *oci.LinuxNetDevice) + RemoveMount(string) + AddMount(oci.Mount) + Mounts() []oci.Mount + SetMounts([]oci.Mount) + AddPreStartHook(oci.Hook) + AddPostStartHook(oci.Hook) + AddPostStopHook(oci.Hook) + AddCreateRuntimeHook(oci.Hook) + AddCreateContainerHook(oci.Hook) + AddStartContainerHook(oci.Hook) + SetLinuxIntelRdt(*oci.LinuxIntelRdt) + AddProcessAdditionalGID(uint32) + ClearLinuxDevices() +} + +// NewSpecEditor returns CDI's native OCI spec editor. +func NewSpecEditor(spec *oci.Spec) (SpecEditor, error) { + if spec == nil { + return nil, errors.New("can't edit nil OCI Spec") + } + + envCache := map[string]int{} + if spec.Process != nil { + envCache = createEnvCacheMap(spec.Process.Env) + } + return &nativeSpecEditor{ + spec: spec, + envMap: envCache, + }, nil +} + +type nativeSpecEditor struct { + spec *oci.Spec + envMap map[string]int +} + +func createEnvCacheMap(env []string) map[string]int { + envMap := make(map[string]int, len(env)) + for i, val := range env { + val, _, _ = strings.Cut(val, "=") + envMap[val] = i + } + return envMap +} + +func (e *nativeSpecEditor) initProcess() { + if e.spec.Process == nil { + e.spec.Process = &oci.Process{} + } +} + +func (e *nativeSpecEditor) initHooks() { + if e.spec.Hooks == nil { + e.spec.Hooks = &oci.Hooks{} + } +} + +func (e *nativeSpecEditor) initLinux() { + if e.spec.Linux == nil { + e.spec.Linux = &oci.Linux{} + } +} + +func (e *nativeSpecEditor) initLinuxResources() { + e.initLinux() + if e.spec.Linux.Resources == nil { + e.spec.Linux.Resources = &oci.LinuxResources{} + } +} + +func (e *nativeSpecEditor) initLinuxNetDevices() { + e.initLinux() + if e.spec.Linux.NetDevices == nil { + e.spec.Linux.NetDevices = map[string]oci.LinuxNetDevice{} + } +} + +func (e *nativeSpecEditor) AddMultipleProcessEnv(envs []string) { + e.initProcess() + + for _, val := range envs { + key, _, _ := strings.Cut(val, "=") + e.addEnv(val, key) + } +} + +func (e *nativeSpecEditor) addEnv(env, key string) { + if idx, ok := e.envMap[key]; ok { + e.spec.Process.Env[idx] = env + return + } + + e.spec.Process.Env = append(e.spec.Process.Env, env) + e.envMap[key] = len(e.spec.Process.Env) - 1 +} + +func (e *nativeSpecEditor) RemoveDevice(path string) { + if e.spec == nil || e.spec.Linux == nil || e.spec.Linux.Devices == nil { + return + } + + for i, device := range e.spec.Linux.Devices { + if device.Path == path { + e.spec.Linux.Devices = append(e.spec.Linux.Devices[:i], e.spec.Linux.Devices[i+1:]...) + return + } + } +} + +func (e *nativeSpecEditor) AddDevice(device oci.LinuxDevice) { + e.initLinux() + + for i, dev := range e.spec.Linux.Devices { + if dev.Path == device.Path { + e.spec.Linux.Devices[i] = device + return + } + } + + e.spec.Linux.Devices = append(e.spec.Linux.Devices, device) +} + +func (e *nativeSpecEditor) AddLinuxResourcesDevice(allow bool, devType string, major, minor *int64, access string) { + e.initLinuxResources() + e.spec.Linux.Resources.Devices = append(e.spec.Linux.Resources.Devices, oci.LinuxDeviceCgroup{ + Allow: allow, + Type: devType, + Major: major, + Minor: minor, + Access: access, + }) +} + +func (e *nativeSpecEditor) SetLinuxNetDevice(hostIf string, netDev *oci.LinuxNetDevice) { + if netDev == nil { + return + } + + e.initLinuxNetDevices() + e.spec.Linux.NetDevices[hostIf] = *netDev +} + +func (e *nativeSpecEditor) RemoveMount(dest string) { + for i, mount := range e.spec.Mounts { + if mount.Destination == dest { + e.spec.Mounts = append(e.spec.Mounts[:i], e.spec.Mounts[i+1:]...) + return + } + } +} + +func (e *nativeSpecEditor) AddMount(mnt oci.Mount) { + e.spec.Mounts = append(e.spec.Mounts, mnt) +} + +func (e *nativeSpecEditor) Mounts() []oci.Mount { + return e.spec.Mounts +} + +func (e *nativeSpecEditor) SetMounts(mounts []oci.Mount) { + e.spec.Mounts = mounts +} + +func (e *nativeSpecEditor) AddPreStartHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.Prestart = append(e.spec.Hooks.Prestart, hook) //nolint:staticcheck // CDI still supports OCI prestart hooks. +} + +func (e *nativeSpecEditor) AddPostStartHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.Poststart = append(e.spec.Hooks.Poststart, hook) +} + +func (e *nativeSpecEditor) AddPostStopHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.Poststop = append(e.spec.Hooks.Poststop, hook) +} + +func (e *nativeSpecEditor) AddCreateRuntimeHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.CreateRuntime = append(e.spec.Hooks.CreateRuntime, hook) +} + +func (e *nativeSpecEditor) AddCreateContainerHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.CreateContainer = append(e.spec.Hooks.CreateContainer, hook) +} + +func (e *nativeSpecEditor) AddStartContainerHook(hook oci.Hook) { + e.initHooks() + e.spec.Hooks.StartContainer = append(e.spec.Hooks.StartContainer, hook) +} + +func (e *nativeSpecEditor) SetLinuxIntelRdt(rdt *oci.LinuxIntelRdt) { + e.initLinux() + e.spec.Linux.IntelRdt = rdt +} + +func (e *nativeSpecEditor) AddProcessAdditionalGID(gid uint32) { + e.initProcess() + if slices.Contains(e.spec.Process.User.AdditionalGids, gid) { + return + } + e.spec.Process.User.AdditionalGids = append(e.spec.Process.User.AdditionalGids, gid) +} + +func (e *nativeSpecEditor) ClearLinuxDevices() { + if e.spec == nil || e.spec.Linux == nil || e.spec.Linux.Devices == nil { + return + } + e.spec.Linux.Devices = []oci.LinuxDevice{} +} diff --git a/vendor/tags.cncf.io/container-device-interface/internal/validation/k8s/validation.go b/vendor/tags.cncf.io/container-device-interface/internal/validation/k8s/validation.go index 5ad6ce27..5ecbbe38 100644 --- a/vendor/tags.cncf.io/container-device-interface/internal/validation/k8s/validation.go +++ b/vendor/tags.cncf.io/container-device-interface/internal/validation/k8s/validation.go @@ -68,48 +68,7 @@ func IsQualifiedName(value string) []string { return errs } -const labelValueFmt string = "(" + qualifiedNameFmt + ")?" -const labelValueErrMsg string = "a valid label must be an empty string or consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character" - -// LabelValueMaxLength is a label's max length -const LabelValueMaxLength int = 63 - -var labelValueRegexp = regexp.MustCompile("^" + labelValueFmt + "$") - -// IsValidLabelValue tests whether the value passed is a valid label value. If -// the value is not valid, a list of error strings is returned. Otherwise an -// empty list (or nil) is returned. -func IsValidLabelValue(value string) []string { - var errs []string - if len(value) > LabelValueMaxLength { - errs = append(errs, MaxLenError(LabelValueMaxLength)) - } - if !labelValueRegexp.MatchString(value) { - errs = append(errs, RegexError(labelValueErrMsg, labelValueFmt, "MyValue", "my_value", "12345")) - } - return errs -} - const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?" -const dns1123LabelErrMsg string = "a lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character" - -// DNS1123LabelMaxLength is a label's max length in DNS (RFC 1123) -const DNS1123LabelMaxLength int = 63 - -var dns1123LabelRegexp = regexp.MustCompile("^" + dns1123LabelFmt + "$") - -// IsDNS1123Label tests for a string that conforms to the definition of a label in -// DNS (RFC 1123). -func IsDNS1123Label(value string) []string { - var errs []string - if len(value) > DNS1123LabelMaxLength { - errs = append(errs, MaxLenError(DNS1123LabelMaxLength)) - } - if !dns1123LabelRegexp.MatchString(value) { - errs = append(errs, RegexError(dns1123LabelErrMsg, dns1123LabelFmt, "my-name", "123-abc")) - } - return errs -} const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*" const dns1123SubdomainErrorMsg string = "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character" @@ -132,49 +91,6 @@ func IsDNS1123Subdomain(value string) []string { return errs } -const dns1035LabelFmt string = "[a-z]([-a-z0-9]*[a-z0-9])?" -const dns1035LabelErrMsg string = "a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character" - -// DNS1035LabelMaxLength is a label's max length in DNS (RFC 1035) -const DNS1035LabelMaxLength int = 63 - -var dns1035LabelRegexp = regexp.MustCompile("^" + dns1035LabelFmt + "$") - -// IsDNS1035Label tests for a string that conforms to the definition of a label in -// DNS (RFC 1035). -func IsDNS1035Label(value string) []string { - var errs []string - if len(value) > DNS1035LabelMaxLength { - errs = append(errs, MaxLenError(DNS1035LabelMaxLength)) - } - if !dns1035LabelRegexp.MatchString(value) { - errs = append(errs, RegexError(dns1035LabelErrMsg, dns1035LabelFmt, "my-name", "abc-123")) - } - return errs -} - -// wildcard definition - RFC 1034 section 4.3.3. -// examples: -// - valid: *.bar.com, *.foo.bar.com -// - invalid: *.*.bar.com, *.foo.*.com, *bar.com, f*.bar.com, * -const wildcardDNS1123SubdomainFmt = "\\*\\." + dns1123SubdomainFmt -const wildcardDNS1123SubdomainErrMsg = "a wildcard DNS-1123 subdomain must start with '*.', followed by a valid DNS subdomain, which must consist of lower case alphanumeric characters, '-' or '.' and end with an alphanumeric character" - -// IsWildcardDNS1123Subdomain tests for a string that conforms to the definition of a -// wildcard subdomain in DNS (RFC 1034 section 4.3.3). -func IsWildcardDNS1123Subdomain(value string) []string { - wildcardDNS1123SubdomainRegexp := regexp.MustCompile("^" + wildcardDNS1123SubdomainFmt + "$") - - var errs []string - if len(value) > DNS1123SubdomainMaxLength { - errs = append(errs, MaxLenError(DNS1123SubdomainMaxLength)) - } - if !wildcardDNS1123SubdomainRegexp.MatchString(value) { - errs = append(errs, RegexError(wildcardDNS1123SubdomainErrMsg, wildcardDNS1123SubdomainFmt, "*.example.com")) - } - return errs -} - // MaxLenError returns a string explanation of a "string too long" validation // failure. func MaxLenError(length int) string { @@ -209,9 +125,3 @@ func prefixEach(msgs []string, prefix string) []string { } return msgs } - -// InclusiveRangeError returns a string explanation of a numeric "must be -// between" validation failure. -func InclusiveRangeError(lo, hi int) string { - return fmt.Sprintf(`must be between %d and %d, inclusive`, lo, hi) -} diff --git a/vendor/tags.cncf.io/container-device-interface/internal/validation/validate.go b/vendor/tags.cncf.io/container-device-interface/internal/validation/validate.go index 5d9b55ff..fe7b62f8 100644 --- a/vendor/tags.cncf.io/container-device-interface/internal/validation/validate.go +++ b/vendor/tags.cncf.io/container-device-interface/internal/validation/validate.go @@ -18,39 +18,29 @@ package validation import ( "fmt" - "strings" "tags.cncf.io/container-device-interface/internal/validation/k8s" ) // ValidateSpecAnnotations checks whether spec annotations are valid. -func ValidateSpecAnnotations(name string, any interface{}) error { - if any == nil { +func ValidateSpecAnnotations(name string, specAnnotations any) error { + values, ok := specAnnotations.(map[string]any) + if !ok { return nil } - switch v := any.(type) { - case map[string]interface{}: - annotations := make(map[string]string) - for k, v := range v { - if s, ok := v.(string); ok { - annotations[k] = s - } else { - return fmt.Errorf("invalid annotation %v.%v; %v is not a string", name, k, any) - } + annotations := make(map[string]string, len(values)) + for k, v := range values { + s, ok := v.(string) + if !ok { + return fmt.Errorf("invalid annotation %v.%v; %v is not a string", name, k, v) } - return validateSpecAnnotations(name, annotations) + annotations[k] = s } - return nil -} - -// validateSpecAnnotations checks whether spec annotations are valid. -func validateSpecAnnotations(name string, annotations map[string]string) error { path := "annotations" if name != "" { - path = strings.Join([]string{name, path}, ".") + path = name + "." + path } - return k8s.ValidateAnnotations(annotations, path) } diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go index ba817a55..d944eaf3 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/cache.go @@ -20,10 +20,10 @@ import ( "errors" "fmt" "io/fs" + "maps" "os" "path/filepath" - "runtime" - "sort" + "slices" "strings" "sync" @@ -37,7 +37,7 @@ type Option func(*Cache) // Cache stores CDI Specs loaded from Spec directories. type Cache struct { - sync.Mutex + mu sync.RWMutex specDirs []string specs map[string][]*Spec devices map[string]*Device @@ -48,6 +48,20 @@ type Cache struct { watch *watch } +// Lock locks the cache. +// +// Deprecated: Cache locking is an implementation detail and should not be managed by callers. +func (c *Cache) Lock() { + c.mu.Lock() +} + +// Unlock unlocks the cache. +// +// Deprecated: Cache locking is an implementation detail and should not be managed by callers. +func (c *Cache) Unlock() { + c.mu.Unlock() +} + // WithAutoRefresh returns an option to control automatic Cache refresh. // By default, auto-refresh is enabled, the list of Spec directories are // monitored and the Cache is automatically refreshed whenever a change @@ -75,15 +89,15 @@ func NewCache(options ...Option) (*Cache, error) { // This function allows testing without handling the nil error returned by the // NewCache function. func newCache(options ...Option) *Cache { + specDirs := slices.Clone(DefaultSpecDirs) + for i := range specDirs { + specDirs[i] = filepath.Clean(specDirs[i]) + } c := &Cache{ + specDirs: specDirs, autoRefresh: true, watch: &watch{}, } - - WithSpecDirs(DefaultSpecDirs...)(c) - c.Lock() - defer c.Unlock() - c.configure(options...) return c } @@ -95,8 +109,8 @@ func (c *Cache) Configure(options ...Option) error { return nil } - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() c.configure(options...) @@ -106,34 +120,35 @@ func (c *Cache) Configure(options ...Option) error { // Configure the Cache. Start/stop CDI Spec directory watch, refresh // the Cache if necessary. func (c *Cache) configure(options ...Option) { + c.watch.stop() + c.dirErrors = nil + for _, o := range options { o(c) } - c.dirErrors = make(map[string]error) - - c.watch.stop() if c.autoRefresh { - c.watch.setup(c.specDirs, c.dirErrors) - c.watch.start(&c.Mutex, c.refresh, c.dirErrors) + c.watch.start(c) } - _ = c.refresh() // we record but ignore errors + c.refresh() } // Refresh rescans the CDI Spec directories and refreshes the Cache. // In manual refresh mode the cache is always refreshed. In auto- // refresh mode the cache is only refreshed if it is out of date. func (c *Cache) Refresh() error { - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() // force a refresh in manual mode - if refreshed, err := c.refreshIfRequired(!c.autoRefresh); refreshed { - return err + if !c.autoRefresh { + c.refresh() + } else { + c.refreshIfRequired() } - // collect and return cached errors, much like refresh() does it - errs := []error{} + // collect and return cached errors. + var errs []error for _, specErrs := range c.errors { errs = append(errs, errors.Join(specErrs...)) } @@ -141,7 +156,7 @@ func (c *Cache) Refresh() error { } // Refresh the Cache by rescanning CDI Spec directories and files. -func (c *Cache) refresh() error { +func (c *Cache) refresh() { var ( specs = map[string][]*Spec{} devices = map[string]*Device{} @@ -172,7 +187,6 @@ func (c *Cache) refresh() error { } _ = scanSpecDirs(c.specDirs, func(path string, priority int, spec *Spec, err error) error { - path = filepath.Clean(path) if err != nil { collectError(fmt.Errorf("failed to load CDI Spec %w", err), path) return nil @@ -202,23 +216,14 @@ func (c *Cache) refresh() error { c.specs = specs c.devices = devices c.errors = specErrors - - errs := []error{} - for _, specErrs := range specErrors { - errs = append(errs, errors.Join(specErrs...)) - } - return errors.Join(errs...) } -// RefreshIfRequired triggers a refresh if necessary. -func (c *Cache) refreshIfRequired(force bool) (bool, error) { - // We need to refresh if - // - it's forced by an explicit call to Refresh() in manual mode - // - a missing Spec dir appears (added to watch) in auto-refresh mode - if force || (c.autoRefresh && c.watch.update(c.dirErrors)) { - return true, c.refresh() +// refreshIfRequired triggers a refresh if necessary. +func (c *Cache) refreshIfRequired() { + // We need to refresh if a missing Spec dir appears (added to watch) in auto-refresh mode. + if c.autoRefresh && c.watch.update(c.dirErrors) { + c.refresh() } - return false, nil } // InjectDevices injects the given qualified devices to an OCI Spec. It @@ -226,22 +231,21 @@ func (c *Cache) refreshIfRequired(force bool) (bool, error) { // any of the devices. Might trigger a cache refresh, in which case any // errors encountered can be obtained using GetErrors(). func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, error) { - var unresolved []string - if ociSpec == nil { return devices, fmt.Errorf("can't inject devices, nil OCI Spec") } - c.Lock() - defer c.Unlock() - - _, _ = c.refreshIfRequired(false) // we record but ignore errors + c.mu.Lock() + c.refreshIfRequired() + cachedDevices := c.devices + c.mu.Unlock() edits := &ContainerEdits{} specs := map[*Spec]struct{}{} + var unresolved []string for _, device := range devices { - d := c.devices[device] + d := cachedDevices[device] if d == nil { unresolved = append(unresolved, device) continue @@ -253,7 +257,7 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e edits.Append(d.edits()) } - if unresolved != nil { + if len(unresolved) > 0 { return unresolved, fmt.Errorf("unresolvable CDI devices %s", strings.Join(unresolved, ", ")) } @@ -268,6 +272,8 @@ func (c *Cache) InjectDevices(ociSpec *oci.Spec, devices ...string) ([]string, e // highestPrioritySpecDir returns the Spec directory with highest priority // and its priority. func (c *Cache) highestPrioritySpecDir() (string, int) { + c.mu.RLock() + defer c.mu.RUnlock() if len(c.specDirs) == 0 { return "", -1 } @@ -282,25 +288,17 @@ func (c *Cache) highestPrioritySpecDir() (string, int) { // priority Spec directory. If name has a "json" or "yaml" extension it // choses the encoding. Otherwise the default YAML encoding is used. func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error { - var ( - specDir string - path string - prio int - spec *Spec - err error - ) - - specDir, prio = c.highestPrioritySpecDir() + specDir, prio := c.highestPrioritySpecDir() if specDir == "" { return errors.New("no Spec directories to write to") } - path = filepath.Join(specDir, name) + path := filepath.Join(specDir, name) if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" { path += defaultSpecExt } - spec, err = newSpec(raw, path, prio) + spec, err := newSpec(raw, path, prio) if err != nil { return err } @@ -313,25 +311,19 @@ func (c *Cache) WriteSpec(raw *cdi.Spec, name string) error { // Spec previously written by WriteSpec(). If the file exists and // its removal fails RemoveSpec returns an error. func (c *Cache) RemoveSpec(name string) error { - var ( - specDir string - path string - err error - ) - - specDir, _ = c.highestPrioritySpecDir() + specDir, _ := c.highestPrioritySpecDir() if specDir == "" { return errors.New("no Spec directories to remove from") } - path = filepath.Join(specDir, name) + path := filepath.Join(specDir, name) if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" { path += defaultSpecExt } - err = os.Remove(path) - if err != nil && errors.Is(err, fs.ErrNotExist) { - err = nil + err := os.Remove(path) + if errors.Is(err, fs.ErrNotExist) { + return nil } return err @@ -341,10 +333,10 @@ func (c *Cache) RemoveSpec(name string) error { // a cache refresh, in which case any errors encountered can be obtained using // GetErrors(). func (c *Cache) GetDevice(device string) *Device { - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() - _, _ = c.refreshIfRequired(false) // we record but ignore errors + c.refreshIfRequired() return c.devices[device] } @@ -352,61 +344,46 @@ func (c *Cache) GetDevice(device string) *Device { // ListDevices lists all cached devices by qualified name. Might trigger a cache // refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListDevices() []string { - var devices []string + c.mu.Lock() + defer c.mu.Unlock() - c.Lock() - defer c.Unlock() + c.refreshIfRequired() - _, _ = c.refreshIfRequired(false) // we record but ignore errors - - for name := range c.devices { - devices = append(devices, name) - } - sort.Strings(devices) - - return devices + return slices.Sorted(maps.Keys(c.devices)) } // ListVendors lists all vendors known to the cache. Might trigger a cache refresh, // in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListVendors() []string { - var vendors []string + c.mu.Lock() + defer c.mu.Unlock() - c.Lock() - defer c.Unlock() + c.refreshIfRequired() - _, _ = c.refreshIfRequired(false) // we record but ignore errors - - for vendor := range c.specs { - vendors = append(vendors, vendor) - } - sort.Strings(vendors) - - return vendors + return slices.Sorted(maps.Keys(c.specs)) } // ListClasses lists all device classes known to the cache. Might trigger a cache // refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) ListClasses() []string { - var ( - cmap = map[string]struct{}{} - classes []string - ) - - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() - _, _ = c.refreshIfRequired(false) // we record but ignore errors + c.refreshIfRequired() + var classes []string + seen := map[string]struct{}{} for _, specs := range c.specs { for _, spec := range specs { - cmap[spec.GetClass()] = struct{}{} + class := spec.GetClass() + if _, ok := seen[class]; ok { + continue + } + seen[class] = struct{}{} + classes = append(classes, class) } } - for class := range cmap { - classes = append(classes, class) - } - sort.Strings(classes) + slices.Sort(classes) return classes } @@ -414,10 +391,10 @@ func (c *Cache) ListClasses() []string { // GetVendorSpecs returns all specs for the given vendor. Might trigger a cache // refresh, in which case any errors encountered can be obtained using GetErrors(). func (c *Cache) GetVendorSpecs(vendor string) []*Spec { - c.Lock() - defer c.Unlock() + c.mu.Lock() + defer c.mu.Unlock() - _, _ = c.refreshIfRequired(false) // we record but ignore errors + c.refreshIfRequired() return c.specs[vendor] } @@ -425,60 +402,40 @@ func (c *Cache) GetVendorSpecs(vendor string) []*Spec { // GetSpecErrors returns all errors encountered for the spec during the // last cache refresh. func (c *Cache) GetSpecErrors(spec *Spec) []error { - var errors []error - - c.Lock() - defer c.Unlock() - - if errs, ok := c.errors[spec.GetPath()]; ok { - errors = make([]error, len(errs)) - copy(errors, errs) - } - - return errors + c.mu.RLock() + defer c.mu.RUnlock() + return slices.Clone(c.errors[spec.GetPath()]) } // GetErrors returns all errors encountered during the last // cache refresh. func (c *Cache) GetErrors() map[string][]error { - c.Lock() - defer c.Unlock() + c.mu.RLock() + defer c.mu.RUnlock() - errors := map[string][]error{} + errsByPath := make(map[string][]error, len(c.errors)+len(c.dirErrors)) for path, errs := range c.errors { - errors[path] = errs + errsByPath[path] = slices.Clone(errs) } for path, err := range c.dirErrors { - errors[path] = []error{err} + errsByPath[path] = append(errsByPath[path], err) } - return errors + return errsByPath } // GetSpecDirectories returns the CDI Spec directories currently in use. func (c *Cache) GetSpecDirectories() []string { - c.Lock() - defer c.Unlock() - - dirs := make([]string, len(c.specDirs)) - copy(dirs, c.specDirs) - return dirs + c.mu.RLock() + defer c.mu.RUnlock() + return slices.Clone(c.specDirs) } // GetSpecDirErrors returns any errors related to configured Spec directories. func (c *Cache) GetSpecDirErrors() map[string]error { - if c.dirErrors == nil { - return nil - } - - c.Lock() - defer c.Unlock() - - errors := make(map[string]error) - for dir, err := range c.dirErrors { - errors[dir] = err - } - return errors + c.mu.RLock() + defer c.mu.RUnlock() + return maps.Clone(c.dirErrors) } // Our fsnotify helper wrapper. @@ -487,31 +444,30 @@ type watch struct { tracked map[string]bool } -// Setup monitoring for the given Spec directories. -func (w *watch) setup(dirs []string, dirErrors map[string]error) { - var ( - dir string - err error - ) - w.tracked = make(map[string]bool) - for _, dir = range dirs { - w.tracked[dir] = false - } - - w.watcher, err = fsnotify.NewWatcher() +// Start watching the Spec directories configured in the cache, recording +// watch errors and triggering cache refreshes as directories change. +func (w *watch) start(c *Cache) { + c.dirErrors = make(map[string]error) + watcher, err := fsnotify.NewWatcher() if err != nil { - for _, dir := range dirs { - dirErrors[dir] = fmt.Errorf("failed to create watcher: %w", err) + for _, dir := range c.specDirs { + c.dirErrors[dir] = fmt.Errorf("failed to create watcher: %w", err) } return } - w.update(dirErrors) -} + w.watcher = watcher + w.tracked = make(map[string]bool, len(c.specDirs)) + for _, dir := range c.specDirs { + if err := watcher.Add(dir); err != nil { + c.dirErrors[dir] = fmt.Errorf("failed to monitor for changes: %w", err) + w.tracked[dir] = false + continue + } + w.tracked[dir] = true + } -// Start watching Spec directories for relevant changes. -func (w *watch) start(m *sync.Mutex, refresh func() error, dirErrors map[string]error) { - go w.watch(w.watcher, m, refresh, dirErrors) + go w.watch(watcher, c) } // Stop watching directories. @@ -521,48 +477,45 @@ func (w *watch) stop() { } _ = w.watcher.Close() + w.watcher = nil w.tracked = nil } // Watch Spec directory changes, triggering a refresh if necessary. -func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error, dirErrors map[string]error) { - watch := fsw - if watch == nil { - return - } - - eventMask := fsnotify.Rename | fsnotify.Remove | fsnotify.Write - // On macOS, we also need to watch for Create events. - if runtime.GOOS == "darwin" { - eventMask |= fsnotify.Create - } +func (w *watch) watch(fsw *fsnotify.Watcher, c *Cache) { + // Watch for Spec file changes. Atomic writes may create a temporary file and + // rename it into place. On Linux, fsnotify reports the destination of such a + // rename as a Create event, so Create must be watched on all platforms. + eventMask := fsnotify.Create | fsnotify.Rename | fsnotify.Remove | fsnotify.Write for { select { - case event, ok := <-watch.Events: + case event, ok := <-fsw.Events: if !ok { return } - if (event.Op & eventMask) == 0 { + fsOp := event.Op & eventMask + if fsOp == 0 { continue } - if event.Op == fsnotify.Write || event.Op == fsnotify.Create { - if ext := filepath.Ext(event.Name); ext != ".json" && ext != ".yaml" { - continue - } - } - m.Lock() - if event.Op == fsnotify.Remove && w.tracked[event.Name] { - w.update(dirErrors, event.Name) - } else { - w.update(dirErrors) + c.mu.Lock() + _, isTracked := w.tracked[event.Name] + + // Ignore changes unrelated to Spec files or configured Spec directories. + if ext := filepath.Ext(event.Name); ext != ".json" && ext != ".yaml" && !isTracked { + c.mu.Unlock() + continue + } + if fsOp&fsnotify.Remove != 0 && isTracked { + w.markRemoved(c.dirErrors, event.Name) } - _ = refresh() - m.Unlock() + w.update(c.dirErrors) + c.refresh() + c.mu.Unlock() - case _, ok := <-watch.Errors: + case _, ok := <-fsw.Errors: if !ok { return } @@ -570,15 +523,16 @@ func (w *watch) watch(fsw *fsnotify.Watcher, m *sync.Mutex, refresh func() error } } -// Update watch with pending/missing or removed directories. -func (w *watch) update(dirErrors map[string]error, removed ...string) bool { - var ( - dir string - ok bool - err error - update bool - ) +// markRemoved marks a configured Spec directory as not currently watched so +// its watch can be restored if the directory is recreated. +func (w *watch) markRemoved(dirErrors map[string]error, dir string) { + w.tracked[dir] = false + dirErrors[dir] = errors.New("directory removed") +} +// update restores watches for configured directories that are not currently +// being watched. It reports whether any watches were restored. +func (w *watch) update(dirErrors map[string]error) bool { // If we failed to create an fsnotify.Watcher we have a nil watcher here // (but with autoRefresh left on). One known case when this can happen is // if we have too many open files. In that case we always return true and @@ -587,25 +541,19 @@ func (w *watch) update(dirErrors map[string]error, removed ...string) bool { return true } - for dir, ok = range w.tracked { - if ok { + var update bool + for dir, watched := range w.tracked { + if watched { continue } - err = w.watcher.Add(dir) - if err == nil { - w.tracked[dir] = true - delete(dirErrors, dir) - update = true - } else { - w.tracked[dir] = false + if err := w.watcher.Add(dir); err != nil { dirErrors[dir] = fmt.Errorf("failed to monitor for changes: %w", err) + continue } - } - for _, dir = range removed { - w.tracked[dir] = false - dirErrors[dir] = errors.New("directory removed") + w.tracked[dir] = true + delete(dirErrors, dir) update = true } diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go index f498049c..71b9ddc5 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/container-edits.go @@ -25,7 +25,7 @@ import ( "strings" oci "github.com/opencontainers/runtime-spec/specs-go" - ocigen "github.com/opencontainers/runtime-tools/generate" + "tags.cncf.io/container-device-interface/internal/ociedit" cdi "tags.cncf.io/container-device-interface/specs-go" ) @@ -42,6 +42,9 @@ const ( PoststartHook = "poststart" // PoststopHook is the name of the OCI "poststop" hook. PoststopHook = "poststop" + + // NoPermissions requests empty cgroup permissions for a device. + NoPermissions = "none" ) var ( @@ -77,9 +80,12 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error { return nil } - specgen := ocigen.NewFromSpec(spec) + editor, err := ociedit.NewSpecEditor(spec) + if err != nil { + return fmt.Errorf("error creating spec editor: %w", err) + } if len(e.Env) > 0 { - specgen.AddMultipleProcessEnv(e.Env) + editor.AddMultipleProcessEnv(e.Env) } for _, d := range e.DeviceNodes { @@ -101,93 +107,76 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error { } } - specgen.RemoveDevice(dev.Path) - specgen.AddDevice(dev) + editor.RemoveDevice(dev.Path) + editor.AddDevice(dev) if dev.Type == "b" || dev.Type == "c" { access := d.Permissions - if access == "" { + switch access { + case "": access = "rwm" + case NoPermissions: + access = "" } - specgen.AddLinuxResourcesDevice(true, dev.Type, &dev.Major, &dev.Minor, access) + editor.AddLinuxResourcesDevice(true, dev.Type, &dev.Major, &dev.Minor, access) } } if len(e.NetDevices) > 0 { - // specgen is currently missing functionality to set Linux NetDevices, - // so we use a locally rolled function for now. for _, dev := range e.NetDevices { - specgenAddLinuxNetDevice(&specgen, dev.HostInterfaceName, (&LinuxNetDevice{dev}).toOCI()) + editor.SetLinuxNetDevice(dev.HostInterfaceName, (&LinuxNetDevice{dev}).toOCI()) } } if len(e.Mounts) > 0 { for _, m := range e.Mounts { - specgen.RemoveMount(m.ContainerPath) - specgen.AddMount((&Mount{m}).toOCI()) + mnt := &Mount{m} + + editor.RemoveMount(m.ContainerPath) + + if !specHasUserNamespace(spec) { + editor.AddMount(mnt.toOCI()) + } else { + editor.AddMount(mnt.toOCI(withIDMapForBindMount())) + } } - sortMounts(&specgen) + sortMounts(editor) } for _, h := range e.Hooks { ociHook := (&Hook{h}).toOCI() switch h.HookName { case PrestartHook: - specgen.AddPreStartHook(ociHook) + editor.AddPreStartHook(ociHook) case PoststartHook: - specgen.AddPostStartHook(ociHook) + editor.AddPostStartHook(ociHook) case PoststopHook: - specgen.AddPostStopHook(ociHook) - // TODO: Maybe runtime-tools/generate should be updated with these... + editor.AddPostStopHook(ociHook) case CreateRuntimeHook: - ensureOCIHooks(spec) - spec.Hooks.CreateRuntime = append(spec.Hooks.CreateRuntime, ociHook) + editor.AddCreateRuntimeHook(ociHook) case CreateContainerHook: - ensureOCIHooks(spec) - spec.Hooks.CreateContainer = append(spec.Hooks.CreateContainer, ociHook) + editor.AddCreateContainerHook(ociHook) case StartContainerHook: - ensureOCIHooks(spec) - spec.Hooks.StartContainer = append(spec.Hooks.StartContainer, ociHook) + editor.AddStartContainerHook(ociHook) default: return fmt.Errorf("unknown hook name %q", h.HookName) } } if e.IntelRdt != nil { - // The specgen is missing functionality to set all parameters so we - // just piggy-back on it to initialize all structs and the copy over. - specgen.SetLinuxIntelRdtClosID(e.IntelRdt.ClosID) - spec.Linux.IntelRdt = (&IntelRdt{e.IntelRdt}).toOCI() + editor.SetLinuxIntelRdt((&IntelRdt{e.IntelRdt}).toOCI()) } for _, additionalGID := range e.AdditionalGIDs { if additionalGID == 0 { continue } - specgen.AddProcessAdditionalGid(additionalGID) + editor.AddProcessAdditionalGID(additionalGID) } return nil } -func specgenAddLinuxNetDevice(specgen *ocigen.Generator, hostIf string, netDev *oci.LinuxNetDevice) { - if specgen == nil || netDev == nil { - return - } - ensureLinuxNetDevices(specgen.Config) - specgen.Config.Linux.NetDevices[hostIf] = *netDev -} - -// Ensure OCI Spec Linux NetDevices map is not nil. -func ensureLinuxNetDevices(spec *oci.Spec) { - if spec.Linux == nil { - spec.Linux = &oci.Linux{} - } - if spec.Linux.NetDevices == nil { - spec.Linux.NetDevices = map[string]oci.LinuxNetDevice{} - } -} - // Validate container edits. func (e *ContainerEdits) Validate() error { if e == nil || e.ContainerEdits == nil { @@ -354,12 +343,14 @@ func (d *DeviceNode) Validate() error { if _, ok := validTypes[d.Type]; !ok { return fmt.Errorf("device %q: invalid type %q", d.Path, d.Type) } - for _, bit := range d.Permissions { - if bit != 'r' && bit != 'w' && bit != 'm' { - return fmt.Errorf("device %q: invalid permissions %q", - d.Path, d.Permissions) - } + switch { + case d.Permissions == "": + case d.Permissions == NoPermissions: + case strings.Trim(d.Permissions, "rwm") != "": + return fmt.Errorf("device %q: invalid permissions %q", + d.Path, d.Permissions) } + return nil } @@ -406,7 +397,9 @@ type IntelRdt struct { // ValidateIntelRdt validates the IntelRdt configuration. // -// Deprecated: ValidateIntelRdt is deprecated use IntelRdt.Validate() instead. +// Deprecated: use [*IntelRdt.Validate] instead. +// +//go:fix inline func ValidateIntelRdt(i *cdi.IntelRdt) error { return (&IntelRdt{i}).Validate() } @@ -422,19 +415,11 @@ func (i *IntelRdt) Validate() error { return nil } -// Ensure OCI Spec hooks are not nil so we can add hooks. -func ensureOCIHooks(spec *oci.Spec) { - if spec.Hooks == nil { - spec.Hooks = &oci.Hooks{} - } -} - // sortMounts sorts the mounts in the given OCI Spec. -func sortMounts(specgen *ocigen.Generator) { - mounts := specgen.Mounts() - specgen.ClearMounts() +func sortMounts(editor ociedit.SpecEditor) { + mounts := editor.Mounts() sort.Stable(orderedMounts(mounts)) - specgen.Config.Mounts = mounts + editor.SetMounts(mounts) } // orderedMounts defines how to sort an OCI Spec Mount slice. @@ -465,3 +450,16 @@ func (m orderedMounts) Swap(i, j int) { func (m orderedMounts) parts(i int) int { return strings.Count(filepath.Clean(m[i].Destination), string(os.PathSeparator)) } + +// specHasUserNamespace returns true if the OCI Spec has a Linux UserNamespace. +func specHasUserNamespace(spec *oci.Spec) bool { + if spec == nil || spec.Linux == nil { + return false + } + for _, ns := range spec.Linux.Namespaces { + if ns.Type == oci.UserNamespace { + return true + } + } + return false +} diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go index f37499fc..68ffafe9 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/oci.go @@ -30,14 +30,46 @@ func (h *Hook) toOCI() spec.Hook { } } +// Additional OCI mount option to apply to injected mounts. +type ociMountOption func(*spec.Mount) + +// withIDMapForBindMount adds any necessary ID mapping options for a bind mount. +func withIDMapForBindMount() ociMountOption { + return func(m *spec.Mount) { + option := "" + if m.Type == "bind" { + option = "idmap" + } + + for _, o := range m.Options { + switch o { + case "idmap", "ridmap": + return + case "bind": + option = "idmap" + case "rbind": + option = "ridmap" + } + } + + if option != "" { + m.Options = append(m.Options, option) + } + } +} + // toOCI returns the opencontainers runtime Spec Mount for this Mount. -func (m *Mount) toOCI() spec.Mount { - return spec.Mount{ +func (m *Mount) toOCI(options ...ociMountOption) spec.Mount { + om := spec.Mount{ Source: m.HostPath, Destination: m.ContainerPath, Options: m.Options, Type: m.Type, } + for _, o := range options { + o(&om) + } + return om } // toOCI returns the opencontainers runtime Spec LinuxDevice for this DeviceNode. diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go index b192f962..f77311fe 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec-dirs.go @@ -30,19 +30,24 @@ const ( DefaultDynamicDir = "/var/run/cdi" ) -var ( - // DefaultSpecDirs is the default Spec directory configuration. - // While altering this variable changes the package defaults, - // the preferred way of overriding the default directories is - // to use a WithSpecDirs options. Otherwise the change is only - // effective if it takes place before creating the cache instance. - DefaultSpecDirs = []string{DefaultStaticDir, DefaultDynamicDir} - // ErrStopScan can be returned from a ScanSpecFunc to stop the scan. - ErrStopScan = errors.New("stop Spec scan") -) +// DefaultSpecDirs is the default Spec directory configuration. +// +// The preferred way of overriding the default directories is +// to use [WithSpecDirs], otherwise the change is only effective +// if it takes place before creating the cache instance. +var DefaultSpecDirs = []string{DefaultStaticDir, DefaultDynamicDir} + +// ErrStopScan can be returned from a scanSpecFunc to stop the scan. +// +// Deprecated: ErrStopScan was only used by internal scan callbacks and is no longer used. +var ErrStopScan = errors.New("stop Spec scan") // WithSpecDirs returns an option to override the CDI Spec directories. func WithSpecDirs(dirs ...string) Option { + // If no spec dirs are specified use the default spec dirs. + if len(dirs) == 0 { + return WithSpecDirs(DefaultSpecDirs...) + } return func(c *Cache) { specDirs := make([]string, len(dirs)) for i, dir := range dirs { @@ -64,47 +69,33 @@ type scanSpecFunc func(string, int, *Spec, error) error // // Scanning stops once all files have been processed or when the scan // function returns an error. The result of ScanSpecDirs is the error -// returned by the scan function, if any. The special error ErrStopScan -// can be used to terminate the scan gracefully without ScanSpecDirs -// returning an error. ScanSpecDirs silently skips any subdirectories. +// returned by the scan function, if any. ScanSpecDirs does not recurse +// into subdirectories. func scanSpecDirs(dirs []string, scanFn scanSpecFunc) error { - var ( - spec *Spec - err error - ) - for priority, dir := range dirs { - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - // for initial stat failure Walk calls us with nil info - if info == nil { - if errors.Is(err, fs.ErrNotExist) { - return nil - } - return err - } - // first call from Walk is for dir itself, others we skip - if info.IsDir() { - if path == dir { - return nil - } - return filepath.SkipDir + entries, err := os.ReadDir(dir) + if errors.Is(err, fs.ErrNotExist) { + continue + } + if err != nil { + return err + } + + for _, entry := range entries { + if entry.IsDir() { + continue } // ignore obviously non-Spec files - if ext := filepath.Ext(path); ext != ".json" && ext != ".yaml" { - return nil + if ext := filepath.Ext(entry.Name()); ext != ".json" && ext != ".yaml" { + continue } - if err != nil { - return scanFn(path, priority, nil, err) + path := filepath.Join(dir, entry.Name()) + spec, specErr := ReadSpec(path, priority) // ignore specErr; it's recorded through scanFn + if err := scanFn(path, priority, spec, specErr); err != nil { + return err } - - spec, err = ReadSpec(path, priority) - return scanFn(path, priority, spec, err) - }) - - if err != nil && err != ErrStopScan { - return err } } diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go index fdaa2684..b5bdc5b5 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/cdi/spec.go @@ -17,6 +17,7 @@ package cdi import ( + "bytes" "encoding/json" "fmt" "os" @@ -25,8 +26,7 @@ import ( "sync" oci "github.com/opencontainers/runtime-spec/specs-go" - orderedyaml "gopkg.in/yaml.v3" - "sigs.k8s.io/yaml" + "go.yaml.in/yaml/v3" "tags.cncf.io/container-device-interface/internal/validation" "tags.cncf.io/container-device-interface/pkg/parser" @@ -136,7 +136,7 @@ func (s *Spec) write(overwrite bool) error { } if filepath.Ext(s.path) == ".yaml" { - data, err = orderedyaml.Marshal(s.Spec) + data, err = yaml.Marshal(s.Spec) data = append([]byte("---\n"), data...) } else { data, err = json.Marshal(s.Spec) @@ -207,7 +207,10 @@ func (s *Spec) edits() *ContainerEdits { } // MinimumRequiredVersion determines the minimum spec version for the input spec. -// Deprecated: use cdi.MinimumRequiredVersion instead +// +// Deprecated: use [cdi.MinimumRequiredVersion] instead. +// +//go:fix inline func MinimumRequiredVersion(spec *cdi.Spec) (string, error) { return cdi.MinimumRequiredVersion(spec) } @@ -250,9 +253,11 @@ func (s *Spec) validate() (map[string]*Device, error) { // ParseSpec parses CDI Spec data into a raw CDI Spec. func ParseSpec(data []byte) (*cdi.Spec, error) { + dec := yaml.NewDecoder(bytes.NewReader(data)) + dec.KnownFields(true) + var raw *cdi.Spec - err := yaml.UnmarshalStrict(data, &raw) - if err != nil { + if err := dec.Decode(&raw); err != nil { return nil, fmt.Errorf("failed to unmarshal CDI Spec: %w", err) } return raw, nil diff --git a/vendor/tags.cncf.io/container-device-interface/pkg/parser/parser.go b/vendor/tags.cncf.io/container-device-interface/pkg/parser/parser.go index 53259895..8512e3ba 100644 --- a/vendor/tags.cncf.io/container-device-interface/pkg/parser/parser.go +++ b/vendor/tags.cncf.io/container-device-interface/pkg/parser/parser.go @@ -83,13 +83,12 @@ func ParseDevice(device string) (string, string, string) { return "", "", device } - parts := strings.SplitN(device, "=", 2) - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { + qualifier, name, ok := strings.Cut(device, "=") + if !ok || qualifier == "" || name == "" { return "", "", device } - name := parts[1] - vendor, class := ParseQualifier(parts[0]) + vendor, class := ParseQualifier(qualifier) if vendor == "" { return "", "", device } @@ -105,11 +104,11 @@ func ParseDevice(device string) (string, string, string) { // If parsing fails, an empty vendor and the class set to the // verbatim input is returned. func ParseQualifier(kind string) (string, string) { - parts := strings.SplitN(kind, "/", 2) - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { + qualifier, value, ok := strings.Cut(kind, "/") + if !ok || qualifier == "" || value == "" { return "", kind } - return parts[0], parts[1] + return qualifier, value } // ValidateVendorName checks the validity of a vendor name. @@ -150,6 +149,9 @@ func validateVendorOrClassName(name string) error { if !IsLetter(rune(name[0])) { return fmt.Errorf("%q, should start with letter", name) } + if len(name) == 1 { + return nil + } for _, c := range string(name[1 : len(name)-1]) { switch { case IsAlphaNumeric(c): diff --git a/vendor/tags.cncf.io/container-device-interface/specs-go/version.go b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go index c3f5a8d1..dc808cd9 100644 --- a/vendor/tags.cncf.io/container-device-interface/specs-go/version.go +++ b/vendor/tags.cncf.io/container-device-interface/specs-go/version.go @@ -19,47 +19,46 @@ package specs import ( "fmt" "strings" - - "golang.org/x/mod/semver" ) -const ( - // CurrentVersion is the current version of the Spec. - CurrentVersion = "1.1.0" - - // vCurrent is the current version as a semver-comparable type - vCurrent version = "v" + CurrentVersion +// CurrentVersion is the current version of the Spec. +const CurrentVersion = "1.1.0" +const ( // These represent the released versions of the CDI specification - v010 version = "v0.1.0" - v020 version = "v0.2.0" - v030 version = "v0.3.0" - v040 version = "v0.4.0" - v050 version = "v0.5.0" - v060 version = "v0.6.0" - v070 version = "v0.7.0" - v080 version = "v0.8.0" - v100 version = "v1.0.0" - v110 version = "v1.1.0" + v010 version = "0.1.0" + v020 version = "0.2.0" + v030 version = "0.3.0" + v040 version = "0.4.0" + v050 version = "0.5.0" + v060 version = "0.6.0" + v070 version = "0.7.0" + v080 version = "0.8.0" + v100 version = "1.0.0" + v110 version = "1.1.0" // vEarliest is the earliest supported version of the CDI specification vEarliest version = v030 ) -// validSpecVersions stores a map of spec versions to functions to check the required versions. +// validSpecVersions stores the known spec versions in newest-to-oldest order, +// together with functions to check whether a version is required. // Adding new fields / spec versions requires that a `requiredFunc` be implemented and -// this map be updated. -var validSpecVersions = requiredVersionMap{ - v010: nil, - v020: nil, - v030: nil, - v040: requiresV040, - v050: requiresV050, - v060: requiresV060, - v070: requiresV070, - v080: requiresV080, - v100: requiresV100, - v110: requiresV110, +// this list be updated. +var validSpecVersions = []struct { + version version + isRequired requiredFunc +}{ + {v110, requiresV110}, + {v100, requiresV100}, + {v080, requiresV080}, + {v070, requiresV070}, + {v060, requiresV060}, + {v050, requiresV050}, + {v040, requiresV040}, + {v030, nil}, + {v020, nil}, + {v010, nil}, } // ValidateVersion checks whether the specified spec version is valid. @@ -67,14 +66,15 @@ var validSpecVersions = requiredVersionMap{ // the spec is inspected to determine whether the features used are available in specified // version. func ValidateVersion(spec *Spec) error { - if !validSpecVersions.isValidVersion(spec.Version) { + specVersion := newVersion(spec.Version) + if !isValidVersion(specVersion) { return fmt.Errorf("invalid version %q", spec.Version) } minVersion, err := MinimumRequiredVersion(spec) if err != nil { return fmt.Errorf("could not determine minimum required version: %w", err) } - if newVersion(minVersion).isGreaterThan(newVersion(spec.Version)) { + if versionIndex(version(minVersion)) < versionIndex(specVersion) { return fmt.Errorf("the spec version must be at least v%v", minVersion) } return nil @@ -82,64 +82,50 @@ func ValidateVersion(spec *Spec) error { // MinimumRequiredVersion determines the minimum spec version for the input spec. func MinimumRequiredVersion(spec *Spec) (string, error) { - minVersion := validSpecVersions.requiredVersion(spec) - return minVersion.String(), nil + minVersion := requiredVersion(spec) + return string(minVersion), nil } -// version represents a semantic version string +// version represents a CDI specification version. type version string -// newVersion creates a version that can be used for semantic version comparisons. +// newVersion normalizes a specification version by removing an optional leading v. func newVersion(v string) version { - return version("v" + strings.TrimPrefix(v, "v")) -} - -// String returns the string representation of the version. -// This trims a leading v if present. -func (v version) String() string { - return strings.TrimPrefix(string(v), "v") -} - -// isGreaterThan checks with a version is greater than the specified version. -func (v version) isGreaterThan(o version) bool { - return semver.Compare(string(v), string(o)) > 0 -} - -// isLatest checks whether the version is the latest supported version -func (v version) isLatest() bool { - return v == vCurrent + return version(strings.TrimPrefix(v, "v")) } type requiredFunc func(*Spec) bool -type requiredVersionMap map[version]requiredFunc - // isValidVersion checks whether the specified version is valid. -// A version is valid if it is contained in the required version map. -func (r requiredVersionMap) isValidVersion(specVersion string) bool { - _, ok := validSpecVersions[newVersion(specVersion)] - - return ok +// A version is valid if it is contained in the list of known spec versions. +func isValidVersion(specVersion version) bool { + for _, known := range validSpecVersions { + if known.version == specVersion { + return true + } + } + return false } -// requiredVersion returns the minimum version required for the given spec -func (r requiredVersionMap) requiredVersion(spec *Spec) version { - minVersion := vEarliest - - for v, isRequired := range validSpecVersions { - if isRequired == nil { - continue - } - if isRequired(spec) && v.isGreaterThan(minVersion) { - minVersion = v - } - // If we have already detected the latest version then no later version could be detected - if minVersion.isLatest() { - break +// requiredVersion returns the minimum version required for the given spec. +func requiredVersion(spec *Spec) version { + for _, known := range validSpecVersions { + if known.isRequired != nil && known.isRequired(spec) { + return known.version } } + return vEarliest +} - return minVersion +// versionIndex returns the index of v in validSpecVersions, which is ordered +// newest-to-oldest. It returns -1 for an unknown version. +func versionIndex(v version) int { + for i, known := range validSpecVersions { + if known.version == v { + return i + } + } + return -1 } // requiresV110 returns true if the spec uses v1.1.0 features. @@ -209,23 +195,20 @@ func requiresV070(spec *Spec) bool { // requiresV060 returns true if the spec uses v0.6.0 features func requiresV060(spec *Spec) bool { // The v0.6.0 spec allows annotations to be specified at a spec level - for range spec.Annotations { + if len(spec.Annotations) > 0 { return true } // The v0.6.0 spec allows annotations to be specified at a device level for _, d := range spec.Devices { - for range d.Annotations { + if len(d.Annotations) > 0 { return true } } // The v0.6.0 spec allows dots "." in Kind name label (class) - if !strings.Contains(spec.Kind, "/") { - return false - } - class := strings.SplitN(spec.Kind, "/", 2)[1] - return strings.Contains(class, ".") + _, class, ok := strings.Cut(spec.Kind, "/") + return ok && strings.Contains(class, ".") } // requiresV050 returns true if the spec uses v0.5.0 features