Compare commits
63 Commits
Author | SHA1 | Date | |
---|---|---|---|
c29dc79f96 | |||
508c94caec | |||
b96f963c7a | |||
518bc80c56 | |||
434e9b9ef7 | |||
0e87bccf19 | |||
0259301ae2 | |||
14cad164ec | |||
1868e4fe2d | |||
5c95925a71 | |||
505f5a7def | |||
dc8b8289fa | |||
196ed2d00e | |||
43139b3375 | |||
18d129f18b | |||
9397270f5e | |||
3656c69d0f | |||
3af6e6b61d | |||
427af8636f | |||
dc704d19d6 | |||
45a24d5d95 | |||
c0533466c8 | |||
ada798a3f7 | |||
eb49a034c4 | |||
670139cffa | |||
717b4337b5 | |||
ef076afac1 | |||
ccc1cfaa58 | |||
78ebd8bfb9 | |||
c666d1400d | |||
ab0b386b4e | |||
52da39d3aa | |||
597408952e | |||
6f05dc325a | |||
8ab3c63c2d | |||
c464674317 | |||
c860b78de4 | |||
9f1bf2a848 | |||
7567d28a73 | |||
ba5bdafe5d | |||
d34720b531 | |||
8fc26ce7a0 | |||
c8d165df6d | |||
1b5811957e | |||
8a3014f202 | |||
019727a392 | |||
352e0512e8 | |||
9c016b5d12 | |||
0729398940 | |||
394ab0d149 | |||
0144de0fcf | |||
47373d2612 | |||
8e8410f726 | |||
2bae9b67d3 | |||
976edfe1bc | |||
cb244060c2 | |||
d1aada912d | |||
8b2b1d20d6 | |||
14bdce598f | |||
7e131a0076 | |||
b6a0e0bc96 | |||
133a764c4d | |||
e6099fb83d |
2
.github/actions/retest-action/Dockerfile
vendored
2
.github/actions/retest-action/Dockerfile
vendored
@ -1,4 +1,4 @@
|
||||
FROM alpine:3.18
|
||||
FROM alpine:3.20
|
||||
|
||||
RUN apk add --no-cache curl jq
|
||||
|
||||
|
2
.github/dependabot.yml
vendored
2
.github/dependabot.yml
vendored
@ -21,3 +21,5 @@ updates:
|
||||
golang:
|
||||
patterns:
|
||||
- "*"
|
||||
exclude-patterns:
|
||||
- "github.com/containernetworking/*"
|
||||
|
114
.github/workflows/release.yaml
vendored
Normal file
114
.github/workflows/release.yaml
vendored
Normal file
@ -0,0 +1,114 @@
|
||||
---
|
||||
name: Release binaries
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
jobs:
|
||||
linux_release:
|
||||
name: Release linux binaries
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
goarch: [amd64, arm, arm64, mips64le, ppc64le, riscv64, s390x]
|
||||
steps:
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.22
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
CGO_ENABLED: 0
|
||||
run: ./build_linux.sh -ldflags '-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=${{ github.ref_name }}'
|
||||
|
||||
- name: COPY files
|
||||
run: cp README.md LICENSE bin/
|
||||
|
||||
- name: Change plugin file ownership
|
||||
working-directory: ./bin
|
||||
run: sudo chown root:root ./*
|
||||
|
||||
- name: Create dist directory
|
||||
run: mkdir dist
|
||||
|
||||
- name: Create archive file
|
||||
working-directory: ./bin
|
||||
run: tar cfzpv ../dist/cni-plugins-linux-${{ matrix.goarch }}-${{ github.ref_name }}.tgz .
|
||||
|
||||
- name: Create sha256 checksum
|
||||
working-directory: ./dist
|
||||
run: sha256sum cni-plugins-linux-${{ matrix.goarch }}-${{ github.ref_name }}.tgz | tee cni-plugins-linux-${{ matrix.goarch }}-${{ github.ref_name }}.tgz.sha256
|
||||
|
||||
- name: Create sha512 checksum
|
||||
working-directory: ./dist
|
||||
run: sha512sum cni-plugins-linux-${{ matrix.goarch }}-${{ github.ref_name }}.tgz | tee cni-plugins-linux-${{ matrix.goarch }}-${{ github.ref_name }}.tgz.sha512
|
||||
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./dist/*
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
|
||||
windows_releases:
|
||||
name: Release windows binaries
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
goarch: [amd64]
|
||||
steps:
|
||||
- name: Install dos2unix
|
||||
run: sudo apt-get install dos2unix
|
||||
|
||||
- name: Install Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.21
|
||||
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
GOARCH: ${{ matrix.goarch }}
|
||||
CGO_ENABLED: 0
|
||||
run: ./build_windows.sh -ldflags '-extldflags -static -X github.com/containernetworking/plugins/pkg/utils/buildversion.BuildVersion=${{ github.ref_name }}'
|
||||
|
||||
- name: COPY files
|
||||
run: cp README.md LICENSE bin/
|
||||
|
||||
- name: Change plugin file ownership
|
||||
working-directory: ./bin
|
||||
run: sudo chown root:root ./*
|
||||
|
||||
- name: Create dist directory
|
||||
run: mkdir dist
|
||||
|
||||
- name: Create archive file
|
||||
working-directory: ./bin
|
||||
run: tar cpfzv ../dist/cni-plugins-windows-${{ matrix.goarch }}-${{ github.ref_name }}.tgz .
|
||||
|
||||
- name: Create sha256 checksum
|
||||
working-directory: ./dist
|
||||
run: sha256sum cni-plugins-windows-${{ matrix.goarch }}-${{ github.ref_name }}.tgz | tee cni-plugins-windows-${{ matrix.goarch }}-${{ github.ref_name }}.tgz.sha256
|
||||
|
||||
- name: Create sha512 checksum
|
||||
working-directory: ./dist
|
||||
run: sha512sum cni-plugins-windows-${{ matrix.goarch }}-${{ github.ref_name }}.tgz | tee cni-plugins-windows-${{ matrix.goarch }}-${{ github.ref_name }}.tgz.sha512
|
||||
|
||||
- name: Upload binaries to release
|
||||
uses: svenstaro/upload-release-action@v2
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./dist/*
|
||||
tag: ${{ github.ref }}
|
||||
overwrite: true
|
||||
file_glob: true
|
13
.github/workflows/test.yaml
vendored
13
.github/workflows/test.yaml
vendored
@ -4,7 +4,7 @@ name: test
|
||||
on: ["push", "pull_request"]
|
||||
|
||||
env:
|
||||
GO_VERSION: "1.21"
|
||||
GO_VERSION: "1.22"
|
||||
LINUX_ARCHES: "amd64 386 arm arm64 s390x mips64le ppc64le riscv64"
|
||||
|
||||
jobs:
|
||||
@ -14,14 +14,15 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- uses: ibiqlik/action-yamllint@v3
|
||||
with:
|
||||
format: auto
|
||||
- uses: golangci/golangci-lint-action@v3
|
||||
- uses: golangci/golangci-lint-action@v6
|
||||
with:
|
||||
version: v1.55.2
|
||||
args: -v
|
||||
skip-cache: true
|
||||
build:
|
||||
@ -31,7 +32,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- name: Build on all supported architectures
|
||||
@ -55,7 +56,7 @@ jobs:
|
||||
run: sudo apt-get install nftables
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- name: Set up Go for root
|
||||
@ -86,7 +87,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v4
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version-file: go.mod
|
||||
- name: test
|
||||
|
40
go.mod
40
go.mod
@ -3,8 +3,8 @@ module github.com/containernetworking/plugins
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/Microsoft/hcsshim v0.11.4
|
||||
github.com/alexflint/go-filemutex v1.2.0
|
||||
github.com/Microsoft/hcsshim v0.12.3
|
||||
github.com/alexflint/go-filemutex v1.3.0
|
||||
github.com/buger/jsonparser v1.1.1
|
||||
github.com/containernetworking/cni v1.1.2
|
||||
github.com/coreos/go-iptables v0.7.0
|
||||
@ -15,36 +15,34 @@ require (
|
||||
github.com/godbus/dbus/v5 v5.1.0
|
||||
github.com/mattn/go-shellwords v1.0.12
|
||||
github.com/networkplumbing/go-nft v0.4.0
|
||||
github.com/onsi/ginkgo/v2 v2.13.2
|
||||
github.com/onsi/gomega v1.30.0
|
||||
github.com/onsi/ginkgo/v2 v2.19.0
|
||||
github.com/onsi/gomega v1.33.1
|
||||
github.com/opencontainers/selinux v1.11.0
|
||||
github.com/safchain/ethtool v0.3.0
|
||||
github.com/safchain/ethtool v0.4.0
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2
|
||||
golang.org/x/sys v0.15.0
|
||||
golang.org/x/sys v0.21.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/containerd/cgroups v1.1.0 // indirect
|
||||
github.com/containerd/containerd v1.6.23 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/containerd/cgroups/v3 v3.0.2 // indirect
|
||||
github.com/containerd/errdefs v0.1.0 // indirect
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4 // indirect
|
||||
github.com/go-logr/logr v1.3.0 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd // indirect
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/vishvananda/netns v0.0.4 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.14.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
golang.org/x/tools v0.21.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
|
||||
google.golang.org/grpc v1.62.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
95
go.sum
95
go.sum
@ -1,11 +1,11 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
|
||||
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
|
||||
github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8=
|
||||
github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w=
|
||||
github.com/alexflint/go-filemutex v1.2.0 h1:1v0TJPDtlhgpW4nJ+GvxCLSlUDC3+gW0CQQvlmfDR/s=
|
||||
github.com/alexflint/go-filemutex v1.2.0/go.mod h1:mYyQSWvw9Tx2/H2n9qXPb52tTYfE0pZAWcBq5mK025c=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/Microsoft/hcsshim v0.12.3 h1:LS9NXqXhMoqNCplK1ApmVSfB4UnVLRDWRapB6EIlxE0=
|
||||
github.com/Microsoft/hcsshim v0.12.3/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ=
|
||||
github.com/alexflint/go-filemutex v1.3.0 h1:LgE+nTUWnQCyRKbpoceKZsPQbs84LivvgwUymZXdOcM=
|
||||
github.com/alexflint/go-filemutex v1.3.0/go.mod h1:U0+VA/i30mGBlLCrFPGtTe9y6wGQfNAWPBTekHQ+c8A=
|
||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@ -14,10 +14,10 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw=
|
||||
github.com/containerd/containerd v1.6.23 h1:KYJd6UJhKHzwMhiD70iTtSmU+k4565ac22GOTI3AuTA=
|
||||
github.com/containerd/containerd v1.6.23/go.mod h1:UrQOiyzrLi3n4aezYJbQH6Il+YzTvnHFbEuO3yfDrM4=
|
||||
github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0=
|
||||
github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE=
|
||||
github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5ZURM=
|
||||
github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0=
|
||||
github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ=
|
||||
github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
|
||||
github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
|
||||
@ -41,16 +41,14 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
@ -80,13 +78,11 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
|
||||
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg=
|
||||
github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
|
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
|
||||
github.com/networkplumbing/go-nft v0.4.0 h1:kExVMwXW48DOAukkBwyI16h4uhE5lN9iMvQd52lpTyU=
|
||||
@ -97,13 +93,13 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
|
||||
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA=
|
||||
github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk=
|
||||
github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0=
|
||||
github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaLpt7tQ7oU=
|
||||
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -111,27 +107,25 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0=
|
||||
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/safchain/ethtool v0.4.0 h1:vq1i2HCjshJNywOXFZ1BpwIjyeFR/kvNdHiRzqSElDI=
|
||||
github.com/safchain/ethtool v0.4.0/go.mod h1:XLLnZmy4OCRTkksP/UiMjij96YmIsBfmBQcs7H6tA48=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
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/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs=
|
||||
github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
|
||||
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
|
||||
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
|
||||
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
@ -143,11 +137,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@ -155,22 +146,19 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@ -188,29 +176,26 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
|
||||
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@ -220,15 +205,15 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc=
|
||||
google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
|
||||
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
|
||||
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@ -240,8 +225,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
|
@ -17,6 +17,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"os"
|
||||
@ -60,6 +61,13 @@ var _ = Describe("Basic PTP using cnitool", func() {
|
||||
netConfPath, err := filepath.Abs("./testdata")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// Flush ipam stores to avoid conflicts
|
||||
err = os.RemoveAll("/tmp/chained-ptp-bandwidth-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = os.RemoveAll("/tmp/basic-ptp-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
env = TestEnv([]string{
|
||||
"CNI_PATH=" + cniPath,
|
||||
"NETCONFPATH=" + netConfPath,
|
||||
@ -82,6 +90,7 @@ var _ = Describe("Basic PTP using cnitool", func() {
|
||||
env.runInNS(hostNS, cnitoolBin, "add", netName, contNS.LongName())
|
||||
|
||||
addrOutput := env.runInNS(contNS, "ip", "addr")
|
||||
|
||||
Expect(addrOutput).To(ContainSubstring(expectedIPPrefix))
|
||||
|
||||
env.runInNS(hostNS, cnitoolBin, "del", netName, contNS.LongName())
|
||||
@ -145,9 +154,13 @@ var _ = Describe("Basic PTP using cnitool", func() {
|
||||
|
||||
chainedBridgeBandwidthEnv.runInNS(hostNS, cnitoolBin, "del", "network-chain-test", contNS1.LongName())
|
||||
basicBridgeEnv.runInNS(hostNS, cnitoolBin, "del", "network-chain-test", contNS2.LongName())
|
||||
|
||||
contNS1.Del()
|
||||
contNS2.Del()
|
||||
hostNS.Del()
|
||||
})
|
||||
|
||||
Measure("limits traffic only on the restricted bandwidth veth device", func(b Benchmarker) {
|
||||
It("limits traffic only on the restricted bandwidth veth device", func() {
|
||||
ipRegexp := regexp.MustCompile(`10\.1[12]\.2\.\d{1,3}`)
|
||||
|
||||
By(fmt.Sprintf("adding %s to %s\n\n", "chained-bridge-bandwidth", contNS1.ShortName()))
|
||||
@ -168,21 +181,23 @@ var _ = Describe("Basic PTP using cnitool", func() {
|
||||
By(fmt.Sprintf("starting echo server in %s\n\n", contNS2.ShortName()))
|
||||
basicBridgePort, basicBridgeSession = startEchoServerInNamespace(contNS2)
|
||||
|
||||
packetInBytes := 20000 // The shaper needs to 'warm'. Send enough to cause it to throttle,
|
||||
// balanced by run time.
|
||||
packetInBytes := 3000
|
||||
|
||||
By(fmt.Sprintf("sending tcp traffic to the chained, bridged, traffic shaped container on ip address '%s:%d'\n\n", chainedBridgeIP, chainedBridgeBandwidthPort))
|
||||
runtimeWithLimit := b.Time("with chained bridge and bandwidth plugins", func() {
|
||||
makeTCPClientInNS(hostNS.ShortName(), chainedBridgeIP, chainedBridgeBandwidthPort, packetInBytes)
|
||||
})
|
||||
start := time.Now()
|
||||
makeTCPClientInNS(hostNS.ShortName(), chainedBridgeIP, chainedBridgeBandwidthPort, packetInBytes)
|
||||
runtimeWithLimit := time.Since(start)
|
||||
|
||||
log.Printf("Runtime with qos limit %.2f seconds", runtimeWithLimit.Seconds())
|
||||
|
||||
By(fmt.Sprintf("sending tcp traffic to the basic bridged container on ip address '%s:%d'\n\n", basicBridgeIP, basicBridgePort))
|
||||
runtimeWithoutLimit := b.Time("with basic bridged plugin", func() {
|
||||
makeTCPClientInNS(hostNS.ShortName(), basicBridgeIP, basicBridgePort, packetInBytes)
|
||||
})
|
||||
start = time.Now()
|
||||
makeTCPClientInNS(hostNS.ShortName(), basicBridgeIP, basicBridgePort, packetInBytes)
|
||||
runtimeWithoutLimit := time.Since(start)
|
||||
log.Printf("Runtime without qos limit %.2f seconds", runtimeWithLimit.Seconds())
|
||||
|
||||
Expect(runtimeWithLimit).To(BeNumerically(">", runtimeWithoutLimit+1000*time.Millisecond))
|
||||
}, 1)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
3
integration/testdata/basic-ptp.json
vendored
3
integration/testdata/basic-ptp.json
vendored
@ -6,6 +6,7 @@
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24"
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "/tmp/basic-ptp-test"
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,8 @@
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.9.2.0/24"
|
||||
"subnet": "10.9.2.0/24",
|
||||
"dataDir": "/tmp/chained-ptp-bandwidth-test"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ func makeVeth(name, vethPeerName string, mtu int, mac string, hostNS ns.NetNS) (
|
||||
if peerExists(peerName) && vethPeerName == "" {
|
||||
continue
|
||||
}
|
||||
return peerName, veth, fmt.Errorf("container veth name provided (%v) already exists", name)
|
||||
return peerName, veth, fmt.Errorf("container veth name (%q) peer provided (%q) already exists", name, peerName)
|
||||
default:
|
||||
return peerName, veth, fmt.Errorf("failed to make veth pair: %v", err)
|
||||
}
|
||||
|
@ -149,9 +149,9 @@ var _ = Describe("Link", func() {
|
||||
It("returns useful error", func() {
|
||||
_ = containerNetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := ip.SetupVeth(containerVethName, mtu, "", hostNetNS)
|
||||
Expect(err.Error()).To(Equal(fmt.Sprintf("container veth name provided (%s) already exists", containerVethName)))
|
||||
testHostVethName := "test" + hostVethName
|
||||
_, _, err := ip.SetupVethWithName(containerVethName, testHostVethName, mtu, "", hostNetNS)
|
||||
Expect(err.Error()).To(Equal(fmt.Sprintf("container veth name (%q) peer provided (%q) already exists", containerVethName, testHostVethName)))
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -180,9 +180,8 @@ var _ = Describe("Link", func() {
|
||||
It("returns useful error", func() {
|
||||
_ = containerNetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
_, _, err := ip.SetupVeth(containerVethName, mtu, "", hostNetNS)
|
||||
Expect(err.Error()).To(HavePrefix("container veth name provided"))
|
||||
Expect(err.Error()).To(HaveSuffix("already exists"))
|
||||
_, _, err := ip.SetupVethWithName(containerVethName, hostVethName, mtu, "", hostNetNS)
|
||||
Expect(err.Error()).To(Equal(fmt.Sprintf("container veth name (%q) peer provided (%q) already exists", containerVethName, hostVethName)))
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
@ -28,6 +28,7 @@ func parseResolvConf(filename string) (*types.DNS, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
dns := types.DNS{}
|
||||
scanner := bufio.NewScanner(fp)
|
||||
|
@ -47,19 +47,20 @@ const defaultBrName = "cni0"
|
||||
|
||||
type NetConf struct {
|
||||
types.NetConf
|
||||
BrName string `json:"bridge"`
|
||||
IsGW bool `json:"isGateway"`
|
||||
IsDefaultGW bool `json:"isDefaultGateway"`
|
||||
ForceAddress bool `json:"forceAddress"`
|
||||
IPMasq bool `json:"ipMasq"`
|
||||
MTU int `json:"mtu"`
|
||||
HairpinMode bool `json:"hairpinMode"`
|
||||
PromiscMode bool `json:"promiscMode"`
|
||||
Vlan int `json:"vlan"`
|
||||
VlanTrunk []*VlanTrunk `json:"vlanTrunk,omitempty"`
|
||||
PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
|
||||
MacSpoofChk bool `json:"macspoofchk,omitempty"`
|
||||
EnableDad bool `json:"enabledad,omitempty"`
|
||||
BrName string `json:"bridge"`
|
||||
IsGW bool `json:"isGateway"`
|
||||
IsDefaultGW bool `json:"isDefaultGateway"`
|
||||
ForceAddress bool `json:"forceAddress"`
|
||||
IPMasq bool `json:"ipMasq"`
|
||||
MTU int `json:"mtu"`
|
||||
HairpinMode bool `json:"hairpinMode"`
|
||||
PromiscMode bool `json:"promiscMode"`
|
||||
Vlan int `json:"vlan"`
|
||||
VlanTrunk []*VlanTrunk `json:"vlanTrunk,omitempty"`
|
||||
PreserveDefaultVlan bool `json:"preserveDefaultVlan"`
|
||||
MacSpoofChk bool `json:"macspoofchk,omitempty"`
|
||||
EnableDad bool `json:"enabledad,omitempty"`
|
||||
DisableContainerInterface bool `json:"disableContainerInterface,omitempty"`
|
||||
|
||||
Args struct {
|
||||
Cni BridgeArgs `json:"cni,omitempty"`
|
||||
@ -530,6 +531,10 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
|
||||
isLayer3 := n.IPAM.Type != ""
|
||||
|
||||
if isLayer3 && n.DisableContainerInterface {
|
||||
return fmt.Errorf("cannot use IPAM when DisableContainerInterface flag is set")
|
||||
}
|
||||
|
||||
if n.IsDefaultGW {
|
||||
n.IsGW = true
|
||||
}
|
||||
@ -676,12 +681,13 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if !n.DisableContainerInterface {
|
||||
if err := netns.Do(func(_ ns.NetNS) error {
|
||||
link, err := netlink.LinkByName(args.IfName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve link: %v", err)
|
||||
}
|
||||
|
||||
// If layer 2 we still need to set the container veth to up
|
||||
if err = netlink.LinkSetUp(link); err != nil {
|
||||
return fmt.Errorf("failed to set %q up: %v", args.IfName, err)
|
||||
@ -692,23 +698,28 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
}
|
||||
|
||||
var hostVeth netlink.Link
|
||||
hostVeth, err := netlink.LinkByName(hostInterface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check bridge port state
|
||||
retries := []int{0, 50, 500, 1000, 1000}
|
||||
for idx, sleep := range retries {
|
||||
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||
if !n.DisableContainerInterface {
|
||||
// check bridge port state
|
||||
retries := []int{0, 50, 500, 1000, 1000}
|
||||
for idx, sleep := range retries {
|
||||
time.Sleep(time.Duration(sleep) * time.Millisecond)
|
||||
|
||||
hostVeth, err = netlink.LinkByName(hostInterface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hostVeth.Attrs().OperState == netlink.OperUp {
|
||||
break
|
||||
}
|
||||
hostVeth, err = netlink.LinkByName(hostInterface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if hostVeth.Attrs().OperState == netlink.OperUp {
|
||||
break
|
||||
}
|
||||
|
||||
if idx == len(retries)-1 {
|
||||
return fmt.Errorf("bridge port in error state: %s", hostVeth.Attrs().OperState)
|
||||
if idx == len(retries)-1 {
|
||||
return fmt.Errorf("bridge port in error state: %s", hostVeth.Attrs().OperState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -779,7 +790,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -78,10 +78,12 @@ type testCase struct {
|
||||
removeDefaultVlan bool
|
||||
ipMasq bool
|
||||
macspoofchk bool
|
||||
AddErr020 string
|
||||
DelErr020 string
|
||||
AddErr010 string
|
||||
DelErr010 string
|
||||
disableContIface bool
|
||||
|
||||
AddErr020 string
|
||||
DelErr020 string
|
||||
AddErr010 string
|
||||
DelErr010 string
|
||||
|
||||
envArgs string // CNI_ARGS
|
||||
runtimeConfig struct {
|
||||
@ -154,6 +156,9 @@ const (
|
||||
netDefault = `,
|
||||
"isDefaultGateway": true`
|
||||
|
||||
disableContainerInterface = `,
|
||||
"disableContainerInterface": true`
|
||||
|
||||
ipamStartStr = `,
|
||||
"ipam": {
|
||||
"type": "host-local"`
|
||||
@ -248,6 +253,10 @@ func (tc testCase) netConfJSON(dataDir string) string {
|
||||
conf += fmt.Sprintf(macspoofchkFormat, tc.macspoofchk)
|
||||
}
|
||||
|
||||
if tc.disableContIface {
|
||||
conf += disableContainerInterface
|
||||
}
|
||||
|
||||
if !tc.isLayer2 {
|
||||
conf += netDefault
|
||||
if tc.subnet != "" || tc.ranges != nil {
|
||||
@ -677,14 +686,16 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().Name).To(Equal(IFNAME))
|
||||
Expect(link).To(BeAssignableToTypeOf(&netlink.Veth{}))
|
||||
assertContainerInterfaceLinkState(&tc, link)
|
||||
|
||||
expCIDRsV4, expCIDRsV6 := tc.expectedCIDRs()
|
||||
addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(addrs).To(HaveLen(len(expCIDRsV4)))
|
||||
addrs, err = netlink.AddrList(link, netlink.FAMILY_V6)
|
||||
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
assertIPv6Addresses(&tc, addrs, expCIDRsV6)
|
||||
|
||||
// Ignore link local address which may or may not be
|
||||
// ready when we read addresses.
|
||||
var foundAddrs int
|
||||
@ -728,6 +739,15 @@ func (tester *testerV10x) cmdAddTest(tc testCase, dataDir string) (types.Result,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func assertContainerInterfaceLinkState(tc *testCase, link netlink.Link) {
|
||||
linkState := int(link.Attrs().OperState)
|
||||
if tc.disableContIface {
|
||||
Expect(linkState).ToNot(Equal(netlink.OperUp))
|
||||
} else {
|
||||
Expect(linkState).To(Equal(netlink.OperUp))
|
||||
}
|
||||
}
|
||||
|
||||
func (tester *testerV10x) cmdCheckTest(tc testCase, conf *Net, _ string) {
|
||||
// Generate network config and command arguments
|
||||
tester.args = tc.createCheckCmdArgs(tester.targetNS, conf)
|
||||
@ -1008,8 +1028,9 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(addrs).To(HaveLen(len(expCIDRsV4)))
|
||||
addrs, err = netlink.AddrList(link, netlink.FAMILY_V6)
|
||||
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
assertIPv6Addresses(&tc, addrs, expCIDRsV6)
|
||||
|
||||
// Ignore link local address which may or may not be
|
||||
// ready when we read addresses.
|
||||
var foundAddrs int
|
||||
@ -1053,6 +1074,14 @@ func (tester *testerV04x) cmdAddTest(tc testCase, dataDir string) (types.Result,
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func assertIPv6Addresses(tc *testCase, addrs []netlink.Addr, expCIDRsV6 []*net.IPNet) {
|
||||
if tc.disableContIface {
|
||||
Expect(addrs).To(BeEmpty())
|
||||
} else {
|
||||
Expect(addrs).To(HaveLen(len(expCIDRsV6) + 1)) // add one for the link-local
|
||||
}
|
||||
}
|
||||
|
||||
func (tester *testerV04x) cmdCheckTest(tc testCase, conf *Net, _ string) {
|
||||
// Generate network config and command arguments
|
||||
tester.args = tc.createCheckCmdArgs(tester.targetNS, conf)
|
||||
@ -2461,6 +2490,36 @@ var _ = Describe("bridge Operations", func() {
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] should fail when both IPAM and DisableContainerInterface are set", ver), func() {
|
||||
Expect(originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
tc := testCase{
|
||||
cniVersion: ver,
|
||||
subnet: "10.1.2.0/24",
|
||||
disableContIface: true,
|
||||
}
|
||||
args := tc.createCmdArgs(targetNS, dataDir)
|
||||
Expect(cmdAdd(args)).To(HaveOccurred())
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] should set the container veth peer state down", ver), func() {
|
||||
Expect(originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
tc := testCase{
|
||||
cniVersion: ver,
|
||||
disableContIface: true,
|
||||
isLayer2: true,
|
||||
AddErr020: "cannot convert: no valid IP addresses",
|
||||
AddErr010: "cannot convert: no valid IP addresses",
|
||||
}
|
||||
cmdAddDelTest(originalNS, targetNS, tc, dataDir)
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
}
|
||||
|
||||
It("check vlan id when loading net conf", func() {
|
||||
|
@ -136,7 +136,6 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
err = netns.Do(func(_ ns.NetNS) error {
|
||||
return ipam.ConfigureIface(args.IfName, result)
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -165,7 +164,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -371,7 +371,7 @@ var _ = Describe("dummy Operations", func() {
|
||||
StdinData: []byte(fmt.Sprintf(confFmt, ver)),
|
||||
}
|
||||
|
||||
_ = originalNS.Do(func(netNS ns.NetNS) error {
|
||||
_ = originalNS.Do(func(_ ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err = testutils.CmdAddWithArgs(args, func() error {
|
||||
|
@ -37,7 +37,10 @@ import (
|
||||
bv "github.com/containernetworking/plugins/pkg/utils/buildversion"
|
||||
)
|
||||
|
||||
var sysBusPCI = "/sys/bus/pci/devices"
|
||||
var (
|
||||
sysBusPCI = "/sys/bus/pci/devices"
|
||||
sysBusAuxiliary = "/sys/bus/auxiliary/devices"
|
||||
)
|
||||
|
||||
// Array of different linux drivers bound to network device needed for DPDK
|
||||
var userspaceDrivers = []string{"vfio-pci", "uio_pci_generic", "igb_uio"}
|
||||
@ -53,6 +56,9 @@ type NetConf struct {
|
||||
RuntimeConfig struct {
|
||||
DeviceID string `json:"deviceID,omitempty"`
|
||||
} `json:"runtimeConfig,omitempty"`
|
||||
|
||||
// for internal use
|
||||
auxDevice string `json:"-"` // Auxiliary device name as appears on Auxiliary bus (/sys/bus/auxiliary)
|
||||
}
|
||||
|
||||
func init() {
|
||||
@ -62,6 +68,31 @@ func init() {
|
||||
runtime.LockOSThread()
|
||||
}
|
||||
|
||||
// handleDeviceID updates netconf fields with DeviceID runtime config
|
||||
func handleDeviceID(netconf *NetConf) error {
|
||||
deviceID := netconf.RuntimeConfig.DeviceID
|
||||
if deviceID == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if deviceID is a PCI device
|
||||
pciPath := filepath.Join(sysBusPCI, deviceID)
|
||||
if _, err := os.Stat(pciPath); err == nil {
|
||||
netconf.PCIAddr = deviceID
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if deviceID is an Auxiliary device
|
||||
auxPath := filepath.Join(sysBusAuxiliary, deviceID)
|
||||
if _, err := os.Stat(auxPath); err == nil {
|
||||
netconf.PCIAddr = ""
|
||||
netconf.auxDevice = deviceID
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("runtime config DeviceID %s not found or unsupported", deviceID)
|
||||
}
|
||||
|
||||
func loadConf(bytes []byte) (*NetConf, error) {
|
||||
n := &NetConf{}
|
||||
var err error
|
||||
@ -69,12 +100,12 @@ func loadConf(bytes []byte) (*NetConf, error) {
|
||||
return nil, fmt.Errorf("failed to load netconf: %v", err)
|
||||
}
|
||||
|
||||
if n.RuntimeConfig.DeviceID != "" {
|
||||
// Override PCI device with the standardized DeviceID provided in Runtime Config.
|
||||
n.PCIAddr = n.RuntimeConfig.DeviceID
|
||||
// Override device with the standardized DeviceID if provided in Runtime Config.
|
||||
if err := handleDeviceID(n); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n.Device == "" && n.HWAddr == "" && n.KernelPath == "" && n.PCIAddr == "" {
|
||||
if n.Device == "" && n.HWAddr == "" && n.KernelPath == "" && n.PCIAddr == "" && n.auxDevice == "" {
|
||||
return nil, fmt.Errorf(`specify either "device", "hwaddr", "kernelpath" or "pciBusID"`)
|
||||
}
|
||||
|
||||
@ -102,7 +133,7 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
result := ¤t.Result{}
|
||||
var contDev netlink.Link
|
||||
if !cfg.DPDKMode {
|
||||
hostDev, err := getLink(cfg.Device, cfg.HWAddr, cfg.KernelPath, cfg.PCIAddr)
|
||||
hostDev, err := getLink(cfg.Device, cfg.HWAddr, cfg.KernelPath, cfg.PCIAddr, cfg.auxDevice)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find host device: %v", err)
|
||||
}
|
||||
@ -199,34 +230,112 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// setTempName sets a temporary name for netdevice, returns updated Link object or error
|
||||
// if occurred.
|
||||
func setTempName(dev netlink.Link) (netlink.Link, error) {
|
||||
tempName := fmt.Sprintf("%s%d", "temp_", dev.Attrs().Index)
|
||||
|
||||
// rename to tempName
|
||||
if err := netlink.LinkSetName(dev, tempName); err != nil {
|
||||
return nil, fmt.Errorf("failed to rename device %q to %q: %v", dev.Attrs().Name, tempName, err)
|
||||
}
|
||||
|
||||
// Get updated Link obj
|
||||
tempDev, err := netlink.LinkByName(tempName)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find %q after rename to %q: %v", dev.Attrs().Name, tempName, err)
|
||||
}
|
||||
|
||||
return tempDev, nil
|
||||
}
|
||||
|
||||
func moveLinkIn(hostDev netlink.Link, containerNs ns.NetNS, ifName string) (netlink.Link, error) {
|
||||
if err := netlink.LinkSetNsFd(hostDev, int(containerNs.Fd())); err != nil {
|
||||
return nil, err
|
||||
origLinkFlags := hostDev.Attrs().Flags
|
||||
hostDevName := hostDev.Attrs().Name
|
||||
defaultNs, err := ns.GetCurrentNS()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get host namespace: %v", err)
|
||||
}
|
||||
|
||||
// Devices can be renamed only when down
|
||||
if err = netlink.LinkSetDown(hostDev); err != nil {
|
||||
return nil, fmt.Errorf("failed to set %q down: %v", hostDev.Attrs().Name, err)
|
||||
}
|
||||
|
||||
// restore original link state in case of error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if origLinkFlags&net.FlagUp == net.FlagUp && hostDev != nil {
|
||||
_ = netlink.LinkSetUp(hostDev)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
hostDev, err = setTempName(hostDev)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to rename device %q to temporary name: %v", hostDevName, err)
|
||||
}
|
||||
|
||||
// restore original netdev name in case of error
|
||||
defer func() {
|
||||
if err != nil && hostDev != nil {
|
||||
_ = netlink.LinkSetName(hostDev, hostDevName)
|
||||
}
|
||||
}()
|
||||
|
||||
if err = netlink.LinkSetNsFd(hostDev, int(containerNs.Fd())); err != nil {
|
||||
return nil, fmt.Errorf("failed to move %q to container ns: %v", hostDev.Attrs().Name, err)
|
||||
}
|
||||
|
||||
var contDev netlink.Link
|
||||
if err := containerNs.Do(func(_ ns.NetNS) error {
|
||||
tempDevName := hostDev.Attrs().Name
|
||||
if err = containerNs.Do(func(_ ns.NetNS) error {
|
||||
var err error
|
||||
contDev, err = netlink.LinkByName(hostDev.Attrs().Name)
|
||||
contDev, err = netlink.LinkByName(tempDevName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find %q: %v", hostDev.Attrs().Name, err)
|
||||
}
|
||||
// Devices can be renamed only when down
|
||||
if err = netlink.LinkSetDown(contDev); err != nil {
|
||||
return fmt.Errorf("failed to set %q down: %v", hostDev.Attrs().Name, err)
|
||||
return fmt.Errorf("failed to find %q: %v", tempDevName, err)
|
||||
}
|
||||
|
||||
// move netdev back to host namespace in case of error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netlink.LinkSetNsFd(contDev, int(defaultNs.Fd()))
|
||||
// we need to get updated link object as link was moved back to host namepsace
|
||||
_ = defaultNs.Do(func(_ ns.NetNS) error {
|
||||
hostDev, _ = netlink.LinkByName(tempDevName)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
// Save host device name into the container device's alias property
|
||||
if err := netlink.LinkSetAlias(contDev, hostDev.Attrs().Name); err != nil {
|
||||
return fmt.Errorf("failed to set alias to %q: %v", hostDev.Attrs().Name, err)
|
||||
if err = netlink.LinkSetAlias(contDev, hostDevName); err != nil {
|
||||
return fmt.Errorf("failed to set alias to %q: %v", tempDevName, err)
|
||||
}
|
||||
// Rename container device to respect args.IfName
|
||||
if err := netlink.LinkSetName(contDev, ifName); err != nil {
|
||||
return fmt.Errorf("failed to rename device %q to %q: %v", hostDev.Attrs().Name, ifName, err)
|
||||
if err = netlink.LinkSetName(contDev, ifName); err != nil {
|
||||
return fmt.Errorf("failed to rename device %q to %q: %v", tempDevName, ifName, err)
|
||||
}
|
||||
|
||||
// restore tempDevName in case of error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netlink.LinkSetName(contDev, tempDevName)
|
||||
}
|
||||
}()
|
||||
|
||||
// Bring container device up
|
||||
if err = netlink.LinkSetUp(contDev); err != nil {
|
||||
return fmt.Errorf("failed to set %q up: %v", ifName, err)
|
||||
}
|
||||
|
||||
// bring device down in case of error
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = netlink.LinkSetDown(contDev)
|
||||
}
|
||||
}()
|
||||
|
||||
// Retrieve link again to get up-to-date name and attributes
|
||||
contDev, err = netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
@ -247,11 +356,14 @@ func moveLinkOut(containerNs ns.NetNS, ifName string) error {
|
||||
}
|
||||
defer defaultNs.Close()
|
||||
|
||||
return containerNs.Do(func(_ ns.NetNS) error {
|
||||
var tempName string
|
||||
var origDev netlink.Link
|
||||
err = containerNs.Do(func(_ ns.NetNS) error {
|
||||
dev, err := netlink.LinkByName(ifName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find %q: %v", ifName, err)
|
||||
}
|
||||
origDev = dev
|
||||
|
||||
// Devices can be renamed only when down
|
||||
if err = netlink.LinkSetDown(dev); err != nil {
|
||||
@ -269,16 +381,49 @@ func moveLinkOut(containerNs ns.NetNS, ifName string) error {
|
||||
}
|
||||
}()
|
||||
|
||||
// Rename the device to its original name from the host namespace
|
||||
if err = netlink.LinkSetName(dev, dev.Attrs().Alias); err != nil {
|
||||
return fmt.Errorf("failed to restore %q to original name %q: %v", ifName, dev.Attrs().Alias, err)
|
||||
newLink, err := setTempName(dev)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to rename device %q to temporary name: %v", ifName, err)
|
||||
}
|
||||
dev = newLink
|
||||
tempName = dev.Attrs().Name
|
||||
|
||||
if err = netlink.LinkSetNsFd(dev, int(defaultNs.Fd())); err != nil {
|
||||
return fmt.Errorf("failed to move %q to host netns: %v", dev.Attrs().Alias, err)
|
||||
return fmt.Errorf("failed to move %q to host netns: %v", tempName, err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rename the device to its original name from the host namespace
|
||||
tempDev, err := netlink.LinkByName(tempName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find %q in host namespace: %v", tempName, err)
|
||||
}
|
||||
|
||||
if err = netlink.LinkSetName(tempDev, tempDev.Attrs().Alias); err != nil {
|
||||
// move device back to container ns so it may be retired
|
||||
defer func() {
|
||||
_ = netlink.LinkSetNsFd(tempDev, int(containerNs.Fd()))
|
||||
_ = containerNs.Do(func(_ ns.NetNS) error {
|
||||
lnk, err := netlink.LinkByName(tempName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = netlink.LinkSetName(lnk, ifName)
|
||||
if origDev.Attrs().Flags&net.FlagUp == net.FlagUp {
|
||||
_ = netlink.LinkSetUp(lnk)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}()
|
||||
return fmt.Errorf("failed to restore %q to original name %q: %v", tempName, tempDev.Attrs().Alias, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func hasDpdkDriver(pciaddr string) (bool, error) {
|
||||
@ -314,11 +459,19 @@ func printLink(dev netlink.Link, cniVersion string, containerNs ns.NetNS) error
|
||||
return types.PrintResult(&result, cniVersion)
|
||||
}
|
||||
|
||||
func getLink(devname, hwaddr, kernelpath, pciaddr string) (netlink.Link, error) {
|
||||
links, err := netlink.LinkList()
|
||||
func linkFromPath(path string) (netlink.Link, error) {
|
||||
entries, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list node links: %v", err)
|
||||
return nil, fmt.Errorf("failed to read directory %s: %q", path, err)
|
||||
}
|
||||
if len(entries) > 0 {
|
||||
// grab the first net device
|
||||
return netlink.LinkByName(entries[0].Name())
|
||||
}
|
||||
return nil, fmt.Errorf("failed to find network device in path %s", path)
|
||||
}
|
||||
|
||||
func getLink(devname, hwaddr, kernelpath, pciaddr string, auxDev string) (netlink.Link, error) {
|
||||
switch {
|
||||
|
||||
case len(devname) > 0:
|
||||
@ -329,6 +482,11 @@ func getLink(devname, hwaddr, kernelpath, pciaddr string) (netlink.Link, error)
|
||||
return nil, fmt.Errorf("failed to parse MAC address %q: %v", hwaddr, err)
|
||||
}
|
||||
|
||||
links, err := netlink.LinkList()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list node links: %v", err)
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if bytes.Equal(link.Attrs().HardwareAddr, hwAddr) {
|
||||
return link, nil
|
||||
@ -339,20 +497,7 @@ func getLink(devname, hwaddr, kernelpath, pciaddr string) (netlink.Link, error)
|
||||
return nil, fmt.Errorf("kernel device path %q must be absolute and begin with /sys/devices/", kernelpath)
|
||||
}
|
||||
netDir := filepath.Join(kernelpath, "net")
|
||||
entries, err := os.ReadDir(netDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to find network devices at %q", netDir)
|
||||
}
|
||||
|
||||
// Grab the first device from eg /sys/devices/pci0000:00/0000:00:19.0/net
|
||||
for _, entry := range entries {
|
||||
// Make sure it's really an interface
|
||||
for _, l := range links {
|
||||
if entry.Name() == l.Attrs().Name {
|
||||
return l, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return linkFromPath(netDir)
|
||||
case len(pciaddr) > 0:
|
||||
netDir := filepath.Join(sysBusPCI, pciaddr, "net")
|
||||
if _, err := os.Lstat(netDir); err != nil {
|
||||
@ -363,14 +508,10 @@ func getLink(devname, hwaddr, kernelpath, pciaddr string) (netlink.Link, error)
|
||||
}
|
||||
netDir = matches[0]
|
||||
}
|
||||
entries, err := os.ReadDir(netDir)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read net directory %s: %q", netDir, err)
|
||||
}
|
||||
if len(entries) > 0 {
|
||||
return netlink.LinkByName(entries[0].Name())
|
||||
}
|
||||
return nil, fmt.Errorf("failed to find device name for pci address %s", pciaddr)
|
||||
return linkFromPath(netDir)
|
||||
case len(auxDev) > 0:
|
||||
netDir := filepath.Join(sysBusAuxiliary, auxDev, "net")
|
||||
return linkFromPath(netDir)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("failed to find physical interface")
|
||||
|
@ -898,6 +898,71 @@ var _ = Describe("base functionality", func() {
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config on auxiliary device", ver), func() {
|
||||
var origLink netlink.Link
|
||||
ifname := "eth0"
|
||||
|
||||
fs := &fakeFilesystem{
|
||||
dirs: []string{
|
||||
fmt.Sprintf("sys/bus/auxiliary/devices/mlx5_core.sf.4/net/%s", ifname),
|
||||
},
|
||||
}
|
||||
defer fs.use()()
|
||||
|
||||
// prepare ifname in original namespace
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err := netlink.LinkAdd(&netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: ifname,
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
origLink, err = netlink.LinkByName(ifname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = netlink.LinkSetUp(origLink)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
|
||||
// call CmdAdd
|
||||
cniName := "net1"
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-host-device-test",
|
||||
"type": "host-device",
|
||||
"runtimeConfig": {"deviceID": %q}
|
||||
}`, ver, "mlx5_core.sf.4")
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
IfName: cniName,
|
||||
Netns: targetNS.Path(),
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
var resI types.Result
|
||||
err := originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
var err error
|
||||
resI, _, err = testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// check that the result was sane
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// call CmdDel
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err = testutils.CmdDelWithArgs(args, func() error {
|
||||
return cmdDel(args)
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Works with a valid %s config with IPAM", ver), func() {
|
||||
var origLink netlink.Link
|
||||
|
||||
@ -1149,6 +1214,114 @@ var _ = Describe("base functionality", func() {
|
||||
return nil
|
||||
})
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("Test CmdAdd/Del when additioinal interface alreay exists in container ns with same name. %s config", ver), func() {
|
||||
var (
|
||||
origLink netlink.Link
|
||||
containerLink netlink.Link
|
||||
)
|
||||
|
||||
hostIfname := "eth0"
|
||||
containerAdditionalIfname := "eth0"
|
||||
|
||||
// prepare host device in original namespace
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err := netlink.LinkAdd(&netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: hostIfname,
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
origLink, err = netlink.LinkByName(hostIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = netlink.LinkSetUp(origLink)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
|
||||
// prepare device in container namespace with same name as host device
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err := netlink.LinkAdd(&netlink.Dummy{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: containerAdditionalIfname,
|
||||
},
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
containerLink, err = netlink.LinkByName(containerAdditionalIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = netlink.LinkSetUp(containerLink)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
|
||||
// call CmdAdd
|
||||
cniName := "net1"
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-host-device-test",
|
||||
"type": "host-device",
|
||||
"device": %q
|
||||
}`, ver, hostIfname)
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: targetNS.Path(),
|
||||
IfName: cniName,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
var resI types.Result
|
||||
err := originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
var err error
|
||||
resI, _, err = testutils.CmdAddWithArgs(args, func() error { return cmdAdd(args) })
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// check that the result was sane
|
||||
t := newTesterByVersion(ver)
|
||||
t.expectInterfaces(resI, cniName, origLink.Attrs().HardwareAddr.String(), targetNS.Path())
|
||||
|
||||
// assert that host device is now in the target namespace and is up
|
||||
_ = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(cniName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(origLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
|
||||
// call CmdDel, expect it to succeed
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
err = testutils.CmdDelWithArgs(args, func() error {
|
||||
return cmdDel(args)
|
||||
})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
|
||||
// assert container interface "eth0" still exists in target namespace and is up
|
||||
err = targetNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
link, err := netlink.LinkByName(containerAdditionalIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(link.Attrs().HardwareAddr).To(Equal(containerLink.Attrs().HardwareAddr))
|
||||
Expect(link.Attrs().Flags & net.FlagUp).To(Equal(net.FlagUp))
|
||||
return nil
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// assert that host device is now back in the original namespace
|
||||
_ = originalNS.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
_, err := netlink.LinkByName(hostIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
return nil
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
@ -1181,6 +1354,7 @@ func (fs *fakeFilesystem) use() func() {
|
||||
}
|
||||
|
||||
sysBusPCI = path.Join(fs.rootDir, "/sys/bus/pci/devices")
|
||||
sysBusAuxiliary = path.Join(fs.rootDir, "/sys/bus/auxiliary/devices")
|
||||
|
||||
return func() {
|
||||
// remove temporary fake fs
|
||||
|
@ -334,7 +334,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -411,7 +411,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -371,7 +371,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -244,7 +244,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -499,7 +499,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
StdinData: []byte(fmt.Sprintf(confFmt, ver, masterInterface, 1600, isInContainer, dataDir)),
|
||||
}
|
||||
|
||||
_ = originalNS.Do(func(netNS ns.NetNS) error {
|
||||
_ = originalNS.Do(func(_ ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err = testutils.CmdAddWithArgs(args, func() error {
|
||||
@ -520,7 +520,7 @@ var _ = Describe("vlan Operations", func() {
|
||||
StdinData: []byte(fmt.Sprintf(confFmt, ver, masterInterface, -100, isInContainer, dataDir)),
|
||||
}
|
||||
|
||||
_ = originalNS.Do(func(netNS ns.NetNS) error {
|
||||
_ = originalNS.Do(func(_ ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err = testutils.CmdAddWithArgs(args, func() error {
|
||||
|
563
plugins/meta/bandwidth/bandwidth_config_test.go
Normal file
563
plugins/meta/bandwidth/bandwidth_config_test.go
Normal file
@ -0,0 +1,563 @@
|
||||
// Copyright 2023 CNI 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
"syscall"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
)
|
||||
|
||||
var _ = Describe("bandwidth config test", func() {
|
||||
var (
|
||||
hostNs ns.NetNS
|
||||
containerNs ns.NetNS
|
||||
ifbDeviceName string
|
||||
hostIfname string
|
||||
containerIfname string
|
||||
hostIP net.IP
|
||||
containerIP net.IP
|
||||
hostIfaceMTU int
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
|
||||
hostIfname = "host-veth"
|
||||
containerIfname = "container-veth"
|
||||
|
||||
hostNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
hostIP = net.IP{169, 254, 0, 1}
|
||||
containerIP = net.IP{10, 254, 0, 1}
|
||||
hostIfaceMTU = 1024
|
||||
ifbDeviceName = "bwpa8eda89404b7"
|
||||
|
||||
createVeth(hostNs, hostIfname, containerNs, containerIfname, hostIP, containerIP, hostIfaceMTU)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(containerNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerNs)).To(Succeed())
|
||||
Expect(hostNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(hostNs)).To(Succeed())
|
||||
})
|
||||
|
||||
// Bandwidth requires host-side interface info, and thus only
|
||||
// supports 0.3.0 and later CNI versions
|
||||
for _, ver := range []string{"0.3.0", "0.3.1", "0.4.0", "1.0.0"} {
|
||||
// Redefine ver inside for scope so real value is picked up by each dynamically defined It()
|
||||
// See Gingkgo's "Patterns for dynamically generating tests" documentation.
|
||||
ver := ver
|
||||
|
||||
Describe("cmdADD", func() {
|
||||
It(fmt.Sprintf("[%s] fails with invalid UnshapedSubnets", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 123,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"unshapedSubnets": ["10.0.0.0/8", "hello"],
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("bad subnet \"hello\" provided, details invalid CIDR address: hello"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] fails with invalid ShapedSubnets", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 123,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"ShapedSubnets": ["10.0.0.0/8", "hello"],
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("bad subnet \"hello\" provided, details invalid CIDR address: hello"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] fails with both ShapedSubnets and UnshapedSubnets specified", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 123,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"shapedSubnets": ["10.0.0.0/8"],
|
||||
"unshapedSubnets": ["192.168.0.0/16"],
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("unshapedSubnets and shapedSubnets cannot be both specified, one of them should be discarded"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] fails an invalid ingress config", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("if burst is set, rate must also be set"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] fails an invalid egress config", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 123,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 0,
|
||||
"egressBurst": 123,
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("if burst is set, rate must also be set"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
// Runtime config parameters are expected to be preempted by the global config ones whenever specified
|
||||
It(fmt.Sprintf("[%s] should apply static config when both static config and runtime config exist", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
"ingressBurst": 0,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"unshapedSubnets": ["192.168.0.0/24"],
|
||||
"runtimeConfig": {
|
||||
"bandWidth": {
|
||||
"ingressRate": 8,
|
||||
"ingressBurst": 8,
|
||||
"egressRate": 16,
|
||||
"egressBurst": 9,
|
||||
"unshapedSubnets": ["10.0.0.0/8", "fd00:db8:abcd:1234:e000::/68"]
|
||||
}
|
||||
},
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: containerIfname,
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
r, out, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
result, err := types100.GetResult(r)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(result.Interfaces).To(HaveLen(3))
|
||||
Expect(result.Interfaces[2].Name).To(Equal(ifbDeviceName))
|
||||
Expect(result.Interfaces[2].Sandbox).To(Equal(""))
|
||||
|
||||
ifbLink, err := netlink.LinkByName(ifbDeviceName)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(ifbLink.Attrs().MTU).To(Equal(hostIfaceMTU))
|
||||
|
||||
qdiscs, err := netlink.QdiscList(ifbLink)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(qdiscs).To(HaveLen(1))
|
||||
Expect(qdiscs[0].Attrs().LinkIndex).To(Equal(ifbLink.Attrs().Index))
|
||||
Expect(qdiscs[0]).To(BeAssignableToTypeOf(&netlink.Htb{}))
|
||||
Expect(qdiscs[0].(*netlink.Htb).Defcls).To(Equal(uint32(ShapedClassMinorID)))
|
||||
|
||||
classes, err := netlink.ClassList(ifbLink, qdiscs[0].Attrs().Handle)
|
||||
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(classes).To(HaveLen(2))
|
||||
|
||||
// Uncapped class
|
||||
Expect(classes[0]).To(BeAssignableToTypeOf(&netlink.HtbClass{}))
|
||||
Expect(classes[0].(*netlink.HtbClass).Handle).To(Equal(netlink.MakeHandle(1, 1)))
|
||||
Expect(classes[0].(*netlink.HtbClass).Rate).To(Equal(UncappedRate))
|
||||
Expect(classes[0].(*netlink.HtbClass).Buffer).To(Equal(uint32(0)))
|
||||
Expect(classes[0].(*netlink.HtbClass).Ceil).To(Equal(UncappedRate))
|
||||
Expect(classes[0].(*netlink.HtbClass).Cbuffer).To(Equal(uint32(0)))
|
||||
|
||||
// Class with traffic shapping settings
|
||||
Expect(classes[1]).To(BeAssignableToTypeOf(&netlink.HtbClass{}))
|
||||
Expect(classes[1].(*netlink.HtbClass).Handle).To(Equal(netlink.MakeHandle(1, uint16(qdiscs[0].(*netlink.Htb).Defcls))))
|
||||
Expect(classes[1].(*netlink.HtbClass).Rate).To(Equal(uint64(15)))
|
||||
// Expect(classes[1].(*netlink.HtbClass).Buffer).To(Equal(uint32(7812500)))
|
||||
Expect(classes[1].(*netlink.HtbClass).Ceil).To(Equal(uint64(30)))
|
||||
// Expect(classes[1].(*netlink.HtbClass).Cbuffer).To(Equal(uint32(0)))
|
||||
|
||||
filters, err := netlink.FilterList(ifbLink, qdiscs[0].Attrs().Handle)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(filters).To(HaveLen(1))
|
||||
|
||||
// traffic to 192.168.0.0/24 redirected to uncapped class
|
||||
Expect(filters[0]).To(BeAssignableToTypeOf(&netlink.U32{}))
|
||||
Expect(filters[0].(*netlink.U32).Actions).To(BeEmpty())
|
||||
Expect(filters[0].Attrs().Protocol).To(Equal(uint16(syscall.ETH_P_IP)))
|
||||
Expect(filters[0].Attrs().LinkIndex).To(Equal(ifbLink.Attrs().Index))
|
||||
Expect(filters[0].Attrs().Priority).To(Equal(uint16(16)))
|
||||
Expect(filters[0].Attrs().Parent).To(Equal(qdiscs[0].Attrs().Handle))
|
||||
Expect(filters[0].(*netlink.U32).ClassId).To(Equal(netlink.MakeHandle(1, 1)))
|
||||
|
||||
filterSel := filters[0].(*netlink.U32).Sel
|
||||
Expect(filterSel).To(BeAssignableToTypeOf(&netlink.TcU32Sel{}))
|
||||
Expect(filterSel.Flags).To(Equal(uint8(netlink.TC_U32_TERMINAL)))
|
||||
Expect(filterSel.Keys).To(HaveLen(1))
|
||||
Expect(filterSel.Nkeys).To(Equal(uint8(1)))
|
||||
|
||||
// The filter should match to 192.168.0.0/24 dst address in other words it should be:
|
||||
// match c0a80000/ffffff00 at 16
|
||||
selKey := filterSel.Keys[0]
|
||||
Expect(selKey.Val).To(Equal(uint32(192*math.Pow(256, 3) + 168*math.Pow(256, 2))))
|
||||
Expect(selKey.Off).To(Equal(int32(16)))
|
||||
Expect(selKey.Mask).To(Equal(uint32(255*math.Pow(256, 3) + 255*math.Pow(256, 2) + 255*256)))
|
||||
|
||||
hostVethLink, err := netlink.LinkByName(hostIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
qdiscFilters, err := netlink.FilterList(hostVethLink, netlink.MakeHandle(0xffff, 0))
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Expect(qdiscFilters).To(HaveLen(1))
|
||||
Expect(qdiscFilters[0].(*netlink.U32).Actions[0].(*netlink.MirredAction).Ifindex).To(Equal(ifbLink.Attrs().Index))
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
// Container ingress (host egress)
|
||||
Expect(hostNs.Do(func(n ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
vethLink, err := netlink.LinkByName(hostIfname)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
qdiscs, err := netlink.QdiscList(vethLink)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
// No ingress QoS just mirroring
|
||||
Expect(qdiscs).To(HaveLen(2))
|
||||
Expect(qdiscs[0].Attrs().LinkIndex).To(Equal(vethLink.Attrs().Index))
|
||||
Expect(qdiscs[0]).NotTo(BeAssignableToTypeOf(&netlink.Htb{}))
|
||||
Expect(qdiscs[1]).NotTo(BeAssignableToTypeOf(&netlink.Htb{}))
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
|
||||
It(fmt.Sprintf("[%s] should apply static config when both static config and runtime config exist (bad config example)", ver), func() {
|
||||
conf := fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "cni-plugin-bandwidth-test",
|
||||
"type": "bandwidth",
|
||||
"ingressRate": 0,
|
||||
"ingressBurst": 123,
|
||||
"egressRate": 123,
|
||||
"egressBurst": 123,
|
||||
"runtimeConfig": {
|
||||
"bandWidth": {
|
||||
"ingressRate": 8,
|
||||
"ingressBurst": 8,
|
||||
"egressRate": 16,
|
||||
"egressBurst": 9
|
||||
}
|
||||
},
|
||||
"prevResult": {
|
||||
"interfaces": [
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": ""
|
||||
},
|
||||
{
|
||||
"name": "%s",
|
||||
"sandbox": "%s"
|
||||
}
|
||||
],
|
||||
"ips": [
|
||||
{
|
||||
"version": "4",
|
||||
"address": "%s/24",
|
||||
"gateway": "10.0.0.1",
|
||||
"interface": 1
|
||||
}
|
||||
],
|
||||
"routes": []
|
||||
}
|
||||
}`, ver, hostIfname, containerIfname, containerNs.Path(), containerIP.String())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy",
|
||||
Netns: containerNs.Path(),
|
||||
IfName: "eth0",
|
||||
StdinData: []byte(conf),
|
||||
}
|
||||
|
||||
Expect(hostNs.Do(func(netNS ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
_, _, err := testutils.CmdAdd(containerNs.Path(), args.ContainerID, "", []byte(conf), func() error { return cmdAdd(args) })
|
||||
Expect(err).To(MatchError("if burst is set, rate must also be set"))
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
Describe("Validating input", func() {
|
||||
It("Should allow only 4GB burst rate", func() {
|
||||
err := validateRateAndBurst(5000, 4*1024*1024*1024*8-16) // 2 bytes less than the max should pass
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
err = validateRateAndBurst(5000, 4*1024*1024*1024*8) // we're 1 bit above MaxUint32
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 1)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(1, 0)
|
||||
Expect(err).To(HaveOccurred())
|
||||
err = validateRateAndBurst(0, 0)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Should fail if both ShapedSubnets and UnshapedSubnets are specified", func() {
|
||||
err := validateSubnets([]string{"10.0.0.0/8"}, []string{"192.168.0.0/24"})
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Should fail if specified UnshapedSubnets are not valid CIDRs", func() {
|
||||
err := validateSubnets([]string{"10.0.0.0/8", "hello"}, []string{})
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
|
||||
It("Should fail if specified ShapedSubnets are not valid CIDRs", func() {
|
||||
err := validateSubnets([]string{}, []string{"10.0.0.0/8", "hello"})
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
})
|
File diff suppressed because it is too large
Load Diff
824
plugins/meta/bandwidth/bandwidth_measure_linux_test.go
Normal file
824
plugins/meta/bandwidth/bandwidth_measure_linux_test.go
Normal file
@ -0,0 +1,824 @@
|
||||
// Copyright 2023 CNI 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 main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gexec"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/invoke"
|
||||
"github.com/containernetworking/cni/pkg/skel"
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
types100 "github.com/containernetworking/cni/pkg/types/100"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
"github.com/containernetworking/plugins/pkg/testutils"
|
||||
)
|
||||
|
||||
var _ = Describe("bandwidth measure test", func() {
|
||||
var (
|
||||
hostNs ns.NetNS
|
||||
containerNs ns.NetNS
|
||||
hostIfname string
|
||||
containerIfname string
|
||||
hostIP net.IP
|
||||
containerIP net.IP
|
||||
hostIfaceMTU int
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
|
||||
hostIfname = "host-veth"
|
||||
containerIfname = "container-veth"
|
||||
|
||||
hostNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerNs, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
hostIP = net.IP{169, 254, 0, 1}
|
||||
containerIP = net.IP{10, 254, 0, 1}
|
||||
hostIfaceMTU = 1024
|
||||
|
||||
createVeth(hostNs, hostIfname, containerNs, containerIfname, hostIP, containerIP, hostIfaceMTU)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(containerNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerNs)).To(Succeed())
|
||||
Expect(hostNs.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(hostNs)).To(Succeed())
|
||||
})
|
||||
|
||||
// Bandwidth requires host-side interface info, and thus only
|
||||
// supports 0.3.0 and later CNI versions
|
||||
for _, ver := range []string{"0.3.0", "0.3.1", "0.4.0", "1.0.0"} {
|
||||
Describe(fmt.Sprintf("[%s] QoS effective", ver), func() {
|
||||
Context(fmt.Sprintf("[%s] when chaining bandwidth plugin with PTP", ver), func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
var packetInBytes int
|
||||
var containerWithoutQoSNS ns.NetNS
|
||||
var containerWithQoSNS ns.NetNS
|
||||
var portServerWithQoS int
|
||||
var portServerWithoutQoS int
|
||||
|
||||
var containerWithQoSRes types.Result
|
||||
var containerWithoutQoSRes types.Result
|
||||
var echoServerWithQoS *gexec.Session
|
||||
var echoServerWithoutQoS *gexec.Session
|
||||
var dataDir string
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
rateInBits = uint64(rateInBytes * 8)
|
||||
burstInBits = rateInBits * 2
|
||||
|
||||
// NOTE: Traffic shapping is not that precise at low rates, would be better to use higher rates + simple time+netcat for data transfer, rather than the provided
|
||||
// client/server bin (limited to small amount of data)
|
||||
packetInBytes = rateInBytes * 3
|
||||
|
||||
var err error
|
||||
dataDir, err = os.MkdirTemp("", "bandwidth_linux_test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ptpConf = fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "myBWnet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "%s"
|
||||
}
|
||||
}`, ver, dataDir)
|
||||
|
||||
const (
|
||||
containerWithQoSIFName = "ptp0"
|
||||
containerWithoutQoSIFName = "ptp1"
|
||||
)
|
||||
|
||||
containerWithQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
Expect(hostNs.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
containerWithQoSRes, _, err = testutils.CmdAdd(containerWithQoSNS.Path(), "dummy", containerWithQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSRes, _, err = testutils.CmdAdd(containerWithoutQoSNS.Path(), "dummy2", containerWithoutQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithQoSResult, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &bandwidthPluginConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
}
|
||||
bandwidthPluginConf.Type = "bandwidth"
|
||||
newConfBytes, err := buildOneConfig(ver, bandwidthPluginConf, containerWithQoSResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newConfBytes,
|
||||
}
|
||||
|
||||
result, out, err := testutils.CmdAdd(containerWithQoSNS.Path(), args.ContainerID, "", newConfBytes, func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
// Do CNI Check
|
||||
checkConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &checkConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
checkConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
}
|
||||
checkConf.Type = "bandwidth"
|
||||
|
||||
newCheckBytes, err := buildOneConfig(ver, checkConf, result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args = &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newCheckBytes,
|
||||
}
|
||||
|
||||
err = testutils.CmdCheck(containerWithQoSNS.Path(), args.ContainerID, "", func() error { return cmdCheck(args) })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
By("starting a tcp server on both containers")
|
||||
portServerWithQoS, echoServerWithQoS = startEchoServerInNamespace(containerWithQoSNS)
|
||||
portServerWithoutQoS, echoServerWithoutQoS = startEchoServerInNamespace(containerWithoutQoSNS)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(os.RemoveAll(dataDir)).To(Succeed())
|
||||
|
||||
Expect(containerWithQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithQoSNS)).To(Succeed())
|
||||
Expect(containerWithoutQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithoutQoSNS)).To(Succeed())
|
||||
|
||||
if echoServerWithoutQoS != nil {
|
||||
echoServerWithoutQoS.Kill()
|
||||
}
|
||||
if echoServerWithQoS != nil {
|
||||
echoServerWithQoS.Kill()
|
||||
}
|
||||
})
|
||||
|
||||
It("limits ingress traffic on veth device", func() {
|
||||
var runtimeWithLimit time.Duration
|
||||
var runtimeWithoutLimit time.Duration
|
||||
|
||||
By("gather timing statistics about both containers")
|
||||
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithLimit = end.Sub(start)
|
||||
log.Printf("Elapsed with qos %.2f", runtimeWithLimit.Seconds())
|
||||
})
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithoutQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithoutLimit = end.Sub(start)
|
||||
log.Printf("Elapsed without qos %.2f", runtimeWithoutLimit.Seconds())
|
||||
})
|
||||
|
||||
Expect(runtimeWithLimit).To(BeNumerically(">", runtimeWithoutLimit+1000*time.Millisecond))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Context(fmt.Sprintf("[%s] when chaining bandwidth plugin with PTP and excluding specific subnets from traffic", ver), func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
var packetInBytes int
|
||||
var containerWithoutQoSNS ns.NetNS
|
||||
var containerWithQoSNS ns.NetNS
|
||||
var portServerWithQoS int
|
||||
var portServerWithoutQoS int
|
||||
|
||||
var containerWithQoSRes types.Result
|
||||
var containerWithoutQoSRes types.Result
|
||||
var echoServerWithQoS *gexec.Session
|
||||
var echoServerWithoutQoS *gexec.Session
|
||||
var dataDir string
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
rateInBits = uint64(rateInBytes * 8)
|
||||
burstInBits = rateInBits * 2
|
||||
unshapedSubnets := []string{"10.1.2.0/24"}
|
||||
// NOTE: Traffic shapping is not that precise at low rates, would be better to use higher rates + simple time+netcat for data transfer, rather than the provided
|
||||
// client/server bin (limited to small amount of data)
|
||||
packetInBytes = rateInBytes * 3
|
||||
|
||||
var err error
|
||||
dataDir, err = os.MkdirTemp("", "bandwidth_linux_test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ptpConf = fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "myBWnet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "%s"
|
||||
}
|
||||
}`, ver, dataDir)
|
||||
|
||||
const (
|
||||
containerWithQoSIFName = "ptp0"
|
||||
containerWithoutQoSIFName = "ptp1"
|
||||
)
|
||||
|
||||
containerWithQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
Expect(hostNs.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
containerWithQoSRes, _, err = testutils.CmdAdd(containerWithQoSNS.Path(), "dummy", containerWithQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSRes, _, err = testutils.CmdAdd(containerWithoutQoSNS.Path(), "dummy2", containerWithoutQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithQoSResult, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &bandwidthPluginConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
UnshapedSubnets: unshapedSubnets,
|
||||
}
|
||||
bandwidthPluginConf.Type = "bandwidth"
|
||||
newConfBytes, err := buildOneConfig(ver, bandwidthPluginConf, containerWithQoSResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newConfBytes,
|
||||
}
|
||||
|
||||
result, out, err := testutils.CmdAdd(containerWithQoSNS.Path(), args.ContainerID, "", newConfBytes, func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
// Do CNI Check
|
||||
checkConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &checkConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
checkConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
UnshapedSubnets: unshapedSubnets,
|
||||
}
|
||||
checkConf.Type = "bandwidth"
|
||||
|
||||
newCheckBytes, err := buildOneConfig(ver, checkConf, result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args = &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newCheckBytes,
|
||||
}
|
||||
|
||||
err = testutils.CmdCheck(containerWithQoSNS.Path(), args.ContainerID, "", func() error { return cmdCheck(args) })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
By("starting a tcp server on both containers")
|
||||
portServerWithQoS, echoServerWithQoS = startEchoServerInNamespace(containerWithQoSNS)
|
||||
portServerWithoutQoS, echoServerWithoutQoS = startEchoServerInNamespace(containerWithoutQoSNS)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(os.RemoveAll(dataDir)).To(Succeed())
|
||||
|
||||
Expect(containerWithQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithQoSNS)).To(Succeed())
|
||||
Expect(containerWithoutQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithoutQoSNS)).To(Succeed())
|
||||
|
||||
if echoServerWithoutQoS != nil {
|
||||
echoServerWithoutQoS.Kill()
|
||||
}
|
||||
if echoServerWithQoS != nil {
|
||||
echoServerWithQoS.Kill()
|
||||
}
|
||||
})
|
||||
|
||||
It("does not limits ingress traffic on veth device coming from 10.1.2.0/24", func() {
|
||||
var runtimeWithLimit time.Duration
|
||||
var runtimeWithoutLimit time.Duration
|
||||
|
||||
By("gather timing statistics about both containers")
|
||||
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithLimit = end.Sub(start)
|
||||
log.Printf("Elapsed with qos %.2f", runtimeWithLimit.Seconds())
|
||||
})
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithoutQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithoutLimit = end.Sub(start)
|
||||
log.Printf("Elapsed without qos %.2f", runtimeWithoutLimit.Seconds())
|
||||
})
|
||||
|
||||
Expect(runtimeWithLimit - runtimeWithoutLimit).To(BeNumerically("<", 100*time.Millisecond))
|
||||
})
|
||||
})
|
||||
|
||||
Context(fmt.Sprintf("[%s] when chaining bandwidth plugin with PTP and only including specific subnets in traffic shapping (not including the main ns one)", ver), func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
var packetInBytes int
|
||||
var containerWithoutQoSNS ns.NetNS
|
||||
var containerWithQoSNS ns.NetNS
|
||||
var portServerWithQoS int
|
||||
var portServerWithoutQoS int
|
||||
|
||||
var containerWithQoSRes types.Result
|
||||
var containerWithoutQoSRes types.Result
|
||||
var echoServerWithQoS *gexec.Session
|
||||
var echoServerWithoutQoS *gexec.Session
|
||||
var dataDir string
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
rateInBits = uint64(rateInBytes * 8)
|
||||
burstInBits = rateInBits * 2
|
||||
shapedSubnets := []string{"10.2.2.0/24"}
|
||||
// NOTE: Traffic shapping is not that precise at low rates, would be better to use higher rates + simple time+netcat for data transfer, rather than the provided
|
||||
// client/server bin (limited to small amount of data)
|
||||
packetInBytes = rateInBytes * 3
|
||||
|
||||
var err error
|
||||
dataDir, err = os.MkdirTemp("", "bandwidth_linux_test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ptpConf = fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "myBWnet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "%s"
|
||||
}
|
||||
}`, ver, dataDir)
|
||||
|
||||
const (
|
||||
containerWithQoSIFName = "ptp0"
|
||||
containerWithoutQoSIFName = "ptp1"
|
||||
)
|
||||
|
||||
containerWithQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
|
||||
Expect(hostNs.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
containerWithQoSRes, _, err = testutils.CmdAdd(containerWithQoSNS.Path(), "dummy", containerWithQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSRes, _, err = testutils.CmdAdd(containerWithoutQoSNS.Path(), "dummy2", containerWithoutQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithQoSResult, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &bandwidthPluginConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
ShapedSubnets: shapedSubnets,
|
||||
}
|
||||
bandwidthPluginConf.Type = "bandwidth"
|
||||
newConfBytes, err := buildOneConfig(ver, bandwidthPluginConf, containerWithQoSResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newConfBytes,
|
||||
}
|
||||
|
||||
result, out, err := testutils.CmdAdd(containerWithQoSNS.Path(), args.ContainerID, "", newConfBytes, func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
// Do CNI Check
|
||||
checkConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &checkConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
checkConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
ShapedSubnets: shapedSubnets,
|
||||
}
|
||||
checkConf.Type = "bandwidth"
|
||||
|
||||
newCheckBytes, err := buildOneConfig(ver, checkConf, result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args = &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newCheckBytes,
|
||||
}
|
||||
|
||||
err = testutils.CmdCheck(containerWithQoSNS.Path(), args.ContainerID, "", func() error { return cmdCheck(args) })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
By("starting a tcp server on both containers")
|
||||
portServerWithQoS, echoServerWithQoS = startEchoServerInNamespace(containerWithQoSNS)
|
||||
portServerWithoutQoS, echoServerWithoutQoS = startEchoServerInNamespace(containerWithoutQoSNS)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(os.RemoveAll(dataDir)).To(Succeed())
|
||||
|
||||
Expect(containerWithQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithQoSNS)).To(Succeed())
|
||||
Expect(containerWithoutQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithoutQoSNS)).To(Succeed())
|
||||
|
||||
if echoServerWithoutQoS != nil {
|
||||
echoServerWithoutQoS.Kill()
|
||||
}
|
||||
if echoServerWithQoS != nil {
|
||||
echoServerWithQoS.Kill()
|
||||
}
|
||||
})
|
||||
|
||||
It("does not limit ingress traffic on veth device coming from non included subnets", func() {
|
||||
var runtimeWithLimit time.Duration
|
||||
var runtimeWithoutLimit time.Duration
|
||||
|
||||
By("gather timing statistics about both containers")
|
||||
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithLimit = end.Sub(start)
|
||||
log.Printf("Elapsed with qos %.2f", runtimeWithLimit.Seconds())
|
||||
})
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithoutQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithoutLimit = end.Sub(start)
|
||||
log.Printf("Elapsed without qos %.2f", runtimeWithoutLimit.Seconds())
|
||||
})
|
||||
|
||||
Expect(runtimeWithLimit - runtimeWithoutLimit).To(BeNumerically("<", 100*time.Millisecond))
|
||||
})
|
||||
})
|
||||
|
||||
Context(fmt.Sprintf("[%s] when chaining bandwidth plugin with PTP and only including specific subnets in traffic shapping (including the main ns one)", ver), func() {
|
||||
var ptpConf string
|
||||
var rateInBits uint64
|
||||
var burstInBits uint64
|
||||
var packetInBytes int
|
||||
var containerWithoutQoSNS ns.NetNS
|
||||
var containerWithQoSNS ns.NetNS
|
||||
var portServerWithQoS int
|
||||
var portServerWithoutQoS int
|
||||
|
||||
var containerWithQoSRes types.Result
|
||||
var containerWithoutQoSRes types.Result
|
||||
var echoServerWithQoS *gexec.Session
|
||||
var echoServerWithoutQoS *gexec.Session
|
||||
var dataDir string
|
||||
|
||||
BeforeEach(func() {
|
||||
rateInBytes := 1000
|
||||
rateInBits = uint64(rateInBytes * 8)
|
||||
burstInBits = rateInBits * 2
|
||||
shapedSubnets := []string{"10.1.2.1/32"}
|
||||
// NOTE: Traffic shapping is not that precise at low rates, would be better to use higher rates + simple time+netcat for data transfer, rather than the provided
|
||||
// client/server bin (limited to small amount of data)
|
||||
packetInBytes = rateInBytes * 3
|
||||
|
||||
var err error
|
||||
dataDir, err = os.MkdirTemp("", "bandwidth_linux_test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
ptpConf = fmt.Sprintf(`{
|
||||
"cniVersion": "%s",
|
||||
"name": "myBWnet",
|
||||
"type": "ptp",
|
||||
"ipMasq": true,
|
||||
"mtu": 512,
|
||||
"ipam": {
|
||||
"type": "host-local",
|
||||
"subnet": "10.1.2.0/24",
|
||||
"dataDir": "%s"
|
||||
}
|
||||
}`, ver, dataDir)
|
||||
|
||||
const (
|
||||
containerWithQoSIFName = "ptp0"
|
||||
containerWithoutQoSIFName = "ptp1"
|
||||
)
|
||||
|
||||
containerWithQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSNS, err = testutils.NewNS()
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
By("create two containers, and use the bandwidth plugin on one of them")
|
||||
|
||||
Expect(hostNs.Do(func(ns.NetNS) error {
|
||||
defer GinkgoRecover()
|
||||
|
||||
containerWithQoSRes, _, err = testutils.CmdAdd(containerWithQoSNS.Path(), "dummy", containerWithQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithoutQoSRes, _, err = testutils.CmdAdd(containerWithoutQoSNS.Path(), "dummy2", containerWithoutQoSIFName, []byte(ptpConf), func() error {
|
||||
r, err := invoke.DelegateAdd(context.TODO(), "ptp", []byte(ptpConf), nil)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(r.Print()).To(Succeed())
|
||||
|
||||
return err
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
containerWithQoSResult, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &bandwidthPluginConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
bandwidthPluginConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
ShapedSubnets: shapedSubnets,
|
||||
}
|
||||
bandwidthPluginConf.Type = "bandwidth"
|
||||
newConfBytes, err := buildOneConfig(ver, bandwidthPluginConf, containerWithQoSResult)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args := &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newConfBytes,
|
||||
}
|
||||
|
||||
result, out, err := testutils.CmdAdd(containerWithQoSNS.Path(), args.ContainerID, "", newConfBytes, func() error { return cmdAdd(args) })
|
||||
Expect(err).NotTo(HaveOccurred(), string(out))
|
||||
|
||||
if testutils.SpecVersionHasCHECK(ver) {
|
||||
// Do CNI Check
|
||||
checkConf := &PluginConf{}
|
||||
err = json.Unmarshal([]byte(ptpConf), &checkConf)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
checkConf.RuntimeConfig.Bandwidth = &BandwidthEntry{
|
||||
IngressBurst: burstInBits,
|
||||
IngressRate: rateInBits,
|
||||
EgressBurst: burstInBits,
|
||||
EgressRate: rateInBits,
|
||||
ShapedSubnets: shapedSubnets,
|
||||
}
|
||||
checkConf.Type = "bandwidth"
|
||||
|
||||
newCheckBytes, err := buildOneConfig(ver, checkConf, result)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
args = &skel.CmdArgs{
|
||||
ContainerID: "dummy3",
|
||||
Netns: containerWithQoSNS.Path(),
|
||||
IfName: containerWithQoSIFName,
|
||||
StdinData: newCheckBytes,
|
||||
}
|
||||
|
||||
err = testutils.CmdCheck(containerWithQoSNS.Path(), args.ContainerID, "", func() error { return cmdCheck(args) })
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
return nil
|
||||
})).To(Succeed())
|
||||
|
||||
By("starting a tcp server on both containers")
|
||||
portServerWithQoS, echoServerWithQoS = startEchoServerInNamespace(containerWithQoSNS)
|
||||
portServerWithoutQoS, echoServerWithoutQoS = startEchoServerInNamespace(containerWithoutQoSNS)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
Expect(os.RemoveAll(dataDir)).To(Succeed())
|
||||
|
||||
Expect(containerWithQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithQoSNS)).To(Succeed())
|
||||
Expect(containerWithoutQoSNS.Close()).To(Succeed())
|
||||
Expect(testutils.UnmountNS(containerWithoutQoSNS)).To(Succeed())
|
||||
|
||||
if echoServerWithoutQoS != nil {
|
||||
echoServerWithoutQoS.Kill()
|
||||
}
|
||||
if echoServerWithQoS != nil {
|
||||
echoServerWithQoS.Kill()
|
||||
}
|
||||
})
|
||||
|
||||
It("limits ingress traffic on veth device coming from included subnets", func() {
|
||||
var runtimeWithLimit time.Duration
|
||||
var runtimeWithoutLimit time.Duration
|
||||
|
||||
By("gather timing statistics about both containers")
|
||||
|
||||
By("sending tcp traffic to the container that has traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithLimit = end.Sub(start)
|
||||
log.Printf("Elapsed with qos %.2f", runtimeWithLimit.Seconds())
|
||||
})
|
||||
|
||||
By("sending tcp traffic to the container that does not have traffic shaped", func() {
|
||||
start := time.Now()
|
||||
result, err := types100.GetResult(containerWithoutQoSRes)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
makeTCPClientInNS(hostNs.Path(), result.IPs[0].Address.IP.String(), portServerWithoutQoS, packetInBytes)
|
||||
end := time.Now()
|
||||
runtimeWithoutLimit = end.Sub(start)
|
||||
log.Printf("Elapsed without qos %.2f", runtimeWithoutLimit.Seconds())
|
||||
})
|
||||
|
||||
Expect(runtimeWithLimit).To(BeNumerically(">", runtimeWithoutLimit+1000*time.Millisecond))
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
@ -15,6 +15,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@ -30,10 +31,11 @@ import (
|
||||
"github.com/onsi/gomega/gexec"
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
"github.com/containernetworking/cni/pkg/types"
|
||||
"github.com/containernetworking/plugins/pkg/ns"
|
||||
)
|
||||
|
||||
func TestTBF(t *testing.T) {
|
||||
func TestHTB(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "plugins/meta/bandwidth")
|
||||
}
|
||||
@ -243,3 +245,47 @@ func createMacvlan(netNS ns.NetNS, master, macvlanName string) {
|
||||
})
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
}
|
||||
|
||||
func buildOneConfig(cniVersion string, orig *PluginConf, prevResult types.Result) ([]byte, error) {
|
||||
var err error
|
||||
|
||||
inject := map[string]interface{}{
|
||||
"name": "myBWnet",
|
||||
"cniVersion": cniVersion,
|
||||
}
|
||||
// Add previous plugin result
|
||||
if prevResult != nil {
|
||||
r, err := prevResult.GetAsVersion(cniVersion)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
inject["prevResult"] = r
|
||||
}
|
||||
|
||||
// Ensure every config uses the same name and version
|
||||
config := make(map[string]interface{})
|
||||
|
||||
confBytes, err := json.Marshal(orig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(confBytes, &config)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
|
||||
}
|
||||
|
||||
for key, value := range inject {
|
||||
config[key] = value
|
||||
}
|
||||
|
||||
newBytes, err := json.Marshal(config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
conf := &PluginConf{}
|
||||
if err := json.Unmarshal(newBytes, &conf); err != nil {
|
||||
return nil, fmt.Errorf("error parsing configuration: %s", err)
|
||||
}
|
||||
|
||||
return newBytes, nil
|
||||
}
|
||||
|
@ -15,6 +15,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"net"
|
||||
"syscall"
|
||||
@ -24,14 +26,24 @@ import (
|
||||
"github.com/containernetworking/plugins/pkg/ip"
|
||||
)
|
||||
|
||||
const latencyInMillis = 25
|
||||
const (
|
||||
latencyInMillis = 25
|
||||
UncappedRate uint64 = 100_000_000_000
|
||||
ShapedClassMinorID uint16 = 48
|
||||
UnShapedClassMinorID uint16 = 1
|
||||
)
|
||||
|
||||
func CreateIfb(ifbDeviceName string, mtu int, qlen int) error {
|
||||
if qlen < 1000 {
|
||||
qlen = 1000
|
||||
}
|
||||
|
||||
func CreateIfb(ifbDeviceName string, mtu int) error {
|
||||
err := netlink.LinkAdd(&netlink.Ifb{
|
||||
LinkAttrs: netlink.LinkAttrs{
|
||||
Name: ifbDeviceName,
|
||||
Flags: net.FlagUp,
|
||||
MTU: mtu,
|
||||
Name: ifbDeviceName,
|
||||
Flags: net.FlagUp,
|
||||
MTU: mtu,
|
||||
TxQLen: qlen,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
@ -49,15 +61,24 @@ func TeardownIfb(deviceName string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func CreateIngressQdisc(rateInBits, burstInBits uint64, hostDeviceName string) error {
|
||||
func CreateIngressQdisc(rateInBits, burstInBits uint64, excludeSubnets []string, includeSubnets []string, hostDeviceName string) error {
|
||||
hostDevice, err := netlink.LinkByName(hostDeviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get host device: %s", err)
|
||||
}
|
||||
return createTBF(rateInBits, burstInBits, hostDevice.Attrs().Index)
|
||||
|
||||
subnets := includeSubnets
|
||||
exclude := false
|
||||
|
||||
if len(excludeSubnets) > 0 {
|
||||
subnets = excludeSubnets
|
||||
exclude = true
|
||||
}
|
||||
|
||||
return createHTB(rateInBits, burstInBits, hostDevice.Attrs().Index, subnets, exclude)
|
||||
}
|
||||
|
||||
func CreateEgressQdisc(rateInBits, burstInBits uint64, hostDeviceName string, ifbDeviceName string) error {
|
||||
func CreateEgressQdisc(rateInBits, burstInBits uint64, excludeSubnets []string, includeSubnets []string, hostDeviceName string, ifbDeviceName string) error {
|
||||
ifbDevice, err := netlink.LinkByName(ifbDeviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get ifb device: %s", err)
|
||||
@ -104,44 +125,216 @@ func CreateEgressQdisc(rateInBits, burstInBits uint64, hostDeviceName string, if
|
||||
return fmt.Errorf("add filter: %s", err)
|
||||
}
|
||||
|
||||
subnets := excludeSubnets
|
||||
exclude := true
|
||||
|
||||
if len(includeSubnets) > 0 {
|
||||
subnets = includeSubnets
|
||||
exclude = false
|
||||
}
|
||||
|
||||
// throttle traffic on ifb device
|
||||
err = createTBF(rateInBits, burstInBits, ifbDevice.Attrs().Index)
|
||||
err = createHTB(rateInBits, burstInBits, ifbDevice.Attrs().Index, subnets, exclude)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create ifb qdisc: %s", err)
|
||||
// egress from the container/netns pov = ingress from the main netns/host pov
|
||||
return fmt.Errorf("create htb container egress qos rules: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func createTBF(rateInBits, burstInBits uint64, linkIndex int) error {
|
||||
// Equivalent to
|
||||
// tc qdisc add dev link root tbf
|
||||
// rate netConf.BandwidthLimits.Rate
|
||||
// burst netConf.BandwidthLimits.Burst
|
||||
if rateInBits <= 0 {
|
||||
return fmt.Errorf("invalid rate: %d", rateInBits)
|
||||
}
|
||||
if burstInBits <= 0 {
|
||||
return fmt.Errorf("invalid burst: %d", burstInBits)
|
||||
}
|
||||
rateInBytes := rateInBits / 8
|
||||
burstInBytes := burstInBits / 8
|
||||
bufferInBytes := buffer(rateInBytes, uint32(burstInBytes))
|
||||
latency := latencyInUsec(latencyInMillis)
|
||||
limitInBytes := limit(rateInBytes, latency, uint32(burstInBytes))
|
||||
func createHTB(rateInBits, burstInBits uint64, linkIndex int, subnets []string, excludeSubnets bool) error {
|
||||
// Netlink struct fields are not clear, let's use shell
|
||||
|
||||
qdisc := &netlink.Tbf{
|
||||
defaultClassID := UnShapedClassMinorID
|
||||
// If no subnets are specified, then shaping should apply to everything
|
||||
if len(subnets) == 0 || excludeSubnets {
|
||||
defaultClassID = ShapedClassMinorID
|
||||
}
|
||||
|
||||
// Step 1 qdisc
|
||||
// cmd := exec.Command("/usr/sbin/tc", "qdisc", "add", "dev", interfaceName, "root", "handle", "1:", "htb", "default", "30")
|
||||
qdisc := &netlink.Htb{
|
||||
QdiscAttrs: netlink.QdiscAttrs{
|
||||
LinkIndex: linkIndex,
|
||||
Handle: netlink.MakeHandle(1, 0),
|
||||
Parent: netlink.HANDLE_ROOT,
|
||||
},
|
||||
Limit: limitInBytes,
|
||||
Rate: rateInBytes,
|
||||
Buffer: bufferInBytes,
|
||||
Defcls: uint32(defaultClassID),
|
||||
// No idea what these are so let's keep the default values from source code...
|
||||
Version: 3,
|
||||
Rate2Quantum: 10,
|
||||
}
|
||||
err := netlink.QdiscAdd(qdisc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create qdisc: %s", err)
|
||||
return fmt.Errorf("error while creating qdisc: %s", err)
|
||||
}
|
||||
|
||||
// Step 2 classes
|
||||
|
||||
rateInBytes := rateInBits / 8
|
||||
burstInBytes := burstInBits / 8
|
||||
bufferInBytes := buffer(rateInBytes, uint32(burstInBytes))
|
||||
|
||||
// The capped class for shaped traffic (included subnets or all but excluded subnets)
|
||||
// cmd = exec.Command("/usr/sbin/tc", "class", "add", "dev", interfaceName, "parent", "1:", "classid", "1:30", "htb", "rate",
|
||||
// fmt.Sprintf("%d", rateInBits), "burst", fmt.Sprintf("%d", burstInBits))
|
||||
shapedClass := &netlink.HtbClass{
|
||||
ClassAttrs: netlink.ClassAttrs{
|
||||
LinkIndex: linkIndex,
|
||||
Handle: netlink.MakeHandle(1, ShapedClassMinorID),
|
||||
Parent: netlink.MakeHandle(1, 0),
|
||||
},
|
||||
Rate: rateInBytes,
|
||||
Buffer: bufferInBytes,
|
||||
// Let's set up the "burst" rate to twice the specified rate
|
||||
Ceil: 2 * rateInBytes,
|
||||
Cbuffer: bufferInBytes,
|
||||
}
|
||||
|
||||
err = netlink.ClassAdd(shapedClass)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while creating htb default class: %s", err)
|
||||
}
|
||||
|
||||
// The uncapped class for non shaped traffic (either all but included subnets or excluded subnets only)
|
||||
// cmd = exec.Command("/usr/sbin/tc", "class", "add", "dev", interfaceName, "parent", "1:", "classid", "1:1", "htb",
|
||||
// "rate", "100000000000")
|
||||
bigRate := UncappedRate
|
||||
unshapedClass := &netlink.HtbClass{
|
||||
ClassAttrs: netlink.ClassAttrs{
|
||||
LinkIndex: linkIndex,
|
||||
Handle: netlink.MakeHandle(1, UnShapedClassMinorID),
|
||||
Parent: qdisc.Handle,
|
||||
},
|
||||
Rate: bigRate,
|
||||
Ceil: bigRate,
|
||||
// No need for any burst, the minimum buffer size in q_htb.c should be enough to handle the rate which
|
||||
// is already more than enough
|
||||
}
|
||||
err = netlink.ClassAdd(unshapedClass)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while creating htb uncapped class: %s", err)
|
||||
}
|
||||
|
||||
// Now add filters to redirect subnets to the class 1 if excluded instead of the default one (30)
|
||||
for _, subnet := range subnets {
|
||||
|
||||
// cmd = exec.Command("/usr/sbin/tc", "filter", "add", "dev", interfaceName, "parent", "1:", "protocol", protocol,
|
||||
// "prio", "16", "u32", "match", "ip", "dst", subnet, "flowid", "1:1")
|
||||
_, nw, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad subnet %s: %s", subnet, err)
|
||||
}
|
||||
var maskBytes []byte = nw.Mask
|
||||
var subnetBytes []byte = nw.IP
|
||||
|
||||
if len(maskBytes) != len(subnetBytes) {
|
||||
return fmt.Errorf("error using net lib for subnet %s len(maskBytes) != len(subnetBytes) "+
|
||||
"(%d != %d) should not happen", subnet, len(maskBytes), len(subnetBytes))
|
||||
}
|
||||
|
||||
isIpv4 := nw.IP.To4() != nil
|
||||
protocol := syscall.ETH_P_IPV6
|
||||
var prio uint16 = 15
|
||||
var offset int32 = 24
|
||||
keepBytes := 16
|
||||
if isIpv4 {
|
||||
protocol = syscall.ETH_P_IP
|
||||
offset = 16
|
||||
keepBytes = 4
|
||||
// prio/pref needs to be changed if we change the protocol, looks like we cannot mix protocols with the same pref
|
||||
prio = 16
|
||||
}
|
||||
|
||||
if len(maskBytes) < keepBytes {
|
||||
return fmt.Errorf("error with net lib, unexpected count of bytes for ipv4 mask (%d < %d)",
|
||||
len(maskBytes), keepBytes)
|
||||
}
|
||||
if len(subnetBytes) < keepBytes {
|
||||
return fmt.Errorf("error with net lib, unexpected count of bytes for ipv4 subnet (%d < %d)",
|
||||
len(subnetBytes), keepBytes)
|
||||
}
|
||||
maskBytes = maskBytes[len(maskBytes)-keepBytes:]
|
||||
subnetBytes = subnetBytes[len(subnetBytes)-keepBytes:]
|
||||
|
||||
// For ipv4 we should have at most 1 key, for ipv6 at most 4
|
||||
keys := make([]netlink.TcU32Key, 0, 4)
|
||||
|
||||
for i := 0; i < len(maskBytes); i += 4 {
|
||||
var mask, subnetI uint32
|
||||
buf := bytes.NewReader(maskBytes[i : i+4])
|
||||
err = binary.Read(buf, binary.BigEndian, &mask)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error, htb filter, unable to build mask match filter, iter %d for subnet %s",
|
||||
i, subnet)
|
||||
}
|
||||
|
||||
if mask != 0 {
|
||||
// If mask == 0, any value on this section will be a match and we do not need a filter for this
|
||||
buf = bytes.NewReader(subnetBytes[i : i+4])
|
||||
err = binary.Read(buf, binary.BigEndian, &subnetI)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error, htb filter, unable to build subnet match filter, iter %d for subnet %s",
|
||||
i, subnet)
|
||||
}
|
||||
keys = append(keys, netlink.TcU32Key{
|
||||
Mask: mask,
|
||||
Val: subnetI,
|
||||
Off: offset,
|
||||
OffMask: 0,
|
||||
})
|
||||
}
|
||||
|
||||
offset += 4
|
||||
}
|
||||
|
||||
if len(keys) != cap(keys) {
|
||||
shrinkedKeys := make([]netlink.TcU32Key, len(keys))
|
||||
copied := copy(shrinkedKeys, keys)
|
||||
if copied != len(keys) {
|
||||
return fmt.Errorf("copy tc u32 keys error, for subnet %s copied %d != keys %d", subnet, copied, len(keys))
|
||||
}
|
||||
keys = shrinkedKeys
|
||||
}
|
||||
|
||||
if isIpv4 && len(keys) > 1 {
|
||||
return fmt.Errorf("error, htb ipv4 filter, unexpected rule length (%d > 1), for subnet %s",
|
||||
len(keys), subnet)
|
||||
} else if len(keys) > 4 {
|
||||
return fmt.Errorf("error, htb ipv6 filter, unexpected rule length (%d > 4), for subnet %s",
|
||||
len(keys), subnet)
|
||||
}
|
||||
|
||||
// If len(keys) == 0, it means that we want to wildcard all traffic on the non default/uncapped class
|
||||
var selector *netlink.TcU32Sel
|
||||
if len(keys) > 0 {
|
||||
selector = &netlink.TcU32Sel{
|
||||
Nkeys: uint8(len(keys)),
|
||||
Flags: netlink.TC_U32_TERMINAL,
|
||||
Keys: keys,
|
||||
}
|
||||
}
|
||||
|
||||
classID := shapedClass.Handle
|
||||
if excludeSubnets {
|
||||
classID = unshapedClass.Handle
|
||||
}
|
||||
|
||||
tcFilter := netlink.U32{
|
||||
FilterAttrs: netlink.FilterAttrs{
|
||||
LinkIndex: linkIndex,
|
||||
Parent: qdisc.Handle,
|
||||
Priority: prio,
|
||||
Protocol: uint16(protocol),
|
||||
},
|
||||
ClassId: classID,
|
||||
Sel: selector,
|
||||
}
|
||||
|
||||
err = netlink.FilterAdd(&tcFilter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error, unable to create htb filter, details %s", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -153,11 +346,3 @@ func time2Tick(time uint32) uint32 {
|
||||
func buffer(rate uint64, burst uint32) uint32 {
|
||||
return time2Tick(uint32(float64(burst) * float64(netlink.TIME_UNITS_PER_SEC) / float64(rate)))
|
||||
}
|
||||
|
||||
func limit(rate uint64, latency float64, buffer uint32) uint32 {
|
||||
return uint32(float64(rate)*latency/float64(netlink.TIME_UNITS_PER_SEC)) + buffer
|
||||
}
|
||||
|
||||
func latencyInUsec(latencyInMillis float64) float64 {
|
||||
return float64(netlink.TIME_UNITS_PER_SEC) * (latencyInMillis / 1000.0)
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"net"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
|
||||
@ -39,11 +40,12 @@ const (
|
||||
// BandwidthEntry corresponds to a single entry in the bandwidth argument,
|
||||
// see CONVENTIONS.md
|
||||
type BandwidthEntry struct {
|
||||
IngressRate uint64 `json:"ingressRate"` // Bandwidth rate in bps for traffic through container. 0 for no limit. If ingressRate is set, ingressBurst must also be set
|
||||
IngressBurst uint64 `json:"ingressBurst"` // Bandwidth burst in bits for traffic through container. 0 for no limit. If ingressBurst is set, ingressRate must also be set
|
||||
|
||||
EgressRate uint64 `json:"egressRate"` // Bandwidth rate in bps for traffic through container. 0 for no limit. If egressRate is set, egressBurst must also be set
|
||||
EgressBurst uint64 `json:"egressBurst"` // Bandwidth burst in bits for traffic through container. 0 for no limit. If egressBurst is set, egressRate must also be set
|
||||
UnshapedSubnets []string `json:"unshapedSubnets"` // Ipv4/ipv6 subnets to be excluded from traffic shaping. UnshapedSubnets and ShapedSubnets parameters are mutually exlusive
|
||||
ShapedSubnets []string `json:"shapedSubnets"` // Ipv4/ipv6 subnets to be included in traffic shaping. UnshapedSubnets and ShapedSubnets parameters are mutually exlusive
|
||||
IngressRate uint64 `json:"ingressRate"` // Bandwidth rate in bps for traffic through container. 0 for no limit. If ingressRate is set, ingressBurst must also be set
|
||||
IngressBurst uint64 `json:"ingressBurst"` // Bandwidth burst in bits for traffic through container. 0 for no limit. If ingressBurst is set, ingressRate must also be set
|
||||
EgressRate uint64 `json:"egressRate"` // Bandwidth rate in bps for traffic through container. 0 for no limit. If egressRate is set, egressBurst must also be set
|
||||
EgressBurst uint64 `json:"egressBurst"` // Bandwidth burst in bits for traffic through container. 0 for no limit. If egressBurst is set, egressRate must also be set
|
||||
}
|
||||
|
||||
func (bw *BandwidthEntry) isZero() bool {
|
||||
@ -96,10 +98,21 @@ func parseConfig(stdin []byte) (*PluginConf, error) {
|
||||
}
|
||||
|
||||
func getBandwidth(conf *PluginConf) *BandwidthEntry {
|
||||
if conf.BandwidthEntry == nil && conf.RuntimeConfig.Bandwidth != nil {
|
||||
return conf.RuntimeConfig.Bandwidth
|
||||
bw := conf.BandwidthEntry
|
||||
if bw == nil && conf.RuntimeConfig.Bandwidth != nil {
|
||||
bw = conf.RuntimeConfig.Bandwidth
|
||||
}
|
||||
return conf.BandwidthEntry
|
||||
|
||||
if bw != nil {
|
||||
if bw.UnshapedSubnets == nil {
|
||||
bw.UnshapedSubnets = make([]string, 0)
|
||||
}
|
||||
if bw.ShapedSubnets == nil {
|
||||
bw.ShapedSubnets = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
return bw
|
||||
}
|
||||
|
||||
func validateRateAndBurst(rate, burst uint64) error {
|
||||
@ -119,13 +132,13 @@ func getIfbDeviceName(networkName string, containerID string) string {
|
||||
return utils.MustFormatHashWithPrefix(maxIfbDeviceLength, ifbDevicePrefix, networkName+containerID)
|
||||
}
|
||||
|
||||
func getMTU(deviceName string) (int, error) {
|
||||
func getMTUAndQLen(deviceName string) (int, int, error) {
|
||||
link, err := netlink.LinkByName(deviceName)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
return -1, -1, err
|
||||
}
|
||||
|
||||
return link.Attrs().MTU, nil
|
||||
return link.Attrs().MTU, link.Attrs().TxQLen, nil
|
||||
}
|
||||
|
||||
// get the veth peer of container interface in host namespace
|
||||
@ -159,6 +172,28 @@ func getHostInterface(interfaces []*current.Interface, containerIfName string, n
|
||||
return nil, fmt.Errorf("no veth peer of container interface found in host ns")
|
||||
}
|
||||
|
||||
func validateSubnets(unshapedSubnets []string, shapedSubnets []string) error {
|
||||
if len(unshapedSubnets) > 0 && len(shapedSubnets) > 0 {
|
||||
return fmt.Errorf("unshapedSubnets and shapedSubnets cannot be both specified, one of them should be discarded")
|
||||
}
|
||||
|
||||
for _, subnet := range unshapedSubnets {
|
||||
_, _, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad subnet %q provided, details %s", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, subnet := range shapedSubnets {
|
||||
_, _, err := net.ParseCIDR(subnet)
|
||||
if err != nil {
|
||||
return fmt.Errorf("bad subnet %q provided, details %s", subnet, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cmdAdd(args *skel.CmdArgs) error {
|
||||
conf, err := parseConfig(args.StdinData)
|
||||
if err != nil {
|
||||
@ -170,6 +205,10 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
return types.PrintResult(conf.PrevResult, conf.CNIVersion)
|
||||
}
|
||||
|
||||
if err = validateSubnets(bandwidth.UnshapedSubnets, bandwidth.ShapedSubnets); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if conf.PrevResult == nil {
|
||||
return fmt.Errorf("must be called as chained plugin")
|
||||
}
|
||||
@ -191,21 +230,22 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
|
||||
if bandwidth.IngressRate > 0 && bandwidth.IngressBurst > 0 {
|
||||
err = CreateIngressQdisc(bandwidth.IngressRate, bandwidth.IngressBurst, hostInterface.Name)
|
||||
err = CreateIngressQdisc(bandwidth.IngressRate, bandwidth.IngressBurst,
|
||||
bandwidth.UnshapedSubnets, bandwidth.ShapedSubnets, hostInterface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if bandwidth.EgressRate > 0 && bandwidth.EgressBurst > 0 {
|
||||
mtu, err := getMTU(hostInterface.Name)
|
||||
mtu, qlen, err := getMTUAndQLen(hostInterface.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ifbDeviceName := getIfbDeviceName(conf.Name, args.ContainerID)
|
||||
|
||||
err = CreateIfb(ifbDeviceName, mtu)
|
||||
err = CreateIfb(ifbDeviceName, mtu, qlen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -219,7 +259,9 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
Name: ifbDeviceName,
|
||||
Mac: ifbDevice.Attrs().HardwareAddr.String(),
|
||||
})
|
||||
err = CreateEgressQdisc(bandwidth.EgressRate, bandwidth.EgressBurst, hostInterface.Name, ifbDeviceName)
|
||||
err = CreateEgressQdisc(bandwidth.EgressRate, bandwidth.EgressBurst,
|
||||
bandwidth.UnshapedSubnets, bandwidth.ShapedSubnets, hostInterface.Name,
|
||||
ifbDeviceName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -292,75 +334,99 @@ func cmdCheck(args *skel.CmdArgs) error {
|
||||
|
||||
bandwidth := getBandwidth(bwConf)
|
||||
|
||||
if err = validateSubnets(bandwidth.UnshapedSubnets, bandwidth.ShapedSubnets); err != nil {
|
||||
return fmt.Errorf("failed to check subnets, details %s", err)
|
||||
}
|
||||
|
||||
if bandwidth.IngressRate > 0 && bandwidth.IngressBurst > 0 {
|
||||
rateInBytes := bandwidth.IngressRate / 8
|
||||
burstInBytes := bandwidth.IngressBurst / 8
|
||||
bufferInBytes := buffer(rateInBytes, uint32(burstInBytes))
|
||||
latency := latencyInUsec(latencyInMillis)
|
||||
limitInBytes := limit(rateInBytes, latency, uint32(burstInBytes))
|
||||
|
||||
qdiscs, err := SafeQdiscList(link)
|
||||
err = checkHTB(link, rateInBytes, bufferInBytes, bandwidth.ShapedSubnets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(qdiscs) == 0 {
|
||||
return fmt.Errorf("Failed to find qdisc")
|
||||
}
|
||||
|
||||
for _, qdisc := range qdiscs {
|
||||
tbf, isTbf := qdisc.(*netlink.Tbf)
|
||||
if !isTbf {
|
||||
break
|
||||
}
|
||||
if tbf.Rate != rateInBytes {
|
||||
return fmt.Errorf("Rate doesn't match")
|
||||
}
|
||||
if tbf.Limit != limitInBytes {
|
||||
return fmt.Errorf("Limit doesn't match")
|
||||
}
|
||||
if tbf.Buffer != bufferInBytes {
|
||||
return fmt.Errorf("Buffer doesn't match")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if bandwidth.EgressRate > 0 && bandwidth.EgressBurst > 0 {
|
||||
rateInBytes := bandwidth.EgressRate / 8
|
||||
burstInBytes := bandwidth.EgressBurst / 8
|
||||
bufferInBytes := buffer(rateInBytes, uint32(burstInBytes))
|
||||
latency := latencyInUsec(latencyInMillis)
|
||||
limitInBytes := limit(rateInBytes, latency, uint32(burstInBytes))
|
||||
|
||||
ifbDeviceName := getIfbDeviceName(bwConf.Name, args.ContainerID)
|
||||
|
||||
ifbDevice, err := netlink.LinkByName(ifbDeviceName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get ifb device: %s", err)
|
||||
}
|
||||
|
||||
qdiscs, err := SafeQdiscList(ifbDevice)
|
||||
err = checkHTB(ifbDevice, rateInBytes, bufferInBytes, bandwidth.ShapedSubnets)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(qdiscs) == 0 {
|
||||
return fmt.Errorf("Failed to find qdisc")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkHTB(link netlink.Link, rateInBytes uint64, bufferInBytes uint32, shapedSubnets []string) error {
|
||||
qdiscs, err := SafeQdiscList(link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(qdiscs) == 0 {
|
||||
return fmt.Errorf("Failed to find qdisc")
|
||||
}
|
||||
foundHTB := false
|
||||
for _, qdisc := range qdiscs {
|
||||
htb, isHtb := qdisc.(*netlink.Htb)
|
||||
if !isHtb {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, qdisc := range qdiscs {
|
||||
tbf, isTbf := qdisc.(*netlink.Tbf)
|
||||
if !isTbf {
|
||||
break
|
||||
if foundHTB {
|
||||
return fmt.Errorf("Several htb qdisc found for device %s", link.Attrs().Name)
|
||||
}
|
||||
|
||||
foundHTB = true
|
||||
defaultClassMinorID := ShapedClassMinorID
|
||||
if len(shapedSubnets) > 0 {
|
||||
defaultClassMinorID = UnShapedClassMinorID
|
||||
}
|
||||
|
||||
if htb.Defcls != uint32(defaultClassMinorID) {
|
||||
return fmt.Errorf("Default class does not match")
|
||||
}
|
||||
|
||||
classes, err := netlink.ClassList(link, htb.Handle)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Unable to list classes bound to htb qdisc for device %s. Details %s",
|
||||
link.Attrs().Name, err)
|
||||
}
|
||||
if len(classes) != 2 {
|
||||
return fmt.Errorf("Number of htb classes does not match for device %s (%d != 2)",
|
||||
link.Attrs().Name, len(classes))
|
||||
}
|
||||
|
||||
for _, c := range classes {
|
||||
htbClass, isHtb := c.(*netlink.HtbClass)
|
||||
if !isHtb {
|
||||
return fmt.Errorf("Unexpected class for parent htb qdisc bound to device %s", link.Attrs().Name)
|
||||
}
|
||||
if tbf.Rate != rateInBytes {
|
||||
return fmt.Errorf("Rate doesn't match")
|
||||
}
|
||||
if tbf.Limit != limitInBytes {
|
||||
return fmt.Errorf("Limit doesn't match")
|
||||
}
|
||||
if tbf.Buffer != bufferInBytes {
|
||||
return fmt.Errorf("Buffer doesn't match")
|
||||
if htbClass.Handle == htb.Defcls {
|
||||
if htbClass.Rate != rateInBytes {
|
||||
return fmt.Errorf("Rate does not match for the default class for device %s (%d != %d)",
|
||||
link.Attrs().Name, htbClass.Rate, rateInBytes)
|
||||
}
|
||||
|
||||
if htbClass.Buffer != bufferInBytes {
|
||||
return fmt.Errorf("Burst buffer size does not match for the default class for device %s (%d != %d)",
|
||||
link.Attrs().Name, htbClass.Buffer, bufferInBytes)
|
||||
}
|
||||
} else if htbClass.Handle == netlink.MakeHandle(1, 1) {
|
||||
if htbClass.Rate != UncappedRate {
|
||||
return fmt.Errorf("Rate does not match for the uncapped class for device %s (%d != %d)",
|
||||
link.Attrs().Name, htbClass.Rate, UncappedRate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check subnet filters
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -66,7 +66,6 @@ func withLockAndNetNS(nspath string, toRun func(_ ns.NetNS) error) error {
|
||||
}
|
||||
|
||||
err = ns.WithNetNSPath(nspath, toRun)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -75,7 +75,6 @@ func cmdAdd(args *skel.CmdArgs) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("cmdAdd failed: %v", err)
|
||||
}
|
||||
@ -121,7 +120,6 @@ func cmdDel(args *skel.CmdArgs) error {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
// if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
|
||||
// so don't return an error if the device is already removed.
|
||||
|
@ -3,7 +3,7 @@ set -xe
|
||||
|
||||
SRC_DIR="${SRC_DIR:-$PWD}"
|
||||
DOCKER="${DOCKER:-docker}"
|
||||
GOLANG="${GOLANG:-golang:1.21-alpine}"
|
||||
GOLANG="${GOLANG:-golang:1.22-alpine}"
|
||||
|
||||
TAG=$(git describe --tags --dirty)
|
||||
RELEASE_DIR=release-${TAG}
|
||||
|
10
vendor/github.com/Microsoft/go-winio/.golangci.yml
generated
vendored
10
vendor/github.com/Microsoft/go-winio/.golangci.yml
generated
vendored
@ -1,7 +1,3 @@
|
||||
run:
|
||||
skip-dirs:
|
||||
- pkg/etw/sample
|
||||
|
||||
linters:
|
||||
enable:
|
||||
# style
|
||||
@ -20,9 +16,13 @@ linters:
|
||||
- gofmt # files are gofmt'ed
|
||||
- gosec # security
|
||||
- nilerr # returns nil even with non-nil error
|
||||
- thelper # test helpers without t.Helper()
|
||||
- unparam # unused function params
|
||||
|
||||
issues:
|
||||
exclude-dirs:
|
||||
- pkg/etw/sample
|
||||
|
||||
exclude-rules:
|
||||
# err is very often shadowed in nested scopes
|
||||
- linters:
|
||||
@ -69,9 +69,7 @@ linters-settings:
|
||||
# struct order is often for Win32 compat
|
||||
# also, ignore pointer bytes/GC issues for now until performance becomes an issue
|
||||
- fieldalignment
|
||||
check-shadowing: true
|
||||
nolintlint:
|
||||
allow-leading-space: false
|
||||
require-explanation: true
|
||||
require-specific: true
|
||||
revive:
|
||||
|
33
vendor/github.com/Microsoft/go-winio/backup.go
generated
vendored
33
vendor/github.com/Microsoft/go-winio/backup.go
generated
vendored
@ -10,14 +10,14 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
|
||||
"github.com/Microsoft/go-winio/internal/fs"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//sys backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
|
||||
//sys backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
|
||||
//sys backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead
|
||||
//sys backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite
|
||||
|
||||
const (
|
||||
BackupData = uint32(iota + 1)
|
||||
@ -104,7 +104,7 @@ func (r *BackupStreamReader) Next() (*BackupHeader, error) {
|
||||
if err := binary.Read(r.r, binary.LittleEndian, name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hdr.Name = syscall.UTF16ToString(name)
|
||||
hdr.Name = windows.UTF16ToString(name)
|
||||
}
|
||||
if wsi.StreamID == BackupSparseBlock {
|
||||
if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil {
|
||||
@ -205,7 +205,7 @@ func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader {
|
||||
// Read reads a backup stream from the file by calling the Win32 API BackupRead().
|
||||
func (r *BackupFileReader) Read(b []byte) (int, error) {
|
||||
var bytesRead uint32
|
||||
err := backupRead(syscall.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
|
||||
err := backupRead(windows.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err}
|
||||
}
|
||||
@ -220,7 +220,7 @@ func (r *BackupFileReader) Read(b []byte) (int, error) {
|
||||
// the underlying file.
|
||||
func (r *BackupFileReader) Close() error {
|
||||
if r.ctx != 0 {
|
||||
_ = backupRead(syscall.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
|
||||
_ = backupRead(windows.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx)
|
||||
runtime.KeepAlive(r.f)
|
||||
r.ctx = 0
|
||||
}
|
||||
@ -244,7 +244,7 @@ func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter {
|
||||
// Write restores a portion of the file using the provided backup stream.
|
||||
func (w *BackupFileWriter) Write(b []byte) (int, error) {
|
||||
var bytesWritten uint32
|
||||
err := backupWrite(syscall.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
|
||||
err := backupWrite(windows.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err}
|
||||
}
|
||||
@ -259,7 +259,7 @@ func (w *BackupFileWriter) Write(b []byte) (int, error) {
|
||||
// close the underlying file.
|
||||
func (w *BackupFileWriter) Close() error {
|
||||
if w.ctx != 0 {
|
||||
_ = backupWrite(syscall.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
|
||||
_ = backupWrite(windows.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx)
|
||||
runtime.KeepAlive(w.f)
|
||||
w.ctx = 0
|
||||
}
|
||||
@ -271,17 +271,14 @@ func (w *BackupFileWriter) Close() error {
|
||||
//
|
||||
// If the file opened was a directory, it cannot be used with Readdir().
|
||||
func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) {
|
||||
winPath, err := syscall.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
h, err := syscall.CreateFile(&winPath[0],
|
||||
access,
|
||||
share,
|
||||
h, err := fs.CreateFile(path,
|
||||
fs.AccessMask(access),
|
||||
fs.FileShareMode(share),
|
||||
nil,
|
||||
createmode,
|
||||
syscall.FILE_FLAG_BACKUP_SEMANTICS|syscall.FILE_FLAG_OPEN_REPARSE_POINT,
|
||||
0)
|
||||
fs.FileCreationDisposition(createmode),
|
||||
fs.FILE_FLAG_BACKUP_SEMANTICS|fs.FILE_FLAG_OPEN_REPARSE_POINT,
|
||||
0,
|
||||
)
|
||||
if err != nil {
|
||||
err = &os.PathError{Op: "open", Path: path, Err: err}
|
||||
return nil, err
|
||||
|
85
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
85
vendor/github.com/Microsoft/go-winio/file.go
generated
vendored
@ -15,26 +15,11 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
//sys cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) = CancelIoEx
|
||||
//sys createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) = CreateIoCompletionPort
|
||||
//sys getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||
//sys setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||
//sys wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
|
||||
|
||||
type atomicBool int32
|
||||
|
||||
func (b *atomicBool) isSet() bool { return atomic.LoadInt32((*int32)(b)) != 0 }
|
||||
func (b *atomicBool) setFalse() { atomic.StoreInt32((*int32)(b), 0) }
|
||||
func (b *atomicBool) setTrue() { atomic.StoreInt32((*int32)(b), 1) }
|
||||
|
||||
//revive:disable-next-line:predeclared Keep "new" to maintain consistency with "atomic" pkg
|
||||
func (b *atomicBool) swap(new bool) bool {
|
||||
var newInt int32
|
||||
if new {
|
||||
newInt = 1
|
||||
}
|
||||
return atomic.SwapInt32((*int32)(b), newInt) == 1
|
||||
}
|
||||
//sys cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) = CancelIoEx
|
||||
//sys createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) = CreateIoCompletionPort
|
||||
//sys getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus
|
||||
//sys setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes
|
||||
//sys wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult
|
||||
|
||||
var (
|
||||
ErrFileClosed = errors.New("file has already been closed")
|
||||
@ -50,7 +35,7 @@ func (*timeoutError) Temporary() bool { return true }
|
||||
type timeoutChan chan struct{}
|
||||
|
||||
var ioInitOnce sync.Once
|
||||
var ioCompletionPort syscall.Handle
|
||||
var ioCompletionPort windows.Handle
|
||||
|
||||
// ioResult contains the result of an asynchronous IO operation.
|
||||
type ioResult struct {
|
||||
@ -60,12 +45,12 @@ type ioResult struct {
|
||||
|
||||
// ioOperation represents an outstanding asynchronous Win32 IO.
|
||||
type ioOperation struct {
|
||||
o syscall.Overlapped
|
||||
o windows.Overlapped
|
||||
ch chan ioResult
|
||||
}
|
||||
|
||||
func initIO() {
|
||||
h, err := createIoCompletionPort(syscall.InvalidHandle, 0, 0, 0xffffffff)
|
||||
h, err := createIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -76,10 +61,10 @@ func initIO() {
|
||||
// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall.
|
||||
// It takes ownership of this handle and will close it if it is garbage collected.
|
||||
type win32File struct {
|
||||
handle syscall.Handle
|
||||
handle windows.Handle
|
||||
wg sync.WaitGroup
|
||||
wgLock sync.RWMutex
|
||||
closing atomicBool
|
||||
closing atomic.Bool
|
||||
socket bool
|
||||
readDeadline deadlineHandler
|
||||
writeDeadline deadlineHandler
|
||||
@ -90,11 +75,11 @@ type deadlineHandler struct {
|
||||
channel timeoutChan
|
||||
channelLock sync.RWMutex
|
||||
timer *time.Timer
|
||||
timedout atomicBool
|
||||
timedout atomic.Bool
|
||||
}
|
||||
|
||||
// makeWin32File makes a new win32File from an existing file handle.
|
||||
func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||
func makeWin32File(h windows.Handle) (*win32File, error) {
|
||||
f := &win32File{handle: h}
|
||||
ioInitOnce.Do(initIO)
|
||||
_, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff)
|
||||
@ -110,7 +95,12 @@ func makeWin32File(h syscall.Handle) (*win32File, error) {
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// Deprecated: use NewOpenFile instead.
|
||||
func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||
return NewOpenFile(windows.Handle(h))
|
||||
}
|
||||
|
||||
func NewOpenFile(h windows.Handle) (io.ReadWriteCloser, error) {
|
||||
// If we return the result of makeWin32File directly, it can result in an
|
||||
// interface-wrapped nil, rather than a nil interface value.
|
||||
f, err := makeWin32File(h)
|
||||
@ -124,13 +114,13 @@ func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) {
|
||||
func (f *win32File) closeHandle() {
|
||||
f.wgLock.Lock()
|
||||
// Atomically set that we are closing, releasing the resources only once.
|
||||
if !f.closing.swap(true) {
|
||||
if !f.closing.Swap(true) {
|
||||
f.wgLock.Unlock()
|
||||
// cancel all IO and wait for it to complete
|
||||
_ = cancelIoEx(f.handle, nil)
|
||||
f.wg.Wait()
|
||||
// at this point, no new IO can start
|
||||
syscall.Close(f.handle)
|
||||
windows.Close(f.handle)
|
||||
f.handle = 0
|
||||
} else {
|
||||
f.wgLock.Unlock()
|
||||
@ -145,14 +135,14 @@ func (f *win32File) Close() error {
|
||||
|
||||
// IsClosed checks if the file has been closed.
|
||||
func (f *win32File) IsClosed() bool {
|
||||
return f.closing.isSet()
|
||||
return f.closing.Load()
|
||||
}
|
||||
|
||||
// prepareIO prepares for a new IO operation.
|
||||
// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning.
|
||||
func (f *win32File) prepareIO() (*ioOperation, error) {
|
||||
f.wgLock.RLock()
|
||||
if f.closing.isSet() {
|
||||
if f.closing.Load() {
|
||||
f.wgLock.RUnlock()
|
||||
return nil, ErrFileClosed
|
||||
}
|
||||
@ -164,12 +154,12 @@ func (f *win32File) prepareIO() (*ioOperation, error) {
|
||||
}
|
||||
|
||||
// ioCompletionProcessor processes completed async IOs forever.
|
||||
func ioCompletionProcessor(h syscall.Handle) {
|
||||
func ioCompletionProcessor(h windows.Handle) {
|
||||
for {
|
||||
var bytes uint32
|
||||
var key uintptr
|
||||
var op *ioOperation
|
||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, syscall.INFINITE)
|
||||
err := getQueuedCompletionStatus(h, &bytes, &key, &op, windows.INFINITE)
|
||||
if op == nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -182,11 +172,11 @@ func ioCompletionProcessor(h syscall.Handle) {
|
||||
// asyncIO processes the return value from ReadFile or WriteFile, blocking until
|
||||
// the operation has actually completed.
|
||||
func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) {
|
||||
if err != syscall.ERROR_IO_PENDING { //nolint:errorlint // err is Errno
|
||||
if err != windows.ERROR_IO_PENDING { //nolint:errorlint // err is Errno
|
||||
return int(bytes), err
|
||||
}
|
||||
|
||||
if f.closing.isSet() {
|
||||
if f.closing.Load() {
|
||||
_ = cancelIoEx(f.handle, &c.o)
|
||||
}
|
||||
|
||||
@ -201,8 +191,8 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er
|
||||
select {
|
||||
case r = <-c.ch:
|
||||
err = r.err
|
||||
if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
|
||||
if f.closing.isSet() {
|
||||
if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
|
||||
if f.closing.Load() {
|
||||
err = ErrFileClosed
|
||||
}
|
||||
} else if err != nil && f.socket {
|
||||
@ -214,7 +204,7 @@ func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, er
|
||||
_ = cancelIoEx(f.handle, &c.o)
|
||||
r = <-c.ch
|
||||
err = r.err
|
||||
if err == syscall.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
|
||||
if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno
|
||||
err = ErrTimeout
|
||||
}
|
||||
}
|
||||
@ -235,23 +225,22 @@ func (f *win32File) Read(b []byte) (int, error) {
|
||||
}
|
||||
defer f.wg.Done()
|
||||
|
||||
if f.readDeadline.timedout.isSet() {
|
||||
if f.readDeadline.timedout.Load() {
|
||||
return 0, ErrTimeout
|
||||
}
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.ReadFile(f.handle, b, &bytes, &c.o)
|
||||
err = windows.ReadFile(f.handle, b, &bytes, &c.o)
|
||||
n, err := f.asyncIO(c, &f.readDeadline, bytes, err)
|
||||
runtime.KeepAlive(b)
|
||||
|
||||
// Handle EOF conditions.
|
||||
if err == nil && n == 0 && len(b) != 0 {
|
||||
return 0, io.EOF
|
||||
} else if err == syscall.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
|
||||
} else if err == windows.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno
|
||||
return 0, io.EOF
|
||||
} else {
|
||||
return n, err
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// Write writes to a file handle.
|
||||
@ -262,12 +251,12 @@ func (f *win32File) Write(b []byte) (int, error) {
|
||||
}
|
||||
defer f.wg.Done()
|
||||
|
||||
if f.writeDeadline.timedout.isSet() {
|
||||
if f.writeDeadline.timedout.Load() {
|
||||
return 0, ErrTimeout
|
||||
}
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.WriteFile(f.handle, b, &bytes, &c.o)
|
||||
err = windows.WriteFile(f.handle, b, &bytes, &c.o)
|
||||
n, err := f.asyncIO(c, &f.writeDeadline, bytes, err)
|
||||
runtime.KeepAlive(b)
|
||||
return n, err
|
||||
@ -282,7 +271,7 @@ func (f *win32File) SetWriteDeadline(deadline time.Time) error {
|
||||
}
|
||||
|
||||
func (f *win32File) Flush() error {
|
||||
return syscall.FlushFileBuffers(f.handle)
|
||||
return windows.FlushFileBuffers(f.handle)
|
||||
}
|
||||
|
||||
func (f *win32File) Fd() uintptr {
|
||||
@ -299,7 +288,7 @@ func (d *deadlineHandler) set(deadline time.Time) error {
|
||||
}
|
||||
d.timer = nil
|
||||
}
|
||||
d.timedout.setFalse()
|
||||
d.timedout.Store(false)
|
||||
|
||||
select {
|
||||
case <-d.channel:
|
||||
@ -314,7 +303,7 @@ func (d *deadlineHandler) set(deadline time.Time) error {
|
||||
}
|
||||
|
||||
timeoutIO := func() {
|
||||
d.timedout.setTrue()
|
||||
d.timedout.Store(true)
|
||||
close(d.channel)
|
||||
}
|
||||
|
||||
|
22
vendor/github.com/Microsoft/go-winio/fileinfo.go
generated
vendored
22
vendor/github.com/Microsoft/go-winio/fileinfo.go
generated
vendored
@ -18,9 +18,18 @@ type FileBasicInfo struct {
|
||||
_ uint32 // padding
|
||||
}
|
||||
|
||||
// alignedFileBasicInfo is a FileBasicInfo, but aligned to uint64 by containing
|
||||
// uint64 rather than windows.Filetime. Filetime contains two uint32s. uint64
|
||||
// alignment is necessary to pass this as FILE_BASIC_INFO.
|
||||
type alignedFileBasicInfo struct {
|
||||
CreationTime, LastAccessTime, LastWriteTime, ChangeTime uint64
|
||||
FileAttributes uint32
|
||||
_ uint32 // padding
|
||||
}
|
||||
|
||||
// GetFileBasicInfo retrieves times and attributes for a file.
|
||||
func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||
bi := &FileBasicInfo{}
|
||||
bi := &alignedFileBasicInfo{}
|
||||
if err := windows.GetFileInformationByHandleEx(
|
||||
windows.Handle(f.Fd()),
|
||||
windows.FileBasicInfo,
|
||||
@ -30,16 +39,21 @@ func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) {
|
||||
return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err}
|
||||
}
|
||||
runtime.KeepAlive(f)
|
||||
return bi, nil
|
||||
// Reinterpret the alignedFileBasicInfo as a FileBasicInfo so it matches the
|
||||
// public API of this module. The data may be unnecessarily aligned.
|
||||
return (*FileBasicInfo)(unsafe.Pointer(bi)), nil
|
||||
}
|
||||
|
||||
// SetFileBasicInfo sets times and attributes for a file.
|
||||
func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error {
|
||||
// Create an alignedFileBasicInfo based on a FileBasicInfo. The copy is
|
||||
// suitable to pass to GetFileInformationByHandleEx.
|
||||
biAligned := *(*alignedFileBasicInfo)(unsafe.Pointer(bi))
|
||||
if err := windows.SetFileInformationByHandle(
|
||||
windows.Handle(f.Fd()),
|
||||
windows.FileBasicInfo,
|
||||
(*byte)(unsafe.Pointer(bi)),
|
||||
uint32(unsafe.Sizeof(*bi)),
|
||||
(*byte)(unsafe.Pointer(&biAligned)),
|
||||
uint32(unsafe.Sizeof(biAligned)),
|
||||
); err != nil {
|
||||
return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err}
|
||||
}
|
||||
|
47
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
47
vendor/github.com/Microsoft/go-winio/hvsock.go
generated
vendored
@ -10,7 +10,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@ -181,13 +180,13 @@ type HvsockConn struct {
|
||||
var _ net.Conn = &HvsockConn{}
|
||||
|
||||
func newHVSocket() (*win32File, error) {
|
||||
fd, err := syscall.Socket(afHVSock, syscall.SOCK_STREAM, 1)
|
||||
fd, err := windows.Socket(afHVSock, windows.SOCK_STREAM, 1)
|
||||
if err != nil {
|
||||
return nil, os.NewSyscallError("socket", err)
|
||||
}
|
||||
f, err := makeWin32File(fd)
|
||||
if err != nil {
|
||||
syscall.Close(fd)
|
||||
windows.Close(fd)
|
||||
return nil, err
|
||||
}
|
||||
f.socket = true
|
||||
@ -197,16 +196,24 @@ func newHVSocket() (*win32File, error) {
|
||||
// ListenHvsock listens for connections on the specified hvsock address.
|
||||
func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) {
|
||||
l := &HvsockListener{addr: *addr}
|
||||
sock, err := newHVSocket()
|
||||
|
||||
var sock *win32File
|
||||
sock, err = newHVSocket()
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", err)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
_ = sock.Close()
|
||||
}
|
||||
}()
|
||||
|
||||
sa := addr.raw()
|
||||
err = socket.Bind(windows.Handle(sock.handle), &sa)
|
||||
err = socket.Bind(sock.handle, &sa)
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("socket", err))
|
||||
}
|
||||
err = syscall.Listen(sock.handle, 16)
|
||||
err = windows.Listen(sock.handle, 16)
|
||||
if err != nil {
|
||||
return nil, l.opErr("listen", os.NewSyscallError("listen", err))
|
||||
}
|
||||
@ -246,7 +253,7 @@ func (l *HvsockListener) Accept() (_ net.Conn, err error) {
|
||||
var addrbuf [addrlen * 2]byte
|
||||
|
||||
var bytes uint32
|
||||
err = syscall.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)
|
||||
err = windows.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o)
|
||||
if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil {
|
||||
return nil, l.opErr("accept", os.NewSyscallError("acceptex", err))
|
||||
}
|
||||
@ -263,7 +270,7 @@ func (l *HvsockListener) Accept() (_ net.Conn, err error) {
|
||||
conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen])))
|
||||
|
||||
// initialize the accepted socket and update its properties with those of the listening socket
|
||||
if err = windows.Setsockopt(windows.Handle(sock.handle),
|
||||
if err = windows.Setsockopt(sock.handle,
|
||||
windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT,
|
||||
(*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil {
|
||||
return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err))
|
||||
@ -334,7 +341,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock
|
||||
}()
|
||||
|
||||
sa := addr.raw()
|
||||
err = socket.Bind(windows.Handle(sock.handle), &sa)
|
||||
err = socket.Bind(sock.handle, &sa)
|
||||
if err != nil {
|
||||
return nil, conn.opErr(op, os.NewSyscallError("bind", err))
|
||||
}
|
||||
@ -347,7 +354,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock
|
||||
var bytes uint32
|
||||
for i := uint(0); i <= d.Retries; i++ {
|
||||
err = socket.ConnectEx(
|
||||
windows.Handle(sock.handle),
|
||||
sock.handle,
|
||||
&sa,
|
||||
nil, // sendBuf
|
||||
0, // sendDataLen
|
||||
@ -367,7 +374,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock
|
||||
|
||||
// update the connection properties, so shutdown can be used
|
||||
if err = windows.Setsockopt(
|
||||
windows.Handle(sock.handle),
|
||||
sock.handle,
|
||||
windows.SOL_SOCKET,
|
||||
windows.SO_UPDATE_CONNECT_CONTEXT,
|
||||
nil, // optvalue
|
||||
@ -378,7 +385,7 @@ func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *Hvsock
|
||||
|
||||
// get the local name
|
||||
var sal rawHvsockAddr
|
||||
err = socket.GetSockName(windows.Handle(sock.handle), &sal)
|
||||
err = socket.GetSockName(sock.handle, &sal)
|
||||
if err != nil {
|
||||
return nil, conn.opErr(op, os.NewSyscallError("getsockname", err))
|
||||
}
|
||||
@ -421,7 +428,7 @@ func (d *HvsockDialer) redialWait(ctx context.Context) (err error) {
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
// assumes error is a plain, unwrapped syscall.Errno provided by direct syscall.
|
||||
// assumes error is a plain, unwrapped windows.Errno provided by direct syscall.
|
||||
func canRedial(err error) bool {
|
||||
//nolint:errorlint // guaranteed to be an Errno
|
||||
switch err {
|
||||
@ -447,9 +454,9 @@ func (conn *HvsockConn) Read(b []byte) (int, error) {
|
||||
return 0, conn.opErr("read", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var flags, bytes uint32
|
||||
err = syscall.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
|
||||
err = windows.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil)
|
||||
n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err)
|
||||
if err != nil {
|
||||
var eno windows.Errno
|
||||
@ -482,9 +489,9 @@ func (conn *HvsockConn) write(b []byte) (int, error) {
|
||||
return 0, conn.opErr("write", err)
|
||||
}
|
||||
defer conn.sock.wg.Done()
|
||||
buf := syscall.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))}
|
||||
var bytes uint32
|
||||
err = syscall.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
|
||||
err = windows.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil)
|
||||
n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err)
|
||||
if err != nil {
|
||||
var eno windows.Errno
|
||||
@ -511,7 +518,7 @@ func (conn *HvsockConn) shutdown(how int) error {
|
||||
return socket.ErrSocketClosed
|
||||
}
|
||||
|
||||
err := syscall.Shutdown(conn.sock.handle, how)
|
||||
err := windows.Shutdown(conn.sock.handle, how)
|
||||
if err != nil {
|
||||
// If the connection was closed, shutdowns fail with "not connected"
|
||||
if errors.Is(err, windows.WSAENOTCONN) ||
|
||||
@ -525,7 +532,7 @@ func (conn *HvsockConn) shutdown(how int) error {
|
||||
|
||||
// CloseRead shuts down the read end of the socket, preventing future read operations.
|
||||
func (conn *HvsockConn) CloseRead() error {
|
||||
err := conn.shutdown(syscall.SHUT_RD)
|
||||
err := conn.shutdown(windows.SHUT_RD)
|
||||
if err != nil {
|
||||
return conn.opErr("closeread", err)
|
||||
}
|
||||
@ -535,7 +542,7 @@ func (conn *HvsockConn) CloseRead() error {
|
||||
// CloseWrite shuts down the write end of the socket, preventing future write operations and
|
||||
// notifying the other endpoint that no more data will be written.
|
||||
func (conn *HvsockConn) CloseWrite() error {
|
||||
err := conn.shutdown(syscall.SHUT_WR)
|
||||
err := conn.shutdown(windows.SHUT_WR)
|
||||
if err != nil {
|
||||
return conn.opErr("closewrite", err)
|
||||
}
|
||||
|
72
vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
generated
vendored
72
vendor/github.com/Microsoft/go-winio/internal/fs/fs.go
generated
vendored
@ -11,12 +11,14 @@ import (
|
||||
//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew
|
||||
//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
|
||||
//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW
|
||||
|
||||
const NullHandle windows.Handle = 0
|
||||
|
||||
// AccessMask defines standard, specific, and generic rights.
|
||||
//
|
||||
// Used with CreateFile and NtCreateFile (and co.).
|
||||
//
|
||||
// Bitmask:
|
||||
// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
|
||||
// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
|
||||
@ -47,6 +49,12 @@ const (
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters
|
||||
FILE_ANY_ACCESS AccessMask = 0
|
||||
|
||||
GENERIC_READ AccessMask = 0x8000_0000
|
||||
GENERIC_WRITE AccessMask = 0x4000_0000
|
||||
GENERIC_EXECUTE AccessMask = 0x2000_0000
|
||||
GENERIC_ALL AccessMask = 0x1000_0000
|
||||
ACCESS_SYSTEM_SECURITY AccessMask = 0x0100_0000
|
||||
|
||||
// Specific Object Access
|
||||
// from ntioapi.h
|
||||
|
||||
@ -124,14 +132,32 @@ const (
|
||||
TRUNCATE_EXISTING FileCreationDisposition = 0x05
|
||||
)
|
||||
|
||||
// Create disposition values for NtCreate*
|
||||
type NTFileCreationDisposition uint32
|
||||
|
||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
|
||||
const (
|
||||
// From ntioapi.h
|
||||
|
||||
FILE_SUPERSEDE NTFileCreationDisposition = 0x00
|
||||
FILE_OPEN NTFileCreationDisposition = 0x01
|
||||
FILE_CREATE NTFileCreationDisposition = 0x02
|
||||
FILE_OPEN_IF NTFileCreationDisposition = 0x03
|
||||
FILE_OVERWRITE NTFileCreationDisposition = 0x04
|
||||
FILE_OVERWRITE_IF NTFileCreationDisposition = 0x05
|
||||
FILE_MAXIMUM_DISPOSITION NTFileCreationDisposition = 0x05
|
||||
)
|
||||
|
||||
// CreateFile and co. take flags or attributes together as one parameter.
|
||||
// Define alias until we can use generics to allow both
|
||||
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants
|
||||
type FileFlagOrAttribute uint32
|
||||
|
||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
|
||||
const ( // from winnt.h
|
||||
const (
|
||||
// from winnt.h
|
||||
|
||||
FILE_FLAG_WRITE_THROUGH FileFlagOrAttribute = 0x8000_0000
|
||||
FILE_FLAG_OVERLAPPED FileFlagOrAttribute = 0x4000_0000
|
||||
FILE_FLAG_NO_BUFFERING FileFlagOrAttribute = 0x2000_0000
|
||||
@ -145,17 +171,51 @@ const ( // from winnt.h
|
||||
FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000
|
||||
)
|
||||
|
||||
// NtCreate* functions take a dedicated CreateOptions parameter.
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/Winternl/nf-winternl-ntcreatefile
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/devnotes/nt-create-named-pipe-file
|
||||
type NTCreateOptions uint32
|
||||
|
||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
|
||||
const (
|
||||
// From ntioapi.h
|
||||
|
||||
FILE_DIRECTORY_FILE NTCreateOptions = 0x0000_0001
|
||||
FILE_WRITE_THROUGH NTCreateOptions = 0x0000_0002
|
||||
FILE_SEQUENTIAL_ONLY NTCreateOptions = 0x0000_0004
|
||||
FILE_NO_INTERMEDIATE_BUFFERING NTCreateOptions = 0x0000_0008
|
||||
|
||||
FILE_SYNCHRONOUS_IO_ALERT NTCreateOptions = 0x0000_0010
|
||||
FILE_SYNCHRONOUS_IO_NONALERT NTCreateOptions = 0x0000_0020
|
||||
FILE_NON_DIRECTORY_FILE NTCreateOptions = 0x0000_0040
|
||||
FILE_CREATE_TREE_CONNECTION NTCreateOptions = 0x0000_0080
|
||||
|
||||
FILE_COMPLETE_IF_OPLOCKED NTCreateOptions = 0x0000_0100
|
||||
FILE_NO_EA_KNOWLEDGE NTCreateOptions = 0x0000_0200
|
||||
FILE_DISABLE_TUNNELING NTCreateOptions = 0x0000_0400
|
||||
FILE_RANDOM_ACCESS NTCreateOptions = 0x0000_0800
|
||||
|
||||
FILE_DELETE_ON_CLOSE NTCreateOptions = 0x0000_1000
|
||||
FILE_OPEN_BY_FILE_ID NTCreateOptions = 0x0000_2000
|
||||
FILE_OPEN_FOR_BACKUP_INTENT NTCreateOptions = 0x0000_4000
|
||||
FILE_NO_COMPRESSION NTCreateOptions = 0x0000_8000
|
||||
)
|
||||
|
||||
type FileSQSFlag = FileFlagOrAttribute
|
||||
|
||||
//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API.
|
||||
const ( // from winbase.h
|
||||
const (
|
||||
// from winbase.h
|
||||
|
||||
SECURITY_ANONYMOUS FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16)
|
||||
SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16)
|
||||
SECURITY_IMPERSONATION FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16)
|
||||
SECURITY_DELEGATION FileSQSFlag = FileSQSFlag(SecurityDelegation << 16)
|
||||
|
||||
SECURITY_SQOS_PRESENT FileSQSFlag = 0x00100000
|
||||
SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F0000
|
||||
SECURITY_SQOS_PRESENT FileSQSFlag = 0x0010_0000
|
||||
SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F_0000
|
||||
)
|
||||
|
||||
// GetFinalPathNameByHandle flags
|
||||
|
9
vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
generated
vendored
9
vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -45,7 +42,7 @@ var (
|
||||
procCreateFileW = modkernel32.NewProc("CreateFileW")
|
||||
)
|
||||
|
||||
func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
|
||||
func CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
@ -54,8 +51,8 @@ func CreateFile(name string, access AccessMask, mode FileShareMode, sa *syscall.
|
||||
return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile)
|
||||
}
|
||||
|
||||
func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *syscall.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateFileW.Addr(), 7, uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile), 0, 0)
|
||||
func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) {
|
||||
r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile))
|
||||
handle = windows.Handle(r0)
|
||||
if handle == windows.InvalidHandle {
|
||||
err = errnoErr(e1)
|
||||
|
8
vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
generated
vendored
8
vendor/github.com/Microsoft/go-winio/internal/socket/socket.go
generated
vendored
@ -156,9 +156,7 @@ func connectEx(
|
||||
bytesSent *uint32,
|
||||
overlapped *windows.Overlapped,
|
||||
) (err error) {
|
||||
// todo: after upgrading to 1.18, switch from syscall.Syscall9 to syscall.SyscallN
|
||||
r1, _, e1 := syscall.Syscall9(connectExFunc.addr,
|
||||
7,
|
||||
r1, _, e1 := syscall.SyscallN(connectExFunc.addr,
|
||||
uintptr(s),
|
||||
uintptr(name),
|
||||
uintptr(namelen),
|
||||
@ -166,8 +164,8 @@ func connectEx(
|
||||
uintptr(sendDataLen),
|
||||
uintptr(unsafe.Pointer(bytesSent)),
|
||||
uintptr(unsafe.Pointer(overlapped)),
|
||||
0,
|
||||
0)
|
||||
)
|
||||
|
||||
if r1 == 0 {
|
||||
if e1 != 0 {
|
||||
err = error(e1)
|
||||
|
9
vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
generated
vendored
9
vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -48,7 +45,7 @@ var (
|
||||
)
|
||||
|
||||
func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procbind.Addr(), 3, uintptr(s), uintptr(name), uintptr(namelen))
|
||||
r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen))
|
||||
if r1 == socketError {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -56,7 +53,7 @@ func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) {
|
||||
}
|
||||
|
||||
func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procgetpeername.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
|
||||
r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
|
||||
if r1 == socketError {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -64,7 +61,7 @@ func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err err
|
||||
}
|
||||
|
||||
func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procgetsockname.Addr(), 3, uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
|
||||
r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen)))
|
||||
if r1 == socketError {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
|
2
vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
generated
vendored
2
vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go
generated
vendored
@ -62,7 +62,7 @@ func (b *WString) Free() {
|
||||
// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the
|
||||
// previous buffer back into pool.
|
||||
func (b *WString) ResizeTo(c uint32) uint32 {
|
||||
// allready sufficient (or n is 0)
|
||||
// already sufficient (or n is 0)
|
||||
if c <= b.Cap() {
|
||||
return b.Cap()
|
||||
}
|
||||
|
125
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
125
vendor/github.com/Microsoft/go-winio/pipe.go
generated
vendored
@ -11,7 +11,6 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"time"
|
||||
"unsafe"
|
||||
|
||||
@ -20,20 +19,44 @@ import (
|
||||
"github.com/Microsoft/go-winio/internal/fs"
|
||||
)
|
||||
|
||||
//sys connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) = ConnectNamedPipe
|
||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) [failretval==syscall.InvalidHandle] = CreateNamedPipeW
|
||||
//sys getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||
//sys getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||
//sys localAlloc(uFlags uint32, length uint32) (ptr uintptr) = LocalAlloc
|
||||
//sys ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile
|
||||
//sys connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) = ConnectNamedPipe
|
||||
//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateNamedPipeW
|
||||
//sys disconnectNamedPipe(pipe windows.Handle) (err error) = DisconnectNamedPipe
|
||||
//sys getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo
|
||||
//sys getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW
|
||||
//sys ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile
|
||||
//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb
|
||||
//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U
|
||||
//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl
|
||||
|
||||
type PipeConn interface {
|
||||
net.Conn
|
||||
Disconnect() error
|
||||
Flush() error
|
||||
}
|
||||
|
||||
// type aliases for mkwinsyscall code
|
||||
type (
|
||||
ntAccessMask = fs.AccessMask
|
||||
ntFileShareMode = fs.FileShareMode
|
||||
ntFileCreationDisposition = fs.NTFileCreationDisposition
|
||||
ntFileOptions = fs.NTCreateOptions
|
||||
)
|
||||
|
||||
type ioStatusBlock struct {
|
||||
Status, Information uintptr
|
||||
}
|
||||
|
||||
// typedef struct _OBJECT_ATTRIBUTES {
|
||||
// ULONG Length;
|
||||
// HANDLE RootDirectory;
|
||||
// PUNICODE_STRING ObjectName;
|
||||
// ULONG Attributes;
|
||||
// PVOID SecurityDescriptor;
|
||||
// PVOID SecurityQualityOfService;
|
||||
// } OBJECT_ATTRIBUTES;
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_attributes
|
||||
type objectAttributes struct {
|
||||
Length uintptr
|
||||
RootDirectory uintptr
|
||||
@ -49,6 +72,17 @@ type unicodeString struct {
|
||||
Buffer uintptr
|
||||
}
|
||||
|
||||
// typedef struct _SECURITY_DESCRIPTOR {
|
||||
// BYTE Revision;
|
||||
// BYTE Sbz1;
|
||||
// SECURITY_DESCRIPTOR_CONTROL Control;
|
||||
// PSID Owner;
|
||||
// PSID Group;
|
||||
// PACL Sacl;
|
||||
// PACL Dacl;
|
||||
// } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
|
||||
//
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor
|
||||
type securityDescriptor struct {
|
||||
Revision byte
|
||||
Sbz1 byte
|
||||
@ -80,6 +114,8 @@ type win32Pipe struct {
|
||||
path string
|
||||
}
|
||||
|
||||
var _ PipeConn = (*win32Pipe)(nil)
|
||||
|
||||
type win32MessageBytePipe struct {
|
||||
win32Pipe
|
||||
writeClosed bool
|
||||
@ -103,6 +139,10 @@ func (f *win32Pipe) SetDeadline(t time.Time) error {
|
||||
return f.SetWriteDeadline(t)
|
||||
}
|
||||
|
||||
func (f *win32Pipe) Disconnect() error {
|
||||
return disconnectNamedPipe(f.win32File.handle)
|
||||
}
|
||||
|
||||
// CloseWrite closes the write side of a message pipe in byte mode.
|
||||
func (f *win32MessageBytePipe) CloseWrite() error {
|
||||
if f.writeClosed {
|
||||
@ -146,7 +186,7 @@ func (f *win32MessageBytePipe) Read(b []byte) (int, error) {
|
||||
// zero-byte message, ensure that all future Read() calls
|
||||
// also return EOF.
|
||||
f.readEOF = true
|
||||
} else if err == syscall.ERROR_MORE_DATA { //nolint:errorlint // err is Errno
|
||||
} else if err == windows.ERROR_MORE_DATA { //nolint:errorlint // err is Errno
|
||||
// ERROR_MORE_DATA indicates that the pipe's read mode is message mode
|
||||
// and the message still has more bytes. Treat this as a success, since
|
||||
// this package presents all named pipes as byte streams.
|
||||
@ -164,21 +204,20 @@ func (s pipeAddress) String() string {
|
||||
}
|
||||
|
||||
// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout.
|
||||
func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask) (syscall.Handle, error) {
|
||||
func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask, impLevel PipeImpLevel) (windows.Handle, error) {
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return syscall.Handle(0), ctx.Err()
|
||||
return windows.Handle(0), ctx.Err()
|
||||
default:
|
||||
wh, err := fs.CreateFile(*path,
|
||||
h, err := fs.CreateFile(*path,
|
||||
access,
|
||||
0, // mode
|
||||
nil, // security attributes
|
||||
fs.OPEN_EXISTING,
|
||||
fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.SECURITY_ANONYMOUS,
|
||||
fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.FileSQSFlag(impLevel),
|
||||
0, // template file handle
|
||||
)
|
||||
h := syscall.Handle(wh)
|
||||
if err == nil {
|
||||
return h, nil
|
||||
}
|
||||
@ -214,15 +253,33 @@ func DialPipe(path string, timeout *time.Duration) (net.Conn, error) {
|
||||
// DialPipeContext attempts to connect to a named pipe by `path` until `ctx`
|
||||
// cancellation or timeout.
|
||||
func DialPipeContext(ctx context.Context, path string) (net.Conn, error) {
|
||||
return DialPipeAccess(ctx, path, syscall.GENERIC_READ|syscall.GENERIC_WRITE)
|
||||
return DialPipeAccess(ctx, path, uint32(fs.GENERIC_READ|fs.GENERIC_WRITE))
|
||||
}
|
||||
|
||||
// PipeImpLevel is an enumeration of impersonation levels that may be set
|
||||
// when calling DialPipeAccessImpersonation.
|
||||
type PipeImpLevel uint32
|
||||
|
||||
const (
|
||||
PipeImpLevelAnonymous = PipeImpLevel(fs.SECURITY_ANONYMOUS)
|
||||
PipeImpLevelIdentification = PipeImpLevel(fs.SECURITY_IDENTIFICATION)
|
||||
PipeImpLevelImpersonation = PipeImpLevel(fs.SECURITY_IMPERSONATION)
|
||||
PipeImpLevelDelegation = PipeImpLevel(fs.SECURITY_DELEGATION)
|
||||
)
|
||||
|
||||
// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx`
|
||||
// cancellation or timeout.
|
||||
func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) {
|
||||
return DialPipeAccessImpLevel(ctx, path, access, PipeImpLevelAnonymous)
|
||||
}
|
||||
|
||||
// DialPipeAccessImpLevel attempts to connect to a named pipe by `path` with
|
||||
// `access` at `impLevel` until `ctx` cancellation or timeout. The other
|
||||
// DialPipe* implementations use PipeImpLevelAnonymous.
|
||||
func DialPipeAccessImpLevel(ctx context.Context, path string, access uint32, impLevel PipeImpLevel) (net.Conn, error) {
|
||||
var err error
|
||||
var h syscall.Handle
|
||||
h, err = tryDialPipe(ctx, &path, fs.AccessMask(access))
|
||||
var h windows.Handle
|
||||
h, err = tryDialPipe(ctx, &path, fs.AccessMask(access), impLevel)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -235,7 +292,7 @@ func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn,
|
||||
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
windows.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -255,7 +312,7 @@ type acceptResponse struct {
|
||||
}
|
||||
|
||||
type win32PipeListener struct {
|
||||
firstHandle syscall.Handle
|
||||
firstHandle windows.Handle
|
||||
path string
|
||||
config PipeConfig
|
||||
acceptCh chan (chan acceptResponse)
|
||||
@ -263,8 +320,8 @@ type win32PipeListener struct {
|
||||
doneCh chan int
|
||||
}
|
||||
|
||||
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (syscall.Handle, error) {
|
||||
path16, err := syscall.UTF16FromString(path)
|
||||
func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (windows.Handle, error) {
|
||||
path16, err := windows.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
@ -280,16 +337,20 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy
|
||||
).Err(); err != nil {
|
||||
return 0, &os.PathError{Op: "open", Path: path, Err: err}
|
||||
}
|
||||
defer localFree(ntPath.Buffer)
|
||||
defer windows.LocalFree(windows.Handle(ntPath.Buffer)) //nolint:errcheck
|
||||
oa.ObjectName = &ntPath
|
||||
oa.Attributes = windows.OBJ_CASE_INSENSITIVE
|
||||
|
||||
// The security descriptor is only needed for the first pipe.
|
||||
if first {
|
||||
if sd != nil {
|
||||
//todo: does `sdb` need to be allocated on the heap, or can go allocate it?
|
||||
l := uint32(len(sd))
|
||||
sdb := localAlloc(0, l)
|
||||
defer localFree(sdb)
|
||||
sdb, err := windows.LocalAlloc(0, l)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("LocalAlloc for security descriptor with of length %d: %w", l, err)
|
||||
}
|
||||
defer windows.LocalFree(windows.Handle(sdb)) //nolint:errcheck
|
||||
copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd)
|
||||
oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb))
|
||||
} else {
|
||||
@ -298,7 +359,7 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy
|
||||
if err := rtlDefaultNpAcl(&dacl).Err(); err != nil {
|
||||
return 0, fmt.Errorf("getting default named pipe ACL: %w", err)
|
||||
}
|
||||
defer localFree(dacl)
|
||||
defer windows.LocalFree(windows.Handle(dacl)) //nolint:errcheck
|
||||
|
||||
sdb := &securityDescriptor{
|
||||
Revision: 1,
|
||||
@ -314,27 +375,27 @@ func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (sy
|
||||
typ |= windows.FILE_PIPE_MESSAGE_TYPE
|
||||
}
|
||||
|
||||
disposition := uint32(windows.FILE_OPEN)
|
||||
access := uint32(syscall.GENERIC_READ | syscall.GENERIC_WRITE | syscall.SYNCHRONIZE)
|
||||
disposition := fs.FILE_OPEN
|
||||
access := fs.GENERIC_READ | fs.GENERIC_WRITE | fs.SYNCHRONIZE
|
||||
if first {
|
||||
disposition = windows.FILE_CREATE
|
||||
disposition = fs.FILE_CREATE
|
||||
// By not asking for read or write access, the named pipe file system
|
||||
// will put this pipe into an initially disconnected state, blocking
|
||||
// client connections until the next call with first == false.
|
||||
access = syscall.SYNCHRONIZE
|
||||
access = fs.SYNCHRONIZE
|
||||
}
|
||||
|
||||
timeout := int64(-50 * 10000) // 50ms
|
||||
|
||||
var (
|
||||
h syscall.Handle
|
||||
h windows.Handle
|
||||
iosb ioStatusBlock
|
||||
)
|
||||
err = ntCreateNamedPipeFile(&h,
|
||||
access,
|
||||
&oa,
|
||||
&iosb,
|
||||
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE,
|
||||
fs.FILE_SHARE_READ|fs.FILE_SHARE_WRITE,
|
||||
disposition,
|
||||
0,
|
||||
typ,
|
||||
@ -359,7 +420,7 @@ func (l *win32PipeListener) makeServerPipe() (*win32File, error) {
|
||||
}
|
||||
f, err := makeWin32File(h)
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
windows.Close(h)
|
||||
return nil, err
|
||||
}
|
||||
return f, nil
|
||||
@ -418,7 +479,7 @@ func (l *win32PipeListener) listenerRoutine() {
|
||||
closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno
|
||||
}
|
||||
}
|
||||
syscall.Close(l.firstHandle)
|
||||
windows.Close(l.firstHandle)
|
||||
l.firstHandle = 0
|
||||
// Notify Close() and Accept() callers that the handle has been closed.
|
||||
close(l.doneCh)
|
||||
|
9
vendor/github.com/Microsoft/go-winio/privilege.go
generated
vendored
9
vendor/github.com/Microsoft/go-winio/privilege.go
generated
vendored
@ -9,7 +9,6 @@ import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unicode/utf16"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
@ -18,8 +17,8 @@ import (
|
||||
//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges
|
||||
//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf
|
||||
//sys revertToSelf() (err error) = advapi32.RevertToSelf
|
||||
//sys openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
|
||||
//sys getCurrentThread() (h syscall.Handle) = GetCurrentThread
|
||||
//sys openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken
|
||||
//sys getCurrentThread() (h windows.Handle) = GetCurrentThread
|
||||
//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW
|
||||
//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW
|
||||
//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW
|
||||
@ -29,7 +28,7 @@ const (
|
||||
SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED
|
||||
|
||||
//revive:disable-next-line:var-naming ALL_CAPS
|
||||
ERROR_NOT_ALL_ASSIGNED syscall.Errno = windows.ERROR_NOT_ALL_ASSIGNED
|
||||
ERROR_NOT_ALL_ASSIGNED windows.Errno = windows.ERROR_NOT_ALL_ASSIGNED
|
||||
|
||||
SeBackupPrivilege = "SeBackupPrivilege"
|
||||
SeRestorePrivilege = "SeRestorePrivilege"
|
||||
@ -177,7 +176,7 @@ func newThreadToken() (windows.Token, error) {
|
||||
}
|
||||
|
||||
var token windows.Token
|
||||
err = openThreadToken(getCurrentThread(), syscall.TOKEN_ADJUST_PRIVILEGES|syscall.TOKEN_QUERY, false, &token)
|
||||
err = openThreadToken(getCurrentThread(), windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, false, &token)
|
||||
if err != nil {
|
||||
rerr := revertToSelf()
|
||||
if rerr != nil {
|
||||
|
37
vendor/github.com/Microsoft/go-winio/sd.go
generated
vendored
37
vendor/github.com/Microsoft/go-winio/sd.go
generated
vendored
@ -5,7 +5,7 @@ package winio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"fmt"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
@ -15,10 +15,6 @@ import (
|
||||
//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW
|
||||
//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW
|
||||
//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW
|
||||
//sys convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) = advapi32.ConvertStringSecurityDescriptorToSecurityDescriptorW
|
||||
//sys convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) = advapi32.ConvertSecurityDescriptorToStringSecurityDescriptorW
|
||||
//sys localFree(mem uintptr) = LocalFree
|
||||
//sys getSecurityDescriptorLength(sd uintptr) (len uint32) = advapi32.GetSecurityDescriptorLength
|
||||
|
||||
type AccountLookupError struct {
|
||||
Name string
|
||||
@ -64,7 +60,7 @@ func LookupSidByName(name string) (sid string, err error) {
|
||||
|
||||
var sidSize, sidNameUse, refDomainSize uint32
|
||||
err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse)
|
||||
if err != nil && err != syscall.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
|
||||
if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sidBuffer := make([]byte, sidSize)
|
||||
@ -78,8 +74,8 @@ func LookupSidByName(name string) (sid string, err error) {
|
||||
if err != nil {
|
||||
return "", &AccountLookupError{name, err}
|
||||
}
|
||||
sid = syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
|
||||
localFree(uintptr(unsafe.Pointer(strBuffer)))
|
||||
sid = windows.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:])
|
||||
_, _ = windows.LocalFree(windows.Handle(unsafe.Pointer(strBuffer)))
|
||||
return sid, nil
|
||||
}
|
||||
|
||||
@ -100,7 +96,7 @@ func LookupNameBySid(sid string) (name string, err error) {
|
||||
if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil {
|
||||
return "", &AccountLookupError{sid, err}
|
||||
}
|
||||
defer localFree(uintptr(unsafe.Pointer(sidPtr)))
|
||||
defer windows.LocalFree(windows.Handle(unsafe.Pointer(sidPtr))) //nolint:errcheck
|
||||
|
||||
var nameSize, refDomainSize, sidNameUse uint32
|
||||
err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse)
|
||||
@ -120,25 +116,18 @@ func LookupNameBySid(sid string) (name string, err error) {
|
||||
}
|
||||
|
||||
func SddlToSecurityDescriptor(sddl string) ([]byte, error) {
|
||||
var sdBuffer uintptr
|
||||
err := convertStringSecurityDescriptorToSecurityDescriptor(sddl, 1, &sdBuffer, nil)
|
||||
sd, err := windows.SecurityDescriptorFromString(sddl)
|
||||
if err != nil {
|
||||
return nil, &SddlConversionError{sddl, err}
|
||||
return nil, &SddlConversionError{Sddl: sddl, Err: err}
|
||||
}
|
||||
defer localFree(sdBuffer)
|
||||
sd := make([]byte, getSecurityDescriptorLength(sdBuffer))
|
||||
copy(sd, (*[0xffff]byte)(unsafe.Pointer(sdBuffer))[:len(sd)])
|
||||
return sd, nil
|
||||
b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length())
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func SecurityDescriptorToSddl(sd []byte) (string, error) {
|
||||
var sddl *uint16
|
||||
// The returned string length seems to include an arbitrary number of terminating NULs.
|
||||
// Don't use it.
|
||||
err := convertSecurityDescriptorToStringSecurityDescriptor(&sd[0], 1, 0xff, &sddl, nil)
|
||||
if err != nil {
|
||||
return "", err
|
||||
if l := int(unsafe.Sizeof(windows.SECURITY_DESCRIPTOR{})); len(sd) < l {
|
||||
return "", fmt.Errorf("SecurityDescriptor (%d) smaller than expected (%d): %w", len(sd), l, windows.ERROR_INCORRECT_SIZE)
|
||||
}
|
||||
defer localFree(uintptr(unsafe.Pointer(sddl)))
|
||||
return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(sddl))[:]), nil
|
||||
s := (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&sd[0]))
|
||||
return s.String(), nil
|
||||
}
|
||||
|
5
vendor/github.com/Microsoft/go-winio/tools.go
generated
vendored
5
vendor/github.com/Microsoft/go-winio/tools.go
generated
vendored
@ -1,5 +0,0 @@
|
||||
//go:build tools
|
||||
|
||||
package winio
|
||||
|
||||
import _ "golang.org/x/tools/cmd/stringer"
|
13
vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go
generated
vendored
13
vendor/github.com/Microsoft/go-winio/vhd/zvhd_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -50,7 +47,7 @@ var (
|
||||
)
|
||||
|
||||
func attachVirtualDisk(handle syscall.Handle, securityDescriptor *uintptr, attachVirtualDiskFlag uint32, providerSpecificFlags uint32, parameters *AttachVirtualDiskParameters, overlapped *syscall.Overlapped) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall6(procAttachVirtualDisk.Addr(), 6, uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)))
|
||||
r0, _, _ := syscall.SyscallN(procAttachVirtualDisk.Addr(), uintptr(handle), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(attachVirtualDiskFlag), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -67,7 +64,7 @@ func createVirtualDisk(virtualStorageType *VirtualStorageType, path string, virt
|
||||
}
|
||||
|
||||
func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, securityDescriptor *uintptr, createVirtualDiskFlags uint32, providerSpecificFlags uint32, parameters *CreateVirtualDiskParameters, overlapped *syscall.Overlapped, handle *syscall.Handle) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall9(procCreateVirtualDisk.Addr(), 9, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle)))
|
||||
r0, _, _ := syscall.SyscallN(procCreateVirtualDisk.Addr(), uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(unsafe.Pointer(securityDescriptor)), uintptr(createVirtualDiskFlags), uintptr(providerSpecificFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(overlapped)), uintptr(unsafe.Pointer(handle)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -75,7 +72,7 @@ func _createVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, vi
|
||||
}
|
||||
|
||||
func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, providerSpecificFlags uint32) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall(procDetachVirtualDisk.Addr(), 3, uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags))
|
||||
r0, _, _ := syscall.SyscallN(procDetachVirtualDisk.Addr(), uintptr(handle), uintptr(detachVirtualDiskFlags), uintptr(providerSpecificFlags))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -83,7 +80,7 @@ func detachVirtualDisk(handle syscall.Handle, detachVirtualDiskFlags uint32, pro
|
||||
}
|
||||
|
||||
func getVirtualDiskPhysicalPath(handle syscall.Handle, diskPathSizeInBytes *uint32, buffer *uint16) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall(procGetVirtualDiskPhysicalPath.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer)))
|
||||
r0, _, _ := syscall.SyscallN(procGetVirtualDiskPhysicalPath.Addr(), uintptr(handle), uintptr(unsafe.Pointer(diskPathSizeInBytes)), uintptr(unsafe.Pointer(buffer)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -100,7 +97,7 @@ func openVirtualDisk(virtualStorageType *VirtualStorageType, path string, virtua
|
||||
}
|
||||
|
||||
func _openVirtualDisk(virtualStorageType *VirtualStorageType, path *uint16, virtualDiskAccessMask uint32, openVirtualDiskFlags uint32, parameters *openVirtualDiskParameters, handle *syscall.Handle) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall6(procOpenVirtualDisk.Addr(), 6, uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
|
||||
r0, _, _ := syscall.SyscallN(procOpenVirtualDisk.Addr(), uintptr(unsafe.Pointer(virtualStorageType)), uintptr(unsafe.Pointer(path)), uintptr(virtualDiskAccessMask), uintptr(openVirtualDiskFlags), uintptr(unsafe.Pointer(parameters)), uintptr(unsafe.Pointer(handle)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
|
211
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
211
vendor/github.com/Microsoft/go-winio/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -45,38 +42,34 @@ var (
|
||||
modntdll = windows.NewLazySystemDLL("ntdll.dll")
|
||||
modws2_32 = windows.NewLazySystemDLL("ws2_32.dll")
|
||||
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procConvertSecurityDescriptorToStringSecurityDescriptorW = modadvapi32.NewProc("ConvertSecurityDescriptorToStringSecurityDescriptorW")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSecurityDescriptorToSecurityDescriptorW = modadvapi32.NewProc("ConvertStringSecurityDescriptorToSecurityDescriptorW")
|
||||
procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
|
||||
procGetSecurityDescriptorLength = modadvapi32.NewProc("GetSecurityDescriptorLength")
|
||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
|
||||
procLocalFree = modkernel32.NewProc("LocalFree")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges")
|
||||
procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW")
|
||||
procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW")
|
||||
procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf")
|
||||
procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW")
|
||||
procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW")
|
||||
procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW")
|
||||
procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW")
|
||||
procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW")
|
||||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procBackupRead = modkernel32.NewProc("BackupRead")
|
||||
procBackupWrite = modkernel32.NewProc("BackupWrite")
|
||||
procCancelIoEx = modkernel32.NewProc("CancelIoEx")
|
||||
procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe")
|
||||
procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort")
|
||||
procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW")
|
||||
procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe")
|
||||
procGetCurrentThread = modkernel32.NewProc("GetCurrentThread")
|
||||
procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW")
|
||||
procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo")
|
||||
procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus")
|
||||
procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U")
|
||||
procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb")
|
||||
procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult")
|
||||
)
|
||||
|
||||
func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) {
|
||||
@ -84,7 +77,7 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou
|
||||
if releaseAll {
|
||||
_p0 = 1
|
||||
}
|
||||
r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||
r0, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize)))
|
||||
success = r0 != 0
|
||||
if true {
|
||||
err = errnoErr(e1)
|
||||
@ -92,33 +85,8 @@ func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, ou
|
||||
return
|
||||
}
|
||||
|
||||
func convertSecurityDescriptorToStringSecurityDescriptor(sd *byte, revision uint32, secInfo uint32, sddl **uint16, sddlSize *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertSecurityDescriptorToStringSecurityDescriptorW.Addr(), 5, uintptr(unsafe.Pointer(sd)), uintptr(revision), uintptr(secInfo), uintptr(unsafe.Pointer(sddl)), uintptr(unsafe.Pointer(sddlSize)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertSidToStringSid(sid *byte, str **uint16) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConvertSidToStringSidW.Addr(), 2, uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)), 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func convertStringSecurityDescriptorToSecurityDescriptor(str string, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(str)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _convertStringSecurityDescriptorToSecurityDescriptor(_p0, revision, sd, size)
|
||||
}
|
||||
|
||||
func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision uint32, sd *uintptr, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procConvertStringSecurityDescriptorToSecurityDescriptorW.Addr(), 4, uintptr(unsafe.Pointer(str)), uintptr(revision), uintptr(unsafe.Pointer(sd)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -126,21 +94,15 @@ func _convertStringSecurityDescriptorToSecurityDescriptor(str *uint16, revision
|
||||
}
|
||||
|
||||
func convertStringSidToSid(str *uint16, sid **byte) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConvertStringSidToSidW.Addr(), 2, uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)), 0)
|
||||
r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getSecurityDescriptorLength(sd uintptr) (len uint32) {
|
||||
r0, _, _ := syscall.Syscall(procGetSecurityDescriptorLength.Addr(), 1, uintptr(sd), 0, 0)
|
||||
len = uint32(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func impersonateSelf(level uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procImpersonateSelf.Addr(), 1, uintptr(level), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(level))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -157,7 +119,7 @@ func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSiz
|
||||
}
|
||||
|
||||
func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procLookupAccountNameW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -165,7 +127,7 @@ func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidS
|
||||
}
|
||||
|
||||
func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procLookupAccountSidW.Addr(), 7, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -182,7 +144,7 @@ func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16,
|
||||
}
|
||||
|
||||
func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeDisplayNameW.Addr(), 5, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)), 0)
|
||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeDisplayNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -199,7 +161,7 @@ func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *
|
||||
}
|
||||
|
||||
func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -221,19 +183,19 @@ func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err err
|
||||
}
|
||||
|
||||
func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
||||
r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||
func openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) {
|
||||
var _p0 uint32
|
||||
if openAsSelf {
|
||||
_p0 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procOpenThreadToken.Addr(), 4, uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
@ -241,14 +203,14 @@ func openThreadToken(thread syscall.Handle, accessMask uint32, openAsSelf bool,
|
||||
}
|
||||
|
||||
func revertToSelf() (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procRevertToSelf.Addr(), 0, 0, 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr())
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
func backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
var _p0 *byte
|
||||
if len(b) > 0 {
|
||||
_p0 = &b[0]
|
||||
@ -261,14 +223,14 @@ func backupRead(h syscall.Handle, b []byte, bytesRead *uint32, abort bool, proce
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupRead.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procBackupRead.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
func backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) {
|
||||
var _p0 *byte
|
||||
if len(b) > 0 {
|
||||
_p0 = &b[0]
|
||||
@ -281,39 +243,39 @@ func backupWrite(h syscall.Handle, b []byte, bytesWritten *uint32, abort bool, p
|
||||
if processSecurity {
|
||||
_p2 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall9(procBackupWrite.Addr(), 7, uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)), 0, 0)
|
||||
r1, _, e1 := syscall.SyscallN(procBackupWrite.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func cancelIoEx(file syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procCancelIoEx.Addr(), 2, uintptr(file), uintptr(unsafe.Pointer(o)), 0)
|
||||
func cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(file), uintptr(unsafe.Pointer(o)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func connectNamedPipe(pipe syscall.Handle, o *syscall.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, uintptr(pipe), uintptr(unsafe.Pointer(o)), 0)
|
||||
func connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(o)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createIoCompletionPort(file syscall.Handle, port syscall.Handle, key uintptr, threadCount uint32) (newport syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall6(procCreateIoCompletionPort.Addr(), 4, uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount), 0, 0)
|
||||
newport = syscall.Handle(r0)
|
||||
func createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) {
|
||||
r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount))
|
||||
newport = windows.Handle(r0)
|
||||
if newport == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(name)
|
||||
if err != nil {
|
||||
@ -322,96 +284,93 @@ func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances ui
|
||||
return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa)
|
||||
}
|
||||
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *syscall.SecurityAttributes) (handle syscall.Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall9(procCreateNamedPipeW.Addr(), 8, uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)), 0)
|
||||
handle = syscall.Handle(r0)
|
||||
if handle == syscall.InvalidHandle {
|
||||
func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) {
|
||||
r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa)))
|
||||
handle = windows.Handle(r0)
|
||||
if handle == windows.InvalidHandle {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getCurrentThread() (h syscall.Handle) {
|
||||
r0, _, _ := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0)
|
||||
h = syscall.Handle(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeHandleState(pipe syscall.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procGetNamedPipeHandleStateW.Addr(), 7, uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize), 0, 0)
|
||||
func disconnectNamedPipe(pipe windows.Handle) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeInfo(pipe syscall.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetNamedPipeInfo.Addr(), 5, uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)), 0)
|
||||
func getCurrentThread() (h windows.Handle) {
|
||||
r0, _, _ := syscall.SyscallN(procGetCurrentThread.Addr())
|
||||
h = windows.Handle(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getQueuedCompletionStatus(port syscall.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetQueuedCompletionStatus.Addr(), 5, uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout), 0)
|
||||
func getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func localAlloc(uFlags uint32, length uint32) (ptr uintptr) {
|
||||
r0, _, _ := syscall.Syscall(procLocalAlloc.Addr(), 2, uintptr(uFlags), uintptr(length), 0)
|
||||
ptr = uintptr(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func localFree(mem uintptr) {
|
||||
syscall.Syscall(procLocalFree.Addr(), 1, uintptr(mem), 0, 0)
|
||||
return
|
||||
}
|
||||
|
||||
func setFileCompletionNotificationModes(h syscall.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.Syscall(procSetFileCompletionNotificationModes.Addr(), 2, uintptr(h), uintptr(flags), 0)
|
||||
func getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *syscall.Handle, access uint32, oa *objectAttributes, iosb *ioStatusBlock, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) {
|
||||
r0, _, _ := syscall.Syscall15(procNtCreateNamedPipeFile.Addr(), 14, uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)), 0)
|
||||
func setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) {
|
||||
r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(h), uintptr(flags))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) {
|
||||
r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout)))
|
||||
status = ntStatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(dacl)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(dacl)))
|
||||
status = ntStatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U.Addr(), 4, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved))
|
||||
status = ntStatus(r0)
|
||||
return
|
||||
}
|
||||
|
||||
func rtlNtStatusToDosError(status ntStatus) (winerr error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlNtStatusToDosErrorNoTeb.Addr(), 1, uintptr(status), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(status))
|
||||
if r0 != 0 {
|
||||
winerr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func wsaGetOverlappedResult(h syscall.Handle, o *syscall.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
func wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) {
|
||||
var _p0 uint32
|
||||
if wait {
|
||||
_p0 = 1
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall6(procWSAGetOverlappedResult.Addr(), 5, uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)), 0)
|
||||
r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags)))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
|
28
vendor/github.com/Microsoft/hcsshim/.golangci.yml
generated
vendored
28
vendor/github.com/Microsoft/hcsshim/.golangci.yml
generated
vendored
@ -20,18 +20,33 @@ linters:
|
||||
# - typecheck
|
||||
# - unused
|
||||
|
||||
- errorlint # error wrapping (eg, not using `errors.Is`, using `%s` instead of `%w` in `fmt.Errorf`)
|
||||
- gofmt # whether code was gofmt-ed
|
||||
- govet # enabled by default, but just to be sure
|
||||
- nolintlint # ill-formed or insufficient nolint directives
|
||||
- stylecheck # golint replacement
|
||||
- thelper # test helpers without t.Helper()
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
# struct order is often for Win32 compat
|
||||
# also, ignore pointer bytes/GC issues for now until performance becomes an issue
|
||||
- fieldalignment
|
||||
check-shadowing: true
|
||||
|
||||
stylecheck:
|
||||
# https://staticcheck.io/docs/checks
|
||||
checks: ["all"]
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
# err is very often shadowed in nested scopes
|
||||
- linters:
|
||||
- govet
|
||||
text: '^shadow: declaration of "err" shadows declaration'
|
||||
|
||||
# path is relative to module root, which is ./test/
|
||||
- path: cri-containerd
|
||||
linters:
|
||||
@ -39,6 +54,12 @@ issues:
|
||||
text: "^ST1003: should not use underscores in package names$"
|
||||
source: "^package cri_containerd$"
|
||||
|
||||
# don't bother with propper error wrapping in test code
|
||||
- path: cri-containerd
|
||||
linters:
|
||||
- errorlint
|
||||
text: "non-wrapping format verb for fmt.Errorf"
|
||||
|
||||
# This repo has a LOT of generated schema files, operating system bindings, and other
|
||||
# things that ST1003 from stylecheck won't like (screaming case Windows api constants for example).
|
||||
# There's also some structs that we *could* change the initialisms to be Go friendly
|
||||
@ -135,7 +156,7 @@ issues:
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
|
||||
|
||||
# v0 APIs are deprecated, but still retained for backwards compatability
|
||||
- path: cmd\\ncproxy\\
|
||||
linters:
|
||||
@ -146,3 +167,8 @@ issues:
|
||||
linters:
|
||||
- staticcheck
|
||||
text: "^SA1019: .*nodenetsvc[/]?v0"
|
||||
|
||||
- path: internal\\vhdx\\info
|
||||
linters:
|
||||
- stylecheck
|
||||
Text: "ST1003:"
|
||||
|
87
vendor/github.com/Microsoft/hcsshim/Makefile
generated
vendored
87
vendor/github.com/Microsoft/hcsshim/Makefile
generated
vendored
@ -29,12 +29,23 @@ ifeq "$(DEV_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-dev.tar.gz
|
||||
endif
|
||||
|
||||
ifeq "$(SNP_BUILD)" "1"
|
||||
DELTA_TARGET=out/delta-snp.tar.gz
|
||||
endif
|
||||
|
||||
# The link aliases for gcstools
|
||||
GCS_TOOLS=\
|
||||
generichook \
|
||||
install-drivers
|
||||
|
||||
.PHONY: all always rootfs test
|
||||
# Common path prefix.
|
||||
PATH_PREFIX:=
|
||||
# These have PATH_PREFIX prepended to obtain the full path in recipies e.g. $(PATH_PREFIX)/$(VMGS_TOOL)
|
||||
VMGS_TOOL:=
|
||||
IGVM_TOOL:=
|
||||
KERNEL_PATH:=
|
||||
|
||||
.PHONY: all always rootfs test snp simple
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
@ -49,9 +60,58 @@ test:
|
||||
|
||||
rootfs: out/rootfs.vhd
|
||||
|
||||
out/rootfs.vhd: out/rootfs.tar.gz bin/cmd/tar2ext4
|
||||
snp: out/kernelinitrd.vmgs out/rootfs.hash.vhd out/rootfs.vhd out/v2056.vmgs
|
||||
|
||||
simple: out/simple.vmgs snp
|
||||
|
||||
%.vmgs: %.bin
|
||||
rm -f $@
|
||||
# du -BM returns the size of the bin file in M, eg 7M. The sed command replaces the M with *1024*1024 and then bc does the math to convert to bytes
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) create --filepath $@ --filesize `du -BM $< | sed "s/M.*/*1024*1024/" | bc`
|
||||
$(PATH_PREFIX)/$(VMGS_TOOL) write --filepath $@ --datapath $< -i=8
|
||||
|
||||
# Simplest debug UVM used to test changes to the linux kernel. No dmverity protection. Boots an initramdisk rather than directly booting a vhd disk.
|
||||
out/simple.bin: out/initrd.img $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup_simple.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 rdinit=/startup_simple.sh" -rdinit out/initrd.img -vtl 0
|
||||
|
||||
ROOTFS_DEVICE:=/dev/sda
|
||||
VERITY_DEVICE:=/dev/sdb
|
||||
# Debug build for use with uvmtester. UVM with dm-verity protected vhd disk mounted directly via the kernel command line. Ignores corruption in dm-verity protected disk. (Use dmesg to see if dm-verity is ignoring data corruption.)
|
||||
out/v2056.bin: out/rootfs.vhd out/rootfs.hash.vhd $(PATH_PREFIX)/$(KERNEL_PATH) out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt boot/startup_v2056.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt) 1 ignore_corruption\" init=/startup_v2056.sh" -vtl 0
|
||||
|
||||
# Full UVM with dm-verity protected vhd disk mounted directly via the kernel command line.
|
||||
out/kernelinitrd.bin: out/rootfs.vhd out/rootfs.hash.vhd out/rootfs.hash.datasectors out/rootfs.hash.datablocksize out/rootfs.hash.hashblocksize out/rootfs.hash.datablocks out/rootfs.hash.rootdigest out/rootfs.hash.salt $(PATH_PREFIX)/$(KERNEL_PATH) boot/startup.sh
|
||||
rm -f $@
|
||||
python3 $(PATH_PREFIX)/$(IGVM_TOOL) -o $@ -kernel $(PATH_PREFIX)/$(KERNEL_PATH) -append "8250_core.nr_uarts=0 panic=-1 debug loglevel=7 root=/dev/dm-0 dm-mod.create=\"dmverity,,,ro,0 $(shell cat out/rootfs.hash.datasectors) verity 1 $(ROOTFS_DEVICE) $(VERITY_DEVICE) $(shell cat out/rootfs.hash.datablocksize) $(shell cat out/rootfs.hash.hashblocksize) $(shell cat out/rootfs.hash.datablocks) 0 sha256 $(shell cat out/rootfs.hash.rootdigest) $(shell cat out/rootfs.hash.salt)\" init=/startup.sh" -vtl 0
|
||||
|
||||
# Rule to make a vhd from a file. This is used to create the rootfs.hash.vhd from rootfs.hash.
|
||||
%.vhd: % bin/cmd/tar2ext4
|
||||
./bin/cmd/tar2ext4 -only-vhd -i $< -o $@
|
||||
|
||||
# Rule to make a vhd from an ext4 file. This is used to create the rootfs.vhd from rootfs.ext4.
|
||||
%.vhd: %.ext4 bin/cmd/tar2ext4
|
||||
./bin/cmd/tar2ext4 -only-vhd -i $< -o $@
|
||||
|
||||
%.hash %.hash.info %.hash.datablocks %.hash.rootdigest %hash.datablocksize %.hash.datasectors %.hash.hashblocksize: %.ext4 %.hash.salt
|
||||
veritysetup format --no-superblock --salt $(shell cat out/rootfs.hash.salt) $< $*.hash > $*.hash.info
|
||||
# Retrieve info required by dm-verity at boot time
|
||||
# Get the blocksize of rootfs
|
||||
cat $*.hash.info | awk '/^Root hash:/{ print $$3 }' > $*.hash.rootdigest
|
||||
cat $*.hash.info | awk '/^Salt:/{ print $$2 }' > $*.hash.salt
|
||||
cat $*.hash.info | awk '/^Data block size:/{ print $$4 }' > $*.hash.datablocksize
|
||||
cat $*.hash.info | awk '/^Hash block size:/{ print $$4 }' > $*.hash.hashblocksize
|
||||
cat $*.hash.info | awk '/^Data blocks:/{ print $$3 }' > $*.hash.datablocks
|
||||
echo $$(( $$(cat $*.hash.datablocks) * $$(cat $*.hash.datablocksize) / 512 )) > $*.hash.datasectors
|
||||
|
||||
out/rootfs.hash.salt:
|
||||
hexdump -vn32 -e'8/4 "%08X" 1 "\n"' /dev/random > $@
|
||||
|
||||
out/rootfs.ext4: out/rootfs.tar.gz bin/cmd/tar2ext4
|
||||
gzip -f -d ./out/rootfs.tar.gz
|
||||
bin/cmd/tar2ext4 -vhd -i ./out/rootfs.tar -o $@
|
||||
./bin/cmd/tar2ext4 -i ./out/rootfs.tar -o $@
|
||||
|
||||
out/rootfs.tar.gz: out/initrd.img
|
||||
rm -rf rootfs-conv
|
||||
@ -74,6 +134,20 @@ out/delta-dev.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report
|
||||
tar -zcf $@ -C rootfs-dev .
|
||||
rm -rf rootfs-dev
|
||||
|
||||
out/delta-snp.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report boot/startup_v2056.sh boot/startup_simple.sh boot/startup.sh
|
||||
rm -rf rootfs-snp
|
||||
mkdir rootfs-snp
|
||||
tar -xzf out/delta.tar.gz -C rootfs-snp
|
||||
cp boot/startup_v2056.sh rootfs-snp/startup_v2056.sh
|
||||
cp boot/startup_simple.sh rootfs-snp/startup_simple.sh
|
||||
cp boot/startup.sh rootfs-snp/startup.sh
|
||||
cp bin/internal/tools/snp-report rootfs-snp/bin/
|
||||
chmod a+x rootfs-snp/startup_v2056.sh
|
||||
chmod a+x rootfs-snp/startup_simple.sh
|
||||
chmod a+x rootfs-snp/startup.sh
|
||||
tar -zcf $@ -C rootfs-snp .
|
||||
rm -rf rootfs-snp
|
||||
|
||||
out/delta.tar.gz: bin/init bin/vsockexec bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths Makefile
|
||||
@mkdir -p out
|
||||
rm -rf rootfs
|
||||
@ -94,7 +168,10 @@ out/delta.tar.gz: bin/init bin/vsockexec bin/cmd/gcs bin/cmd/gcstools bin/cmd/ho
|
||||
tar -zcf $@ -C rootfs .
|
||||
rm -rf rootfs
|
||||
|
||||
bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report:
|
||||
out/containerd-shim-runhcs-v1.exe:
|
||||
GOOS=windows $(GO_BUILD) -o $@ $(SRCROOT)/cmd/containerd-shim-runhcs-v1
|
||||
|
||||
bin/cmd/gcs bin/cmd/gcstools bin/cmd/hooks/wait-paths bin/cmd/tar2ext4 bin/internal/tools/snp-report bin/cmd/dmverity-vhd:
|
||||
@mkdir -p $(dir $@)
|
||||
GOOS=linux $(GO_BUILD) -o $@ $(SRCROOT)/$(@:bin/%=%)
|
||||
|
||||
@ -108,4 +185,4 @@ bin/init: init/init.o vsockexec/vsock.o
|
||||
|
||||
%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
|
55
vendor/github.com/Microsoft/hcsshim/Protobuild.toml
generated
vendored
55
vendor/github.com/Microsoft/hcsshim/Protobuild.toml
generated
vendored
@ -1,52 +1,25 @@
|
||||
version = "1"
|
||||
generator = "gogoctrd"
|
||||
plugins = ["grpc", "fieldpath"]
|
||||
version = "2"
|
||||
generators = ["go", "go-grpc"]
|
||||
|
||||
# Control protoc include paths. Below are usually some good defaults, but feel
|
||||
# free to try it without them if it works for your project.
|
||||
# Control protoc include paths.
|
||||
[includes]
|
||||
# Include paths that will be added before all others. Typically, you want to
|
||||
# treat the root of the project as an include, but this may not be necessary.
|
||||
before = ["./protobuf"]
|
||||
|
||||
# defaults are "/usr/local/include" and "/usr/include", which don't exist on Windows.
|
||||
# override defaults to supress errors about non-existant directories.
|
||||
after = []
|
||||
|
||||
# Paths that should be treated as include roots in relation to the vendor
|
||||
# directory. These will be calculated with the vendor directory nearest the
|
||||
# target package.
|
||||
packages = ["github.com/gogo/protobuf"]
|
||||
|
||||
# This section maps protobuf imports to Go packages. These will become
|
||||
# `-M` directives in the call to the go protobuf generator.
|
||||
# This section maps protobuf imports to Go packages.
|
||||
[packages]
|
||||
"gogoproto/gogo.proto" = "github.com/gogo/protobuf/gogoproto"
|
||||
"google/protobuf/any.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/empty.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/struct.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/descriptor.proto" = "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
|
||||
"google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types"
|
||||
"google/protobuf/duration.proto" = "github.com/gogo/protobuf/types"
|
||||
"github/containerd/cgroups/stats/v1/metrics.proto" = "github.com/containerd/cgroups/stats/v1"
|
||||
# github.com/containerd/cgroups protofiles still list their go path as "github.com/containerd/cgroups/cgroup1/stats"
|
||||
"github.com/containerd/cgroups/v3/cgroup1/stats/metrics.proto" = "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
|
||||
[[overrides]]
|
||||
prefixes = ["github.com/Microsoft/hcsshim/internal/shimdiag"]
|
||||
plugins = ["ttrpc"]
|
||||
|
||||
[[overrides]]
|
||||
prefixes = ["github.com/Microsoft/hcsshim/internal/extendedtask"]
|
||||
plugins = ["ttrpc"]
|
||||
|
||||
[[overrides]]
|
||||
prefixes = ["github.com/Microsoft/hcsshim/internal/computeagent"]
|
||||
plugins = ["ttrpc"]
|
||||
|
||||
[[overrides]]
|
||||
prefixes = ["github.com/Microsoft/hcsshim/internal/ncproxyttrpc"]
|
||||
plugins = ["ttrpc"]
|
||||
|
||||
[[overrides]]
|
||||
prefixes = ["github.com/Microsoft/hcsshim/internal/vmservice"]
|
||||
plugins = ["ttrpc"]
|
||||
prefixes = [
|
||||
"github.com/Microsoft/hcsshim/internal/shimdiag",
|
||||
"github.com/Microsoft/hcsshim/internal/extendedtask",
|
||||
"github.com/Microsoft/hcsshim/internal/computeagent",
|
||||
"github.com/Microsoft/hcsshim/internal/ncproxyttrpc",
|
||||
"github.com/Microsoft/hcsshim/internal/vmservice",
|
||||
]
|
||||
generators = ["go", "go-ttrpc"]
|
||||
|
84
vendor/github.com/Microsoft/hcsshim/README.md
generated
vendored
84
vendor/github.com/Microsoft/hcsshim/README.md
generated
vendored
@ -9,15 +9,18 @@ It is primarily used in the [Moby](https://github.com/moby/moby) and [Containerd
|
||||
## Building
|
||||
|
||||
While this repository can be used as a library of sorts to call the HCS apis, there are a couple binaries built out of the repository as well. The main ones being the Linux guest agent, and an implementation of the [runtime v2 containerd shim api](https://github.com/containerd/containerd/blob/master/runtime/v2/README.md).
|
||||
|
||||
### Linux Hyper-V Container Guest Agent
|
||||
|
||||
To build the Linux guest agent itself all that's needed is to set your GOOS to "Linux" and build out of ./cmd/gcs.
|
||||
|
||||
```powershell
|
||||
C:\> $env:GOOS="linux"
|
||||
C:\> go build .\cmd\gcs\
|
||||
```
|
||||
|
||||
or on a Linux machine
|
||||
|
||||
```sh
|
||||
> go build ./cmd/gcs
|
||||
```
|
||||
@ -33,13 +36,15 @@ make all
|
||||
```
|
||||
|
||||
If the build is successful, in the `./out` folder you should see:
|
||||
|
||||
```sh
|
||||
> ls ./out/
|
||||
delta.tar.gz initrd.img rootfs.tar.gz
|
||||
```
|
||||
|
||||
### Containerd Shim
|
||||
For info on the Runtime V2 API: https://github.com/containerd/containerd/blob/master/runtime/v2/README.md.
|
||||
|
||||
For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/master/runtime/v2/README.md).
|
||||
|
||||
Contrary to the typical Linux architecture of shim -> runc, the runhcs shim is used both to launch and manage the lifetime of containers.
|
||||
|
||||
@ -48,7 +53,9 @@ C:\> $env:GOOS="windows"
|
||||
C:\> go build .\cmd\containerd-shim-runhcs-v1
|
||||
```
|
||||
|
||||
Then place the binary in the same directory that Containerd is located at in your environment. A default Containerd configuration file can be generated by running:
|
||||
Then place the binary in the same directory that Containerd is located at in your environment.
|
||||
A default Containerd configuration file can be generated by running:
|
||||
|
||||
```powershell
|
||||
.\containerd.exe config default | Out-File "C:\Program Files\containerd\config.toml" -Encoding ascii
|
||||
```
|
||||
@ -56,6 +63,7 @@ Then place the binary in the same directory that Containerd is located at in you
|
||||
This config file will already have the shim set as the default runtime for cri interactions.
|
||||
|
||||
To trial using the shim out with ctr.exe:
|
||||
|
||||
```powershell
|
||||
C:\> ctr.exe run --runtime io.containerd.runhcs.v1 --rm mcr.microsoft.com/windows/nanoserver:2004 windows-test cmd /c "echo Hello World!"
|
||||
```
|
||||
@ -64,16 +72,69 @@ C:\> ctr.exe run --runtime io.containerd.runhcs.v1 --rm mcr.microsoft.com/window
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.microsoft.com.
|
||||
the rights to use your contribution. For details, visit [Microsoft CLA](https://cla.microsoft.com).
|
||||
|
||||
When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
We also require that contributors [sign their commits](https://git-scm.com/docs/git-commit) using `git commit -s` or `git commit --signoff` to
|
||||
certify they either authored the work themselves or otherwise have permission to use it in this project. Please see https://developercertificate.org/ for
|
||||
more info, as well as to make sure that you can attest to the rules listed. Our CI uses the [DCO Github app](https://github.com/apps/dco) to ensure
|
||||
that all commits in a given PR are signed-off.
|
||||
We require that contributors sign their commits
|
||||
to certify they either authored the work themselves or otherwise have permission to use it in this project.
|
||||
|
||||
We also require that contributors sign their commits using using [`git commit --signoff`][git-commit-s]
|
||||
to certify they either authored the work themselves or otherwise have permission to use it in this project.
|
||||
A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s].
|
||||
|
||||
Please see [the developer certificate](https://developercertificate.org) for more info,
|
||||
as well as to make sure that you can attest to the rules listed.
|
||||
Our CI uses the [DCO Github app](https://github.com/apps/dco) to ensure that all commits in a given PR are signed-off.
|
||||
|
||||
### Linting
|
||||
|
||||
Code must pass a linting stage, which uses [`golangci-lint`][lint].
|
||||
Since `./test` is a separate Go module, the linter is run from both the root and the
|
||||
`test` directories. Additionally, the linter is run with `GOOS` set to both `windows` and
|
||||
`linux`.
|
||||
|
||||
The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run
|
||||
automatically with VSCode by adding the following to your workspace or folder settings:
|
||||
|
||||
```json
|
||||
"go.lintTool": "golangci-lint",
|
||||
"go.lintOnSave": "package",
|
||||
```
|
||||
|
||||
Additional editor [integrations options are also available][lint-ide].
|
||||
|
||||
Alternatively, `golangci-lint` can be [installed][lint-install] and run locally:
|
||||
|
||||
```shell
|
||||
# use . or specify a path to only lint a package
|
||||
# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0"
|
||||
> golangci-lint run
|
||||
```
|
||||
|
||||
To run across the entire repo for both `GOOS=windows` and `linux`:
|
||||
|
||||
```powershell
|
||||
> foreach ( $goos in ('windows', 'linux') ) {
|
||||
foreach ( $repo in ('.', 'test') ) {
|
||||
pwsh -Command "cd $repo && go env -w GOOS=$goos && golangci-lint.exe run --verbose"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Go Generate
|
||||
|
||||
The pipeline checks that auto-generated code, via `go generate`, are up to date.
|
||||
Similar to the [linting stage](#linting), `go generate` is run in both the root and test Go modules.
|
||||
|
||||
This can be done via:
|
||||
|
||||
```shell
|
||||
> go generate ./...
|
||||
> cd test && go generate ./...
|
||||
```
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
@ -83,7 +144,7 @@ contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additio
|
||||
|
||||
## Dependencies
|
||||
|
||||
This project requires Golang 1.17 or newer to build.
|
||||
This project requires Golang 1.18 or newer to build.
|
||||
|
||||
For system requirements to run this project, see the Microsoft docs on [Windows Container requirements](https://docs.microsoft.com/en-us/virtualization/windowscontainers/deploy-containers/system-requirements).
|
||||
|
||||
@ -100,3 +161,10 @@ For additional details, see [Report a Computer Security Vulnerability](https://t
|
||||
|
||||
---------------
|
||||
Copyright (c) 2018 Microsoft Corp. All rights reserved.
|
||||
|
||||
[lint]: https://golangci-lint.run/
|
||||
[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration
|
||||
[lint-install]: https://golangci-lint.run/usage/install/#local-installation
|
||||
|
||||
[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s
|
||||
[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff
|
||||
|
28
vendor/github.com/Microsoft/hcsshim/computestorage/attach.go
generated
vendored
28
vendor/github.com/Microsoft/hcsshim/computestorage/attach.go
generated
vendored
@ -38,3 +38,31 @@ func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData L
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AttachOverlayFilter sets up a filter of the given type on a writable container layer. Currently the only
|
||||
// supported filter types are WCIFS & UnionFS (defined in internal/hcs/schema2/layer.go)
|
||||
//
|
||||
// `volumePath` is volume path at which writable layer is mounted. If the
|
||||
// path does not end in a `\` the platform will append it automatically.
|
||||
//
|
||||
// `layerData` is the parent read-only layer data.
|
||||
func AttachOverlayFilter(ctx context.Context, volumePath string, layerData LayerData) (err error) {
|
||||
title := "hcsshim::AttachOverlayFilter"
|
||||
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(
|
||||
trace.StringAttribute("volumePath", volumePath),
|
||||
)
|
||||
|
||||
bytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsAttachOverlayFilter(volumePath, string(bytes))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to attach overlay filter")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
26
vendor/github.com/Microsoft/hcsshim/computestorage/detach.go
generated
vendored
26
vendor/github.com/Microsoft/hcsshim/computestorage/detach.go
generated
vendored
@ -4,7 +4,9 @@ package computestorage
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"github.com/pkg/errors"
|
||||
"go.opencensus.io/trace"
|
||||
@ -26,3 +28,27 @@ func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DetachOverlayFilter detaches the filter on a writable container layer.
|
||||
//
|
||||
// `volumePath` is a path to writable container volume.
|
||||
func DetachOverlayFilter(ctx context.Context, volumePath string, filterType hcsschema.FileSystemFilterType) (err error) {
|
||||
title := "hcsshim::DetachOverlayFilter"
|
||||
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(trace.StringAttribute("volumePath", volumePath))
|
||||
|
||||
layerData := LayerData{}
|
||||
layerData.FilterType = filterType
|
||||
bytes, err := json.Marshal(layerData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = hcsDetachOverlayFilter(volumePath, string(bytes))
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to detach overlay filter")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/computestorage/helpers.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/computestorage/helpers.go
generated
vendored
@ -16,7 +16,9 @@ import (
|
||||
"github.com/Microsoft/hcsshim/internal/security"
|
||||
)
|
||||
|
||||
const defaultVHDXBlockSizeInMB = 1
|
||||
const (
|
||||
defaultVHDXBlockSizeInMB = 1
|
||||
)
|
||||
|
||||
// SetupContainerBaseLayer is a helper to setup a containers scratch. It
|
||||
// will create and format the vhdx's inside and the size is configurable with the sizeInGB
|
||||
|
9
vendor/github.com/Microsoft/hcsshim/computestorage/storage.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/computestorage/storage.go
generated
vendored
@ -11,7 +11,7 @@ import (
|
||||
|
||||
//sys hcsImportLayer(layerPath string, sourceFolderPath string, layerData string) (hr error) = computestorage.HcsImportLayer?
|
||||
//sys hcsExportLayer(layerPath string, exportFolderPath string, layerData string, options string) (hr error) = computestorage.HcsExportLayer?
|
||||
//sys hcsDestroyLayer(layerPath string) (hr error) = computestorage.HcsDestoryLayer?
|
||||
//sys hcsDestroyLayer(layerPath string) (hr error) = computestorage.HcsDestroyLayer?
|
||||
//sys hcsSetupBaseOSLayer(layerPath string, handle windows.Handle, options string) (hr error) = computestorage.HcsSetupBaseOSLayer?
|
||||
//sys hcsInitializeWritableLayer(writableLayerPath string, layerData string, options string) (hr error) = computestorage.HcsInitializeWritableLayer?
|
||||
//sys hcsAttachLayerStorageFilter(layerPath string, layerData string) (hr error) = computestorage.HcsAttachLayerStorageFilter?
|
||||
@ -19,14 +19,17 @@ import (
|
||||
//sys hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) = computestorage.HcsFormatWritableLayerVhd?
|
||||
//sys hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr error) = computestorage.HcsGetLayerVhdMountPath?
|
||||
//sys hcsSetupBaseOSVolume(layerPath string, volumePath string, options string) (hr error) = computestorage.HcsSetupBaseOSVolume?
|
||||
//sys hcsAttachOverlayFilter(volumePath string, layerData string) (hr error) = computestorage.HcsAttachOverlayFilter?
|
||||
//sys hcsDetachOverlayFilter(volumePath string, layerData string) (hr error) = computestorage.HcsDetachOverlayFilter?
|
||||
|
||||
type Version = hcsschema.Version
|
||||
type Layer = hcsschema.Layer
|
||||
|
||||
// LayerData is the data used to describe parent layer information.
|
||||
type LayerData struct {
|
||||
SchemaVersion Version `json:"SchemaVersion,omitempty"`
|
||||
Layers []Layer `json:"Layers,omitempty"`
|
||||
SchemaVersion Version `json:"SchemaVersion,omitempty"`
|
||||
Layers []Layer `json:"Layers,omitempty"`
|
||||
FilterType hcsschema.FileSystemFilterType `json:"FilterType,omitempty"`
|
||||
}
|
||||
|
||||
// ExportLayerOptions are the set of options that are used with the `computestorage.HcsExportLayer` syscall.
|
||||
|
87
vendor/github.com/Microsoft/hcsshim/computestorage/zsyscall_windows.go
generated
vendored
87
vendor/github.com/Microsoft/hcsshim/computestorage/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -43,8 +40,10 @@ var (
|
||||
modcomputestorage = windows.NewLazySystemDLL("computestorage.dll")
|
||||
|
||||
procHcsAttachLayerStorageFilter = modcomputestorage.NewProc("HcsAttachLayerStorageFilter")
|
||||
procHcsDestoryLayer = modcomputestorage.NewProc("HcsDestoryLayer")
|
||||
procHcsAttachOverlayFilter = modcomputestorage.NewProc("HcsAttachOverlayFilter")
|
||||
procHcsDestroyLayer = modcomputestorage.NewProc("HcsDestroyLayer")
|
||||
procHcsDetachLayerStorageFilter = modcomputestorage.NewProc("HcsDetachLayerStorageFilter")
|
||||
procHcsDetachOverlayFilter = modcomputestorage.NewProc("HcsDetachOverlayFilter")
|
||||
procHcsExportLayer = modcomputestorage.NewProc("HcsExportLayer")
|
||||
procHcsFormatWritableLayerVhd = modcomputestorage.NewProc("HcsFormatWritableLayerVhd")
|
||||
procHcsGetLayerVhdMountPath = modcomputestorage.NewProc("HcsGetLayerVhdMountPath")
|
||||
@ -73,7 +72,36 @@ func _hcsAttachLayerStorageFilter(layerPath *uint16, layerData *uint16) (hr erro
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsAttachLayerStorageFilter.Addr(), 2, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(layerData)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsAttachLayerStorageFilter.Addr(), uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(layerData)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsAttachOverlayFilter(volumePath string, layerData string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(volumePath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsAttachOverlayFilter(_p0, _p1)
|
||||
}
|
||||
|
||||
func _hcsAttachOverlayFilter(volumePath *uint16, layerData *uint16) (hr error) {
|
||||
hr = procHcsAttachOverlayFilter.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procHcsAttachOverlayFilter.Addr(), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(layerData)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -93,11 +121,11 @@ func hcsDestroyLayer(layerPath string) (hr error) {
|
||||
}
|
||||
|
||||
func _hcsDestroyLayer(layerPath *uint16) (hr error) {
|
||||
hr = procHcsDestoryLayer.Find()
|
||||
hr = procHcsDestroyLayer.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsDestoryLayer.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsDestroyLayer.Addr(), uintptr(unsafe.Pointer(layerPath)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -121,7 +149,36 @@ func _hcsDetachLayerStorageFilter(layerPath *uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsDetachLayerStorageFilter.Addr(), 1, uintptr(unsafe.Pointer(layerPath)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsDetachLayerStorageFilter.Addr(), uintptr(unsafe.Pointer(layerPath)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
}
|
||||
hr = syscall.Errno(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func hcsDetachOverlayFilter(volumePath string, layerData string) (hr error) {
|
||||
var _p0 *uint16
|
||||
_p0, hr = syscall.UTF16PtrFromString(volumePath)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
var _p1 *uint16
|
||||
_p1, hr = syscall.UTF16PtrFromString(layerData)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
return _hcsDetachOverlayFilter(_p0, _p1)
|
||||
}
|
||||
|
||||
func _hcsDetachOverlayFilter(volumePath *uint16, layerData *uint16) (hr error) {
|
||||
hr = procHcsDetachOverlayFilter.Find()
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.SyscallN(procHcsDetachOverlayFilter.Addr(), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(layerData)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -160,7 +217,7 @@ func _hcsExportLayer(layerPath *uint16, exportFolderPath *uint16, layerData *uin
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcsExportLayer.Addr(), 4, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(exportFolderPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsExportLayer.Addr(), uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(exportFolderPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -175,7 +232,7 @@ func hcsFormatWritableLayerVhd(handle windows.Handle) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsFormatWritableLayerVhd.Addr(), 1, uintptr(handle), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsFormatWritableLayerVhd.Addr(), uintptr(handle))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -190,7 +247,7 @@ func hcsGetLayerVhdMountPath(vhdHandle windows.Handle, mountPath **uint16) (hr e
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsGetLayerVhdMountPath.Addr(), 2, uintptr(vhdHandle), uintptr(unsafe.Pointer(mountPath)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcsGetLayerVhdMountPath.Addr(), uintptr(vhdHandle), uintptr(unsafe.Pointer(mountPath)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -224,7 +281,7 @@ func _hcsImportLayer(layerPath *uint16, sourceFolderPath *uint16, layerData *uin
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsImportLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(sourceFolderPath)), uintptr(unsafe.Pointer(layerData)))
|
||||
r0, _, _ := syscall.SyscallN(procHcsImportLayer.Addr(), uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(sourceFolderPath)), uintptr(unsafe.Pointer(layerData)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -258,7 +315,7 @@ func _hcsInitializeWritableLayer(writableLayerPath *uint16, layerData *uint16, o
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsInitializeWritableLayer.Addr(), 3, uintptr(unsafe.Pointer(writableLayerPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)))
|
||||
r0, _, _ := syscall.SyscallN(procHcsInitializeWritableLayer.Addr(), uintptr(unsafe.Pointer(writableLayerPath)), uintptr(unsafe.Pointer(layerData)), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -287,7 +344,7 @@ func _hcsSetupBaseOSLayer(layerPath *uint16, handle windows.Handle, options *uin
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsSetupBaseOSLayer.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(handle), uintptr(unsafe.Pointer(options)))
|
||||
r0, _, _ := syscall.SyscallN(procHcsSetupBaseOSLayer.Addr(), uintptr(unsafe.Pointer(layerPath)), uintptr(handle), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -321,7 +378,7 @@ func _hcsSetupBaseOSVolume(layerPath *uint16, volumePath *uint16, options *uint1
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcsSetupBaseOSVolume.Addr(), 3, uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(options)))
|
||||
r0, _, _ := syscall.SyscallN(procHcsSetupBaseOSVolume.Addr(), uintptr(unsafe.Pointer(layerPath)), uintptr(unsafe.Pointer(volumePath)), uintptr(unsafe.Pointer(options)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/container.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/container.go
generated
vendored
@ -75,7 +75,7 @@ func init() {
|
||||
func CreateContainer(id string, c *ContainerConfig) (Container, error) {
|
||||
fullConfig, err := mergemaps.MergeJSON(c, createContainerAdditionalJSON)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to merge additional JSON '%s': %s", createContainerAdditionalJSON, err)
|
||||
return nil, fmt.Errorf("failed to merge additional JSON '%s': %w", createContainerAdditionalJSON, err)
|
||||
}
|
||||
|
||||
system, err := hcs.CreateComputeSystem(context.Background(), id, fullConfig)
|
||||
|
11
vendor/github.com/Microsoft/hcsshim/errors.go
generated
vendored
11
vendor/github.com/Microsoft/hcsshim/errors.go
generated
vendored
@ -115,6 +115,7 @@ func (e *ContainerError) Error() string {
|
||||
s += " encountered an error during " + e.Operation
|
||||
}
|
||||
|
||||
//nolint:errorlint // legacy code
|
||||
switch e.Err.(type) {
|
||||
case nil:
|
||||
break
|
||||
@ -145,6 +146,7 @@ func (e *ProcessError) Error() string {
|
||||
s += " encountered an error during " + e.Operation
|
||||
}
|
||||
|
||||
//nolint:errorlint // legacy code
|
||||
switch e.Err.(type) {
|
||||
case nil:
|
||||
break
|
||||
@ -166,10 +168,10 @@ func (e *ProcessError) Error() string {
|
||||
// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
|
||||
// will currently return true when the error is ErrElementNotFound.
|
||||
func IsNotExist(err error) bool {
|
||||
if _, ok := err.(EndpointNotFoundError); ok {
|
||||
if _, ok := err.(EndpointNotFoundError); ok { //nolint:errorlint // legacy code
|
||||
return true
|
||||
}
|
||||
if _, ok := err.(NetworkNotFoundError); ok {
|
||||
if _, ok := err.(NetworkNotFoundError); ok { //nolint:errorlint // legacy code
|
||||
return true
|
||||
}
|
||||
return hcs.IsNotExist(getInnerError(err))
|
||||
@ -224,6 +226,7 @@ func IsAccessIsDenied(err error) bool {
|
||||
}
|
||||
|
||||
func getInnerError(err error) error {
|
||||
//nolint:errorlint // legacy code
|
||||
switch pe := err.(type) {
|
||||
case nil:
|
||||
return nil
|
||||
@ -236,14 +239,14 @@ func getInnerError(err error) error {
|
||||
}
|
||||
|
||||
func convertSystemError(err error, c *container) error {
|
||||
if serr, ok := err.(*hcs.SystemError); ok {
|
||||
if serr, ok := err.(*hcs.SystemError); ok { //nolint:errorlint // legacy code
|
||||
return &ContainerError{Container: c, Operation: serr.Op, Err: serr.Err, Events: serr.Events}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func convertProcessError(err error, p *process) error {
|
||||
if perr, ok := err.(*hcs.ProcessError); ok {
|
||||
if perr, ok := err.(*hcs.ProcessError); ok { //nolint:errorlint // legacy code
|
||||
return &ProcessError{Process: p, Operation: perr.Op, Err: perr.Err, Events: perr.Events}
|
||||
}
|
||||
return err
|
||||
|
12
vendor/github.com/Microsoft/hcsshim/hcn/hcn.go
generated
vendored
12
vendor/github.com/Microsoft/hcsshim/hcn/hcn.go
generated
vendored
@ -312,6 +312,18 @@ func NestedIpSetSupported() error {
|
||||
return platformDoesNotSupportError("NestedIpSet")
|
||||
}
|
||||
|
||||
// DisableHostPortSupported returns an error if the HCN version does not support DisableHostPort flag
|
||||
func DisableHostPortSupported() error {
|
||||
supported, err := GetCachedSupportedFeatures()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if supported.DisableHostPort {
|
||||
return nil
|
||||
}
|
||||
return platformDoesNotSupportError("DisableHostPort")
|
||||
}
|
||||
|
||||
// RequestType are the different operations performed to settings.
|
||||
// Used to update the settings of Endpoint/Namespace objects.
|
||||
type RequestType string
|
||||
|
57
vendor/github.com/Microsoft/hcsshim/hcn/hcnerrors.go
generated
vendored
57
vendor/github.com/Microsoft/hcsshim/hcn/hcnerrors.go
generated
vendored
@ -6,11 +6,12 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/windows"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/hcs"
|
||||
"github.com/Microsoft/hcsshim/internal/hcserror"
|
||||
"github.com/Microsoft/hcsshim/internal/interop"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -63,8 +64,8 @@ func (e *HcnError) Error() string {
|
||||
}
|
||||
|
||||
func CheckErrorWithCode(err error, code ErrorCode) bool {
|
||||
hcnError, ok := err.(*HcnError)
|
||||
if ok {
|
||||
var hcnError *HcnError
|
||||
if errors.As(err, &hcnError) {
|
||||
return hcnError.code == code
|
||||
}
|
||||
return false
|
||||
@ -81,7 +82,7 @@ func IsPortAlreadyExistsError(err error) bool {
|
||||
func new(hr error, title string, rest string) error {
|
||||
err := &HcnError{}
|
||||
hcsError := hcserror.New(hr, title, rest)
|
||||
err.HcsError = hcsError.(*hcserror.HcsError)
|
||||
err.HcsError = hcsError.(*hcserror.HcsError) //nolint:errorlint
|
||||
err.code = ErrorCode(hcserror.Win32FromError(hr))
|
||||
return err
|
||||
}
|
||||
@ -97,6 +98,8 @@ type NetworkNotFoundError struct {
|
||||
NetworkID string
|
||||
}
|
||||
|
||||
var _ error = NetworkNotFoundError{}
|
||||
|
||||
func (e NetworkNotFoundError) Error() string {
|
||||
if e.NetworkName != "" {
|
||||
return fmt.Sprintf("Network name %q not found", e.NetworkName)
|
||||
@ -110,6 +113,8 @@ type EndpointNotFoundError struct {
|
||||
EndpointID string
|
||||
}
|
||||
|
||||
var _ error = EndpointNotFoundError{}
|
||||
|
||||
func (e EndpointNotFoundError) Error() string {
|
||||
if e.EndpointName != "" {
|
||||
return fmt.Sprintf("Endpoint name %q not found", e.EndpointName)
|
||||
@ -122,6 +127,8 @@ type NamespaceNotFoundError struct {
|
||||
NamespaceID string
|
||||
}
|
||||
|
||||
var _ error = NamespaceNotFoundError{}
|
||||
|
||||
func (e NamespaceNotFoundError) Error() string {
|
||||
return fmt.Sprintf("Namespace ID %q not found", e.NamespaceID)
|
||||
}
|
||||
@ -131,6 +138,8 @@ type LoadBalancerNotFoundError struct {
|
||||
LoadBalancerId string
|
||||
}
|
||||
|
||||
var _ error = LoadBalancerNotFoundError{}
|
||||
|
||||
func (e LoadBalancerNotFoundError) Error() string {
|
||||
return fmt.Sprintf("LoadBalancer %q not found", e.LoadBalancerId)
|
||||
}
|
||||
@ -140,6 +149,8 @@ type RouteNotFoundError struct {
|
||||
RouteId string
|
||||
}
|
||||
|
||||
var _ error = RouteNotFoundError{}
|
||||
|
||||
func (e RouteNotFoundError) Error() string {
|
||||
return fmt.Sprintf("SDN Route %q not found", e.RouteId)
|
||||
}
|
||||
@ -147,19 +158,31 @@ func (e RouteNotFoundError) Error() string {
|
||||
// IsNotFoundError returns a boolean indicating whether the error was caused by
|
||||
// a resource not being found.
|
||||
func IsNotFoundError(err error) bool {
|
||||
switch pe := err.(type) {
|
||||
case NetworkNotFoundError:
|
||||
// Calling [errors.As] in a loop over `[]error{NetworkNotFoundError{}, ...}` will not work,
|
||||
// since the loop variable will be an interface type (ie, `error`) and `errors.As(error, *error)` will
|
||||
// always succeed.
|
||||
// Unless golang adds loops over (or arrays of) types, we need to manually call `errors.As` for
|
||||
// each potential error type.
|
||||
//
|
||||
// Also, for T = NetworkNotFoundError and co, the error implementation is for T, not *T
|
||||
if e := (NetworkNotFoundError{}); errors.As(err, &e) {
|
||||
return true
|
||||
case EndpointNotFoundError:
|
||||
return true
|
||||
case NamespaceNotFoundError:
|
||||
return true
|
||||
case LoadBalancerNotFoundError:
|
||||
return true
|
||||
case RouteNotFoundError:
|
||||
return true
|
||||
case *hcserror.HcsError:
|
||||
return pe.Err == hcs.ErrElementNotFound
|
||||
}
|
||||
if e := (EndpointNotFoundError{}); errors.As(err, &e) {
|
||||
return true
|
||||
}
|
||||
if e := (NamespaceNotFoundError{}); errors.As(err, &e) {
|
||||
return true
|
||||
}
|
||||
if e := (LoadBalancerNotFoundError{}); errors.As(err, &e) {
|
||||
return true
|
||||
}
|
||||
if e := (RouteNotFoundError{}); errors.As(err, &e) {
|
||||
return true
|
||||
}
|
||||
if e := (&hcserror.HcsError{}); errors.As(err, &e) {
|
||||
return errors.Is(e.Err, hcs.ErrElementNotFound)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
3
vendor/github.com/Microsoft/hcsshim/hcn/hcnglobals.go
generated
vendored
3
vendor/github.com/Microsoft/hcsshim/hcn/hcnglobals.go
generated
vendored
@ -84,6 +84,9 @@ var (
|
||||
|
||||
//HNS 15.0 allows for NestedIpSet support
|
||||
NestedIpSetVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 15, Minor: 0}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
|
||||
|
||||
//HNS 15.1 allows support for DisableHostPort flag.
|
||||
DisableHostPortVersion = VersionRanges{VersionRange{MinVersion: Version{Major: 15, Minor: 1}, MaxVersion: Version{Major: math.MaxInt32, Minor: math.MaxInt32}}}
|
||||
)
|
||||
|
||||
// GetGlobals returns the global properties of the HCN Service.
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/hcn/hcnnamespace.go
generated
vendored
@ -4,6 +4,7 @@ package hcn
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"syscall"
|
||||
|
||||
@ -378,7 +379,8 @@ func (namespace *HostComputeNamespace) Sync() error {
|
||||
shimPath := runhcs.VMPipePath(cfg.HostUniqueID)
|
||||
if err := runhcs.IssueVMRequest(shimPath, &req); err != nil {
|
||||
// The shim is likely gone. Simply ignore the sync as if it didn't exist.
|
||||
if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
var perr *os.PathError
|
||||
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ERROR_FILE_NOT_FOUND) {
|
||||
// Remove the reg key there is no point to try again
|
||||
_ = cfg.Remove()
|
||||
return nil
|
||||
|
1
vendor/github.com/Microsoft/hcsshim/hcn/hcnnetwork.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/hcn/hcnnetwork.go
generated
vendored
@ -72,6 +72,7 @@ type NetworkFlags uint32
|
||||
const (
|
||||
None NetworkFlags = 0
|
||||
EnableNonPersistent NetworkFlags = 8
|
||||
DisableHostPort NetworkFlags = 1024
|
||||
)
|
||||
|
||||
// HostComputeNetwork represents a network
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/hcn/hcnsupport.go
generated
vendored
@ -37,6 +37,7 @@ type SupportedFeatures struct {
|
||||
TierAcl bool `json:"TierAcl"`
|
||||
NetworkACL bool `json:"NetworkACL"`
|
||||
NestedIpSet bool `json:"NestedIpSet"`
|
||||
DisableHostPort bool `json:"DisableHostPort"`
|
||||
}
|
||||
|
||||
// AclFeatures are the supported ACL possibilities.
|
||||
@ -114,6 +115,7 @@ func getSupportedFeatures() (SupportedFeatures, error) {
|
||||
features.TierAcl = isFeatureSupported(globals.Version, TierAclPolicyVersion)
|
||||
features.NetworkACL = isFeatureSupported(globals.Version, NetworkACLPolicyVersion)
|
||||
features.NestedIpSet = isFeatureSupported(globals.Version, NestedIpSetVersion)
|
||||
features.DisableHostPort = isFeatureSupported(globals.Version, DisableHostPortVersion)
|
||||
|
||||
log.L.WithFields(logrus.Fields{
|
||||
"version": globals.Version,
|
||||
|
77
vendor/github.com/Microsoft/hcsshim/hcn/zsyscall_windows.go
generated
vendored
77
vendor/github.com/Microsoft/hcsshim/hcn/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -88,7 +85,7 @@ func hcnCloseEndpoint(endpoint hcnEndpoint) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnCloseEndpoint.Addr(), 1, uintptr(endpoint), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCloseEndpoint.Addr(), uintptr(endpoint))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -103,7 +100,7 @@ func hcnCloseLoadBalancer(loadBalancer hcnLoadBalancer) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnCloseLoadBalancer.Addr(), 1, uintptr(loadBalancer), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCloseLoadBalancer.Addr(), uintptr(loadBalancer))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -118,7 +115,7 @@ func hcnCloseNamespace(namespace hcnNamespace) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnCloseNamespace.Addr(), 1, uintptr(namespace), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCloseNamespace.Addr(), uintptr(namespace))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -133,7 +130,7 @@ func hcnCloseNetwork(network hcnNetwork) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnCloseNetwork.Addr(), 1, uintptr(network), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCloseNetwork.Addr(), uintptr(network))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -148,7 +145,7 @@ func hcnCloseRoute(route hcnRoute) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnCloseSdnRoute.Addr(), 1, uintptr(route), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCloseSdnRoute.Addr(), uintptr(route))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -172,7 +169,7 @@ func _hcnCreateEndpoint(network hcnNetwork, id *_guid, settings *uint16, endpoin
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnCreateEndpoint.Addr(), 5, uintptr(network), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(endpoint)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCreateEndpoint.Addr(), uintptr(network), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(endpoint)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -196,7 +193,7 @@ func _hcnCreateLoadBalancer(id *_guid, settings *uint16, loadBalancer *hcnLoadBa
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnCreateLoadBalancer.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(loadBalancer)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCreateLoadBalancer.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(loadBalancer)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -220,7 +217,7 @@ func _hcnCreateNamespace(id *_guid, settings *uint16, namespace *hcnNamespace, r
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnCreateNamespace.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(namespace)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCreateNamespace.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(namespace)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -244,7 +241,7 @@ func _hcnCreateNetwork(id *_guid, settings *uint16, network *hcnNetwork, result
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnCreateNetwork.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(network)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCreateNetwork.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(network)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -268,7 +265,7 @@ func _hcnCreateRoute(id *_guid, settings *uint16, route *hcnRoute, result **uint
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnCreateSdnRoute.Addr(), 4, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnCreateSdnRoute.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -283,7 +280,7 @@ func hcnDeleteEndpoint(id *_guid, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnDeleteEndpoint.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnDeleteEndpoint.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -298,7 +295,7 @@ func hcnDeleteLoadBalancer(id *_guid, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnDeleteLoadBalancer.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnDeleteLoadBalancer.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -313,7 +310,7 @@ func hcnDeleteNamespace(id *_guid, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnDeleteNamespace.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnDeleteNamespace.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -328,7 +325,7 @@ func hcnDeleteNetwork(id *_guid, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnDeleteNetwork.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnDeleteNetwork.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -343,7 +340,7 @@ func hcnDeleteRoute(id *_guid, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnDeleteSdnRoute.Addr(), 2, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnDeleteSdnRoute.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -367,7 +364,7 @@ func _hcnEnumerateEndpoints(query *uint16, endpoints **uint16, result **uint16)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnEnumerateEndpoints.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(endpoints)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnEnumerateEndpoints.Addr(), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(endpoints)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -391,7 +388,7 @@ func _hcnEnumerateLoadBalancers(query *uint16, loadBalancers **uint16, result **
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnEnumerateLoadBalancers.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(loadBalancers)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnEnumerateLoadBalancers.Addr(), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(loadBalancers)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -415,7 +412,7 @@ func _hcnEnumerateNamespaces(query *uint16, namespaces **uint16, result **uint16
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnEnumerateNamespaces.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(namespaces)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnEnumerateNamespaces.Addr(), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(namespaces)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -439,7 +436,7 @@ func _hcnEnumerateNetworks(query *uint16, networks **uint16, result **uint16) (h
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnEnumerateNetworks.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(networks)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnEnumerateNetworks.Addr(), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(networks)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -463,7 +460,7 @@ func _hcnEnumerateRoutes(query *uint16, routes **uint16, result **uint16) (hr er
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnEnumerateSdnRoutes.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(routes)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnEnumerateSdnRoutes.Addr(), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(routes)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -487,7 +484,7 @@ func _hcnModifyEndpoint(endpoint hcnEndpoint, settings *uint16, result **uint16)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnModifyEndpoint.Addr(), 3, uintptr(endpoint), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnModifyEndpoint.Addr(), uintptr(endpoint), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -511,7 +508,7 @@ func _hcnModifyLoadBalancer(loadBalancer hcnLoadBalancer, settings *uint16, resu
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnModifyLoadBalancer.Addr(), 3, uintptr(loadBalancer), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnModifyLoadBalancer.Addr(), uintptr(loadBalancer), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -535,7 +532,7 @@ func _hcnModifyNamespace(namespace hcnNamespace, settings *uint16, result **uint
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnModifyNamespace.Addr(), 3, uintptr(namespace), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnModifyNamespace.Addr(), uintptr(namespace), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -559,7 +556,7 @@ func _hcnModifyNetwork(network hcnNetwork, settings *uint16, result **uint16) (h
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnModifyNetwork.Addr(), 3, uintptr(network), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnModifyNetwork.Addr(), uintptr(network), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -583,7 +580,7 @@ func _hcnModifyRoute(route hcnRoute, settings *uint16, result **uint16) (hr erro
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnModifySdnRoute.Addr(), 3, uintptr(route), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnModifySdnRoute.Addr(), uintptr(route), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -598,7 +595,7 @@ func hcnOpenEndpoint(id *_guid, endpoint *hcnEndpoint, result **uint16) (hr erro
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnOpenEndpoint.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(endpoint)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnOpenEndpoint.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(endpoint)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -613,7 +610,7 @@ func hcnOpenLoadBalancer(id *_guid, loadBalancer *hcnLoadBalancer, result **uint
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnOpenLoadBalancer.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(loadBalancer)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnOpenLoadBalancer.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(loadBalancer)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -628,7 +625,7 @@ func hcnOpenNamespace(id *_guid, namespace *hcnNamespace, result **uint16) (hr e
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnOpenNamespace.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(namespace)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnOpenNamespace.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(namespace)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -643,7 +640,7 @@ func hcnOpenNetwork(id *_guid, network *hcnNetwork, result **uint16) (hr error)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnOpenNetwork.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(network)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnOpenNetwork.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(network)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -658,7 +655,7 @@ func hcnOpenRoute(id *_guid, route *hcnRoute, result **uint16) (hr error) {
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall(procHcnOpenSdnRoute.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)))
|
||||
r0, _, _ := syscall.SyscallN(procHcnOpenSdnRoute.Addr(), uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(route)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -682,7 +679,7 @@ func _hcnQueryEndpointProperties(endpoint hcnEndpoint, query *uint16, properties
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnQueryEndpointProperties.Addr(), 4, uintptr(endpoint), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnQueryEndpointProperties.Addr(), uintptr(endpoint), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -706,7 +703,7 @@ func _hcnQueryLoadBalancerProperties(loadBalancer hcnLoadBalancer, query *uint16
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnQueryLoadBalancerProperties.Addr(), 4, uintptr(loadBalancer), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnQueryLoadBalancerProperties.Addr(), uintptr(loadBalancer), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -730,7 +727,7 @@ func _hcnQueryNamespaceProperties(namespace hcnNamespace, query *uint16, propert
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnQueryNamespaceProperties.Addr(), 4, uintptr(namespace), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnQueryNamespaceProperties.Addr(), uintptr(namespace), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -754,7 +751,7 @@ func _hcnQueryNetworkProperties(network hcnNetwork, query *uint16, properties **
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnQueryNetworkProperties.Addr(), 4, uintptr(network), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnQueryNetworkProperties.Addr(), uintptr(network), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -778,7 +775,7 @@ func _hcnQueryRouteProperties(route hcnRoute, query *uint16, properties **uint16
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHcnQuerySdnRouteProperties.Addr(), 4, uintptr(route), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHcnQuerySdnRouteProperties.Addr(), uintptr(route), uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -789,7 +786,7 @@ func _hcnQueryRouteProperties(route hcnRoute, query *uint16, properties **uint16
|
||||
}
|
||||
|
||||
func SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) {
|
||||
r0, _, _ := syscall.Syscall(procSetCurrentThreadCompartmentId.Addr(), 1, uintptr(compartmentId), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procSetCurrentThreadCompartmentId.Addr(), uintptr(compartmentId))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
@ -823,7 +820,7 @@ func __hnsCall(method *uint16, path *uint16, object *uint16, response **uint16)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHNSCall.Addr(), 4, uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHNSCall.Addr(), uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
|
56
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
generated
vendored
56
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
generated
vendored
@ -12,14 +12,16 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"go.opencensus.io/trace"
|
||||
|
||||
"github.com/Microsoft/hcsshim/internal/cow"
|
||||
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
|
||||
"github.com/Microsoft/hcsshim/internal/log"
|
||||
"github.com/Microsoft/hcsshim/internal/oc"
|
||||
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
|
||||
"github.com/Microsoft/hcsshim/internal/vmcompute"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// ContainerError is an error encountered in HCS
|
||||
type Process struct {
|
||||
handleLock sync.RWMutex
|
||||
handle vmcompute.HcsProcess
|
||||
@ -50,35 +52,6 @@ func newProcess(process vmcompute.HcsProcess, processID int, computeSystem *Syst
|
||||
}
|
||||
}
|
||||
|
||||
type processModifyRequest struct {
|
||||
Operation string
|
||||
ConsoleSize *consoleSize `json:",omitempty"`
|
||||
CloseHandle *closeHandle `json:",omitempty"`
|
||||
}
|
||||
|
||||
type consoleSize struct {
|
||||
Height uint16
|
||||
Width uint16
|
||||
}
|
||||
|
||||
type closeHandle struct {
|
||||
Handle string
|
||||
}
|
||||
|
||||
type processStatus struct {
|
||||
ProcessID uint32
|
||||
Exited bool
|
||||
ExitCode uint32
|
||||
LastWaitResult int32
|
||||
}
|
||||
|
||||
const stdIn string = "StdIn"
|
||||
|
||||
const (
|
||||
modifyConsoleSize string = "ConsoleSize"
|
||||
modifyCloseHandle string = "CloseHandle"
|
||||
)
|
||||
|
||||
// Pid returns the process ID of the process within the container.
|
||||
func (process *Process) Pid() int {
|
||||
return process.processID
|
||||
@ -90,7 +63,7 @@ func (process *Process) SystemID() string {
|
||||
}
|
||||
|
||||
func (process *Process) processSignalResult(ctx context.Context, err error) (bool, error) {
|
||||
switch err {
|
||||
switch err { //nolint:errorlint
|
||||
case nil:
|
||||
return true, nil
|
||||
case ErrVmcomputeOperationInvalidState, ErrComputeSystemDoesNotExist, ErrElementNotFound:
|
||||
@ -260,14 +233,14 @@ func (process *Process) waitBackground() {
|
||||
process.handleLock.RLock()
|
||||
defer process.handleLock.RUnlock()
|
||||
|
||||
// Make sure we didnt race with Close() here
|
||||
// Make sure we didn't race with Close() here
|
||||
if process.handle != 0 {
|
||||
propertiesJSON, resultJSON, err = vmcompute.HcsGetProcessProperties(ctx, process.handle)
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
if err != nil {
|
||||
err = makeProcessError(process, operation, err, events)
|
||||
} else {
|
||||
properties := &processStatus{}
|
||||
properties := &hcsschema.ProcessStatus{}
|
||||
err = json.Unmarshal([]byte(propertiesJSON), properties)
|
||||
if err != nil {
|
||||
err = makeProcessError(process, operation, err, nil)
|
||||
@ -318,10 +291,9 @@ func (process *Process) ResizeConsole(ctx context.Context, width, height uint16)
|
||||
if process.handle == 0 {
|
||||
return makeProcessError(process, operation, ErrAlreadyClosed, nil)
|
||||
}
|
||||
|
||||
modifyRequest := processModifyRequest{
|
||||
Operation: modifyConsoleSize,
|
||||
ConsoleSize: &consoleSize{
|
||||
modifyRequest := hcsschema.ProcessModifyRequest{
|
||||
Operation: guestrequest.ModifyProcessConsoleSize,
|
||||
ConsoleSize: &hcsschema.ConsoleSize{
|
||||
Height: height,
|
||||
Width: width,
|
||||
},
|
||||
@ -423,10 +395,10 @@ func (process *Process) CloseStdin(ctx context.Context) (err error) {
|
||||
|
||||
//HcsModifyProcess request to close stdin will fail if the process has already exited
|
||||
if !process.stopped() {
|
||||
modifyRequest := processModifyRequest{
|
||||
Operation: modifyCloseHandle,
|
||||
CloseHandle: &closeHandle{
|
||||
Handle: stdIn,
|
||||
modifyRequest := hcsschema.ProcessModifyRequest{
|
||||
Operation: guestrequest.CloseProcessHandle,
|
||||
CloseHandle: &hcsschema.CloseHandle{
|
||||
Handle: guestrequest.STDInHandle,
|
||||
},
|
||||
}
|
||||
|
||||
|
25
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cim_mount.go
generated
vendored
Normal file
25
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/cim_mount.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* HCS API
|
||||
*
|
||||
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
|
||||
*
|
||||
* API version: 2.5
|
||||
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
|
||||
*/
|
||||
|
||||
package hcsschema
|
||||
|
||||
const (
|
||||
CimMountFlagNone uint32 = 0x0
|
||||
CimMountFlagChildOnly uint32 = 0x1
|
||||
CimMountFlagEnableDax uint32 = 0x2
|
||||
CimMountFlagCacheFiles uint32 = 0x4
|
||||
CimMountFlagCacheRegions uint32 = 0x8
|
||||
)
|
||||
|
||||
type CimMount struct {
|
||||
ImagePath string `json:"ImagePath,omitempty"`
|
||||
FileSystemName string `json:"FileSystemName,omitempty"`
|
||||
VolumeGuid string `json:"VolumeGuid,omitempty"`
|
||||
MountFlags uint32 `json:"MountFlags,omitempty"`
|
||||
}
|
4
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/close_handle.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/close_handle.go
generated
vendored
@ -9,6 +9,8 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
import "github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
|
||||
|
||||
type CloseHandle struct {
|
||||
Handle string `json:"Handle,omitempty"`
|
||||
Handle guestrequest.STDIOHandle `json:"Handle,omitempty"` // NOTE: Swagger generated as string. Locally updated.
|
||||
}
|
||||
|
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/console_size.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/console_size.go
generated
vendored
@ -9,8 +9,11 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
type ConsoleSize struct {
|
||||
Height int32 `json:"Height,omitempty"`
|
||||
// NOTE: Swagger generated fields as int32. Locally updated to uint16 to match documentation.
|
||||
// https://learn.microsoft.com/en-us/virtualization/api/hcs/schemareference#ConsoleSize
|
||||
|
||||
Width int32 `json:"Width,omitempty"`
|
||||
type ConsoleSize struct {
|
||||
Height uint16 `json:"Height,omitempty"`
|
||||
|
||||
Width uint16 `json:"Width,omitempty"`
|
||||
}
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/isolation_settings.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/isolation_settings.go
generated
vendored
@ -17,5 +17,5 @@ type IsolationSettings struct {
|
||||
DebugPort int64 `json:"DebugPort,omitempty"`
|
||||
// Optional data passed by host on isolated virtual machine start
|
||||
LaunchData string `json:"LaunchData,omitempty"`
|
||||
HclEnabled bool `json:"HclEnabled,omitempty"`
|
||||
HclEnabled *bool `json:"HclEnabled,omitempty"`
|
||||
}
|
||||
|
7
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/layer.go
generated
vendored
7
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/layer.go
generated
vendored
@ -9,6 +9,13 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
type FileSystemFilterType string
|
||||
|
||||
const (
|
||||
UnionFS FileSystemFilterType = "UnionFS"
|
||||
WCIFS FileSystemFilterType = "WCIFS"
|
||||
)
|
||||
|
||||
type Layer struct {
|
||||
Id string `json:"Id,omitempty"`
|
||||
|
||||
|
6
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_modify_request.go
generated
vendored
6
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_modify_request.go
generated
vendored
@ -9,9 +9,11 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Passed to HcsRpc_ModifyProcess
|
||||
import "github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
|
||||
|
||||
// Passed to HcsRpc_ModifyProcess
|
||||
type ProcessModifyRequest struct {
|
||||
Operation string `json:"Operation,omitempty"`
|
||||
Operation guestrequest.ProcessModifyOperation `json:"Operation,omitempty"` // NOTE: Swagger generated as string. Locally updated.
|
||||
|
||||
ConsoleSize *ConsoleSize `json:"ConsoleSize,omitempty"`
|
||||
|
||||
|
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_status.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/process_status.go
generated
vendored
@ -9,13 +9,16 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Status of a process running in a container
|
||||
// NOTE: Swagger generated fields as int32. Locally updated to uint16 to match documentation.
|
||||
// https://learn.microsoft.com/en-us/virtualization/api/hcs/schemareference#ConsoleSize
|
||||
|
||||
// Status of a process running in a container
|
||||
type ProcessStatus struct {
|
||||
ProcessId int32 `json:"ProcessId,omitempty"`
|
||||
ProcessId uint32 `json:"ProcessId,omitempty"` // NOTE: Swagger generated as int32. Locally updated to match documentation.
|
||||
|
||||
Exited bool `json:"Exited,omitempty"`
|
||||
|
||||
ExitCode int32 `json:"ExitCode,omitempty"`
|
||||
ExitCode uint32 `json:"ExitCode,omitempty"` // NOTE: Swagger generated as int32. Locally updated to match documentation.
|
||||
|
||||
LastWaitResult int32 `json:"LastWaitResult,omitempty"`
|
||||
}
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/properties.go
generated
vendored
@ -10,7 +10,7 @@
|
||||
package hcsschema
|
||||
|
||||
import (
|
||||
v1 "github.com/containerd/cgroups/stats/v1"
|
||||
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
|
||||
)
|
||||
|
||||
type Properties struct {
|
||||
|
13
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_hive.go
generated
vendored
Normal file
13
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_hive.go
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
package hcsschema
|
||||
|
||||
// NOTE: manually added
|
||||
|
||||
type RegistryHive string
|
||||
|
||||
// List of RegistryHive
|
||||
const (
|
||||
RegistryHive_SYSTEM RegistryHive = "System"
|
||||
RegistryHive_SOFTWARE RegistryHive = "Software"
|
||||
RegistryHive_SECURITY RegistryHive = "Security"
|
||||
RegistryHive_SAM RegistryHive = "Sam"
|
||||
)
|
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_key.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_key.go
generated
vendored
@ -10,7 +10,7 @@
|
||||
package hcsschema
|
||||
|
||||
type RegistryKey struct {
|
||||
Hive string `json:"Hive,omitempty"`
|
||||
Hive RegistryHive `json:"Hive,omitempty"`
|
||||
|
||||
Name string `json:"Name,omitempty"`
|
||||
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_value.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_value.go
generated
vendored
@ -14,7 +14,7 @@ type RegistryValue struct {
|
||||
|
||||
Name string `json:"Name,omitempty"`
|
||||
|
||||
Type_ string `json:"Type,omitempty"`
|
||||
Type_ RegistryValueType `json:"Type,omitempty"`
|
||||
|
||||
// One and only one value type must be set.
|
||||
StringValue string `json:"StringValue,omitempty"`
|
||||
|
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_value_type.go
generated
vendored
Normal file
17
vendor/github.com/Microsoft/hcsshim/internal/hcs/schema2/registry_value_type.go
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
package hcsschema
|
||||
|
||||
// NOTE: manually added
|
||||
|
||||
type RegistryValueType string
|
||||
|
||||
// List of RegistryValueType
|
||||
const (
|
||||
RegistryValueType_NONE RegistryValueType = "None"
|
||||
RegistryValueType_STRING RegistryValueType = "String"
|
||||
RegistryValueType_EXPANDED_STRING RegistryValueType = "ExpandedString"
|
||||
RegistryValueType_MULTI_STRING RegistryValueType = "MultiString"
|
||||
RegistryValueType_BINARY RegistryValueType = "Binary"
|
||||
RegistryValueType_D_WORD RegistryValueType = "DWord"
|
||||
RegistryValueType_Q_WORD RegistryValueType = "QWord"
|
||||
RegistryValueType_CUSTOM_TYPE RegistryValueType = "CustomType"
|
||||
)
|
39
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
39
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
generated
vendored
@ -97,7 +97,7 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in
|
||||
events, err := processAsyncHcsResult(ctx, createError, resultJSON, computeSystem.callbackNumber,
|
||||
hcsNotificationSystemCreateCompleted, &timeout.SystemCreate)
|
||||
if err != nil {
|
||||
if err == ErrTimeout {
|
||||
if errors.Is(err, ErrTimeout) {
|
||||
// Terminate the compute system if it still exists. We're okay to
|
||||
// ignore a failure here.
|
||||
_ = computeSystem.Terminate(ctx)
|
||||
@ -238,7 +238,7 @@ func (computeSystem *System) Shutdown(ctx context.Context) error {
|
||||
|
||||
resultJSON, err := vmcompute.HcsShutdownComputeSystem(ctx, computeSystem.handle, "")
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
switch err {
|
||||
switch err { //nolint:errorlint
|
||||
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
|
||||
default:
|
||||
return makeSystemError(computeSystem, operation, err, events)
|
||||
@ -259,7 +259,7 @@ func (computeSystem *System) Terminate(ctx context.Context) error {
|
||||
|
||||
resultJSON, err := vmcompute.HcsTerminateComputeSystem(ctx, computeSystem.handle, "")
|
||||
events := processHcsResult(ctx, resultJSON)
|
||||
switch err {
|
||||
switch err { //nolint:errorlint
|
||||
case nil, ErrVmcomputeAlreadyStopped, ErrComputeSystemDoesNotExist, ErrVmcomputeOperationPending:
|
||||
default:
|
||||
return makeSystemError(computeSystem, operation, err, events)
|
||||
@ -279,7 +279,7 @@ func (computeSystem *System) waitBackground() {
|
||||
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
|
||||
|
||||
err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
|
||||
switch err {
|
||||
switch err { //nolint:errorlint
|
||||
case nil:
|
||||
log.G(ctx).Debug("system exited")
|
||||
case ErrVmcomputeUnexpectedExit:
|
||||
@ -304,11 +304,22 @@ func (computeSystem *System) WaitError() error {
|
||||
return computeSystem.waitError
|
||||
}
|
||||
|
||||
// Wait synchronously waits for the compute system to shutdown or terminate. If
|
||||
// the compute system has already exited returns the previous error (if any).
|
||||
// Wait synchronously waits for the compute system to shutdown or terminate.
|
||||
// If the compute system has already exited returns the previous error (if any).
|
||||
func (computeSystem *System) Wait() error {
|
||||
<-computeSystem.WaitChannel()
|
||||
return computeSystem.WaitError()
|
||||
return computeSystem.WaitCtx(context.Background())
|
||||
}
|
||||
|
||||
// WaitCtx synchronously waits for the compute system to shutdown or terminate, or the context to be cancelled.
|
||||
//
|
||||
// See [System.Wait] for more information.
|
||||
func (computeSystem *System) WaitCtx(ctx context.Context) error {
|
||||
select {
|
||||
case <-computeSystem.WaitChannel():
|
||||
return computeSystem.WaitError()
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
}
|
||||
|
||||
// stopped returns true if the compute system stopped.
|
||||
@ -735,9 +746,17 @@ func (computeSystem *System) OpenProcess(ctx context.Context, pid int) (*Process
|
||||
}
|
||||
|
||||
// Close cleans up any state associated with the compute system but does not terminate or wait for it.
|
||||
func (computeSystem *System) Close() (err error) {
|
||||
func (computeSystem *System) Close() error {
|
||||
return computeSystem.CloseCtx(context.Background())
|
||||
}
|
||||
|
||||
// CloseCtx is similar to [System.Close], but accepts a context.
|
||||
//
|
||||
// The context is used for all operations, including waits, so timeouts/cancellations may prevent
|
||||
// proper system cleanup.
|
||||
func (computeSystem *System) CloseCtx(ctx context.Context) (err error) {
|
||||
operation := "hcs::System::Close"
|
||||
ctx, span := oc.StartSpan(context.Background(), operation)
|
||||
ctx, span := oc.StartSpan(ctx, operation)
|
||||
defer span.End()
|
||||
defer func() { oc.SetSpanStatus(span, err) }()
|
||||
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go
generated
vendored
@ -14,14 +14,14 @@ import (
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
|
||||
// makeOpenFiles calls winio.NewOpenFile for each handle in a slice but closes all the handles
|
||||
// if there is an error.
|
||||
func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
|
||||
fs := make([]io.ReadWriteCloser, len(hs))
|
||||
for i, h := range hs {
|
||||
if h != syscall.Handle(0) {
|
||||
if err == nil {
|
||||
fs[i], err = winio.MakeOpenFile(h)
|
||||
fs[i], err = winio.NewOpenFile(windows.Handle(h))
|
||||
}
|
||||
if err != nil {
|
||||
syscall.Close(h)
|
||||
|
2
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsfuncs.go
generated
vendored
2
vendor/github.com/Microsoft/hcsshim/internal/hns/hnsfuncs.go
generated
vendored
@ -31,7 +31,7 @@ func hnsCallRawResponse(method, path, request string) (*hnsResponse, error) {
|
||||
func hnsCall(method, path, request string, returnResponse interface{}) error {
|
||||
hnsresponse, err := hnsCallRawResponse(method, path, request)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed during hnsCallRawResponse: %v", err)
|
||||
return fmt.Errorf("failed during hnsCallRawResponse: %w", err)
|
||||
}
|
||||
if !hnsresponse.Success {
|
||||
return fmt.Errorf("hns failed with error : %s", hnsresponse.Error)
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/hns/namespace.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/hns/namespace.go
generated
vendored
@ -56,7 +56,7 @@ func issueNamespaceRequest(id *string, method, subpath string, request interface
|
||||
if strings.Contains(err.Error(), "Element not found.") {
|
||||
return nil, os.ErrNotExist
|
||||
}
|
||||
return nil, fmt.Errorf("%s %s: %s", method, hnspath, err)
|
||||
return nil, fmt.Errorf("%s %s: %w", method, hnspath, err)
|
||||
}
|
||||
return &ns, err
|
||||
}
|
||||
@ -86,7 +86,7 @@ func GetNamespaceEndpoints(id string) ([]string, error) {
|
||||
var endpoint namespaceEndpointRequest
|
||||
err = json.Unmarshal(rsrc.Data, &endpoint)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unmarshal endpoint: %s", err)
|
||||
return nil, fmt.Errorf("unmarshal endpoint: %w", err)
|
||||
}
|
||||
endpoints = append(endpoints, endpoint.ID)
|
||||
}
|
||||
|
5
vendor/github.com/Microsoft/hcsshim/internal/hns/zsyscall_windows.go
generated
vendored
5
vendor/github.com/Microsoft/hcsshim/internal/hns/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -69,7 +66,7 @@ func __hnsCall(method *uint16, path *uint16, object *uint16, response **uint16)
|
||||
if hr != nil {
|
||||
return
|
||||
}
|
||||
r0, _, _ := syscall.Syscall6(procHNSCall.Addr(), 4, uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procHNSCall.Addr(), uintptr(unsafe.Pointer(method)), uintptr(unsafe.Pointer(path)), uintptr(unsafe.Pointer(object)), uintptr(unsafe.Pointer(response)))
|
||||
if int32(r0) < 0 {
|
||||
if r0&0x1fff0000 == 0x00070000 {
|
||||
r0 &= 0xffff
|
||||
|
5
vendor/github.com/Microsoft/hcsshim/internal/interop/zsyscall_windows.go
generated
vendored
5
vendor/github.com/Microsoft/hcsshim/internal/interop/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -46,6 +43,6 @@ var (
|
||||
)
|
||||
|
||||
func coTaskMemFree(buffer unsafe.Pointer) {
|
||||
syscall.Syscall(procCoTaskMemFree.Addr(), 1, uintptr(buffer), 0, 0)
|
||||
syscall.SyscallN(procCoTaskMemFree.Addr(), uintptr(buffer))
|
||||
return
|
||||
}
|
||||
|
3
vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go
generated
vendored
3
vendor/github.com/Microsoft/hcsshim/internal/jobobject/iocp.go
generated
vendored
@ -4,6 +4,7 @@ package jobobject
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"unsafe"
|
||||
@ -59,7 +60,7 @@ func pollIOCP(ctx context.Context, iocpHandle windows.Handle) {
|
||||
}).Warn("failed to parse job object message")
|
||||
continue
|
||||
}
|
||||
if err := msq.Enqueue(notification); err == queue.ErrQueueClosed {
|
||||
if err := msq.Enqueue(notification); errors.Is(err, queue.ErrQueueClosed) {
|
||||
// Write will only return an error when the queue is closed.
|
||||
// The only time a queue would ever be closed is when we call `Close` on
|
||||
// the job it belongs to which also removes it from the jobMap, so something
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/jobobject/jobobject.go
generated
vendored
@ -167,7 +167,7 @@ func Create(ctx context.Context, options *Options) (_ *JobObject, err error) {
|
||||
//
|
||||
// Returns a JobObject structure and an error if there is one.
|
||||
func Open(ctx context.Context, options *Options) (_ *JobObject, err error) {
|
||||
if options == nil || (options != nil && options.Name == "") {
|
||||
if options == nil || options.Name == "" {
|
||||
return nil, errors.New("no job object name specified to open")
|
||||
}
|
||||
|
||||
@ -374,7 +374,7 @@ func (job *JobObject) Pids() ([]uint32, error) {
|
||||
return []uint32{}, nil
|
||||
}
|
||||
|
||||
if err != winapi.ERROR_MORE_DATA {
|
||||
if err != winapi.ERROR_MORE_DATA { //nolint:errorlint
|
||||
return nil, fmt.Errorf("failed initial query for PIDs in job object: %w", err)
|
||||
}
|
||||
|
||||
|
7
vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
7
vendor/github.com/Microsoft/hcsshim/internal/jobobject/limits.go
generated
vendored
@ -143,6 +143,13 @@ func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error {
|
||||
return err
|
||||
}
|
||||
info.BasicLimitInformation.LimitFlags |= uint32(windows.JOB_OBJECT_LIMIT_AFFINITY)
|
||||
|
||||
// We really, really shouldn't be running on 32 bit, but just in case (and to satisfy CodeQL) ...
|
||||
const maxUintptr = ^uintptr(0)
|
||||
if affinityBitMask > uint64(maxUintptr) {
|
||||
return fmt.Errorf("affinity bitmask (%d) exceeds max allowable value (%d)", affinityBitMask, maxUintptr)
|
||||
}
|
||||
|
||||
info.BasicLimitInformation.Affinity = uintptr(affinityBitMask)
|
||||
return job.setExtendedInformation(info)
|
||||
}
|
||||
|
44
vendor/github.com/Microsoft/hcsshim/internal/log/format.go
generated
vendored
44
vendor/github.com/Microsoft/hcsshim/internal/log/format.go
generated
vendored
@ -8,6 +8,10 @@ import (
|
||||
"net"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// TimeFormat is [time.RFC3339Nano] with nanoseconds padded using
|
||||
@ -61,25 +65,49 @@ func formatAddr(a net.Addr) string {
|
||||
func Format(ctx context.Context, v interface{}) string {
|
||||
b, err := encode(v)
|
||||
if err != nil {
|
||||
G(ctx).WithError(err).Warning("could not format value")
|
||||
// logging errors aren't really warning worthy, and can potentially spam a lot of logs out
|
||||
G(ctx).WithFields(logrus.Fields{
|
||||
logrus.ErrorKey: err,
|
||||
"type": fmt.Sprintf("%T", v),
|
||||
}).Debug("could not format value")
|
||||
return ""
|
||||
}
|
||||
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func encode(v interface{}) ([]byte, error) {
|
||||
return encodeBuffer(&bytes.Buffer{}, v)
|
||||
}
|
||||
func encode(v interface{}) (_ []byte, err error) {
|
||||
if m, ok := v.(proto.Message); ok {
|
||||
// use canonical JSON encoding for protobufs (instead of [encoding/json])
|
||||
// https://protobuf.dev/programming-guides/proto3/#json
|
||||
var b []byte
|
||||
b, err = protojson.MarshalOptions{
|
||||
AllowPartial: true,
|
||||
// protobuf defaults to camel case for JSON encoding; use proto field name instead (snake case)
|
||||
UseProtoNames: true,
|
||||
}.Marshal(m)
|
||||
if err == nil {
|
||||
// the protojson marshaller tries to unmarshal anypb.Any fields, which can
|
||||
// fail for types encoded with "github.com/containerd/typeurl/v2"
|
||||
// we can try creating a dedicated protoregistry.MessageTypeResolver that uses typeurl, but, its
|
||||
// more robust to fall back on json marshalling for errors in general
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func encodeBuffer(buf *bytes.Buffer, v interface{}) ([]byte, error) {
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
enc := json.NewEncoder(buf)
|
||||
enc.SetEscapeHTML(false)
|
||||
enc.SetIndent("", "")
|
||||
|
||||
if err := enc.Encode(v); err != nil {
|
||||
err = fmt.Errorf("could not marshall %T to JSON for logging: %w", v, err)
|
||||
return nil, err
|
||||
if jErr := enc.Encode(v); jErr != nil {
|
||||
if err != nil {
|
||||
// TODO (go1.20): use multierror via fmt.Errorf("...: %w; ...: %w", ...)
|
||||
//nolint:errorlint // non-wrapping format verb for fmt.Errorf
|
||||
return nil, fmt.Errorf("protojson encoding: %v; json encoding: %w", err, jErr)
|
||||
}
|
||||
return nil, fmt.Errorf("json encoding: %w", jErr)
|
||||
}
|
||||
|
||||
// encoder.Encode appends a newline to the end
|
||||
|
12
vendor/github.com/Microsoft/hcsshim/internal/log/nopformatter.go
generated
vendored
Normal file
12
vendor/github.com/Microsoft/hcsshim/internal/log/nopformatter.go
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type NopFormatter struct{}
|
||||
|
||||
var _ logrus.Formatter = NopFormatter{}
|
||||
|
||||
// Format does nothing and returns a nil slice.
|
||||
func (NopFormatter) Format(*logrus.Entry) ([]byte, error) { return nil, nil }
|
8
vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go
generated
vendored
8
vendor/github.com/Microsoft/hcsshim/internal/log/scrub.go
generated
vendored
@ -55,7 +55,7 @@ func ScrubProcessParameters(s string) (string, error) {
|
||||
}
|
||||
pp.Environment = map[string]string{_scrubbedReplacement: _scrubbedReplacement}
|
||||
|
||||
b, err := encodeBuffer(bytes.NewBuffer(b[:0]), pp)
|
||||
b, err := encode(pp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -89,11 +89,11 @@ func scrubBridgeCreate(m genMap) error {
|
||||
}
|
||||
|
||||
func scrubLinuxHostedSystem(m genMap) error {
|
||||
if m, ok := index(m, "OciSpecification"); ok {
|
||||
if m, ok := index(m, "OciSpecification"); ok { //nolint:govet // shadow
|
||||
if _, ok := m["annotations"]; ok {
|
||||
m["annotations"] = map[string]string{_scrubbedReplacement: _scrubbedReplacement}
|
||||
}
|
||||
if m, ok := index(m, "process"); ok {
|
||||
if m, ok := index(m, "process"); ok { //nolint:govet // shadow
|
||||
if _, ok := m["env"]; ok {
|
||||
m["env"] = []string{_scrubbedReplacement}
|
||||
return nil
|
||||
@ -113,7 +113,7 @@ func scrubExecuteProcess(m genMap) error {
|
||||
if !isRequestBase(m) {
|
||||
return ErrUnknownType
|
||||
}
|
||||
if m, ok := index(m, "Settings"); ok {
|
||||
if m, ok := index(m, "Settings"); ok { //nolint:govet // shadow
|
||||
if ss, ok := m["ProcessParameters"]; ok {
|
||||
// ProcessParameters is a json encoded struct passed as a regular sting field
|
||||
s, ok := ss.(string)
|
||||
|
1
vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go
generated
vendored
1
vendor/github.com/Microsoft/hcsshim/internal/logfields/fields.go
generated
vendored
@ -46,6 +46,7 @@ const (
|
||||
|
||||
ExpectedType = "expected-type"
|
||||
Bool = "bool"
|
||||
Int32 = "int32"
|
||||
Uint32 = "uint32"
|
||||
Uint64 = "uint64"
|
||||
|
||||
|
6
vendor/github.com/Microsoft/hcsshim/internal/memory/pool.go
generated
vendored
6
vendor/github.com/Microsoft/hcsshim/internal/memory/pool.go
generated
vendored
@ -126,7 +126,7 @@ func (pa *PoolAllocator) Allocate(size uint64) (MappedRegion, error) {
|
||||
// this means that there are no more regions for the current class, try expanding
|
||||
if nextCls != memCls {
|
||||
if err := pa.split(memCls); err != nil {
|
||||
if err == ErrInvalidMemoryClass {
|
||||
if errors.Is(err, ErrInvalidMemoryClass) {
|
||||
return nil, ErrNotEnoughSpace
|
||||
}
|
||||
return nil, err
|
||||
@ -147,7 +147,7 @@ func (pa *PoolAllocator) Allocate(size uint64) (MappedRegion, error) {
|
||||
}
|
||||
|
||||
// Release marks a memory region of class `memCls` and offset `offset` as free and tries to merge smaller regions into
|
||||
// a bigger one
|
||||
// a bigger one.
|
||||
func (pa *PoolAllocator) Release(reg MappedRegion) error {
|
||||
mp := pa.pools[reg.Type()]
|
||||
if mp == nil {
|
||||
@ -164,7 +164,7 @@ func (pa *PoolAllocator) Release(reg MappedRegion) error {
|
||||
return ErrNotAllocated
|
||||
}
|
||||
if err := pa.merge(n.parent); err != nil {
|
||||
if err != ErrEarlyMerge {
|
||||
if !errors.Is(err, ErrEarlyMerge) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
4
vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go
generated
vendored
4
vendor/github.com/Microsoft/hcsshim/internal/oc/errors.go
generated
vendored
@ -6,7 +6,7 @@ import (
|
||||
"net"
|
||||
"os"
|
||||
|
||||
"github.com/containerd/containerd/errdefs"
|
||||
"github.com/containerd/errdefs"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
@ -16,7 +16,7 @@ import (
|
||||
|
||||
func toStatusCode(err error) codes.Code {
|
||||
// checks if err implements GRPCStatus() *"google.golang.org/grpc/status".Status,
|
||||
// wraps an error defined in "github.com/containerd/containerd/errdefs", or is a
|
||||
// wraps an error defined in "github.com/containerd/errdefs", or is a
|
||||
// context timeout or cancelled error
|
||||
if s, ok := status.FromError(errdefs.ToGRPC(err)); ok {
|
||||
return s.Code()
|
||||
|
22
vendor/github.com/Microsoft/hcsshim/internal/protocol/guestrequest/types.go
generated
vendored
22
vendor/github.com/Microsoft/hcsshim/internal/protocol/guestrequest/types.go
generated
vendored
@ -5,7 +5,7 @@ package guestrequest
|
||||
type RequestType string
|
||||
type ResourceType string
|
||||
|
||||
// RequestType const
|
||||
// RequestType const.
|
||||
const (
|
||||
RequestTypeAdd RequestType = "Add"
|
||||
RequestTypeRemove RequestType = "Remove"
|
||||
@ -54,3 +54,23 @@ var (
|
||||
"305891a9-b251-5dfe-91a2-c25d9212275b",
|
||||
}
|
||||
)
|
||||
|
||||
// constants for v2 schema ProcessModifyRequest
|
||||
|
||||
// Operation type for [hcsschema.ProcessModifyRequest].
|
||||
type ProcessModifyOperation string
|
||||
|
||||
const (
|
||||
ModifyProcessConsoleSize ProcessModifyOperation = "ConsoleSize"
|
||||
CloseProcessHandle ProcessModifyOperation = "CloseHandle"
|
||||
)
|
||||
|
||||
// Standard IO handle(s) to close for [hcsschema.CloseHandle] in [hcsschema.ProcessModifyRequest].
|
||||
type STDIOHandle string
|
||||
|
||||
const (
|
||||
STDInHandle STDIOHandle = "StdIn"
|
||||
STDOutHandle STDIOHandle = "StdOut"
|
||||
STDErrHandle STDIOHandle = "StdErr"
|
||||
AllHandles STDIOHandle = "All"
|
||||
)
|
||||
|
16
vendor/github.com/Microsoft/hcsshim/internal/regstate/regstate.go
generated
vendored
16
vendor/github.com/Microsoft/hcsshim/internal/regstate/regstate.go
generated
vendored
@ -4,6 +4,7 @@ package regstate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
@ -44,8 +45,8 @@ func (err *NotFoundError) Error() string {
|
||||
}
|
||||
|
||||
func IsNotFoundError(err error) bool {
|
||||
_, ok := err.(*NotFoundError)
|
||||
return ok
|
||||
var e *NotFoundError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
type NoStateError struct {
|
||||
@ -152,7 +153,8 @@ func (k *Key) openid(id string) (*Key, error) {
|
||||
escaped := url.PathEscape(id)
|
||||
fullpath := filepath.Join(k.Name, escaped)
|
||||
nk, err := k.open(escaped)
|
||||
if perr, ok := err.(*os.PathError); ok && perr.Err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
var perr *os.PathError
|
||||
if errors.As(err, &perr) && errors.Is(perr.Err, syscall.ERROR_FILE_NOT_FOUND) {
|
||||
return nil, &NotFoundError{id}
|
||||
}
|
||||
if err != nil {
|
||||
@ -165,7 +167,7 @@ func (k *Key) Remove(id string) error {
|
||||
escaped := url.PathEscape(id)
|
||||
err := registry.DeleteKey(k.Key, escaped)
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND { //nolint:errorlint
|
||||
return &NotFoundError{id}
|
||||
}
|
||||
return &os.PathError{Op: "RegDeleteKey", Path: filepath.Join(k.Name, escaped), Err: err}
|
||||
@ -215,7 +217,7 @@ func (k *Key) set(id string, create bool, key string, state interface{}) error {
|
||||
err = sk.SetBinaryValue(key, js)
|
||||
}
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND { //nolint:errorlint
|
||||
return &NoStateError{id, key}
|
||||
}
|
||||
return &os.PathError{Op: "RegSetValueEx", Path: sk.Name + ":" + key, Err: err}
|
||||
@ -239,7 +241,7 @@ func (k *Key) Clear(id, key string) error {
|
||||
defer sk.Close()
|
||||
err = sk.DeleteValue(key)
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND { //nolint:errorlint
|
||||
return &NoStateError{id, key}
|
||||
}
|
||||
return &os.PathError{Op: "RegDeleteValue", Path: sk.Name + ":" + key, Err: err}
|
||||
@ -278,7 +280,7 @@ func (k *Key) Get(id, key string, state interface{}) error {
|
||||
js, _, err = sk.GetBinaryValue(key)
|
||||
}
|
||||
if err != nil {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND {
|
||||
if err == syscall.ERROR_FILE_NOT_FOUND { //nolint:errorlint
|
||||
return &NoStateError{id, key}
|
||||
}
|
||||
return &os.PathError{Op: "RegQueryValueEx", Path: sk.Name + ":" + key, Err: err}
|
||||
|
5
vendor/github.com/Microsoft/hcsshim/internal/regstate/zsyscall_windows.go
generated
vendored
5
vendor/github.com/Microsoft/hcsshim/internal/regstate/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -46,7 +43,7 @@ var (
|
||||
)
|
||||
|
||||
func regCreateKeyEx(key syscall.Handle, subkey *uint16, reserved uint32, class *uint16, options uint32, desired uint32, sa *syscall.SecurityAttributes, result *syscall.Handle, disposition *uint32) (regerrno error) {
|
||||
r0, _, _ := syscall.Syscall9(procRegCreateKeyExW.Addr(), 9, uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
|
||||
r0, _, _ := syscall.SyscallN(procRegCreateKeyExW.Addr(), uintptr(key), uintptr(unsafe.Pointer(subkey)), uintptr(reserved), uintptr(unsafe.Pointer(class)), uintptr(options), uintptr(desired), uintptr(unsafe.Pointer(sa)), uintptr(unsafe.Pointer(result)), uintptr(unsafe.Pointer(disposition)))
|
||||
if r0 != 0 {
|
||||
regerrno = syscall.Errno(r0)
|
||||
}
|
||||
|
10
vendor/github.com/Microsoft/hcsshim/internal/safefile/safeopen.go
generated
vendored
10
vendor/github.com/Microsoft/hcsshim/internal/safefile/safeopen.go
generated
vendored
@ -243,7 +243,7 @@ func RemoveRelative(path string, root *os.File) error {
|
||||
if err == nil {
|
||||
defer f.Close()
|
||||
err = deleteOnClose(f)
|
||||
if err == syscall.ERROR_ACCESS_DENIED {
|
||||
if err == syscall.ERROR_ACCESS_DENIED { //nolint:errorlint
|
||||
// Maybe the file is marked readonly. Clear the bit and retry.
|
||||
_ = clearReadOnly(f)
|
||||
err = deleteOnClose(f)
|
||||
@ -276,7 +276,7 @@ func RemoveAllRelative(path string, root *os.File) error {
|
||||
}
|
||||
|
||||
// It is necessary to use os.Open as Readdirnames does not work with
|
||||
// OpenRelative. This is safe because the above lstatrelative fails
|
||||
// OpenRelative. This is safe because the above LstatRelative fails
|
||||
// if the target is outside the root, and we know this is not a
|
||||
// symlink from the above FILE_ATTRIBUTE_REPARSE_POINT check.
|
||||
fd, err := os.Open(filepath.Join(root.Name(), path))
|
||||
@ -293,12 +293,12 @@ func RemoveAllRelative(path string, root *os.File) error {
|
||||
for {
|
||||
names, err1 := fd.Readdirnames(100)
|
||||
for _, name := range names {
|
||||
err1 := RemoveAllRelative(path+string(os.PathSeparator)+name, root)
|
||||
if err == nil {
|
||||
err = err1
|
||||
if err2 := RemoveAllRelative(path+string(os.PathSeparator)+name, root); err == nil {
|
||||
err = err2
|
||||
}
|
||||
}
|
||||
if err1 == io.EOF {
|
||||
// Readdirnames has no more files to return
|
||||
break
|
||||
}
|
||||
// If Readdirnames returned an error, use it.
|
||||
|
9
vendor/github.com/Microsoft/hcsshim/internal/security/zsyscall_windows.go
generated
vendored
9
vendor/github.com/Microsoft/hcsshim/internal/security/zsyscall_windows.go
generated
vendored
@ -33,9 +33,6 @@ func errnoErr(e syscall.Errno) error {
|
||||
case errnoERROR_IO_PENDING:
|
||||
return errERROR_IO_PENDING
|
||||
}
|
||||
// TODO: add more here, after collecting data on the common
|
||||
// error values see on Windows. (perhaps when running
|
||||
// all.bat?)
|
||||
return e
|
||||
}
|
||||
|
||||
@ -48,7 +45,7 @@ var (
|
||||
)
|
||||
|
||||
func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidOwner **uintptr, ppsidGroup **uintptr, ppDacl *uintptr, ppSacl *uintptr, ppSecurityDescriptor *uintptr) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall9(procGetSecurityInfo.Addr(), 8, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)), 0)
|
||||
r0, _, _ := syscall.SyscallN(procGetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(si), uintptr(unsafe.Pointer(ppsidOwner)), uintptr(unsafe.Pointer(ppsidGroup)), uintptr(unsafe.Pointer(ppDacl)), uintptr(unsafe.Pointer(ppSacl)), uintptr(unsafe.Pointer(ppSecurityDescriptor)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -56,7 +53,7 @@ func getSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, ppsidO
|
||||
}
|
||||
|
||||
func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *uintptr) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall6(procSetEntriesInAclW.Addr(), 4, uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procSetEntriesInAclW.Addr(), uintptr(count), uintptr(pListOfEEs), uintptr(oldAcl), uintptr(unsafe.Pointer(newAcl)))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
@ -64,7 +61,7 @@ func setEntriesInAcl(count uintptr, pListOfEEs uintptr, oldAcl uintptr, newAcl *
|
||||
}
|
||||
|
||||
func setSecurityInfo(handle syscall.Handle, objectType uint32, si uint32, psidOwner uintptr, psidGroup uintptr, pDacl uintptr, pSacl uintptr) (win32err error) {
|
||||
r0, _, _ := syscall.Syscall9(procSetSecurityInfo.Addr(), 7, uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl), 0, 0)
|
||||
r0, _, _ := syscall.SyscallN(procSetSecurityInfo.Addr(), uintptr(handle), uintptr(objectType), uintptr(si), uintptr(psidOwner), uintptr(psidGroup), uintptr(pDacl), uintptr(pSacl))
|
||||
if r0 != 0 {
|
||||
win32err = syscall.Errno(r0)
|
||||
}
|
||||
|
16
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
16
vendor/github.com/Microsoft/hcsshim/internal/vmcompute/vmcompute.go
generated
vendored
@ -104,7 +104,7 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if ctx.Err() == gcontext.DeadlineExceeded {
|
||||
if ctx.Err() == gcontext.DeadlineExceeded { //nolint:errorlint
|
||||
log.G(ctx).WithField(logfields.Timeout, trueTimeout).
|
||||
Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. " +
|
||||
"If it appears to be making no forward progress, obtain the stacks and see if there is a syscall " +
|
||||
@ -150,7 +150,7 @@ func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration strin
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -205,7 +205,7 @@ func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -228,7 +228,7 @@ func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, opt
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -251,7 +251,7 @@ func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, op
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -274,7 +274,7 @@ func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -297,7 +297,7 @@ func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, optio
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
@ -621,7 +621,7 @@ func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options
|
||||
if result != "" {
|
||||
span.AddAttributes(trace.StringAttribute("result", result))
|
||||
}
|
||||
if hr != errVmcomputeOperationPending {
|
||||
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
|
||||
oc.SetSpanStatus(span, hr)
|
||||
}
|
||||
}()
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user