vendor: align dependencies with Moby

Update shared Go dependencies to the versions used by Moby and
regenerate vendor. Leave go-archive and sys/userns unchanged.

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
This commit is contained in:
Tonis Tiigi committed 2026-08-26 01:59:09 -07:00
1 parent bde2482d9f
commit db47e7a46b
635 files changed
+31289 -15074

No files matched your search

+35 -36
View File
@@ -7,7 +7,7 @@ require (
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.13.1
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.5.0
github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29
github.com/Microsoft/hcsshim v0.15.0-rc.1
github.com/Microsoft/hcsshim v0.15.0-rc.4
github.com/ProtonMail/go-crypto v1.4.1
github.com/agext/levenshtein v1.2.3
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
@@ -65,15 +65,15 @@ require (
github.com/opencontainers/runtime-spec v1.3.0
github.com/opencontainers/selinux v1.15.1
github.com/package-url/packageurl-go v0.1.1
github.com/pelletier/go-toml/v2 v2.3.1
github.com/pelletier/go-toml/v2 v2.4.3
github.com/pkg/errors v0.9.1
github.com/pkg/profile v1.7.0
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/procfs v0.20.1
github.com/prometheus/client_golang v1.24.1
github.com/prometheus/procfs v0.21.1
github.com/serialx/hashring v0.0.0-20200727003509-22c0c7ab6b1b
github.com/sigstore/sigstore-go v1.2.2
github.com/sirupsen/logrus v1.9.4
github.com/sirupsen/logrus v1.10.1
github.com/spdx/tools-golang v0.5.7
github.com/stretchr/testify v1.12.1
github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323
@@ -87,43 +87,43 @@ require (
github.com/vishvananda/netlink v1.3.1
github.com/vishvananda/netns v0.0.5
go.etcd.io/bbolt v1.5.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0
go.opentelemetry.io/otel v1.44.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0
go.opentelemetry.io/otel v1.45.0
go.opentelemetry.io/otel/exporters/jaeger v1.17.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0
go.opentelemetry.io/otel/exporters/prometheus v0.66.0
go.opentelemetry.io/otel/metric v1.44.0
go.opentelemetry.io/otel/sdk v1.44.0
go.opentelemetry.io/otel/sdk/metric v1.44.0
go.opentelemetry.io/otel/trace v1.44.0
go.opentelemetry.io/proto/otlp v1.10.0
golang.org/x/crypto v0.54.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0
go.opentelemetry.io/otel/exporters/prometheus v0.67.0
go.opentelemetry.io/otel/metric v1.45.0
go.opentelemetry.io/otel/sdk v1.45.0
go.opentelemetry.io/otel/sdk/metric v1.45.0
go.opentelemetry.io/otel/trace v1.45.0
go.opentelemetry.io/proto/otlp v1.11.0
golang.org/x/crypto v0.55.0
golang.org/x/exp v0.0.0-20260603202125-055de637280b
golang.org/x/mod v0.38.0
golang.org/x/net v0.57.0
golang.org/x/mod v0.40.0
golang.org/x/net v0.58.0
golang.org/x/sync v0.22.0
golang.org/x/sys v0.47.0
golang.org/x/time v0.15.0
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa
google.golang.org/grpc v1.82.1
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d
google.golang.org/grpc v1.83.1
google.golang.org/protobuf v1.36.12
kernel.org/pub/linux/libs/security/libcap/cap v1.2.78
tags.cncf.io/container-device-interface v1.1.0
)
require (
cyphar.com/go-pathrs v0.2.1 // indirect
cyphar.com/go-pathrs v0.2.5 // indirect
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0 // indirect
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 // indirect
github.com/anchore/go-struct-converter v0.1.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.39 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.39 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.39 // indirect
@@ -147,16 +147,16 @@ require (
github.com/containerd/ttrpc v1.2.9 // indirect
github.com/containernetworking/cni v1.3.0 // indirect
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
github.com/cyphar/filepath-securejoin v0.6.0 // indirect
github.com/cyphar/filepath-securejoin v0.6.1 // indirect
github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect
github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect
github.com/dimchansky/utfbom v1.1.1 // indirect
github.com/docker/docker-credential-helpers v0.9.8 // indirect
github.com/docker/go-metrics v0.0.1 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/felixge/httpsnoop v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.9.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.25.2 // indirect
github.com/go-openapi/errors v0.22.8 // indirect
@@ -201,7 +201,7 @@ require (
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/otlptranslator v1.0.0 // indirect
github.com/sasha-s/go-deadlock v0.3.5 // indirect
github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect
@@ -216,14 +216,13 @@ require (
github.com/transparency-dev/merkle v0.0.2 // indirect
github.com/vbatts/tar-split v0.12.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.5 // indirect
golang.org/x/term v0.45.0 // indirect
golang.org/x/text v0.40.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 // indirect
golang.org/x/text v0.41.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d // indirect
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.140.0 // indirect
kernel.org/pub/linux/libs/security/libcap/psx v1.2.78 // indirect
+74 -149
View File
@@ -1,4 +1,3 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE=
cloud.google.com/go v0.123.0/go.mod h1:xBoMV08QcqUGuPW65Qfm1o9Y4zKZBpGS+7bImXLTAZU=
cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA=
@@ -13,8 +12,8 @@ cloud.google.com/go/kms v1.31.0 h1:LS8N92OxFDgOLg5NCo3OmbvjtQAIVT5gUHVLKIDHaFE=
cloud.google.com/go/kms v1.31.0/go.mod h1:YIyXZym11R5uovJJt4oN5eUL3oPmirF3yKeIh6QAf4U=
cloud.google.com/go/longrunning v1.0.0 h1:lwzWEYD8+NkYV7dhexOz6kmlvajZA70+bW/xMhRVVdY=
cloud.google.com/go/longrunning v1.0.0/go.mod h1:8nqFBPOO1U/XkhWl0I19AMZEphrHi73VNABIpKYaTwM=
cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
cyphar.com/go-pathrs v0.2.5 h1:SnX9FBvnoyn3lUs1dkMgZ52bAETpirNu3FTRh5HlRik=
cyphar.com/go-pathrs v0.2.5/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
filippo.io/mldsa v0.0.0-20260215214346-43d0283efc3e h1:VsUbObBMxXlc23Eb9VeeJYE4jvTs87qa5RqSN2U5FJU=
@@ -43,14 +42,13 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJ
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0 h1:4iB+IesclUXdP0ICgAabvq2FYLXrJWKx1fJQ+GxSo3Y=
github.com/AzureAD/microsoft-authentication-library-for-go v1.7.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29 h1:0kQAzHq8vLs7Pptv+7TxjdETLf/nIqJpIB4oC6Ba4vY=
github.com/Microsoft/go-winio v0.6.3-0.20251027160822-ad3df93bed29/go.mod h1:ZWa7ssZJT30CCDGJ7fk/2SBTq9BIQrrVjrcss0UW2s0=
github.com/Microsoft/hcsshim v0.15.0-rc.1 h1:FbbwtQmiD+BVHynGkx5S65JkLyhkEiiTP8nrpmg2SZw=
github.com/Microsoft/hcsshim v0.15.0-rc.1/go.mod h1:HWvvUPIy9HF6LotILj1G4VyS065rcLQ6tqj6tMUdOfI=
github.com/Microsoft/hcsshim v0.15.0-rc.4 h1:aZFX4LH0S20Lgjq0wG61StIClj7im4yzrxIClkaR8Z8=
github.com/Microsoft/hcsshim v0.15.0-rc.4/go.mod h1:BA9CBztgu4h/6Jsvo1O1M4qjWw09PoYpaEYgexPE578=
github.com/ProtonMail/go-crypto v1.4.1 h1:9RfcZHqEQUvP8RzecWEUafnZVtEvrBVL9BiF67IQOfM=
github.com/ProtonMail/go-crypto v1.4.1/go.mod h1:e1OaTyu5SYVrO9gKOEhTc+5UcXtTUa+P3uLudwcgPqo=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
@@ -67,8 +65,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go-v2 v1.43.8 h1:fpnrxwuwsoGIgjvgLeDU3y9w7YaHBxyF6AF3vQL8duw=
github.com/aws/aws-sdk-go-v2 v1.43.8/go.mod h1:j7gYSq8dL95QejkFXxvQNESH4I9WGHFI6iO+vhqEi5Q=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16 h1:aiuaKlDweRC5qExJondpWjOgyzMHpofpwspGXUtwn4c=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.16/go.mod h1:nG/LOlmox9BDe9HvQnXWzgcK8uKbgBMZ/Hp5pVt/21I=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18 h1:LAfOuhAH331fmOjTQpAaOlH+Ftn7RzSDJ2VFwjdMMy4=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.18/go.mod h1:4e5xhuXHx1e4U9EthvbPP1r/DIMp5c2823OL8karzcM=
github.com/aws/aws-sdk-go-v2/config v1.32.39 h1:3TYUWYWawsE9KF02G3dA7vsbwoCphyGOpFFEUugRs/4=
github.com/aws/aws-sdk-go-v2/config v1.32.39/go.mod h1:/lPP/ciQurgJa6l6mbBX+b5MB1qaLrC9dd3YHtGvrhk=
github.com/aws/aws-sdk-go-v2/credentials v1.19.38 h1:Xf8j1+vzwPRCta9pFXjj0677BzXrRO2JbpAVNcdXnnI=
@@ -117,16 +115,13 @@ github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK3
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
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/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
github.com/containerd/accelerated-container-image v1.3.0 h1:sFbTgSuMboeKHa9f7MY11hWF1XxVWjFoiTsXYtOtvdU=
@@ -179,8 +174,8 @@ github.com/coreos/go-systemd/v22 v22.7.0 h1:LAEzFkke61DFROc7zNLX/WA2i5J8gYqe0rSj
github.com/coreos/go-systemd/v22 v22.7.0/go.mod h1:xNUYtjHu2EDXbsxz1i41wouACIwT7Ybq9o0BQhMwD0w=
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
github.com/cyphar/filepath-securejoin v0.6.1 h1:5CeZ1jPXEiYt3+Z6zqprSAgSWiggmpVyciv8syjIpVE=
github.com/cyphar/filepath-securejoin v0.6.1/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
github.com/danieljoos/wincred v1.2.3 h1:v7dZC2x32Ut3nEfRH+vhoZGvN72+dQ/snVXo/vMFLdQ=
github.com/danieljoos/wincred v1.2.3/go.mod h1:6qqX0WNrS4RzPZ1tnroDzq9kY3fu1KwE7MRLQK4X0bs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -202,18 +197,14 @@ github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQ
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/erofs/go-erofs v0.3.0 h1:o/W5ABAA3sHYl97WL93dacKEfeDpJhdFf3c2snAti7I=
github.com/erofs/go-erofs v0.3.0/go.mod h1:XkSeN9MHszGd4+3gcEjadJLYHCQpWzJ7/8yznzMuzJs=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc=
github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE=
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM=
@@ -224,8 +215,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/analysis v0.25.2 h1:I0vy4n3alz+DHTiN1PRhCb7QZxkK6g5YmswZKv2TKuw=
@@ -294,31 +285,16 @@ github.com/gohugoio/hashstructure v0.6.0 h1:7wMB/2CfXoThFYhdWRGv3u3rUM761Cq29CxU
github.com/gohugoio/hashstructure v0.6.0/go.mod h1:lapVLk9XidheHG1IQ4ZSbyYrXcaILU1ZEP/+vno5rBQ=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
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-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/certificate-transparency-go v1.3.3 h1:hq/rSxztSkXN2tx/3jQqF6Xc0O565UQPdHrOWvZwybo=
github.com/google/certificate-transparency-go v1.3.3/go.mod h1:iR17ZgSaXRzSa5qvjFl8TnVD5h8ky2JMVio+dzoKMgA=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/go-containerregistry v0.21.7 h1:/vPFuVXDjtFREsVArW+0h1CIl5urnOhzei4X2DMW9IU=
@@ -333,7 +309,6 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaU
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/trillian v1.7.3 h1:hziW+vo4czis48tzx2GK5xRBl/ZxBA9B0/UR5avXOro=
github.com/google/trillian v1.7.3/go.mod h1:qh8iy4x/GvnVXUBd5pK4oncuT1Y9vVYfibQVsR/WpKg=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.3.16 h1:F/VPrx0YPBdksZJQdCAp0WUsqnNmZpUZszzfYt0M5Dw=
@@ -473,8 +448,8 @@ github.com/opencontainers/selinux v1.15.1/go.mod h1:LenyElirjUHszfxrjuFqC85HIeXZ
github.com/package-url/packageurl-go v0.1.1 h1:KTRE0bK3sKbFKAk3yy63DpeskU7Cvs/x/Da5l+RtzyU=
github.com/package-url/packageurl-go v0.1.1/go.mod h1:uQd4a7Rh3ZsVg5j0lNyAfyxIeGde9yrlhjF78GzeW0c=
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pelletier/go-toml/v2 v2.4.3 h1:GTRvJQutkOSftxIFD5xw9aepkYNuPWmVJpffdDPYVpY=
github.com/pelletier/go-toml/v2 v2.4.3/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw=
github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
@@ -490,24 +465,23 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
github.com/prometheus/otlptranslator v1.0.0 h1:s0LJW/iN9dkIH+EnhiD3BlkkP5QVIUVEoIwkU+A6qos=
github.com/prometheus/otlptranslator v1.0.0/go.mod h1:vRYWnXvI6aWGpsdY/mOT/cbeVRBlPWtBNDb7kGR3uKM=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
@@ -547,8 +521,8 @@ github.com/sigstore/sigstore/pkg/signature/kms/hashivault v1.10.8/go.mod h1:6IDF
github.com/sigstore/timestamp-authority/v2 v2.1.2 h1:7DDhnknLL4w8VwomyvW2W8qblOS9LDR8oihna+jc7Ls=
github.com/sigstore/timestamp-authority/v2 v2.1.2/go.mod h1:o6rAVZceFyejClIj/uStRNIemP16bVMZtbMmhk6pr0U=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
github.com/sirupsen/logrus v1.10.1 h1:xi4336Zh11WpU14fXR6I67V3yaTPQYwRx2WEtHbRg4Q=
github.com/sirupsen/logrus v1.10.1/go.mod h1:vsQHnG7xzNsxk3NrwboUiWPnIC3dmbjcGPykD7+tiHk=
github.com/spdx/tools-golang v0.5.7 h1:+sWcKGnhwp3vLdMqPcLdA6QK679vd86cK9hQWH3AwCg=
github.com/spdx/tools-golang v0.5.7/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
@@ -558,14 +532,12 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.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/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE=
github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg=
github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
@@ -620,44 +592,42 @@ github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97
github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk=
go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU=
go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 h1:2yEATaop1/a1I4psnSLgWVPLWwCzkqWakgJy7xTDVy0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0 h1:MCcYL7J6Vt/X0kjqbMZkekCmwsurbQRbL69vkiye2lk=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0/go.mod h1:3jnStNwSufK+f5ktjL4EPcwtig4rtd81NS70lqHuXl8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0 h1:oECp5f+hN7nkwjU/8BxQ/q23bGPb8FIrD839owX222E=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.70.0/go.mod h1:DqEFwLumhzMBDQv9PcWbyoDxHI/4lAk6CM4nJBH39sc=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.0 h1:aVgLpGksz0vjoe6OynycqX8daNOAxJx5ZEhJXIXOVIU=
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.70.0/go.mod h1:kmJlX6WuTrAH1fOCSbPJFrSnUagB8c3SY3E87It3JD8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04=
go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0 h1:SUplec5dp06reu1zaXmOXdvqH398taqrDXqUl99jxSc=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.44.0/go.mod h1:ho2g4N+ane+swq5I/VBkKWnRDY4kUINH3FuqyZqX/Ug=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0 h1:RuynHbfU8JUEw7DyONgkVYg2SVtsoF28y0LGIr69jgA=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.44.0/go.mod h1:qZF+/lBs71APw8mlnEZcqZHMzqrYrsFiJOv83lX1OGo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0 h1:lgh3PiVrRUWMLOVSkQicxzZll5NjF1r+AtsX1XRIHw0=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.44.0/go.mod h1:5Cnhth3m/AgOeTgE3ex12pPmiu/gGtZit03kSzx9X7s=
go.opentelemetry.io/otel/exporters/prometheus v0.66.0 h1:vkrK8PAznv2NKt2r+kdu252ccGzkEqLc2aSXbQIALYQ=
go.opentelemetry.io/otel/exporters/prometheus v0.66.0/go.mod h1:V/UB6D3vMF/UBOL5igAsAYnk1nG/bzYYTzvsB16cy7o=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/metric/x v0.66.0 h1:YkCrx1zLOChi9ZcZ6euupOcsgzbVlec7D/xoEU1+cTA=
go.opentelemetry.io/otel/metric/x v0.66.0/go.mod h1:d1+BDj9t96do0/1LoU1ayfCv79ZgNE41qbhBvnMOBZk=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0 h1:klTViGcsvLCd1xN3rZzfZ12NslC/OimbmR+k+A006RI=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.45.0/go.mod h1:jRsK04CWmXuY8A0O+wMpSf+t90RHZ53o5Qmxn2PQPfk=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0 h1:pnxy6c/kvNBWdNNFzqpjuJLm9Hjhgk/Q0nY221rwuk0=
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.45.0/go.mod h1:qw6YsFapotRwoDhXRZvljzaOvCQB7UfnafEJagpN2TA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0 h1:QBajQ2SrwQijzHyZbQlPsuIzpl/ll8DY6wPWsajeGcI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.45.0/go.mod h1:08ZQLjrPLQ6R4kAXvuOvODEer5Yh4CoFvll5qB2BCI8=
go.opentelemetry.io/otel/exporters/prometheus v0.67.0 h1:7IefDa35e6V3NoiqIeLDMDxMFyZDk5qcoC0Ax4cC16E=
go.opentelemetry.io/otel/exporters/prometheus v0.67.0/go.mod h1:nsPI1awTg5Vmg1YrommL2mVarVGlqc4yXOoKAkPRD0c=
go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
go.opentelemetry.io/otel/metric/x v0.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns=
go.opentelemetry.io/otel/metric/x v0.67.0/go.mod h1:FBjCWZe6wgcqxcMtjdGiClDKXb2YxxXii0CXftE4QtI=
go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk=
go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E=
go.step.sm/crypto v0.77.7 h1:6azC+pD678Vjju8yXnMDHCZJ+HzFaEmL3sCryiezTIA=
go.step.sm/crypto v0.77.7/go.mod h1:OW/2sEHwTtDKq70PvSQ5B0JGy/CrLyDKOiVy3YvZMTQ=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
@@ -674,43 +644,26 @@ go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw=
go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M=
golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis=
golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q=
golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
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.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk=
golang.org/x/mod v0.38.0/go.mod h1:V6Xz0pq8TQ3dGqVQ1FVHuelZpAL0uNhSkk9ogYP3c40=
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/mod v0.40.0 h1:hUv+3cXcdRHz08UmSiOob7sadHig73uo5bkXxQ/tvUs=
golang.org/x/mod v0.40.0/go.mod h1:0/weTWkPWGBikyTWAX3dkjVztMmBA5hM0DH6BElSupE=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/net v0.58.0 h1:ynWG7rqYi4ccpTEuPZ2QGWHktVEM9DMCj9yzDE0Q7To=
golang.org/x/net v0.58.0/go.mod h1:YwCddHnFlT7eLQqVprV19OnhLGtc5xOKgE0RyqgfWAU=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
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-20181221193216-37e7f081c4d4/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.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -720,54 +673,28 @@ golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
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.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/text v0.41.0 h1:vz/seA0lnX87Othu2f/0L24RcgrXD9/YFTSuGjj3rH8=
golang.org/x/text v0.41.0/go.mod h1:jvf1O8ajNzZqhSrQBPbutR/EB83Cc0CFrezNQIwbb5M=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
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.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/tools v0.49.0 h1:3NI7VXzL9+1WZD52Dx2ttoPwD5DWrFGpl9mFZDlmisI=
golang.org/x/tools v0.49.0/go.mod h1:SJNXV9DBKT0UbdttsQjbfJlAE/q+y36++zo3uL3N0Oo=
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
google.golang.org/api v0.283.0 h1:0lkp8u0MPwJVHqRL+nJlMAoZVVzbmiXmFHXMOTmSPik=
google.golang.org/api v0.283.0/go.mod h1:6Wssta4c5n9qHq5CBhmlai5h/PUa1djdDAIhYEHyvcM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/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-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0=
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
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.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE=
google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1 h1:/WILD1UcXj/ujCxgoL/DvRgt2CP3txG8+FwkUbb9110=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.1/go.mod h1:YNKnb2OAApgYn2oYY47Rn7alMr1zWjb2U8Q0aoGWiNc=
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=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc=
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.83.1 h1:HIO0+BEtBP6soyqvqC8sNUjZ7bTs+0hFQuFF+RAy++Y=
google.golang.org/grpc v1.83.1/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2 h1:rgSNvqscFZ1JgV/4wH5GOsZFSFkR2Eua9As3KIr2LlM=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.6.2/go.mod h1:iMEtFwDlAhjDU9L5mY6U1XLwlIId/G3h+QcBHDIvrJ8=
google.golang.org/protobuf v1.36.12 h1:pJOKDDOyeXErUroCihFAd5LQuwXBSpVnKGrj5o/fwxc=
google.golang.org/protobuf v1.36.12/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
@@ -779,8 +706,6 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
kernel.org/pub/linux/libs/security/libcap/cap v1.2.78 h1:jgqg4gyu2BaYW9L6uzEtGLf8GNREwk/z4UFdwt5F3pE=
+1 -1
View File
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: MPL-2.0
#
# libpathrs: safe path resolution on Linux
# Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
# Copyright (C) 2019-2025 SUSE LLC
# Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
+1 -1
View File
@@ -1,8 +1,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
+8 -10
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,6 +17,8 @@ import (
"fmt"
"os"
"golang.org/x/sys/unix"
"cyphar.com/go-pathrs/internal/fdutils"
"cyphar.com/go-pathrs/internal/libpathrs"
)
@@ -30,11 +32,9 @@ import (
// you can try to use [Root.Open] or [Root.OpenFile].
//
// It is critical that perform all relevant operations through this [Handle]
// (rather than fetching the file descriptor yourself with [Handle.IntoRaw]),
// (rather than fetching the underlying [os.File] yourself with [Handle.IntoFile]),
// because the security properties of libpathrs depend on users doing all
// relevant filesystem operations through libpathrs.
//
// [os.File]: https://pkg.go.dev/os#File
type Handle struct {
inner *os.File
}
@@ -43,7 +43,7 @@ type Handle struct {
// handle will be copied by this method, so the original handle should still be
// freed by the caller.
//
// This is effectively the inverse operation of [Handle.IntoRaw], and is used
// This is effectively the inverse operation of [Handle.IntoFile], and is used
// for "deserialising" pathrs root handles.
func HandleFromFile(file *os.File) (*Handle, error) {
newFile, err := fdutils.DupFile(file)
@@ -58,11 +58,11 @@ func HandleFromFile(file *os.File) (*Handle, error) {
// and can be opened multiple times.
//
// The handle returned is only usable for reading, and this is method is
// shorthand for [Handle.OpenFile] with os.O_RDONLY.
// shorthand for [Handle.OpenFile] with [unix.O_RDONLY].
//
// TODO: Rename these to "Reopen" or something.
func (h *Handle) Open() (*os.File, error) {
return h.OpenFile(os.O_RDONLY)
return h.OpenFile(unix.O_RDONLY)
}
// OpenFile creates an "upgraded" file handle to the file referenced by the
@@ -73,7 +73,7 @@ func (h *Handle) Open() (*os.File, error) {
// handle.
//
// TODO: Rename these to "Reopen" or something.
func (h *Handle) OpenFile(flags int) (*os.File, error) {
func (h *Handle) OpenFile(flags uint64) (*os.File, error) {
return fdutils.WithFileFd(h.inner, func(fd uintptr) (*os.File, error) {
newFd, err := libpathrs.Reopen(fd, flags)
if err != nil {
@@ -92,8 +92,6 @@ func (h *Handle) OpenFile(flags int) (*os.File, error) {
// calling [Handle.Close] will also close any copies of the returned [os.File].
// If you want to get an independent copy, use [Handle.Clone] followed by
// [Handle.IntoFile] on the cloned [Handle].
//
// [os.File]: https://pkg.go.dev/os#File
func (h *Handle) IntoFile() *os.File {
// TODO: Figure out if we really don't want to make a copy.
// TODO: We almost certainly want to clear r.inner here, but we can't do
+1 -1
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
+1 -1
View File
@@ -5,8 +5,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
+55 -27
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -60,8 +60,8 @@ func OpenRoot(path string) (uintptr, error) {
}
// Reopen wraps pathrs_reopen.
func Reopen(fd uintptr, flags int) (uintptr, error) {
newFd := C.pathrs_reopen(C.int(fd), C.int(flags))
func Reopen(fd uintptr, flags uint64) (uintptr, error) {
newFd := C.pathrs_reopen(C.int(fd), C.uint64_t(flags))
return uintptr(newFd), fetchError(newFd)
}
@@ -84,11 +84,11 @@ func InRootResolveNoFollow(rootFd uintptr, path string) (uintptr, error) {
}
// InRootOpen wraps pathrs_inroot_open.
func InRootOpen(rootFd uintptr, path string, flags int) (uintptr, error) {
func InRootOpen(rootFd uintptr, path string, flags uint64) (uintptr, error) {
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.int(flags))
fd := C.pathrs_inroot_open(C.int(rootFd), cPath, C.uint64_t(flags))
return uintptr(fd), fetchError(fd)
}
@@ -100,7 +100,7 @@ func InRootReadlink(rootFd uintptr, path string) (string, error) {
size := 128
for {
linkBuf := make([]byte, size)
n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf)))
n := C.pathrs_inroot_readlink(C.int(rootFd), cPath, C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf)))
switch {
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
return "", fetchError(n)
@@ -145,23 +145,23 @@ func InRootRemoveAll(rootFd uintptr, path string) error {
}
// InRootCreat wraps pathrs_inroot_creat.
func InRootCreat(rootFd uintptr, path string, flags int, mode uint32) (uintptr, error) {
func InRootCreat(rootFd uintptr, path string, flags uint64, mode uint32) (uintptr, error) {
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.int(flags), C.uint(mode))
fd := C.pathrs_inroot_creat(C.int(rootFd), cPath, C.uint64_t(flags), C.uint(mode))
return uintptr(fd), fetchError(fd)
}
// InRootRename wraps pathrs_inroot_rename.
func InRootRename(rootFd uintptr, src, dst string, flags uint) error {
cSrc := C.CString(src)
defer C.free(unsafe.Pointer(cSrc))
func InRootRename(oldRootFd uintptr, oldPath string, newRootFd uintptr, newPath string, flags uint64) error {
cOldPath := C.CString(oldPath)
defer C.free(unsafe.Pointer(cOldPath))
cDst := C.CString(dst)
defer C.free(unsafe.Pointer(cDst))
cNewPath := C.CString(newPath)
defer C.free(unsafe.Pointer(cNewPath))
err := C.pathrs_inroot_rename(C.int(rootFd), cSrc, cDst, C.uint(flags))
err := C.pathrs_inroot_rename(C.int(oldRootFd), cOldPath, C.int(newRootFd), cNewPath, C.uint64_t(flags))
return fetchError(err)
}
@@ -193,26 +193,26 @@ func InRootMknod(rootFd uintptr, path string, mode uint32, dev uint64) error {
}
// InRootSymlink wraps pathrs_inroot_symlink.
func InRootSymlink(rootFd uintptr, path, target string) error {
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
func InRootSymlink(target string, rootFd uintptr, linkpath string) error {
cLinkpath := C.CString(linkpath)
defer C.free(unsafe.Pointer(cLinkpath))
cTarget := C.CString(target)
defer C.free(unsafe.Pointer(cTarget))
err := C.pathrs_inroot_symlink(C.int(rootFd), cPath, cTarget)
err := C.pathrs_inroot_symlink(cTarget, C.int(rootFd), cLinkpath)
return fetchError(err)
}
// InRootHardlink wraps pathrs_inroot_hardlink.
func InRootHardlink(rootFd uintptr, path, target string) error {
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
func InRootHardlink(oldRootFd uintptr, oldPath string, newRootFd uintptr, newPath string, flags uint64) error {
cNewPath := C.CString(newPath)
defer C.free(unsafe.Pointer(cNewPath))
cTarget := C.CString(target)
defer C.free(unsafe.Pointer(cTarget))
cOldPath := C.CString(oldPath)
defer C.free(unsafe.Pointer(cOldPath))
err := C.pathrs_inroot_hardlink(C.int(rootFd), cPath, cTarget)
err := C.pathrs_inroot_hardlink(C.int(oldRootFd), cOldPath, C.int(newRootFd), cNewPath, C.uint64_t(flags))
return fetchError(err)
}
@@ -277,13 +277,13 @@ func init() {
func ProcPid(pid uint32) ProcBase { return ProcBaseTypePid | ProcBase(pid) }
// ProcOpenat wraps pathrs_proc_openat.
func ProcOpenat(procRootFd int, base ProcBase, path string, flags int) (uintptr, error) {
func ProcOpenat(procRootFd int, base ProcBase, path string, flags uint64) (uintptr, error) {
cBase := C.pathrs_proc_base_t(base)
cPath := C.CString(path)
defer C.free(unsafe.Pointer(cPath))
fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.int(flags))
fd := C.pathrs_proc_openat(C.int(procRootFd), cBase, cPath, C.uint64_t(flags))
return uintptr(fd), fetchError(fd)
}
@@ -301,7 +301,7 @@ func ProcReadlinkat(procRootFd int, base ProcBase, path string) (string, error)
linkBuf := make([]byte, size)
n := C.pathrs_proc_readlinkat(
C.int(procRootFd), cBase, cPath,
C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.ulong(len(linkBuf)))
C.cast_ptr(unsafe.Pointer(&linkBuf[0])), C.size_t(len(linkBuf)))
switch {
case int(n) < C.__PATHRS_MAX_ERR_VALUE:
return "", fetchError(n)
@@ -335,3 +335,31 @@ func ProcfsOpen(how *ProcfsOpenHow) (uintptr, error) {
fd := C.pathrs_procfs_open((*C.pathrs_procfs_open_how)(how), C.size_t(unsafe.Sizeof(*how)))
return uintptr(fd), fetchError(fd)
}
// VersionInfo is a Go-friendly form of pathrs_version_info_t (struct).
type VersionInfo struct {
VersionString string
}
// versionInfo is pathrs_version_info_t (struct).
type versionInfo C.pathrs_version_info_t
// Version is pathrs_version_info_t (sizeof(version) is passed automatically).
func Version() (*VersionInfo, error) {
var rawVersion versionInfo
size := C.pathrs_version((*C.pathrs_version_info_t)(&rawVersion), C.size_t(unsafe.Sizeof(rawVersion)))
switch {
case size < 0:
return nil, fetchError(size)
case size > 0:
// TODO(log): Logging?
fallthrough
default:
// TODO(log): Add a log statement if sizeof(rawVersion) is bigger than
// the number of fields we store in VersionInfo. Otherwise a rebuild
// will mask that Go callers cannot see any new fields.
return &VersionInfo{
VersionString: C.GoString(rawVersion.version_string),
}, nil
}
}
+9 -16
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -56,16 +56,15 @@ var (
// *before* you call wait(2)or any equivalent method that could reap
// zombies).
func ProcPid(pid int) ProcBase {
if pid < 0 || pid >= 1<<31 {
if pid < 0 || uint64(pid) >= 1<<31 {
panic("invalid ProcBasePid value") // TODO: should this be an error?
}
return ProcBase{inner: libpathrs.ProcPid(uint32(pid))}
pid32 := uint32(pid) //nolint:gosec // G115 false positive <https://github.com/securego/gosec/issues/1212>
return ProcBase{inner: libpathrs.ProcPid(pid32)}
}
// ThreadCloser is a callback that needs to be called when you are done
// operating on an [os.File] fetched using [Handle.OpenThreadSelf].
//
// [os.File]: https://pkg.go.dev/os#File
type ThreadCloser func()
// Handle is a wrapper around an *os.File handle to "/proc", which can be
@@ -128,7 +127,7 @@ func (proc *Handle) fd() int {
}
// TODO: Should we expose open?
func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Closer ThreadCloser, Err error) {
func (proc *Handle) open(base ProcBase, path string, flags uint64) (_ *os.File, Closer ThreadCloser, Err error) {
var closer ThreadCloser
if base == ProcThreadSelf {
runtime.LockOSThread()
@@ -155,7 +154,7 @@ func (proc *Handle) open(base ProcBase, path string, flags int) (_ *os.File, Clo
// (such as /proc/cpuinfo) or information about other processes (such as
// /proc/1). Accessing your own process information should be done using
// [Handle.OpenSelf] or [Handle.OpenThreadSelf].
func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) {
func (proc *Handle) OpenRoot(path string, flags uint64) (*os.File, error) {
file, closer, err := proc.open(ProcRoot, path, flags)
if closer != nil {
// should not happen
@@ -181,9 +180,7 @@ func (proc *Handle) OpenRoot(path string, flags int) (*os.File, error) {
// Unlike [Handle.OpenThreadSelf], this method does not involve locking
// the goroutine to the current OS thread and so is simpler to use and
// theoretically has slightly less overhead.
//
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) {
func (proc *Handle) OpenSelf(path string, flags uint64) (*os.File, error) {
file, closer, err := proc.open(ProcSelf, path, flags)
if closer != nil {
// should not happen
@@ -201,7 +198,7 @@ func (proc *Handle) OpenSelf(path string, flags int) (*os.File, error) {
// Be aware that due to PID recycling, using this is generally not safe except
// in certain circumstances. See the documentation of [ProcPid] for more
// details.
func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) {
func (proc *Handle) OpenPid(pid int, path string, flags uint64) (*os.File, error) {
file, closer, err := proc.open(ProcPid(pid), path, flags)
if closer != nil {
// should not happen
@@ -228,11 +225,7 @@ func (proc *Handle) OpenPid(pid int, path string, flags int) (*os.File, error) {
// callback MUST be called AFTER you have finished using the returned
// [os.File]. This callback is completely separate to [os.File.Close], so it
// must be called regardless of how you close the handle.
//
// [runtime.LockOSThread]: https://pkg.go.dev/runtime#LockOSThread
// [os.File]: https://pkg.go.dev/os#File
// [os.File.Close]: https://pkg.go.dev/os#File.Close
func (proc *Handle) OpenThreadSelf(path string, flags int) (*os.File, ThreadCloser, error) {
func (proc *Handle) OpenThreadSelf(path string, flags uint64) (*os.File, ThreadCloser, error) {
return proc.open(ProcThreadSelf, path, flags)
}
+30 -54
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -19,6 +19,8 @@ import (
"os"
"syscall"
"golang.org/x/sys/unix"
"cyphar.com/go-pathrs/internal/fdutils"
"cyphar.com/go-pathrs/internal/libpathrs"
)
@@ -27,7 +29,7 @@ import (
// purpose of this "root handle" is to perform operations within the directory
// tree, or to get a [Handle] to inodes within the directory tree.
//
// At time of writing, it is considered a *VERY BAD IDEA* to open a [Root]
// At time of writing, it is considered a *VERY BAD IDEA* to open a Root
// inside a possibly-attacker-controlled directory tree. While we do have
// protections that should defend against it, it's far more dangerous than just
// opening a directory tree which is not inside a potentially-untrusted
@@ -54,8 +56,6 @@ func OpenRoot(path string) (*Root, error) {
// still be closed by the caller.
//
// This is effectively the inverse operation of [Root.IntoFile].
//
// [os.File]: https://pkg.go.dev/os#File
func RootFromFile(file *os.File) (*Root, error) {
newFile, err := fdutils.DupFile(file)
if err != nil {
@@ -70,7 +70,7 @@ func RootFromFile(file *os.File) (*Root, error) {
//
// All symlinks (including trailing symlinks) are followed, but they are
// resolved within the rootfs. If you wish to open a handle to the symlink
// itself, use [ResolveNoFollow].
// itself, use [Root.ResolveNoFollow].
func (r *Root) Resolve(path string) (*Handle, error) {
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) {
handleFd, err := libpathrs.InRootResolve(rootFd, path)
@@ -85,10 +85,10 @@ func (r *Root) Resolve(path string) (*Handle, error) {
})
}
// ResolveNoFollow is effectively an O_NOFOLLOW version of [Resolve]. Their
// behaviour is identical, except that *trailing* symlinks will not be
// followed. If the final component is a trailing symlink, an O_PATH|O_NOFOLLOW
// handle to the symlink itself is returned.
// ResolveNoFollow is effectively an [unix.O_NOFOLLOW] version of
// [Root.Resolve]. Their behaviour is identical, except that *trailing*
// symlinks will not be followed. If the final component is a trailing symlink,
// an [unix.O_PATH]|[unix.O_NOFOLLOW] handle to the symlink itself is returned.
func (r *Root) ResolveNoFollow(path string) (*Handle, error) {
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*Handle, error) {
handleFd, err := libpathrs.InRootResolveNoFollow(rootFd, path)
@@ -103,33 +103,29 @@ func (r *Root) ResolveNoFollow(path string) (*Handle, error) {
})
}
// Open is effectively shorthand for [Resolve] followed by [Handle.Open], but
// can be slightly more efficient (it reduces CGo overhead and the number of
// syscalls used when using the openat2-based resolver) and is arguably more
// Open is effectively shorthand for [Root.Resolve] followed by [Handle.Open],
// but can be slightly more efficient (it reduces CGo overhead and the number
// of syscalls used when using the openat2-based resolver) and is arguably more
// ergonomic to use.
//
// This is effectively equivalent to [os.Open].
//
// [os.Open]: https://pkg.go.dev/os#Open
func (r *Root) Open(path string) (*os.File, error) {
return r.OpenFile(path, os.O_RDONLY)
return r.OpenFile(path, unix.O_RDONLY)
}
// OpenFile is effectively shorthand for [Resolve] followed by
// OpenFile is effectively shorthand for [Root.Resolve] followed by
// [Handle.OpenFile], but can be slightly more efficient (it reduces CGo
// overhead and the number of syscalls used when using the openat2-based
// resolver) and is arguably more ergonomic to use.
//
// However, if flags contains os.O_NOFOLLOW and the path is a symlink, then
// However, if flags contains [unix.O_NOFOLLOW] and the path is a symlink, then
// OpenFile's behaviour will match that of openat2. In most cases an error will
// be returned, but if os.O_PATH is provided along with os.O_NOFOLLOW then a
// file equivalent to [ResolveNoFollow] will be returned instead.
// be returned, but if [unix.O_PATH] is provided along with [unix.O_NOFOLLOW]
// then a file equivalent to [Root.ResolveNoFollow] will be returned instead.
//
// This is effectively equivalent to [os.OpenFile], except that os.O_CREAT is
// not supported.
//
// [os.OpenFile]: https://pkg.go.dev/os#OpenFile
func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
// This is effectively equivalent to [os.OpenFile], except that [unix.O_CREAT]
// is not supported.
func (r *Root) OpenFile(path string, flags uint64) (*os.File, error) {
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (*os.File, error) {
fd, err := libpathrs.InRootOpen(rootFd, path, flags)
if err != nil {
@@ -145,9 +141,7 @@ func (r *Root) OpenFile(path string, flags int) (*os.File, error) {
//
// Unlike [os.Create], if the file already exists an error is created rather
// than the file being opened and truncated.
//
// [os.Create]: https://pkg.go.dev/os#Create
func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error) {
func (r *Root) Create(path string, flags uint64, mode os.FileMode) (*os.File, error) {
unixMode, err := toUnixMode(mode, false)
if err != nil {
return nil, err
@@ -163,9 +157,9 @@ func (r *Root) Create(path string, flags int, mode os.FileMode) (*os.File, error
// Rename two paths within a [Root]'s directory tree. The flags argument is
// identical to the RENAME_* flags to the renameat2(2) system call.
func (r *Root) Rename(src, dst string, flags uint) error {
func (r *Root) Rename(src, dst string, flags uint64) error {
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
err := libpathrs.InRootRename(rootFd, src, dst, flags)
err := libpathrs.InRootRename(rootFd, src, rootFd, dst, flags)
return struct{}{}, err
})
return err
@@ -194,8 +188,6 @@ func (r *Root) RemoveFile(path string) error {
// directory tree.
//
// This is effectively equivalent to [os.Remove].
//
// [os.Remove]: https://pkg.go.dev/os#Remove
func (r *Root) Remove(path string) error {
// In order to match os.Remove's implementation we need to also do both
// syscalls unconditionally and adjust the error based on whether
@@ -219,8 +211,6 @@ func (r *Root) Remove(path string) error {
// RemoveAll recursively deletes a path and all of its children.
//
// This is effectively equivalent to [os.RemoveAll].
//
// [os.RemoveAll]: https://pkg.go.dev/os#RemoveAll
func (r *Root) RemoveAll(path string) error {
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
err := libpathrs.InRootRemoveAll(rootFd, path)
@@ -233,8 +223,6 @@ func (r *Root) RemoveAll(path string) error {
// mode is used for the new directory (the process's umask applies).
//
// This is effectively equivalent to [os.Mkdir].
//
// [os.Mkdir]: https://pkg.go.dev/os#Mkdir
func (r *Root) Mkdir(path string, mode os.FileMode) error {
unixMode, err := toUnixMode(mode, false)
if err != nil {
@@ -253,8 +241,6 @@ func (r *Root) Mkdir(path string, mode os.FileMode) error {
// directories created by this function (the process's umask applies).
//
// This is effectively equivalent to [os.MkdirAll].
//
// [os.MkdirAll]: https://pkg.go.dev/os#MkdirAll
func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) {
unixMode, err := toUnixMode(mode, false)
if err != nil {
@@ -278,9 +264,7 @@ func (r *Root) MkdirAll(path string, mode os.FileMode) (*Handle, error) {
// directory tree. The provided mode is used for the new directory (the
// process's umask applies).
//
// This is effectively equivalent to [unix.Mknod].
//
// [unix.Mknod]: https://pkg.go.dev/golang.org/x/sys/unix#Mknod
// This is effectively equivalent to [golang.org/x/sys/unix.Mknod].
func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
unixMode, err := toUnixMode(mode, true)
if err != nil {
@@ -295,30 +279,26 @@ func (r *Root) Mknod(path string, mode os.FileMode, dev uint64) error {
}
// Symlink creates a symlink within a [Root]'s directory tree. The symlink is
// created at path and is a link to target.
// created at newname and is a link to oldname.
//
// This is effectively equivalent to [os.Symlink].
//
// [os.Symlink]: https://pkg.go.dev/os#Symlink
func (r *Root) Symlink(path, target string) error {
func (r *Root) Symlink(oldname, newname string) error {
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
err := libpathrs.InRootSymlink(rootFd, path, target)
err := libpathrs.InRootSymlink(oldname, rootFd, newname)
return struct{}{}, err
})
return err
}
// Hardlink creates a hardlink within a [Root]'s directory tree. The hardlink
// is created at path and is a link to target. Both paths are within the
// is created at newname and is a link to oldname. Both paths are within the
// [Root]'s directory tree (you cannot hardlink to a different [Root] or the
// host).
//
// This is effectively equivalent to [os.Link].
//
// [os.Link]: https://pkg.go.dev/os#Link
func (r *Root) Hardlink(path, target string) error {
func (r *Root) Hardlink(oldname, newname string) error {
_, err := fdutils.WithFileFd(r.inner, func(rootFd uintptr) (struct{}, error) {
err := libpathrs.InRootHardlink(rootFd, path, target)
err := libpathrs.InRootHardlink(rootFd, oldname, rootFd, newname, 0)
return struct{}{}, err
})
return err
@@ -327,8 +307,6 @@ func (r *Root) Hardlink(path, target string) error {
// Readlink returns the target of a symlink with a [Root]'s directory tree.
//
// This is effectively equivalent to [os.Readlink].
//
// [os.Readlink]: https://pkg.go.dev/os#Readlink
func (r *Root) Readlink(path string) (string, error) {
return fdutils.WithFileFd(r.inner, func(rootFd uintptr) (string, error) {
return libpathrs.InRootReadlink(rootFd, path)
@@ -345,8 +323,6 @@ func (r *Root) Readlink(path string) (string, error) {
// calling [Root.Close] will also close any copies of the returned [os.File].
// If you want to get an independent copy, use [Root.Clone] followed by
// [Root.IntoFile] on the cloned [Root].
//
// [os.File]: https://pkg.go.dev/os#File
func (r *Root) IntoFile() *os.File {
// TODO: Figure out if we really don't want to make a copy.
// TODO: We almost certainly want to clear r.inner here, but we can't do
+1 -1
View File
@@ -3,8 +3,8 @@
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2019-2025 Aleksa Sarai <cyphar@cyphar.com>
* Copyright (C) 2019-2025 SUSE LLC
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
+27
View File
@@ -0,0 +1,27 @@
//go:build linux
// SPDX-License-Identifier: MPL-2.0
/*
* libpathrs: safe path resolution on Linux
* Copyright (C) 2026 Aleksa Sarai <cyphar@cyphar.com>
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
package pathrs
import (
"cyphar.com/go-pathrs/internal/libpathrs"
)
// LibraryVersionInfo contains information about the version and features
// supported by the underlying libpathrs.so library at runtime.
type LibraryVersionInfo = libpathrs.VersionInfo
// LibraryVersion returns information about the version and features supported
// by the underlying libpathrs.so library at runtime.
func LibraryVersion() (*LibraryVersionInfo, error) {
return libpathrs.Version()
}
+7
View File
@@ -4,6 +4,11 @@
*.so
*.dylib
# manifest related generated files
*.syso
manifest.xml
*.exe.manifest
# Ignore vscode setting files
.vscode/
.idea/
@@ -51,3 +56,5 @@ go.work.sum
# keys and related artifacts
*.pem
*.cose
rust/target/
+11 -1
View File
@@ -5,6 +5,11 @@ include Makefile.bootfiles
# enable loading kernel modules in init
KMOD:=0
# whether the base rootfs uses a usr-merged layout (i.e. /bin is a symlink to
# /usr/bin). This defaults to disabled; set USR_MERGED_ROOTFS=1 for a
# usr-merged base rootfs such as Azure Linux.
USR_MERGED_ROOTFS:=0
CFLAGS:=-O2 -Wall
LDFLAGS:=-static -s #strip C binaries
LDLIBS:=
@@ -89,7 +94,12 @@ out/delta-snp.tar.gz: out/delta.tar.gz bin/internal/tools/snp-report boot/startu
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
mkdir -p rootfs/bin/
ifeq "$(USR_MERGED_ROOTFS)" "1"
mkdir -p rootfs/usr/bin
ln -s usr/bin rootfs/bin
else
mkdir -p rootfs/bin
endif
mkdir -p rootfs/info/
cp bin/init rootfs/
cp bin/vsockexec rootfs/bin/
+3 -2
View File
@@ -6,7 +6,7 @@ generators = ["go", "go-grpc"]
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.
# override defaults to supress errors about non-existent directories.
after = []
# This section maps protobuf imports to Go packages.
@@ -19,7 +19,8 @@ prefixes = [
"github.com/Microsoft/hcsshim/internal/shimdiag",
"github.com/Microsoft/hcsshim/internal/extendedtask",
"github.com/Microsoft/hcsshim/internal/computeagent",
"github.com/Microsoft/hcsshim/internal/controller",
"github.com/Microsoft/hcsshim/internal/ncproxyttrpc",
"github.com/Microsoft/hcsshim/internal/vmservice",
"github.com/Microsoft/hcsshim/pkg/migration",
]
generators = ["go", "go-ttrpc"]
+100 -1
View File
@@ -44,7 +44,7 @@ delta.tar.gz initrd.img rootfs.tar.gz
### Containerd Shim
For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/core/runtime/v2/README.md).
For info on the [Runtime V2 API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md).
Contrary to the typical Linux architecture of shim -> runc, the runhcs shim is used both to launch and manage the lifetime of containers.
@@ -68,6 +68,105 @@ To trial using the shim out with ctr.exe:
C:\> ctr.exe run --runtime io.containerd.runhcs.v1 --rm mcr.microsoft.com/windows/nanoserver:2004 windows-test cmd /c "echo Hello World!"
```
### Containerd Shim V2
The V2 shims are the rewrite of the Windows containerd shim. The V1 shim
([`containerd-shim-runhcs-v1`](./cmd/containerd-shim-runhcs-v1)) is a single, monolithic
binary that handles LCOW (Linux Containers on Windows), Hyper-V WCOW (Windows Containers on Windows), process-isolated
WCOW and host-process containers. In the V2 model that monolith is split into focused,
per-platform shims, each backed 1:1 by a sandbox.
V2 shims are used with containerd in the same way as the V1 shim, but the
API surface they expose is different. The V1 shim implemented only the containerd
[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md),
and used it to manage both the sandbox lifecycle and the container/process (task)
lifecycle through a single service. Each V2 shim instead splits these responsibilities
across the two APIs that containerd now provides for this purpose: the
[Sandbox API](https://github.com/containerd/containerd/blob/main/docs/sandbox-api.md)
is used to manage the sandbox, while the
[Task API](https://github.com/containerd/containerd/blob/main/docs/runtime-v2.md)
is used to manage containers and processes running inside it. Internally each V2 shim
implements these as separate sandbox and task services, alongside an auxiliary
`shimdiag` service used for diagnostics.
All three shims honor the same CRI pod model. A task annotated with
`"io.kubernetes.cri.container-type": "sandbox"` is treated as the pause/infra container
that creates the pod; sibling workload tasks set `"io.kubernetes.cri.container-type":
"container"` and reference their pause via `"io.kubernetes.cri.sandbox-id"`. What a
"sandbox" *physically* corresponds to depends on the shim, and is described in each
subsection below.
#### containerd-shim-lcow-v2
- **Purpose:** Runs Linux Containers on Windows (LCOW) — a Linux utility VM hosting Linux
containers.
- **Sandbox:** The Linux UVM. Each shim instance is backed 1:1 by a single UVM. This shim supports running
*multiple pods in the same UVM*, so a single shim instance may host more than one
CRI pods.
- **Tasks:** Linux containers and processes running inside the UVM, identified via the
same CRI annotations described above.
- **Implementation:** [`./cmd/containerd-shim-lcow-v2`](./cmd/containerd-shim-lcow-v2).
- **Build Tag:** lcow
- **Platform requirement:** Windows Server 2025 (build 26100) or later.
#### containerd-shim-wcow-v2
- **Purpose:** Runs Hyper-V isolated Windows containers (WCOW) — a Windows utility VM hosting
Process and/or Host Process Containers inside it.
- **Sandbox:** The Windows utility VM (UVM). Each shim instance is backed 1:1 by a single UVM.
- **Tasks:** the Windows containers and processes running inside the UVM, identified
via the standard CRI annotations described above.
- **Implementation:** coming soon.
- **Build Tag:** wcow
#### containerd-shim-process-v2
- **Purpose:** Runs Process-isolated Windows Server containers and Host
Process Containers — workloads that execute directly on the host with no utility VM.
- **Sandbox:** A *pause container*. The pause container is a minimal, long-lived
container that owns the pod's shared resources (such as the network namespace) and
keeps them alive while sibling workload containers are started, stopped or replaced.
This is the standard Kubernetes pod model: the pause container is the sandbox that
the rest of the pod attaches to.
- **Tasks:** the actual workload containers belonging to the pod, linked back to the
pause via the `io.kubernetes.cri.sandbox-id` annotation.
- **Implementation:** coming soon.
- **Build Tag:** process
##### Building
The V2 shim sources are guarded by the build tags as mentioned above, so the tag must be passed
to `go build`. For example the `LCOW` shim has `lcow` tag-
```powershell
C:\> $env:GOOS="windows"
C:\> go build -tags lcow .\cmd\containerd-shim-lcow-v2
```
Place the resulting `containerd-shim-lcow-v2.exe` in the same directory as `containerd.exe`,
the same as for the V1 shim.
##### Running unit tests
The shim's unit tests (and the rest of the tagged packages) are run with the
shim specific build tag:
```powershell
C:\> go test -tags lcow ./...
```
##### Running parity tests
The repository ships parity tests under [`./test/parity`](./test/parity) that feed
identical inputs through the legacy V1 and the new V2 pipelines and assert that the
resulting HCS ComputeSystem documents are equivalent. They live in the `test` Go
module and are also built with the build tag:
```powershell
C:\> cd test
C:\> go test -tags lcow ./parity/...
```
## Contributing
This project welcomes contributions and suggestions. Most contributions require you to agree to a
@@ -1,6 +1,6 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.36.10
// protoc-gen-go v1.36.12
// protoc v5.26.0
// source: github.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto
@@ -187,8 +187,9 @@ type Options struct {
// no_inherit_host_timezone specifies to skip inheriting the hosts time zone for WCOW UVMs and instead default to
// UTC.
NoInheritHostTimezone bool `protobuf:"varint,19,opt,name=no_inherit_host_timezone,json=noInheritHostTimezone,proto3" json:"no_inherit_host_timezone,omitempty"`
// scrub_logs enables removing environment variables and other potentially sensitive information from logs
ScrubLogs bool `protobuf:"varint,20,opt,name=scrub_logs,json=scrubLogs,proto3" json:"scrub_logs,omitempty"`
// scrub_logs controls removing environment variables and other potentially sensitive information from logs.
// If unset, scrubbing is enabled by default. Set explicitly to false to disable.
ScrubLogs *bool `protobuf:"varint,20,opt,name=scrub_logs,json=scrubLogs,proto3,oneof" json:"scrub_logs,omitempty"`
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -357,8 +358,8 @@ func (x *Options) GetNoInheritHostTimezone() bool {
}
func (x *Options) GetScrubLogs() bool {
if x != nil {
return x.ScrubLogs
if x != nil && x.ScrubLogs != nil {
return *x.ScrubLogs
}
return false
}
@@ -477,7 +478,7 @@ var File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runh
const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto_rawDesc = "" +
"\n" +
"Ogithub.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto\x12\x14containerd.runhcs.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xd9\t\n" +
"Ogithub.com/Microsoft/hcsshim/cmd/containerd-shim-runhcs-v1/options/runhcs.proto\x12\x14containerd.runhcs.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xed\t\n" +
"\aOptions\x12\x14\n" +
"\x05debug\x18\x01 \x01(\bR\x05debug\x12F\n" +
"\n" +
@@ -501,9 +502,9 @@ const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_ru
"\tlog_level\x18\x10 \x01(\tR\blogLevel\x124\n" +
"\x17io_retry_timeout_in_sec\x18\x11 \x01(\x05R\x13ioRetryTimeoutInSec\x12\x82\x01\n" +
"\x1ddefault_container_annotations\x18\x12 \x03(\v2>.containerd.runhcs.v1.Options.DefaultContainerAnnotationsEntryR\x1bdefaultContainerAnnotations\x127\n" +
"\x18no_inherit_host_timezone\x18\x13 \x01(\bR\x15noInheritHostTimezone\x12\x1d\n" +
"\x18no_inherit_host_timezone\x18\x13 \x01(\bR\x15noInheritHostTimezone\x12\"\n" +
"\n" +
"scrub_logs\x18\x14 \x01(\bR\tscrubLogs\x1aN\n" +
"scrub_logs\x18\x14 \x01(\bH\x00R\tscrubLogs\x88\x01\x01\x1aN\n" +
" DefaultContainerAnnotationsEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" +
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\")\n" +
@@ -514,7 +515,8 @@ const file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_ru
"\x10SandboxIsolation\x12\v\n" +
"\aPROCESS\x10\x00\x12\x0e\n" +
"\n" +
"HYPERVISOR\x10\x01\"\xb6\x03\n" +
"HYPERVISOR\x10\x01B\r\n" +
"\v_scrub_logs\"\xb6\x03\n" +
"\x0eProcessDetails\x12\x1d\n" +
"\n" +
"image_name\x18\x01 \x01(\tR\timageName\x129\n" +
@@ -570,6 +572,7 @@ func file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_run
if File_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto != nil {
return
}
file_github_com_Microsoft_hcsshim_cmd_containerd_shim_runhcs_v1_options_runhcs_proto_msgTypes[0].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
@@ -105,8 +105,9 @@ message Options {
// UTC.
bool no_inherit_host_timezone = 19;
// scrub_logs enables removing environment variables and other potentially sensitive information from logs
bool scrub_logs = 20;
// scrub_logs controls removing environment variables and other potentially sensitive information from logs.
// If unset, scrubbing is enabled by default. Set explicitly to false to disable.
optional bool scrub_logs = 20;
}
// ProcessDetails contains additional information about a process. This is the additional
+10 -10
View File
@@ -6,9 +6,9 @@ import (
"context"
"encoding/json"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
)
// AttachLayerStorageFilter sets up the layer storage filter on a writable
@@ -20,11 +20,11 @@ import (
// `layerData` is the parent read-only layer data.
func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData LayerData) (err error) {
title := "hcsshim::AttachLayerStorageFilter"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
)
bytes, err := json.Marshal(layerData)
@@ -48,11 +48,11 @@ func AttachLayerStorageFilter(ctx context.Context, layerPath string, layerData L
// `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
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("volumePath", volumePath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("volumePath", volumePath),
)
bytes, err := json.Marshal(layerData)
+5 -5
View File
@@ -4,10 +4,10 @@ package computestorage
import (
"context"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
)
// DestroyLayer deletes a container layer.
@@ -15,10 +15,10 @@ import (
// `layerPath` is a path to a directory containing the layer to export.
func DestroyLayer(ctx context.Context, layerPath string) (err error) {
title := "hcsshim::DestroyLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("layerPath", layerPath))
err = hcsDestroyLayer(layerPath)
if err != nil {
+8 -8
View File
@@ -7,9 +7,9 @@ import (
"encoding/json"
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
)
// DetachLayerStorageFilter detaches the layer storage filter on a writable container layer.
@@ -17,10 +17,10 @@ import (
// `layerPath` is a path to a directory containing the layer to export.
func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error) {
title := "hcsshim::DetachLayerStorageFilter"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("layerPath", layerPath))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("layerPath", layerPath))
err = hcsDetachLayerStorageFilter(layerPath)
if err != nil {
@@ -34,10 +34,10 @@ func DetachLayerStorageFilter(ctx context.Context, layerPath string) (err error)
// `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
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("volumePath", volumePath))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("volumePath", volumePath))
layerData := LayerData{}
layerData.FilterType = filterType
+7 -7
View File
@@ -5,10 +5,10 @@ package computestorage
import (
"context"
"encoding/json"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
)
// ExportLayer exports a container layer.
@@ -22,12 +22,12 @@ import (
// `options` are the export options applied to the exported layer.
func ExportLayer(ctx context.Context, layerPath, exportFolderPath string, layerData LayerData, options ExportLayerOptions) (err error) {
title := "hcsshim::ExportLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
trace.StringAttribute("exportFolderPath", exportFolderPath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
attribute.String("exportFolderPath", exportFolderPath),
)
ldBytes, err := json.Marshal(layerData)
+3 -3
View File
@@ -5,7 +5,7 @@ package computestorage
import (
"context"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
)
@@ -20,9 +20,9 @@ import (
// that can be obtained from the virtdisk APIs.
func FormatWritableLayerVhd(ctx context.Context, vhdHandle windows.Handle) (err error) {
title := "hcsshim::FormatWritableLayerVhd"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
defer func() { ot.SetSpanStatus(span, err) }()
err = hcsFormatWritableLayerVhd(vhdHandle)
if err != nil {
+7 -7
View File
@@ -6,9 +6,9 @@ import (
"context"
"encoding/json"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
)
// ImportLayer imports a container layer.
@@ -22,12 +22,12 @@ import (
// `layerData` is the parent layer data.
func ImportLayer(ctx context.Context, layerPath, sourceFolderPath string, layerData LayerData) (err error) {
title := "hcsshim::ImportLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
trace.StringAttribute("sourceFolderPath", sourceFolderPath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
attribute.String("sourceFolderPath", sourceFolderPath),
)
bytes, err := json.Marshal(layerData)
+6 -6
View File
@@ -5,10 +5,10 @@ package computestorage
import (
"context"
"encoding/json"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"go.opencensus.io/trace"
)
// InitializeWritableLayer initializes a writable layer for a container.
@@ -19,11 +19,11 @@ import (
// `layerData` is the parent read-only layer data.
func InitializeWritableLayer(ctx context.Context, layerPath string, layerData LayerData) (err error) {
title := "hcsshim::InitializeWritableLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
)
bytes, err := json.Marshal(layerData)
+3 -3
View File
@@ -6,7 +6,7 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
)
@@ -14,9 +14,9 @@ import (
// GetLayerVhdMountPath returns the volume path for a virtual disk of a writable container layer.
func GetLayerVhdMountPath(ctx context.Context, vhdHandle windows.Handle) (path string, err error) {
title := "hcsshim::GetLayerVhdMountPath"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
defer func() { ot.SetSpanStatus(span, err) }()
var mountPath *uint16
err = hcsGetLayerVhdMountPath(vhdHandle, &mountPath)
+11 -11
View File
@@ -6,10 +6,10 @@ import (
"context"
"encoding/json"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/osversion"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
"golang.org/x/sys/windows"
)
@@ -24,11 +24,11 @@ import (
// `options` are the options applied while processing the layer.
func SetupBaseOSLayer(ctx context.Context, layerPath string, vhdHandle windows.Handle, options OsLayerOptions) (err error) {
title := "hcsshim::SetupBaseOSLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
)
bytes, err := json.Marshal(options)
@@ -59,12 +59,12 @@ func SetupBaseOSVolume(ctx context.Context, layerPath, volumePath string, option
return errors.New("SetupBaseOSVolume is not present on builds older than 19645")
}
title := "hcsshim::SetupBaseOSVolume"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("layerPath", layerPath),
trace.StringAttribute("volumePath", volumePath),
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("layerPath", layerPath),
attribute.String("volumePath", volumePath),
)
bytes, err := json.Marshal(options)
+4 -4
View File
@@ -18,12 +18,12 @@ import (
// NamespaceResourceEndpoint represents an Endpoint attached to a Namespace.
type NamespaceResourceEndpoint struct {
Id string `json:"ID,"`
Id string `json:"ID"`
}
// NamespaceResourceContainer represents a Container attached to a Namespace.
type NamespaceResourceContainer struct {
Id string `json:"ID,"`
Id string `json:"ID"`
}
// NamespaceResourceType determines whether the Namespace resource is a Container or Endpoint.
@@ -38,8 +38,8 @@ var (
// NamespaceResource is associated with a namespace
type NamespaceResource struct {
Type NamespaceResourceType `json:","` // Container, Endpoint
Data json.RawMessage `json:","`
Type NamespaceResourceType `json:""` // Container, Endpoint
Data json.RawMessage `json:""`
}
// NamespaceType determines whether the Namespace is for a Host or Guest
+14 -9
View File
@@ -127,8 +127,8 @@ const (
// AclPolicySetting creates firewall rules on an endpoint
type AclPolicySetting struct {
Protocols string `json:",omitempty"` // EX: 6 (TCP), 17 (UDP), 1 (ICMPv4), 58 (ICMPv6), 2 (IGMP)
Action ActionType `json:","`
Direction DirectionType `json:","`
Action ActionType `json:""`
Direction DirectionType `json:""`
LocalAddresses string `json:",omitempty"`
RemoteAddresses string `json:",omitempty"`
LocalPorts string `json:",omitempty"`
@@ -161,8 +161,8 @@ type SDNRoutePolicySetting struct {
// NetworkACLPolicySetting creates ACL rules on a network
type NetworkACLPolicySetting struct {
Protocols string `json:",omitempty"` // EX: 6 (TCP), 17 (UDP), 1 (ICMPv4), 58 (ICMPv6), 2 (IGMP)
Action ActionType `json:","`
Direction DirectionType `json:","`
Action ActionType `json:""`
Direction DirectionType `json:""`
LocalAddresses string `json:",omitempty"`
RemoteAddresses string `json:",omitempty"`
LocalPorts string `json:",omitempty"`
@@ -243,6 +243,11 @@ type NetAdapterNameNetworkPolicySetting struct {
NetworkAdapterName string `json:",omitempty"`
}
// ProviderAddressNetworkPolicySetting sets network adapter of a network based on IP address.
type ProviderAddressNetworkPolicySetting struct {
ProviderAddress string `json:",omitempty"`
}
// VSwitchExtensionNetworkPolicySetting enables/disabled VSwitch extensions for a network.
type VSwitchExtensionNetworkPolicySetting struct {
ExtensionID string `json:",omitempty"`
@@ -267,12 +272,12 @@ type LayerConstraintNetworkPolicySetting struct {
// VlanPolicySetting isolates a subnet with VLAN tagging.
type VlanPolicySetting struct {
IsolationId uint32 `json:","`
IsolationId uint32 `json:""`
}
// VsidPolicySetting isolates a subnet with VSID tagging.
type VsidPolicySetting struct {
IsolationId uint32 `json:","`
IsolationId uint32 `json:""`
}
// RemoteSubnetRoutePolicySetting creates remote subnet route rules on a network
@@ -330,7 +335,7 @@ type L4ProxyPolicySetting struct {
type TierAclRule struct {
Id string `json:",omitempty"`
Protocols string `json:",omitempty"`
TierAclRuleAction ActionType `json:","`
TierAclRuleAction ActionType `json:""`
LocalAddresses string `json:",omitempty"`
RemoteAddresses string `json:",omitempty"`
LocalPorts string `json:",omitempty"`
@@ -340,8 +345,8 @@ type TierAclRule struct {
// TierAclPolicySetting represents a Tier containing ACLs
type TierAclPolicySetting struct {
Name string `json:","`
Direction DirectionType `json:","`
Name string `json:""`
Direction DirectionType `json:""`
Order uint16 `json:""`
TierAclRules []TierAclRule `json:",omitempty"`
}
+19
View File
@@ -8,8 +8,17 @@ import (
"github.com/Microsoft/hcsshim/internal/hcs/schema1"
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
"github.com/Microsoft/hcsshim/internal/jobobject"
)
// MigrationState captures the host-side identifiers needed to rebind a
// process during live migration. Zero fields mean the host doesn't use the
// corresponding facility (e.g. vsock or a GCS bridge).
type MigrationState struct {
StdinPort, StdoutPort, StderrPort uint32
WaitCallID int64
}
// Process is the interface for an OS process running in a container or utility VM.
type Process interface {
// Close releases resources associated with the process and closes the
@@ -27,6 +36,10 @@ type Process interface {
CloseStderr(ctx context.Context) error
// Pid returns the process ID.
Pid() int
// MigrationState returns the host-side identifiers (vsock stdio ports
// and GCS bridge wait-call id) needed by the live-migration save path.
// Zero fields indicate the host doesn't use those facilities.
MigrationState() MigrationState
// Stdio returns the stdio streams for a process. These may be nil if a stream
// was not requested during CreateProcess.
Stdio() (_ io.Writer, _ io.Reader, _ io.Reader)
@@ -96,4 +109,10 @@ type Container interface {
WaitError() error
// Modify sends a request to modify container resources
Modify(ctx context.Context, config interface{}) error
// SetCPUGroupAffinities pins the container's processes to the given CPU
// group affinities. It exists because CPU affinity is not part of the HCS
// container Processor schema and must be applied out of band (on the silo's
// job object for process-isolated Windows containers). Implementations that
// do not support setting CPU affinity return errdefs.ErrNotImplemented.
SetCPUGroupAffinities(ctx context.Context, affinities []jobobject.GroupAffinity) error
}
+5 -1
View File
@@ -59,6 +59,10 @@ var (
// ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110)
// ErrVmcomputeSystemAlreadyStopped is returned when an operation targets a compute system that is no longer running
// (e.g. modifying a UVM during migration teardown after it has been stopped).
ErrVmcomputeSystemAlreadyStopped = syscall.Errno(0x80370110)
// ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
ErrVmcomputeOperationPending = syscall.Errno(0xC0370103)
@@ -300,7 +304,7 @@ func IsTimeout(err error) bool {
// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
// will currently return true when the error is ErrElementNotFound.
func IsAlreadyStopped(err error) bool {
return IsAny(err, ErrVmcomputeAlreadyStopped, ErrProcessAlreadyStopped, ErrElementNotFound)
return IsAny(err, ErrVmcomputeAlreadyStopped, ErrVmcomputeSystemAlreadyStopped, ErrProcessAlreadyStopped, ErrElementNotFound)
}
// IsNotSupported returns a boolean indicating whether the error is caused by
+38 -33
View File
@@ -12,14 +12,13 @@ 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/ot"
"github.com/Microsoft/hcsshim/internal/protocol/guestrequest"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"go.opentelemetry.io/otel/attribute"
)
type Process struct {
@@ -57,6 +56,12 @@ func (process *Process) Pid() int {
return process.processID
}
// MigrationState returns the zero value: HCS processes route stdio over
// named pipes and don't use a GCS bridge.
func (process *Process) MigrationState() cow.MigrationState {
return cow.MigrationState{}
}
// SystemID returns the ID of the process's compute system.
func (process *Process) SystemID() string {
return process.system.ID()
@@ -211,11 +216,11 @@ func (process *Process) Kill(ctx context.Context) (bool, error) {
// call multiple times.
func (process *Process) waitBackground() {
operation := "hcs::Process::waitBackground"
ctx, span := oc.StartSpan(context.Background(), operation)
ctx, span := ot.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
var (
err error
@@ -260,7 +265,7 @@ func (process *Process) waitBackground() {
process.waitError = err
close(process.waitBlock)
})
oc.SetSpanStatus(span, err)
ot.SetSpanStatus(span, err)
}
// Wait waits for the process to exit. If the process has already exited returns
@@ -329,12 +334,12 @@ func (process *Process) ExitCode() (int, error) {
// are the responsibility of the caller to close.
func (process *Process) StdioLegacy() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
operation := "hcs::Process::StdioLegacy"
ctx, span := oc.StartSpan(context.Background(), operation)
ctx, span := ot.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
process.handleLock.RLock()
defer process.handleLock.RUnlock()
@@ -378,12 +383,12 @@ func (process *Process) Stdio() (stdin io.Writer, stdout, stderr io.Reader) {
// notified on the read side that there is no more data in stdin.
func (process *Process) CloseStdin(ctx context.Context) (err error) {
operation := "hcs::Process::CloseStdin"
ctx, span := trace.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
process.handleLock.RLock()
defer process.handleLock.RUnlock()
@@ -424,12 +429,12 @@ func (process *Process) CloseStdin(ctx context.Context) (err error) {
}
func (process *Process) CloseStdout(ctx context.Context) (err error) {
ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, "hcs::Process::CloseStdout") //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
process.handleLock.Lock()
defer process.handleLock.Unlock()
@@ -448,12 +453,12 @@ func (process *Process) CloseStdout(ctx context.Context) (err error) {
}
func (process *Process) CloseStderr(ctx context.Context) (err error) {
ctx, span := oc.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, "hcs::Process::CloseStderr") //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
process.handleLock.Lock()
defer process.handleLock.Unlock()
@@ -475,12 +480,12 @@ func (process *Process) CloseStderr(ctx context.Context) (err error) {
// or wait on it.
func (process *Process) Close() (err error) {
operation := "hcs::Process::Close"
ctx, span := oc.StartSpan(context.Background(), operation)
ctx, span := ot.StartSpan(context.Background(), operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("cid", process.SystemID()),
trace.Int64Attribute("pid", int64(process.processID)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("cid", process.SystemID()),
attribute.Int64("pid", int64(process.processID)))
process.handleLock.Lock()
defer process.handleLock.Unlock()
+1
View File
@@ -222,6 +222,7 @@ type GuestDefinedCapabilities struct {
DeleteContainerStateSupported bool `json:",omitempty"`
UpdateContainerSupported bool `json:",omitempty"`
LogForwardingSupported bool `json:",omitempty"`
HostProcessContainerSupported bool `json:",omitempty"`
}
// GuestConnectionInfo is the structure of an iterm return by a GuestConnection call on a utility VM
+1 -1
View File
@@ -9,7 +9,7 @@
package hcsschema
// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port.
// ComPort specifies the named pipe that will be used for the port, with empty string indicating a disconnected port.
type ComPort struct {
NamedPipe string `json:"NamedPipe,omitempty"`
+11
View File
@@ -9,6 +9,15 @@
package hcsschema
// IsolationType describes the isolation mode of a container.
type IsolationType string
const (
// IsolationTypeHostProcess is a privileged (Windows) HostProcess
// container that shares the host namespace.
IsolationTypeHostProcess IsolationType = "HostProcess"
)
type Container struct {
GuestOs *GuestOs `json:"GuestOs,omitempty"`
@@ -33,4 +42,6 @@ type Container struct {
AssignedDevices []Device `json:"AssignedDevices,omitempty"`
AdditionalDeviceNamespace *ContainerDefinitionDevice `json:"AdditionalDeviceNamespace,omitempty"`
IsolationType IsolationType `json:"IsolationType,omitempty"`
}
@@ -9,7 +9,7 @@
package hcsschema
// memory usage as viewed from within the container
// memory usage as viewed from within the container
type ContainerMemoryInformation struct {
TotalPhysicalBytes int32 `json:"TotalPhysicalBytes,omitempty"`
@@ -9,7 +9,7 @@
package hcsschema
// Information about the guest.
// Information about the guest.
type GuestConnectionInfo struct {
// Each schema version x.y stands for the range of versions a.b where a==x and b<=y. This list comes from the SupportedSchemaVersions field in GcsCapabilities.
+1 -1
View File
@@ -9,7 +9,7 @@
package hcsschema
// HvSocket configuration for a VM
// HvSocket configuration for a VM
type HvSocket2 struct {
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
}
@@ -9,8 +9,8 @@
package hcsschema
// This class defines address settings applied to a VM
// by the GCS every time a VM starts or restores.
// This class defines address settings applied to a VM
// by the GCS every time a VM starts or restores.
type HvSocketAddress struct {
LocalAddress string `json:"LocalAddress,omitempty"`
ParentAddress string `json:"ParentAddress,omitempty"`
@@ -9,7 +9,7 @@
package hcsschema
// This is the HCS Schema version of the HvSocket configuration. The VMWP version is located in Config.Devices.IC in V1.
// This is the HCS Schema version of the HvSocket configuration. The VMWP version is located in Config.Devices.IC in V1.
type HvSocketSystemConfig struct {
// SDDL string that HvSocket will check before allowing a host process to bind to an unlisted service for this specific container/VM (not wildcard binds).
+1 -1
View File
@@ -9,7 +9,7 @@
package hcsschema
// Memory runtime statistics
// Memory runtime statistics
type MemoryStats struct {
MemoryUsageCommitBytes uint64 `json:"MemoryUsageCommitBytes,omitempty"`
+205
View File
@@ -0,0 +1,205 @@
package hcsschema
import (
"encoding/json"
"time"
)
// MigrationInitializeOptions is a set of options for the migration workflow.
type MigrationInitializeOptions struct {
// Origin is the side of migration the workflow is performed on.
Origin MigrationOrigin `json:"Origin,omitempty"`
// MemoryTransport specifies the settings for memory transfer during migration. On source, this
// setting is required when migration is started. On destination, this setting is required when
// migration is initiated.
MemoryTransport MigrationMemoryTransport `json:"MemoryTransport,omitempty"`
// MemoryTransferThrottleParams specifies settings for throttling during memory transfer.
MemoryTransferThrottleParams *MemoryMigrationTransferThrottleParams `json:"MemoryTransferThrottleParams,omitempty"`
// CompressionSettings specifies additional settings when compression is enabled.
CompressionSettings *MigrationCompressionSettings `json:"CompressionSettings,omitempty"`
// ChecksumVerification enables memory checksum verification.
ChecksumVerification bool `json:"ChecksumVerification,omitempty"`
// PerfTracingEnabled enables performance tracing during migration.
PerfTracingEnabled bool `json:"PerfTracingEnabled,omitempty"`
// CancelIfBlackoutThresholdExceeds cancels the operation if the blackout threshold is exceeded.
CancelIfBlackoutThresholdExceeds bool `json:"CancelIfBlackoutThresholdExceeds,omitempty"`
// PrepareMemoryTransferMode extends timeout for cross-version live migration.
PrepareMemoryTransferMode bool `json:"PrepareMemoryTransferMode,omitempty"`
// CompatibilityData is the compatibility information required for the destination VM.
CompatibilityData *CompatibilityInfo `json:"CompatibilityData,omitempty"`
}
// MigrationFinalizedOptions is a set of additional options used for HcsLiveMigrationFinalization.
type MigrationFinalizedOptions struct {
// Origin is the side of migration the workflow is performed on.
Origin MigrationOrigin `json:"Origin,omitempty"`
// FinalizedOperation is the final state transition for the VM as part of concluding the LM workflow.
FinalizedOperation MigrationFinalOperation `json:"FinalizedOperation,omitempty"`
}
// MigrationStartOptions specifies options for starting a migration.
type MigrationStartOptions struct {
// NetworkSettings specifies network settings for the socket provided.
NetworkSettings *MigrationNetworkSettings `json:"NetworkSettings,omitempty"`
}
// MigrationTransferOptions specifies options for the migration transfer phase.
type MigrationTransferOptions struct {
// Origin is the side of migration the workflow is performed on.
Origin MigrationOrigin `json:"Origin,omitempty"`
}
// MigrationCancelOptions is a set of options used to cancel a live migration.
type MigrationCancelOptions struct {
// Origin is the side of migration the workflow is performed on.
Origin MigrationOrigin `json:"Origin,omitempty"`
}
// StartOptions specifies options for starting a compute system.
type StartOptions struct {
// DestinationMigrationOptions specifies settings to use when starting a migration on the destination side.
DestinationMigrationOptions *MigrationStartOptions `json:"DestinationMigrationOptions,omitempty"`
}
// MigrationOrigin indicates where migration is initiated from.
type MigrationOrigin string
const (
// MigrationOriginSource indicates the source side of migration.
MigrationOriginSource MigrationOrigin = "Source"
// MigrationOriginDestination indicates the destination side of migration.
MigrationOriginDestination MigrationOrigin = "Destination"
)
// MigrationMemoryTransport is the transport protocol used for memory transfer during migration.
type MigrationMemoryTransport string
const (
// MigrationMemoryTransportTCP indicates the VM memory is copied over a TCP/IP connection.
MigrationMemoryTransportTCP MigrationMemoryTransport = "TCP"
)
// MemoryMigrationTransferThrottleParams specifies settings for migration memory transfer throttling.
type MemoryMigrationTransferThrottleParams struct {
// SkipThrottling indicates whether throttling should be skipped.
SkipThrottling *bool `json:"SkipThrottling,omitempty"`
// ThrottlingScale is the scale of the throttling as a percentage (1-100).
ThrottlingScale *float64 `json:"ThrottlingScale,omitempty"`
// MinimumThrottlePercentage is the minimum percentage to which memory transfer can be throttled.
MinimumThrottlePercentage *uint8 `json:"MinimumThrottlePercentage,omitempty"`
// TargetNumberOfBrownoutTransferPasses is the number of passes targeted before the VM enters blackout.
TargetNumberOfBrownoutTransferPasses *uint32 `json:"TargetNumberOfBrownoutTransferPasses,omitempty"`
// StartingBrownoutPassNumberForThrottling is the transfer pass where throttling begins.
StartingBrownoutPassNumberForThrottling *uint32 `json:"StartingBrownoutPassNumberForThrottling,omitempty"`
// MaximumNumberOfBrownoutTransferPasses is the maximum number of passes before forcing blackout.
MaximumNumberOfBrownoutTransferPasses *uint32 `json:"MaximumNumberOfBrownoutTransferPasses,omitempty"`
// TargetBlackoutTransferTime is the expected duration for blackout transfer time.
TargetBlackoutTransferTime *uint32 `json:"TargetBlackoutTransferTime,omitempty"`
// BlackoutTimeThresholdForCancellingMigration is the blackout duration threshold for cancelling migration.
BlackoutTimeThresholdForCancellingMigration *uint32 `json:"BlackoutTimeThresholdForCancellingMigration,omitempty"`
}
// MigrationCompressionSettings specifies compression settings for migration.
type MigrationCompressionSettings struct {
// ThrottleWorkerCount is the [de]compression thread count. Values higher than what the host
// and VM configuration can support will be adjusted. The value should be non-zero.
ThrottleWorkerCount *uint32 `json:"ThrottleWorkerCount,omitempty"`
}
// CompatibilityInfo is opaque VM compatibility data, primarily used in migration.
type CompatibilityInfo struct {
// Data is the raw compatibility information.
Data []byte `json:"Data,omitempty"`
}
// MigrationFinalOperation is the final operation performed on the compute system to finalize the live migration workflow.
type MigrationFinalOperation string
const (
// MigrationFinalOperationResume resumes the VM.
MigrationFinalOperationResume MigrationFinalOperation = "Resume"
// MigrationFinalOperationStop stops the VM.
MigrationFinalOperationStop MigrationFinalOperation = "Stop"
)
// MigrationNetworkSettings specifies the transport protocol for network connection provided by client.
type MigrationNetworkSettings struct {
// SessionID is the session ID associated with the socket connection between source and destination.
SessionID uint32 `json:"SessionId,omitempty"`
}
// OperationSystemMigrationNotificationInfo is a notification payload describing
// the current state of an in-progress live migration operation. It is emitted
// by HCS over the migration notification channel as the workflow progresses.
type OperationSystemMigrationNotificationInfo struct {
// Origin indicates which side of the live migration this notification
// pertains to (source or destination).
Origin MigrationOrigin `json:"Origin,omitempty"`
// Event is the type of live migration event being reported.
Event MigrationEvent `json:"Event,omitempty"`
// Result is an optional outcome accompanying the event. It is typically
// populated for terminal events.
Result MigrationResult `json:"Result,omitempty"`
// AdditionalDetails carries extra event-specific information whose schema
// depends on the event being reported. HCS models this as the schema `Any`
// type; we keep it as raw JSON so callers can decode it into the concrete
// event-specific struct (e.g. BlackoutExitedEventDetails for
// MigrationEventBlackoutExited) once they have inspected Event.
AdditionalDetails json.RawMessage `json:"AdditionalDetails,omitempty"`
}
// BlackoutExitedEventDetails carries additional details reported alongside
// MigrationEventBlackoutExited, describing the blackout that just ended.
// Mirrors the HCS MigrationBlackoutExitedEventDetails schema.
type BlackoutExitedEventDetails struct {
// BlackoutDurationMilliseconds is the duration of the blackout phase, in milliseconds.
BlackoutDurationMilliseconds uint64 `json:"BlackoutDurationMilliseconds,omitempty"`
// BlackoutStopTimestamp is the timestamp at which the blackout phase ended.
BlackoutStopTimestamp time.Time `json:"BlackoutStopTimestamp,omitempty"`
}
// MigrationEvent describes a live migration event reported by HCS.
type MigrationEvent string
const (
// MigrationEventUnknown indicates an unspecified or unrecognized event.
MigrationEventUnknown MigrationEvent = "Unknown"
// MigrationEventMigrationDone indicates that migration has completed.
MigrationEventMigrationDone MigrationEvent = "MigrationDone"
// MigrationEventBlackoutStarted indicates that the VM has entered the blackout phase.
MigrationEventBlackoutStarted MigrationEvent = "BlackoutStarted"
// MigrationEventOfflineDone indicates that taking the VM offline has completed.
MigrationEventOfflineDone MigrationEvent = "OfflineDone"
// MigrationEventBlackoutExited indicates that the VM has successfully started
// again after the blackout phase.
MigrationEventBlackoutExited MigrationEvent = "BlackoutExited"
// MigrationEventSetupDone indicates that the live migration setup has completed.
MigrationEventSetupDone MigrationEvent = "SetupDone"
// MigrationEventTransferInProgress indicates that the VM is still transferring
// memory and other necessary state.
MigrationEventTransferInProgress MigrationEvent = "TransferInProgress"
// MigrationEventMigrationRecoveryDone indicates that migration recovery has been performed.
MigrationEventMigrationRecoveryDone MigrationEvent = "MigrationRecoveryDone"
// MigrationEventMigrationFailed indicates that migration failed.
MigrationEventMigrationFailed MigrationEvent = "MigrationFailed"
)
// MigrationResult describes the possible result of a migration operation.
type MigrationResult string
const (
// MigrationResultInvalid indicates an invalid or unspecified result.
MigrationResultInvalid MigrationResult = "Invalid"
// MigrationResultSuccess indicates the migration operation succeeded.
MigrationResultSuccess MigrationResult = "Success"
// MigrationResultMigrationCancelled indicates the migration was cancelled.
MigrationResultMigrationCancelled MigrationResult = "MigrationCancelled"
// MigrationResultGuestInitiatedCancellation indicates the guest initiated the cancellation.
MigrationResultGuestInitiatedCancellation MigrationResult = "GuestInitiatedCancellation"
// MigrationResultSourceMigrationFailed indicates the migration failed on the source side.
MigrationResultSourceMigrationFailed MigrationResult = "SourceMigrationFailed"
// MigrationResultDestinationMigrationFailed indicates the migration failed on the destination side.
MigrationResultDestinationMigrationFailed MigrationResult = "DestinationMigrationFailed"
// MigrationResultMigrationRecoveryFailed indicates the migration recovery failed.
MigrationResultMigrationRecoveryFailed MigrationResult = "MigrationRecoveryFailed"
)
+6 -6
View File
@@ -12,10 +12,10 @@
package hcsschema
type NumaSetting struct {
VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"`
PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"`
VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"`
CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"`
CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"`
MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"`
VirtualNodeNumber uint32 `json:"VirtualNodeNumber,omitempty"`
PhysicalNodeNumber uint32 `json:"PhysicalNodeNumber,omitempty"`
VirtualSocketNumber uint32 `json:"VirtualSocketNumber,omitempty"`
CountOfProcessors uint32 `json:"CountOfProcessors,omitempty"`
CountOfMemoryBlocks uint64 `json:"CountOfMemoryBlocks,omitempty"`
MemoryBackingType MemoryBackingType `json:"MemoryBackingType,omitempty"`
}
@@ -9,7 +9,7 @@
package hcsschema
// Notification data that is indicated to components running in the Virtual Machine.
// Notification data that is indicated to components running in the Virtual Machine.
type PauseNotification struct {
Reason string `json:"Reason,omitempty"`
}
+1 -1
View File
@@ -9,7 +9,7 @@
package hcsschema
// Options for HcsPauseComputeSystem
// Options for HcsPauseComputeSystem
type PauseOptions struct {
SuspensionLevel string `json:"SuspensionLevel,omitempty"`
+1 -10
View File
@@ -19,16 +19,7 @@ type Plan9Share struct {
Port int32 `json:"Port,omitempty"`
// Flags are marked private. Until they are exported correctly
//
// ReadOnly 0x00000001
// LinuxMetadata 0x00000004
// CaseSensitive 0x00000008
Flags int32 `json:"Flags,omitempty"`
ReadOnly bool `json:"ReadOnly,omitempty"`
UseShareRootIdentity bool `json:"UseShareRootIdentity,omitempty"`
Flags Plan9ShareFlags `json:"Flags,omitempty"`
AllowedFiles []string `json:"AllowedFiles,omitempty"`
}
@@ -0,0 +1,38 @@
/*
* HCS API
*
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* API version: 2.1
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
package hcsschema
// Plan9ShareFlags is a bitfield controlling Plan9 share behavior.
type Plan9ShareFlags int32
const (
// Plan9ShareFlagsNone indicates no flags are set.
Plan9ShareFlagsNone Plan9ShareFlags = 0x00000000
// Plan9ShareFlagsReadOnly makes the share read-only.
Plan9ShareFlagsReadOnly Plan9ShareFlags = 0x00000001
// Plan9ShareFlagsLinuxMetadata enables writing Linux metadata.
Plan9ShareFlagsLinuxMetadata Plan9ShareFlags = 0x00000004
// Plan9ShareFlagsCaseSensitive creates directories in case-sensitive mode.
Plan9ShareFlagsCaseSensitive Plan9ShareFlags = 0x00000008
// Plan9ShareFlagsUseShareRootIdentity uses the identity of the share root
// when opening.
Plan9ShareFlagsUseShareRootIdentity Plan9ShareFlags = 0x00000010
// Plan9ShareFlagsRestrictFileAccess enables single-file mapping mode.
Plan9ShareFlagsRestrictFileAccess Plan9ShareFlags = 0x00000080
// Plan9ShareFlagsUnlimitedConnections allows multiple connections to this
// share.
Plan9ShareFlagsUnlimitedConnections Plan9ShareFlags = 0x00000100
)
@@ -13,7 +13,7 @@ import (
"time"
)
// Information about a process running in a container
// Information about a process running in a container
type ProcessDetails struct {
ProcessId int32 `json:"ProcessId,omitempty"`
+1 -1
View File
@@ -3,7 +3,7 @@
*
* No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen)
*
* API version: 2.1
* API version: 2.4
* Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git)
*/
@@ -9,7 +9,7 @@
package hcsschema
// CPU runtime statistics
// CPU runtime statistics
type ProcessorStats struct {
TotalRuntime100ns uint64 `json:"TotalRuntime100ns,omitempty"`
+10
View File
@@ -10,6 +10,8 @@
package hcsschema
import (
"encoding/json"
v1 "github.com/containerd/cgroups/v3/cgroup1/stats"
)
@@ -50,7 +52,15 @@ type Properties struct {
GuestConnectionInfo *GuestConnectionInfo `json:"GuestConnectionInfo,omitempty"`
// PropertyResponses maps requested property names to their associated response objects.
PropertyResponses map[string]PropertyResponse `json:"PropertyResponses,omitempty"`
// Metrics is not part of the API for HCS but this is used for LCOW v2 to
// return the full cgroup metrics from the guest.
Metrics *v1.Metrics `json:"LCOWMetrics,omitempty"`
}
// PropertyResponse is the response object associated with a property query.
type PropertyResponse struct {
Response json.RawMessage `json:"Response,omitempty"`
}
@@ -9,7 +9,11 @@
package hcsschema
// By default the basic properties will be returned. This query provides a way to request specific properties.
// By default the basic properties will be returned. This query provides a way to request specific properties.
type PropertyQuery struct {
PropertyTypes []PropertyType `json:"PropertyTypes,omitempty"`
// Queries is a new property request object, introduced in version 2.5, which takes the
// names of the properties and their associated query objects if needed.
Queries map[string]interface{} `json:"Queries,omitempty"`
}
@@ -9,7 +9,7 @@
package hcsschema
// Silo job information
// Silo job information
type SiloProperties struct {
Enabled bool `json:"Enabled,omitempty"`
+1 -1
View File
@@ -13,7 +13,7 @@ import (
"time"
)
// Runtime statistics for a container
// Runtime statistics for a container
type Statistics struct {
Timestamp time.Time `json:"Timestamp,omitempty"`
+3
View File
@@ -18,4 +18,7 @@ type Storage struct {
Path string `json:"Path,omitempty"`
QoS *StorageQoS `json:"QoS,omitempty"`
// Path to the root of the container's filesystem. This is useful in case of HostProcess containers where the container rootfs is different from C:\.
PrivilegedContainerRootPath string `json:"PrivilegedContainerRootPath,omitempty"`
}
+1 -1
View File
@@ -9,7 +9,7 @@
package hcsschema
// Storage runtime statistics
// Storage runtime statistics
type StorageStats struct {
ReadCountNormalized uint64 `json:"ReadCountNormalized,omitempty"`
+3 -3
View File
@@ -12,7 +12,7 @@
package hcsschema
type Topology struct {
Memory *VirtualMachineMemory `json:"Memory,omitempty"`
Processor *VirtualMachineProcessor `json:"Processor,omitempty"`
Numa *Numa `json:"Numa,omitempty"`
Memory *VirtualMachineMemory `json:"Memory,omitempty"`
Processor *VirtualMachineProcessor `json:"Processor,omitempty"`
Numa *Numa `json:"Numa,omitempty"`
}
+14 -11
View File
@@ -15,15 +15,18 @@ package hcsschema
type VirtualMachine struct {
Version *Version `json:"Version,omitempty"`
// When set to true, the virtual machine will treat a reset as a stop, releasing resources and cleaning up state.
StopOnReset bool `json:"StopOnReset,omitempty"`
Chipset *Chipset `json:"Chipset,omitempty"`
ComputeTopology *Topology `json:"ComputeTopology,omitempty"`
Devices *Devices `json:"Devices,omitempty"`
GuestState *GuestState `json:"GuestState,omitempty"`
RestoreState *RestoreState `json:"RestoreState,omitempty"`
RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"`
StorageQoS *StorageQoS `json:"StorageQoS,omitempty"`
DebugOptions *DebugOptions `json:"DebugOptions,omitempty"`
GuestConnection *GuestConnection `json:"GuestConnection,omitempty"`
SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"`
StopOnReset bool `json:"StopOnReset,omitempty"`
Chipset *Chipset `json:"Chipset,omitempty"`
ComputeTopology *Topology `json:"ComputeTopology,omitempty"`
Devices *Devices `json:"Devices,omitempty"`
GuestState *GuestState `json:"GuestState,omitempty"`
RestoreState *RestoreState `json:"RestoreState,omitempty"`
RegistryChanges *RegistryChanges `json:"RegistryChanges,omitempty"`
StorageQoS *StorageQoS `json:"StorageQoS,omitempty"`
DebugOptions *DebugOptions `json:"DebugOptions,omitempty"`
GuestConnection *GuestConnection `json:"GuestConnection,omitempty"`
SecuritySettings *SecuritySettings `json:"SecuritySettings,omitempty"`
ResourcePartitionId string `json:"ResourcePartitionId,omitempty"`
// Live migration options to be used on destination.
MigrationOptions *MigrationInitializeOptions `json:"MigrationOptions,omitempty"`
}
@@ -15,7 +15,7 @@ type VirtualMachineMemory struct {
SizeInMB uint64 `json:"SizeInMB,omitempty"`
Backing *MemoryBackingType `json:"Backing,omitempty"`
// If enabled, then the VM's memory is backed by the Windows pagefile rather than physically backed, statically allocated memory.
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
AllowOvercommit bool `json:"AllowOvercommit,omitempty"`
// If enabled, then the memory hot hint feature is exposed to the VM, allowing it to prefetch pages into its working set. (if supported by the guest operating system).
EnableHotHint bool `json:"EnableHotHint,omitempty"`
// If enabled, then the memory cold hint feature is exposed to the VM, allowing it to trim zeroed pages from its working set (if supported by the guest operating system).
@@ -27,7 +27,7 @@ type VirtualMachineMemory struct {
// Low MMIO region allocated below 4GB
LowMMIOGapInMB uint64 `json:"LowMmioGapInMB,omitempty"`
// High MMIO region allocated above 4GB (base and size)
HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"`
HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"`
SlitType *VirtualSlitType `json:"SlitType,omitempty"`
HighMMIOBaseInMB uint64 `json:"HighMmioBaseInMB,omitempty"`
HighMMIOGapInMB uint64 `json:"HighMmioGapInMB,omitempty"`
SlitType *VirtualSlitType `json:"SlitType,omitempty"`
}
@@ -12,10 +12,10 @@
package hcsschema
type VirtualMachineProcessor struct {
Count uint32 `json:"Count,omitempty"`
Limit uint64 `json:"Limit,omitempty"`
Weight uint64 `json:"Weight,omitempty"`
Reservation uint64 `json:"Reservation,omitempty"`
CpuGroup *CpuGroup `json:"CpuGroup,omitempty"`
NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"`
Count uint32 `json:"Count,omitempty"`
Limit uint64 `json:"Limit,omitempty"`
Weight uint64 `json:"Weight,omitempty"`
Reservation uint64 `json:"Reservation,omitempty"`
CpuGroup *CpuGroup `json:"CpuGroup,omitempty"`
NumaProcessorsSettings *NumaProcessors `json:"NumaProcessorsSettings,omitempty"`
}
@@ -12,6 +12,6 @@ package hcsschema
// TODO: PropagateNumaAffinity is pre-release/experimental field in schema 2.11. Need to add build number
// docs when a public build with this is out.
type VirtualPciDevice struct {
Functions []VirtualPciFunction `json:",omitempty"`
PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"`
Functions []VirtualPciFunction `json:",omitempty"`
PropagateNumaAffinity *bool `json:"PropagateNumaAffinity,omitempty"`
}
+129 -32
View File
@@ -18,11 +18,11 @@ import (
"github.com/Microsoft/hcsshim/internal/jobobject"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/internal/timeout"
"github.com/Microsoft/hcsshim/internal/vmcompute"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
)
type System struct {
@@ -61,10 +61,10 @@ func CreateComputeSystem(ctx context.Context, id string, hcsDocumentInterface in
// hcsCreateComputeSystemContext is an async operation. Start the outer span
// here to measure the full create time.
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", id))
computeSystem := newSystem(id)
@@ -191,16 +191,16 @@ func GetComputeSystems(ctx context.Context, q schema1.ComputeSystemQuery) ([]sch
return computeSystems, nil
}
// Start synchronously starts the computeSystem.
// Start synchronously starts the computeSystem using HCS V1 API.
func (computeSystem *System) Start(ctx context.Context) (err error) {
operation := "hcs::System::Start"
// hcsStartComputeSystemContext is an async operation. Start the outer span
// here to measure the full start time.
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
@@ -277,9 +277,9 @@ func (computeSystem *System) Terminate(ctx context.Context) error {
// safe to call multiple times.
func (computeSystem *System) waitBackground() {
operation := "hcs::System::waitBackground"
ctx, span := oc.StartSpan(context.Background(), operation)
ctx, span := ot.StartSpan(context.Background(), operation)
defer span.End()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
span.SetAttributes(attribute.String("cid", computeSystem.id))
err := waitForNotification(ctx, computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
if err == nil {
@@ -296,7 +296,7 @@ func (computeSystem *System) waitBackground() {
computeSystem.stopTime = time.Now()
close(computeSystem.waitBlock)
})
oc.SetSpanStatus(span, err)
ot.SetSpanStatus(span, err)
}
func (computeSystem *System) WaitChannel() <-chan struct{} {
@@ -379,6 +379,20 @@ func (computeSystem *System) Properties(ctx context.Context, types ...schema1.Pr
return properties, nil
}
// openSilo opens the container's server silo job object by its well-known name
// (`\Container_<id>`). HCS owns the silo; the only way to open it from the shim is
// by name, and only while running as SYSTEM. The caller owns the returned handle and
// must Close it.
//
// In the future we can make use of some new functionality in HCS that allows you to
// pass a job object for HCS to use for the container.
func (computeSystem *System) openSilo(ctx context.Context) (*jobobject.JobObject, error) {
return jobobject.Open(ctx, &jobobject.Options{
UseNTVariant: true,
Name: siloNameFmt(computeSystem.id),
})
}
// queryInProc handles querying for container properties without reaching out to HCS. `props`
// will be updated to contain any data returned from the queries present in `types`. If any properties
// failed to be queried they will be tallied up and returned in as the first return value. Failures on
@@ -389,14 +403,7 @@ func (computeSystem *System) queryInProc(
props *hcsschema.Properties,
types []hcsschema.PropertyType,
) ([]hcsschema.PropertyType, error) {
// In the future we can make use of some new functionality in the HCS that allows you
// to pass a job object for HCS to use for the container. Currently, the only way we'll
// be able to open the job/silo is if we're running as SYSTEM.
jobOptions := &jobobject.Options{
UseNTVariant: true,
Name: siloNameFmt(computeSystem.id),
}
job, err := jobobject.Open(ctx, jobOptions)
job, err := computeSystem.openSilo(ctx)
if err != nil {
return nil, err
}
@@ -490,6 +497,48 @@ func (computeSystem *System) statisticsInProc(job *jobobject.JobObject) (*hcssch
}, nil
}
// SetCPUGroupAffinities pins the container's server silo to the given processor
// group affinities. HCS does not expose a CPU-affinity field on the container Processor
// schema, so for process-isolated (Argon) containers we set the affinity directly on the
// silo's job object via SetInformationJobObject(JobObjectGroupInformationEx).
//
// HCS owns the silo; we only open a transient handle (by the silo's well-known job name,
// the same handle queryInProc opens) to record the affinity property. The kernel enforces
// it on every process that joins the silo via AssignProcessToJobObject — including the init
// process at Start and any descendants it spawns.
//
// This must be called after the compute system is created but before it is started, so the
// affinity is already recorded on the job when HCS assigns the init process. Applying it to
// an already-running silo is also safe: the kernel re-applies the mask to current members and
// migrates threads at the next scheduling dispatch.
//
// It implements the cow.Container interface.
func (computeSystem *System) SetCPUGroupAffinities(ctx context.Context, affinities []jobobject.GroupAffinity) error {
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
// Guard the compute system's lifecycle while we touch its silo: the RLock blocks
// a concurrent Close(), and handle == 0 means it is already torn down.
if computeSystem.handle == 0 {
return fmt.Errorf("set cpu group affinities on %s silo: %w", computeSystem.ID(), ErrAlreadyClosed)
}
// The silo job object only exists for containers, not VM-based compute systems.
if computeSystem.typ != "container" {
return fmt.Errorf("cpu group affinities are only supported on container compute systems, got %q", computeSystem.typ)
}
job, err := computeSystem.openSilo(ctx)
if err != nil {
return fmt.Errorf("open %s silo: %w", computeSystem.ID(), err)
}
defer job.Close()
if err := job.SetCPUGroupAffinities(affinities); err != nil {
return fmt.Errorf("set cpu group affinities on %s silo: %w", computeSystem.ID(), err)
}
return nil
}
// hcsPropertiesV2Query is a helper to make a HcsGetComputeSystemProperties call using the V2 schema property types.
func (computeSystem *System) hcsPropertiesV2Query(ctx context.Context, types []hcsschema.PropertyType) (*hcsschema.Properties, error) {
operation := "hcs::System::PropertiesV2"
@@ -574,16 +623,64 @@ func (computeSystem *System) PropertiesV2(ctx context.Context, types ...hcsschem
return hcsProperties, nil
}
// PropertiesV3 returns the requested compute system properties using a V2 schema property query.
// Unlike [System.PropertiesV2], this method accepts a full [hcsschema.PropertyQuery] directly,
// giving the caller more control over the query structure. The query is forwarded to HCS as-is
// without any in-proc optimisations such as that is V2.
func (computeSystem *System) PropertiesV3(ctx context.Context, query *hcsschema.PropertyQuery) (_ *hcsschema.Properties, err error) {
operation := "hcs::System::PropertiesV3"
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
if computeSystem.handle == 0 {
return nil, makeSystemError(computeSystem, operation, ErrAlreadyClosed, nil)
}
log.G(ctx).WithFields(logrus.Fields{
logfields.ContainerID: computeSystem.id,
"propertyTypes": query.PropertyTypes,
"propertyQueries": query.Queries,
}).Debug("querying compute system properties via PropertiesV3")
queryBytes, err := json.Marshal(query)
if err != nil {
return nil, makeSystemError(computeSystem, operation, err, nil)
}
propertiesJSON, resultJSON, err := vmcompute.HcsGetComputeSystemProperties(ctx, computeSystem.handle, string(queryBytes))
events := processHcsResult(ctx, resultJSON)
if err != nil {
return nil, makeSystemError(computeSystem, operation, err, events)
}
if propertiesJSON == "" {
return nil, ErrUnexpectedValue
}
props := &hcsschema.Properties{}
if err := json.Unmarshal([]byte(propertiesJSON), props); err != nil {
return nil, makeSystemError(computeSystem, operation, err, nil)
}
return props, nil
}
// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
func (computeSystem *System) Pause(ctx context.Context) (err error) {
operation := "hcs::System::Pause"
// hcsPauseComputeSystemContext is an async operation. Start the outer span
// here to measure the full pause time.
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
@@ -608,10 +705,10 @@ func (computeSystem *System) Resume(ctx context.Context) (err error) {
// hcsResumeComputeSystemContext is an async operation. Start the outer span
// here to measure the full restore time.
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
computeSystem.handleLock.RLock()
defer computeSystem.handleLock.RUnlock()
@@ -636,10 +733,10 @@ func (computeSystem *System) Save(ctx context.Context, options interface{}) (err
// hcsSaveComputeSystemContext is an async operation. Start the outer span
// here to measure the full save time.
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
saveOptions, err := json.Marshal(options)
if err != nil {
@@ -759,10 +856,10 @@ func (computeSystem *System) Close() error {
// proper system cleanup.
func (computeSystem *System) CloseCtx(ctx context.Context) (err error) {
operation := "hcs::System::Close"
ctx, span := oc.StartSpan(ctx, operation)
ctx, span := ot.StartSpan(ctx, operation)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("cid", computeSystem.id))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("cid", computeSystem.id))
computeSystem.handleLock.Lock()
defer computeSystem.handleLock.Unlock()
+12 -1
View File
@@ -28,11 +28,22 @@ type JobObject struct {
handleLock sync.RWMutex
}
// GroupAffinity specifies a processor group and an affinity mask within that group.
// It corresponds to the Win32 GROUP_AFFINITY structure and is used for multi-group
// CPU affinity on machines with more than 64 logical processors (WS2022+).
type GroupAffinity struct {
// Mask is the bitmask of processors within Group.
Mask uint64
// Group is the processor group number (0-based).
Group uint16
}
// JobLimits represents the resource constraints that can be applied to a job object.
type JobLimits struct {
CPULimit uint32
CPUWeight uint32
CPUAffinity uint64
CPUAffinity uint64 // legacy single-group (group 0) affinity mask; use GroupAffinities when non-empty
GroupAffinities []GroupAffinity // multi-processor-group affinity (WS2022+); takes precedence over CPUAffinity
MemoryLimitInBytes uint64
MaxIOPS int64
MaxBandwidth int64
+93 -2
View File
@@ -3,10 +3,12 @@
package jobobject
import (
"context"
"errors"
"fmt"
"unsafe"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/winapi"
"golang.org/x/sys/windows"
)
@@ -20,7 +22,7 @@ func isFlagSet(flag, controlFlags uint32) bool {
}
// SetResourceLimits sets resource limits on the job object (cpu, memory, storage).
func (job *JobObject) SetResourceLimits(limits *JobLimits) error {
func (job *JobObject) SetResourceLimits(ctx context.Context, limits *JobLimits) error {
// Go through and check what limits were specified and apply them to the job.
if limits.MemoryLimitInBytes != 0 {
if err := job.SetMemoryLimit(limits.MemoryLimitInBytes); err != nil {
@@ -38,7 +40,15 @@ func (job *JobObject) SetResourceLimits(limits *JobLimits) error {
}
}
if limits.CPUAffinity != 0 {
if len(limits.GroupAffinities) > 0 && limits.CPUAffinity != 0 {
log.G(ctx).WithField("limits", log.Format(ctx, limits)).Warn("both group and CPU affinity set; CPU affinity will be overridden")
}
if len(limits.GroupAffinities) > 0 {
if err := job.SetCPUGroupAffinities(limits.GroupAffinities); err != nil {
return fmt.Errorf("failed to set job object cpu group affinities: %w", err)
}
} else if limits.CPUAffinity != 0 {
if err := job.SetCPUAffinity(limits.CPUAffinity); err != nil {
return fmt.Errorf("failed to set job object cpu affinity: %w", err)
}
@@ -141,8 +151,89 @@ func (job *JobObject) GetCPULimit(rateControlType CPURateControlType) (uint32, e
return info.Value, nil
}
// SetCPUGroupAffinities sets the processor group affinities for the job object using
// JobObjectGroupInformationEx, which supports multi-processor-group machines (WS2022+).
// Each entry in affinities specifies a processor group number and a bitmask of processors
// within that group. affinities must be non-empty.
// https://learn.microsoft.com/en-us/windows/win32/api/jobapi2/nf-jobapi2-setinformationjobobject
func (job *JobObject) SetCPUGroupAffinities(affinities []GroupAffinity) error {
if len(affinities) == 0 {
return errors.New("affinities must be non-empty")
}
winapiAffinities := make([]winapi.GROUP_AFFINITY, len(affinities))
for i, a := range affinities {
winapiAffinities[i] = winapi.GROUP_AFFINITY{
Mask: uintptr(a.Mask),
Group: a.Group,
}
}
job.handleLock.RLock()
defer job.handleLock.RUnlock()
if job.handle == 0 {
return ErrAlreadyClosed
}
if _, err := windows.SetInformationJobObject(
job.handle,
windows.JobObjectGroupInformationEx,
uintptr(unsafe.Pointer(&winapiAffinities[0])),
uint32(len(winapiAffinities))*uint32(unsafe.Sizeof(winapiAffinities[0])),
); err != nil {
return fmt.Errorf("failed to set cpu group affinities on job object: %w", err)
}
return nil
}
// GetCPUGroupAffinities returns the processor group affinities set on the job object.
// https://learn.microsoft.com/en-us/windows/win32/api/jobapi2/nf-jobapi2-queryinformationjobobject
func (job *JobObject) GetCPUGroupAffinities() ([]GroupAffinity, error) {
job.handleLock.RLock()
defer job.handleLock.RUnlock()
if job.handle == 0 {
return nil, ErrAlreadyClosed
}
// QueryInformationJobObject(JobObjectGroupInformationEx) returns one
// GROUP_AFFINITY per processor group assigned to the job. Most machines
// have a single processor group; start with 1 and grow on
// ERROR_INSUFFICIENT_BUFFER.
count := uint32(1)
for {
winapiAffinities := make([]winapi.GROUP_AFFINITY, count)
var returnLen uint32
err := winapi.QueryInformationJobObject(
job.handle,
windows.JobObjectGroupInformationEx,
unsafe.Pointer(&winapiAffinities[0]),
count*uint32(unsafe.Sizeof(winapiAffinities[0])),
&returnLen,
)
if err == nil {
actualCount := returnLen / uint32(unsafe.Sizeof(winapiAffinities[0]))
result := make([]GroupAffinity, actualCount)
for i, a := range winapiAffinities[:actualCount] {
result[i] = GroupAffinity{Mask: uint64(a.Mask), Group: a.Group}
}
return result, nil
}
if !errors.Is(err, windows.ERROR_INSUFFICIENT_BUFFER) {
return nil, fmt.Errorf("failed to query cpu group affinities on job object: %w", err)
}
newCount := returnLen / uint32(unsafe.Sizeof(winapiAffinities[0]))
if newCount <= count {
return nil, fmt.Errorf("failed to query cpu group affinities on job object: buffer size did not grow (%d -> %d entries)", count, newCount)
}
count = newCount
}
}
// SetCPUAffinity sets the processor affinity for the job object.
// The affinity is passed in as a bitmask.
// Note: this uses JOB_OBJECT_LIMIT_AFFINITY which is restricted to processor group 0.
// For machines with more than 64 logical processors, use SetCPUGroupAffinities instead.
func (job *JobObject) SetCPUAffinity(affinityBitMask uint64) error {
info, err := job.getExtendedInformation()
if err != nil {
+1 -1
View File
@@ -61,7 +61,7 @@ func formatAddr(a net.Addr) string {
// HTML escapes.
// Context is used to output a log waring if the conversion fails.
//
// This is intended primarily for `trace.StringAttribute()`
// This is intended primarily for `attribute.String()`
func Format(ctx context.Context, v interface{}) string {
b, err := encode(v)
if err != nil {
+6 -6
View File
@@ -2,12 +2,12 @@ package log
import (
"bytes"
"go.opentelemetry.io/otel/trace"
"reflect"
"time"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
)
const nullString = "null"
@@ -107,8 +107,8 @@ func (h *Hook) encode(e *logrus.Entry) {
switch vv := v.(type) {
// built in types
// "json" marshals errors as "{}", so leave alone here
case bool, string, error, uintptr,
case bool, string, uintptr,
error, // "json" marshals errors as "{}", so leave alone here
int8, int16, int32, int64, int,
uint8, uint32, uint64, uint,
float32, float64:
@@ -163,11 +163,11 @@ func (h *Hook) addSpanContext(e *logrus.Entry) {
if !h.AddSpanContext || ctx == nil {
return
}
span := trace.FromContext(ctx)
span := trace.SpanFromContext(ctx)
if span == nil {
return
}
sctx := span.SpanContext()
e.Data[logfields.TraceID] = sctx.TraceID.String()
e.Data[logfields.SpanID] = sctx.SpanID.String()
e.Data[logfields.TraceID] = sctx.TraceID().String()
e.Data[logfields.SpanID] = sctx.SpanID().String()
}
+20 -1
View File
@@ -29,7 +29,13 @@ var (
_scrub atomic.Bool
)
// SetScrubbing enables scrubbing
func init() {
// Scrubbing is enabled by default to prevent sensitive information
// (such as environment variables containing secrets) from leaking to logs.
_scrub.Store(true)
}
// SetScrubbing enables or disables scrubbing of potentially sensitive information from logging.
func SetScrubbing(enable bool) { _scrub.Store(enable) }
// IsScrubbingEnabled checks if scrubbing is enabled
@@ -174,6 +180,19 @@ func isRequestBase(m genMap) bool {
return a && c
}
// ScrubCreateOptions scrubs a JSON-encoded CreateOptions struct,
// removing sensitive fields (env vars, annotations) from the embedded OCI Spec.
func ScrubCreateOptions(b []byte) ([]byte, error) {
return scrubBytes(b, scrubCreateOptions)
}
func scrubCreateOptions(m genMap) error {
if spec, ok := index(m, "Spec"); ok {
return scrubOCISpec(spec)
}
return nil
}
// combination `m, ok := m[s]` and `m, ok := m.(genMap)`
func index(m genMap, s string) (genMap, bool) {
if m, ok := m[s]; ok {
+35 -7
View File
@@ -7,13 +7,23 @@ const (
Namespace = "namespace"
Operation = "operation"
ID = "id"
ContainerID = "cid"
ExecID = "eid"
ProcessID = "pid"
TaskID = "tid"
UVMID = "uvm-id"
SandboxID = "sandbox-id"
ID = "id"
SourceContainerID = "src_cid"
DestinationContainerID = "dst_cid"
ContainerID = "cid"
GCSContainerID = "gcs_container_id"
ExecID = "eid"
GuestNetworkNamespaceID = "guest_netns_id"
MigratedNamespaceID = "migrated_netns_id"
NamespaceID = "namespace-id"
SourcePodID = "src_pod_id"
DestinationPodID = "dst_pod_id"
PodID = "pod-id"
ProcessID = "pid"
SandboxID = "sandbox-id"
TaskID = "tid"
UVMID = "uvm-id"
VirtualSandboxID = "virtual-sandbox-id"
// networking and IO
@@ -22,6 +32,13 @@ const (
Bytes = "bytes"
Pipe = "pipe"
// SCSI Constants
Controller = "controller"
LUN = "lun"
DiskType = "disk-type"
Partition = "partition"
// Common Misc
Attempt = "attemptNo"
@@ -70,6 +87,12 @@ const (
ShimPid = "shim-pid"
TaskPid = "task-pid"
// vpci device
VMBusGUID = "vmBusGUID"
DeviceID = "deviceInstanceID"
VFIndex = "virtualFunctionIndex"
// sandbox
NetNsPath = "net-ns-path"
@@ -88,6 +111,11 @@ const (
VMShimOperation = "vmshim-op"
// migration
SessionID = "session-id"
Action = "action"
// logging and tracing
TraceID = "traceID"
-69
View File
@@ -1,69 +0,0 @@
package oc
import (
"errors"
"io"
"net"
"os"
errdefs "github.com/containerd/errdefs/pkg/errgrpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
// todo: break import cycle with "internal/hcs/errors.go" and reference errors defined there
// todo: add errors defined in "internal/guest/gcserror" (Hresult does not implement error)
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/errdefs", or is a
// context timeout or cancelled error
if s, ok := status.FromError(errdefs.ToGRPC(err)); ok {
return s.Code()
}
switch {
// case isAny(err):
// return codes.Cancelled
case isAny(err, os.ErrInvalid):
return codes.InvalidArgument
case isAny(err, os.ErrDeadlineExceeded):
return codes.DeadlineExceeded
case isAny(err, os.ErrNotExist):
return codes.NotFound
case isAny(err, os.ErrExist):
return codes.AlreadyExists
case isAny(err, os.ErrPermission):
return codes.PermissionDenied
// case isAny(err):
// return codes.ResourceExhausted
case isAny(err, os.ErrClosed, net.ErrClosed, io.ErrClosedPipe, io.ErrShortBuffer):
return codes.FailedPrecondition
// case isAny(err):
// return codes.Aborted
// case isAny(err):
// return codes.OutOfRange
// case isAny(err):
// return codes.Unimplemented
case isAny(err, io.ErrNoProgress):
return codes.Internal
// case isAny(err):
// return codes.Unavailable
case isAny(err, io.ErrShortWrite, io.ErrUnexpectedEOF):
return codes.DataLoss
// case isAny(err):
// return codes.Unauthenticated
default:
return codes.Unknown
}
}
// isAny returns true if errors.Is is true for any of the provided errors, errs.
func isAny(err error, errs ...error) bool {
for _, e := range errs {
if errors.Is(err, e) {
return true
}
}
return false
}
-86
View File
@@ -1,86 +0,0 @@
package oc
import (
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"google.golang.org/grpc/codes"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
)
const spanMessage = "Span %s"
var _errorCodeKey = logrus.ErrorKey + "Code"
// LogrusExporter is an OpenCensus `trace.Exporter` that exports
// `trace.SpanData` to logrus output.
type LogrusExporter struct{}
var _ trace.Exporter = &LogrusExporter{}
// ExportSpan exports `s` based on the the following rules:
//
// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`,
// `s.SpanID`, and `s.ParentSpanID` for correlation
//
// 2. Any calls to .Annotate will not be supported.
//
// 3. The span itself will be written at `logrus.InfoLevel` unless
// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel`
// providing `s.Status.Message` as the error value.
func (le *LogrusExporter) ExportSpan(s *trace.SpanData) {
if s.DroppedAnnotationCount > 0 {
logrus.WithFields(logrus.Fields{
"name": s.Name,
logfields.TraceID: s.TraceID.String(),
logfields.SpanID: s.SpanID.String(),
"dropped": s.DroppedAttributeCount,
"maxAttributes": len(s.Attributes),
}).Warning("span had dropped attributes")
}
entry := log.L.Dup()
// Combine all span annotations with span data (eg, trace ID, span ID, parent span ID,
// error, status code)
// (OC) Span attributes are guaranteed to be strings, bools, or int64s, so we can
// can skip overhead in entry.WithFields() and add them directly to entry.Data.
// Preallocate ahead of time, since we should add, at most, 10 additional entries
data := make(logrus.Fields, len(entry.Data)+len(s.Attributes)+10)
// Default log entry may have prexisting/application-wide data
for k, v := range entry.Data {
data[k] = v
}
for k, v := range s.Attributes {
data[k] = v
}
data[logfields.Name] = s.Name
data[logfields.TraceID] = s.TraceID.String()
data[logfields.SpanID] = s.SpanID.String()
data[logfields.ParentSpanID] = s.ParentSpanID.String()
data[logfields.StartTime] = s.StartTime
data[logfields.EndTime] = s.EndTime
data[logfields.Duration] = s.EndTime.Sub(s.StartTime)
if sk := spanKindToString(s.SpanKind); sk != "" {
data["spanKind"] = sk
}
level := logrus.InfoLevel
if s.Code != 0 {
level = logrus.ErrorLevel
// don't overwrite an existing "error" or "errorCode" attributes
if _, ok := data[logrus.ErrorKey]; !ok {
data[logrus.ErrorKey] = s.Message
}
if _, ok := data[_errorCodeKey]; !ok {
data[_errorCodeKey] = codes.Code(s.Code).String()
}
}
entry.Data = data
entry.Time = s.StartTime
entry.Logf(level, spanMessage, s.Name)
}
-58
View File
@@ -1,58 +0,0 @@
package oc
import (
"context"
"github.com/Microsoft/hcsshim/internal/log"
"go.opencensus.io/trace"
)
var DefaultSampler = trace.AlwaysSample()
// SetSpanStatus sets `span.SetStatus` to the proper status depending on `err`. If
// `err` is `nil` assumes `trace.StatusCodeOk`.
func SetSpanStatus(span *trace.Span, err error) {
status := trace.Status{}
if err != nil {
status.Code = int32(toStatusCode(err))
status.Message = err.Error()
}
span.SetStatus(status)
}
// StartSpan wraps "go.opencensus.io/trace".StartSpan, but, if the span is sampling,
// adds a log entry to the context that points to the newly created span.
func StartSpan(ctx context.Context, name string, o ...trace.StartOption) (context.Context, *trace.Span) {
ctx, s := trace.StartSpan(ctx, name, o...)
return update(ctx, s)
}
// StartSpanWithRemoteParent wraps "go.opencensus.io/trace".StartSpanWithRemoteParent.
//
// See StartSpan for more information.
func StartSpanWithRemoteParent(ctx context.Context, name string, parent trace.SpanContext, o ...trace.StartOption) (context.Context, *trace.Span) {
ctx, s := trace.StartSpanWithRemoteParent(ctx, name, parent, o...)
return update(ctx, s)
}
func update(ctx context.Context, s *trace.Span) (context.Context, *trace.Span) {
if s.IsRecordingEvents() {
ctx = log.UpdateContext(ctx)
}
return ctx, s
}
var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer)
var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindClient)
func spanKindToString(sk int) string {
switch sk {
case trace.SpanKindClient:
return "client"
case trace.SpanKindServer:
return "server"
default:
return ""
}
}
+98
View File
@@ -0,0 +1,98 @@
package ot
import (
"context"
"maps"
"github.com/sirupsen/logrus"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
otelcodes "go.opentelemetry.io/otel/codes"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
)
const spanMessage = "Span"
var _errorCodeKey = logrus.ErrorKey + "Code"
// LogrusExporter is an OpenTelemetry `sdktrace.SpanExporter` that exports
// `trace.ReadOnlySpan` to logrus output.
type LogrusExporter struct{}
var _ sdktrace.SpanExporter = &LogrusExporter{}
// ExportSpans exports each `spans` based on the following rules:
//
// 1. All output will contain `s.Attributes`, `s.SpanKind`, `s.TraceID`,
// `s.SpanID`, and `s.ParentSpanID` for correlation
//
// 2. Any calls to .Annotate will not be supported.
//
// 3. The span itself will be written at `logrus.InfoLevel` unless
// `s.Status.Code != 0` in which case it will be written at `logrus.ErrorLevel`
// providing `s.Status.Message` as the error value.
func (le *LogrusExporter) ExportSpans(ctx context.Context, spans []sdktrace.ReadOnlySpan) error {
for _, s := range spans {
if s.DroppedAttributes() > 0 {
logrus.WithFields(logrus.Fields{
"name": s.Name(),
logfields.TraceID: s.SpanContext().TraceID().String(),
logfields.SpanID: s.SpanContext().SpanID().String(),
"dropped": s.DroppedAttributes(),
"maxAttributes": len(s.Attributes()),
}).Warning("span had dropped attributes")
}
entry := log.L.Dup()
// Combine all span annotations with span data (eg, trace ID, span ID, parent span ID,
// error, status code)
// Span attributes are guaranteed to be strings, bools, or int64s, so we can
// skip overhead in entry.WithFields() and add them directly to entry.Data.
// Preallocate ahead of time, since we should add, at most, 10 additional entries
data := make(logrus.Fields, len(entry.Data)+len(s.Attributes())+10)
// Default log entry may have prexisting/application-wide data
maps.Copy(data, entry.Data)
for _, attr := range s.Attributes() {
data[string(attr.Key)] = attr.Value.AsInterface()
}
sc := s.SpanContext()
data[logfields.Name] = s.Name()
data[logfields.TraceID] = sc.TraceID().String()
data[logfields.SpanID] = sc.SpanID().String()
if s.Parent().IsValid() {
data[logfields.ParentSpanID] = s.Parent().SpanID().String()
}
data[logfields.StartTime] = s.StartTime()
data[logfields.EndTime] = s.EndTime()
data[logfields.Duration] = s.EndTime().Sub(s.StartTime())
if sk := spanKindToString(s.SpanKind()); sk != "" {
data["spanKind"] = sk
}
level := logrus.InfoLevel
if s.Status().Code == otelcodes.Error {
level = logrus.ErrorLevel
// don't overwrite an existing "error" or "errorCode" attributes
if _, ok := data[logrus.ErrorKey]; !ok {
data[logrus.ErrorKey] = s.Status().Description
}
if _, ok := data[_errorCodeKey]; !ok {
data[_errorCodeKey] = s.Status().Code.String()
}
}
entry.Data = data
entry.Time = s.StartTime()
entry.Log(level, spanMessage)
}
return nil
}
func (le *LogrusExporter) Shutdown(ctx context.Context) error {
log.G(ctx).Trace("LogrusExporter shutting down")
return nil
}
+76
View File
@@ -0,0 +1,76 @@
package ot
import (
"context"
"github.com/Microsoft/hcsshim/internal/log"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/codes"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/trace"
)
const (
TracerName = "containerd-shim-runhcs-v1"
)
var DefaultSampler = sdktrace.AlwaysSample()
// SetSpanStatus sets the span's OpenTelemetry status based on `err`.
//
// If `err` is non-nil the error is recorded on the span and the status is
// set to `codes.Error`.
//
// If `err` is nil the span is left in its default (Unset) status. The
// exporter treats Unset the same as Ok for level selection (Info), so
// downstream log level does not change. Leaving the status Unset instead of
// calling SetStatus(Ok, "") avoids the OpenTelemetry spec's "Ok is terminal"
// rule, under which a subsequent SetStatus(Error, ...) would be silently
// dropped.
func SetSpanStatus(span trace.Span, err error) {
if err == nil {
return
}
span.RecordError(err)
span.SetStatus(codes.Error, err.Error())
}
// StartSpan wraps otel.Start(), but, if the span is sampling,
// adds a log entry to the context that points to the newly created span.
func StartSpan(ctx context.Context, name string, o ...trace.SpanStartOption) (context.Context, trace.Span) {
tracer := otel.Tracer(TracerName)
ctx, s := tracer.Start(ctx, name, o...)
return update(ctx, s)
}
// StartSpanWithRemoteParent wraps "go.opentelemetry.io/otel/trace".ContextWithRemoteSpanContext
//
// See StartSpan for more information.
func StartSpanWithRemoteParent(ctx context.Context, name string, parent trace.SpanContext, o ...trace.SpanStartOption) (context.Context, trace.Span) {
tracer := otel.Tracer(TracerName)
ctx = trace.ContextWithRemoteSpanContext(ctx, parent)
ctx, s := tracer.Start(ctx, name, o...)
return update(ctx, s)
}
func update(ctx context.Context, s trace.Span) (context.Context, trace.Span) {
if s.IsRecording() {
ctx = log.UpdateContext(ctx)
}
return ctx, s
}
var WithServerSpanKind = trace.WithSpanKind(trace.SpanKindServer)
var WithClientSpanKind = trace.WithSpanKind(trace.SpanKindClient)
func spanKindToString(sk trace.SpanKind) string {
switch sk {
case trace.SpanKindClient:
return "client"
case trace.SpanKindServer:
return "server"
default:
return ""
}
}
+93 -94
View File
@@ -7,14 +7,13 @@ import (
"syscall"
"time"
"github.com/sirupsen/logrus"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/internal/timeout"
"github.com/sirupsen/logrus"
"go.opentelemetry.io/otel/attribute"
)
//go:generate go tool github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go vmcompute.go
@@ -117,15 +116,15 @@ func execute(ctx gcontext.Context, timeout time.Duration, f func() error) error
}
func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSystems, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsEnumerateComputeSystems")
ctx, span := ot.StartSpan(ctx, "HcsEnumerateComputeSystems")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("query", query))
span.SetAttributes(attribute.String("query", query))
return computeSystems, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
@@ -144,19 +143,19 @@ func HcsEnumerateComputeSystems(ctx gcontext.Context, query string) (computeSyst
}
func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration string, identity syscall.Handle) (computeSystem HcsSystem, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsCreateComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsCreateComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(
trace.StringAttribute("id", id),
trace.StringAttribute("configuration", configuration))
span.SetAttributes(
attribute.String("id", id),
attribute.String("configuration", configuration))
return computeSystem, result, execute(ctx, timeout.SystemCreate, func() error {
var resultp *uint16
@@ -169,13 +168,13 @@ func HcsCreateComputeSystem(ctx gcontext.Context, id string, configuration strin
}
func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSystem, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsOpenComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsOpenComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
return computeSystem, result, execute(ctx, timeout.SyscallWatcher, func() error {
@@ -189,9 +188,9 @@ func HcsOpenComputeSystem(ctx gcontext.Context, id string) (computeSystem HcsSys
}
func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr error) {
ctx, span := oc.StartSpan(ctx, "HcsCloseComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsCloseComputeSystem")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsCloseComputeSystem(computeSystem)
@@ -199,17 +198,17 @@ func HcsCloseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem) (hr er
}
func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsStartComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsStartComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SystemStart, func() error {
var resultp *uint16
@@ -222,17 +221,17 @@ func HcsStartComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option
}
func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsShutdownComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsShutdownComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -245,17 +244,17 @@ func HcsShutdownComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, opt
}
func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsTerminateComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsTerminateComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -268,17 +267,17 @@ func HcsTerminateComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, op
}
func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsPauseComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsPauseComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SystemPause, func() error {
var resultp *uint16
@@ -291,17 +290,17 @@ func HcsPauseComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, option
}
func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsResumeComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsResumeComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SystemResume, func() error {
var resultp *uint16
@@ -314,15 +313,15 @@ func HcsResumeComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, optio
}
func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem, propertyQuery string) (properties, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsGetComputeSystemProperties")
ctx, span := ot.StartSpan(ctx, "HcsGetComputeSystemProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery))
span.SetAttributes(attribute.String("propertyQuery", propertyQuery))
return properties, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
@@ -341,15 +340,15 @@ func HcsGetComputeSystemProperties(ctx gcontext.Context, computeSystem HcsSystem
}
func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, configuration string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsModifyComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsModifyComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("configuration", configuration))
span.SetAttributes(attribute.String("configuration", configuration))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -362,15 +361,15 @@ func HcsModifyComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, confi
}
func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsModifyServiceSettings")
ctx, span := ot.StartSpan(ctx, "HcsModifyServiceSettings")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("settings", settings))
span.SetAttributes(attribute.String("settings", settings))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -383,9 +382,9 @@ func HcsModifyServiceSettings(ctx gcontext.Context, settings string) (result str
}
func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSystem, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsRegisterComputeSystemCallback")
ctx, span := ot.StartSpan(ctx, "HcsRegisterComputeSystemCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error {
return hcsRegisterComputeSystemCallback(computeSystem, callback, context, &callbackHandle)
@@ -393,9 +392,9 @@ func HcsRegisterComputeSystemCallback(ctx gcontext.Context, computeSystem HcsSys
}
func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) {
ctx, span := oc.StartSpan(ctx, "HcsUnregisterComputeSystemCallback")
ctx, span := ot.StartSpan(ctx, "HcsUnregisterComputeSystemCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsUnregisterComputeSystemCallback(callbackHandle)
@@ -403,18 +402,18 @@ func HcsUnregisterComputeSystemCallback(ctx gcontext.Context, callbackHandle Hcs
}
func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processParameters string) (processInformation HcsProcessInformation, process HcsProcess, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsCreateProcess")
ctx, span := ot.StartSpan(ctx, "HcsCreateProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
if span.IsRecordingEvents() {
if span.IsRecording() {
// wont handle v1 process parameters
if s, err := log.ScrubProcessParameters(processParameters); err == nil {
span.AddAttributes(trace.StringAttribute("processParameters", s))
span.SetAttributes(attribute.String("processParameters", s))
}
}
@@ -429,15 +428,15 @@ func HcsCreateProcess(ctx gcontext.Context, computeSystem HcsSystem, processPara
}
func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (process HcsProcess, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsOpenProcess")
ctx, span := ot.StartSpan(ctx, "HcsOpenProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.Int64Attribute("pid", int64(pid)))
span.SetAttributes(attribute.Int64("pid", int64(pid)))
return process, result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -450,9 +449,9 @@ func HcsOpenProcess(ctx gcontext.Context, computeSystem HcsSystem, pid uint32) (
}
func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) {
ctx, span := oc.StartSpan(ctx, "HcsCloseProcess")
ctx, span := ot.StartSpan(ctx, "HcsCloseProcess")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsCloseProcess(process)
@@ -460,13 +459,13 @@ func HcsCloseProcess(ctx gcontext.Context, process HcsProcess) (hr error) {
}
func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsTerminateProcess")
ctx, span := ot.StartSpan(ctx, "HcsTerminateProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
return result, execute(ctx, timeout.SyscallWatcher, func() error {
@@ -480,15 +479,15 @@ func HcsTerminateProcess(ctx gcontext.Context, process HcsProcess) (result strin
}
func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsSignalProcess")
ctx, span := ot.StartSpan(ctx, "HcsSignalProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("options", options))
span.SetAttributes(attribute.String("options", options))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -501,13 +500,13 @@ func HcsSignalProcess(ctx gcontext.Context, process HcsProcess, options string)
}
func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInformation HcsProcessInformation, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsGetProcessInfo")
ctx, span := ot.StartSpan(ctx, "HcsGetProcessInfo")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
return processInformation, result, execute(ctx, timeout.SyscallWatcher, func() error {
@@ -521,13 +520,13 @@ func HcsGetProcessInfo(ctx gcontext.Context, process HcsProcess) (processInforma
}
func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processProperties, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsGetProcessProperties")
ctx, span := ot.StartSpan(ctx, "HcsGetProcessProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
return processProperties, result, execute(ctx, timeout.SyscallWatcher, func() error {
@@ -547,15 +546,15 @@ func HcsGetProcessProperties(ctx gcontext.Context, process HcsProcess) (processP
}
func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsModifyProcess")
ctx, span := ot.StartSpan(ctx, "HcsModifyProcess")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("settings", settings))
span.SetAttributes(attribute.String("settings", settings))
return result, execute(ctx, timeout.SyscallWatcher, func() error {
var resultp *uint16
@@ -568,15 +567,15 @@ func HcsModifyProcess(ctx gcontext.Context, process HcsProcess, settings string)
}
func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (properties, result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsGetServiceProperties")
ctx, span := ot.StartSpan(ctx, "HcsGetServiceProperties")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}()
span.AddAttributes(trace.StringAttribute("propertyQuery", propertyQuery))
span.SetAttributes(attribute.String("propertyQuery", propertyQuery))
return properties, result, execute(ctx, timeout.SyscallWatcher, func() error {
var (
@@ -595,9 +594,9 @@ func HcsGetServiceProperties(ctx gcontext.Context, propertyQuery string) (proper
}
func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callback uintptr, context uintptr) (callbackHandle HcsCallback, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsRegisterProcessCallback")
ctx, span := ot.StartSpan(ctx, "HcsRegisterProcessCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return callbackHandle, execute(ctx, timeout.SyscallWatcher, func() error {
return hcsRegisterProcessCallback(process, callback, context, &callbackHandle)
@@ -605,9 +604,9 @@ func HcsRegisterProcessCallback(ctx gcontext.Context, process HcsProcess, callba
}
func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallback) (hr error) {
ctx, span := oc.StartSpan(ctx, "HcsUnregisterProcessCallback")
ctx, span := ot.StartSpan(ctx, "HcsUnregisterProcessCallback")
defer span.End()
defer func() { oc.SetSpanStatus(span, hr) }()
defer func() { ot.SetSpanStatus(span, hr) }()
return execute(ctx, timeout.SyscallWatcher, func() error {
return hcsUnregisterProcessCallback(callbackHandle)
@@ -615,14 +614,14 @@ func HcsUnregisterProcessCallback(ctx gcontext.Context, callbackHandle HcsCallba
}
func HcsSaveComputeSystem(ctx gcontext.Context, computeSystem HcsSystem, options string) (result string, hr error) {
ctx, span := oc.StartSpan(ctx, "HcsSaveComputeSystem")
ctx, span := ot.StartSpan(ctx, "HcsSaveComputeSystem")
defer span.End()
defer func() {
if result != "" {
span.AddAttributes(trace.StringAttribute("result", result))
span.SetAttributes(attribute.String("result", result))
}
if hr != errVmcomputeOperationPending { //nolint:errorlint // explicitly returned
oc.SetSpanStatus(span, hr)
ot.SetSpanStatus(span, hr)
}
}()
+5 -5
View File
@@ -6,8 +6,8 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// ActivateLayer will find the layer with the given id and mount it's filesystem.
@@ -16,10 +16,10 @@ import (
// An activated layer must later be deactivated via DeactivateLayer.
func ActivateLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::ActivateLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = activateLayer(&stdDriverInfo, path)
if err != nil {
+5 -5
View File
@@ -12,12 +12,12 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/internal/longpath"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/trace"
)
type baseLayerReader struct {
s *trace.Span
s trace.Span
root string
result chan *fileEntry
proceed chan bool
@@ -25,7 +25,7 @@ type baseLayerReader struct {
backupReader *winio.BackupFileReader
}
func newBaseLayerReader(root string, s *trace.Span) (r *baseLayerReader) {
func newBaseLayerReader(root string, s trace.Span) (r *baseLayerReader) {
r = &baseLayerReader{
s: s,
root: root,
@@ -207,7 +207,7 @@ func (r *baseLayerReader) Read(b []byte) (int, error) {
func (r *baseLayerReader) Close() (err error) {
defer r.s.End()
defer func() {
oc.SetSpanStatus(r.s, err)
ot.SetSpanStatus(r.s, err)
close(r.proceed)
}()
r.proceed <- false
+4 -4
View File
@@ -11,15 +11,15 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/internal/safefile"
"github.com/Microsoft/hcsshim/internal/winapi"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/trace"
)
type baseLayerWriter struct {
ctx context.Context
s *trace.Span
s trace.Span
root *os.File
f *os.File
@@ -145,7 +145,7 @@ func (w *baseLayerWriter) Write(b []byte) (int, error) {
func (w *baseLayerWriter) Close() (err error) {
defer w.s.End()
defer func() { oc.SetSpanStatus(w.s, err) }()
defer func() { ot.SetSpanStatus(w.s, err) }()
defer func() {
w.root.Close()
w.root = nil
@@ -10,11 +10,11 @@ import (
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/longpath"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/internal/safefile"
"github.com/Microsoft/hcsshim/internal/winapi"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
"golang.org/x/sys/windows"
)
@@ -137,10 +137,10 @@ func convertToBaseLayer(ctx context.Context, root *os.File) error {
// desired file content for a UtilityVM under UtilityVM/Files/
func ConvertToBaseLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::ConvertToBaseLayer"
ctx, span := trace.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
root, err := safefile.OpenRoot(path)
if err != nil {
+7 -7
View File
@@ -6,20 +6,20 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// CreateLayer creates a new, empty, read-only layer on the filesystem based on
// the parent layer provided.
func CreateLayer(ctx context.Context, path, parent string) (err error) {
title := "hcsshim::CreateLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("parent", parent))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.String("parent", parent))
err = createLayer(&stdDriverInfo, path, parent)
if err != nil {
@@ -7,20 +7,20 @@ import (
"strings"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// CreateScratchLayer creates and populates new read-write layer for use by a container.
// This requires the full list of paths to all parent layers up to the base
func CreateScratchLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) {
title := "hcsshim::CreateScratchLayer"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
// Generate layer descriptors
layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
+5 -5
View File
@@ -6,17 +6,17 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// DeactivateLayer will dismount a layer that was mounted via ActivateLayer.
func DeactivateLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::DeactivateLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = deactivateLayer(&stdDriverInfo, path)
if err != nil {
+5 -5
View File
@@ -6,18 +6,18 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// DestroyLayer will remove the on-disk files representing the layer with the given
// path, including that layer's containing folder, if any.
func DestroyLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::DestroyLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = destroyLayer(&stdDriverInfo, path)
if err != nil {
+9 -8
View File
@@ -4,25 +4,26 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"os"
"path/filepath"
"syscall"
"unsafe"
"github.com/Microsoft/go-winio/vhd"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// ExpandScratchSize expands the size of a layer to at least size bytes.
func ExpandScratchSize(ctx context.Context, path string, size uint64) (err error) {
title := "hcsshim::ExpandScratchSize"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.Int64Attribute("size", int64(size)))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.Int64("size", int64(size)))
err = expandSandboxSize(&stdDriverInfo, path, size)
if err != nil {
@@ -75,7 +76,7 @@ func attachVhd(path string) (syscall.Handle, error) {
if err != nil {
return 0, &os.PathError{Op: "OpenVirtualDisk", Path: path, Err: err}
}
err = attachVirtualDisk(handle, 0, 0, 0, 0, 0)
err = vhd.AttachVirtualDisk(handle, vhd.AttachVirtualDiskFlagBypassDefaultEncryptionPolicy, nil)
if err != nil {
syscall.Close(handle)
return 0, &os.PathError{Op: "AttachVirtualDisk", Path: path, Err: err}
+16 -15
View File
@@ -9,8 +9,9 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// ExportLayer will create a folder at exportFolderPath and fill that folder with
@@ -20,13 +21,13 @@ import (
// perform the export.
func ExportLayer(ctx context.Context, path string, exportFolderPath string, parentLayerPaths []string) (err error) {
title := "hcsshim::ExportLayer"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("exportFolderPath", exportFolderPath),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.String("exportFolderPath", exportFolderPath),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
// Generate layer descriptors
layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
@@ -58,16 +59,16 @@ type LayerReader interface {
// The caller must have taken the SeBackupPrivilege privilege
// to call this and any methods on the resulting LayerReader.
func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string) (_ LayerReader, err error) {
ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerReader")
ctx, span := ot.StartSpan(ctx, "hcsshim::NewLayerReader")
defer func() {
if err != nil {
oc.SetSpanStatus(span, err)
ot.SetSpanStatus(span, err)
span.End()
}
}()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
span.SetAttributes(
attribute.String("path", path),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
if len(parentLayerPaths) == 0 {
// This is a base layer. It gets exported differently.
@@ -92,14 +93,14 @@ func NewLayerReader(ctx context.Context, path string, parentLayerPaths []string)
type legacyLayerReaderWrapper struct {
ctx context.Context
s *trace.Span
s trace.Span
*legacyLayerReader
}
func (r *legacyLayerReaderWrapper) Close() (err error) {
defer r.s.End()
defer func() { oc.SetSpanStatus(r.s, err) }()
defer func() { ot.SetSpanStatus(r.s, err) }()
err = r.legacyLayerReader.Close()
os.RemoveAll(r.root)
+6 -6
View File
@@ -4,12 +4,12 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"syscall"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// GetLayerMountPath will look for a mounted layer with the given path and return
@@ -18,10 +18,10 @@ import (
// folder path at which the layer is stored.
func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) {
title := "hcsshim::GetLayerMountPath"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
var mountPathLength uintptr = 0
@@ -47,6 +47,6 @@ func GetLayerMountPath(ctx context.Context, path string) (_ string, err error) {
}
mountPath := syscall.UTF16ToString(mountPathp[0:])
span.AddAttributes(trace.StringAttribute("mountPath", mountPath))
span.SetAttributes(attribute.String("mountPath", mountPath))
return mountPath, nil
}
@@ -7,8 +7,8 @@ import (
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// GetSharedBaseImages will enumerate the images stored in the common central
@@ -16,9 +16,9 @@ import (
// of registering them with the graphdriver, graph, and tagstore.
func GetSharedBaseImages(ctx context.Context) (_ string, err error) {
title := "hcsshim::GetSharedBaseImages"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
defer func() { ot.SetSpanStatus(span, err) }()
var buffer *uint16
err = getBaseImages(&buffer)
@@ -26,6 +26,6 @@ func GetSharedBaseImages(ctx context.Context) (_ string, err error) {
return "", hcserror.New(err, title, "")
}
imageData := interop.ConvertAndFreeCoTaskMemString(buffer)
span.AddAttributes(trace.StringAttribute("imageData", imageData))
span.SetAttributes(attribute.String("imageData", imageData))
return imageData, nil
}
+7 -7
View File
@@ -4,21 +4,21 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// GrantVmAccess adds access to a file for a given VM
func GrantVmAccess(ctx context.Context, vmid string, filepath string) (err error) {
title := "hcsshim::GrantVmAccess"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("vm-id", vmid),
trace.StringAttribute("path", filepath))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("vm-id", vmid),
attribute.String("path", filepath))
err = grantVmAccess(vmid, filepath)
if err != nil {
+20 -15
View File
@@ -10,9 +10,10 @@ import (
"github.com/Microsoft/go-winio"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/ot"
"github.com/Microsoft/hcsshim/internal/safefile"
"go.opencensus.io/trace"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/trace"
)
// ImportLayer will take the contents of the folder at importFolderPath and import
@@ -21,13 +22,13 @@ import (
// be present on the system at the paths provided in parentLayerPaths.
func ImportLayer(ctx context.Context, path string, importFolderPath string, parentLayerPaths []string) (err error) {
title := "hcsshim::ImportLayer"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("importFolderPath", importFolderPath),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.String("importFolderPath", importFolderPath),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
// Generate layer descriptors
layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
@@ -59,7 +60,7 @@ type LayerWriter interface {
type legacyLayerWriterWrapper struct {
ctx context.Context
s *trace.Span
s trace.Span
*legacyLayerWriter
path string
@@ -68,7 +69,7 @@ type legacyLayerWriterWrapper struct {
func (r *legacyLayerWriterWrapper) Close() (err error) {
defer r.s.End()
defer func() { oc.SetSpanStatus(r.s, err) }()
defer func() { ot.SetSpanStatus(r.s, err) }()
defer os.RemoveAll(r.root.Name())
defer r.CloseRoots()
@@ -125,16 +126,16 @@ func (r *legacyLayerWriterWrapper) Close() (err error) {
// The caller must have taken the SeBackupPrivilege and SeRestorePrivilege privileges
// to call this and any methods on the resulting LayerWriter.
func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string) (_ LayerWriter, err error) {
ctx, span := oc.StartSpan(ctx, "hcsshim::NewLayerWriter")
ctx, span := ot.StartSpan(ctx, "hcsshim::NewLayerWriter")
defer func() {
if err != nil {
oc.SetSpanStatus(span, err)
ot.SetSpanStatus(span, err)
span.End()
}
}()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
span.SetAttributes(
attribute.String("path", path),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
if len(parentLayerPaths) == 0 {
// This is a base layer. It gets imported differently.
@@ -155,6 +156,10 @@ func NewLayerWriter(ctx context.Context, path string, parentLayerPaths []string)
}
w, err := newLegacyLayerWriter(importPath, parentLayerPaths, path)
if err != nil {
// Clean up the temporary import directory so it is not leaked when
// the writer fails to initialize (matches NewLayerReader's handling
// of exportPath).
os.RemoveAll(importPath)
return nil, err
}
return &legacyLayerWriterWrapper{
+6 -6
View File
@@ -4,20 +4,20 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// LayerExists will return true if a layer with the given id exists and is known
// to the system.
func LayerExists(ctx context.Context, path string) (_ bool, err error) {
title := "hcsshim::LayerExists"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
// Call the procedure itself.
var exists uint32
@@ -25,6 +25,6 @@ func LayerExists(ctx context.Context, path string) (_ bool, err error) {
if err != nil {
return false, hcserror.New(err, title, "")
}
span.AddAttributes(trace.BoolAttribute("layer-exists", exists != 0))
span.SetAttributes(attribute.Bool("layer-exists", exists != 0))
return exists != 0, nil
}
+5 -5
View File
@@ -4,20 +4,20 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"path/filepath"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// LayerID returns the layer ID of a layer on disk.
func LayerID(ctx context.Context, path string) (_ guid.GUID, err error) {
title := "hcsshim::LayerID"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
_, file := filepath.Split(path)
return NameToGuid(ctx, file)
+23 -14
View File
@@ -436,13 +436,32 @@ func (w *legacyLayerWriter) initUtilityVM() error {
return nil
}
func (w *legacyLayerWriter) reset() error {
err := w.bufWriter.Flush()
if err != nil {
func (w *legacyLayerWriter) reset() (err error) {
// Always close the current backup writer and file handle, even if an error
// occurs below (e.g. bufWriter.Flush fails with ENOSPC when the disk is
// full). Leaving these handles open on Windows prevents the temporary
// import directory (defaults to SystemTemp, i.e. C:\Windows\SystemTemp\hcs*)
// from being removed by the deferred os.RemoveAll in legacyLayerWriterWrapper.Close,
// which leaks the directory and compounds disk-space exhaustion.
defer func() {
if w.backupWriter != nil {
w.backupWriter.Close()
w.backupWriter = nil
}
if w.currentFile != nil {
w.currentFile.Close()
w.currentFile = nil
w.currentFileName = ""
w.currentFileRoot = nil
}
w.currentIsDir = false
}()
if err = w.bufWriter.Flush(); err != nil {
return err
}
w.bufWriter.Reset(io.Discard)
if w.currentIsDir {
if w.currentIsDir && w.currentFile != nil {
r := w.currentFile
br := winio.NewBackupStreamReader(r)
// Seek to the beginning of the backup stream, skipping the fileattrs
@@ -475,16 +494,6 @@ func (w *legacyLayerWriter) reset() error {
}
w.currentIsDir = false
}
if w.backupWriter != nil {
w.backupWriter.Close()
w.backupWriter = nil
}
if w.currentFile != nil {
w.currentFile.Close()
w.currentFile = nil
w.currentFileName = ""
w.currentFileRoot = nil
}
return nil
}
+6 -6
View File
@@ -4,11 +4,11 @@ package wclayer
import (
"context"
"go.opentelemetry.io/otel/attribute"
"github.com/Microsoft/go-winio/pkg/guid"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
)
// NameToGuid converts the given string into a GUID using the algorithm in the
@@ -16,16 +16,16 @@ import (
// across all clients.
func NameToGuid(ctx context.Context, name string) (_ guid.GUID, err error) {
title := "hcsshim::NameToGuid"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("objectName", name))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("objectName", name))
var id guid.GUID
err = nameToGuid(name, &id)
if err != nil {
return guid.GUID{}, hcserror.New(err, title, "")
}
span.AddAttributes(trace.StringAttribute("guid", id.String()))
span.SetAttributes(attribute.String("guid", id.String()))
return id, nil
}
+7 -7
View File
@@ -8,8 +8,8 @@ import (
"sync"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
var prepareLayerLock sync.Mutex
@@ -21,12 +21,12 @@ var prepareLayerLock sync.Mutex
// Disabling the filter must be done via UnprepareLayer.
func PrepareLayer(ctx context.Context, path string, parentLayerPaths []string) (err error) {
title := "hcsshim::PrepareLayer"
ctx, span := oc.StartSpan(ctx, title)
ctx, span := ot.StartSpan(ctx, title)
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(
trace.StringAttribute("path", path),
trace.StringAttribute("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(
attribute.String("path", path),
attribute.String("parentLayerPaths", strings.Join(parentLayerPaths, ", ")))
// Generate layer descriptors
layers, err := layerPathsToDescriptors(ctx, parentLayerPaths)
+8 -8
View File
@@ -6,18 +6,18 @@ import (
"context"
"os"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// ProcessBaseLayer post-processes a base layer that has had its files extracted.
// The files should have been extracted to <path>\Files.
func ProcessBaseLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::ProcessBaseLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = processBaseImage(path)
if err != nil {
@@ -30,10 +30,10 @@ func ProcessBaseLayer(ctx context.Context, path string) (err error) {
// The files should have been extracted to <path>\Files.
func ProcessUtilityVMImage(ctx context.Context, path string) (err error) {
title := "hcsshim::ProcessUtilityVMImage"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = processUtilityImage(path)
if err != nil {
+5 -5
View File
@@ -6,18 +6,18 @@ import (
"context"
"github.com/Microsoft/hcsshim/internal/hcserror"
"github.com/Microsoft/hcsshim/internal/oc"
"go.opencensus.io/trace"
"github.com/Microsoft/hcsshim/internal/ot"
"go.opentelemetry.io/otel/attribute"
)
// UnprepareLayer disables the filesystem filter for the read-write layer with
// the given id.
func UnprepareLayer(ctx context.Context, path string) (err error) {
title := "hcsshim::UnprepareLayer"
ctx, span := oc.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
ctx, span := ot.StartSpan(ctx, title) //nolint:ineffassign,staticcheck
defer span.End()
defer func() { oc.SetSpanStatus(span, err) }()
span.AddAttributes(trace.StringAttribute("path", path))
defer func() { ot.SetSpanStatus(span, err) }()
span.SetAttributes(attribute.String("path", path))
err = unprepareLayer(&stdDriverInfo, path)
if err != nil {
+36 -1
View File
@@ -3,7 +3,9 @@
package cimwriter
import (
"fmt"
"sync"
"unsafe"
"github.com/sirupsen/logrus"
"golang.org/x/sys/windows"
@@ -53,7 +55,12 @@ var load = sync.OnceValue(func() error {
var buf [windows.MAX_PATH]uint16
n, _ := windows.GetModuleFileName(windows.Handle(modcimwriter.Handle()), &buf[0], uint32(len(buf)))
if n > 0 {
logrus.WithField("path", windows.UTF16ToString(buf[:n])).Info("loaded cimwriter.dll")
path := windows.UTF16ToString(buf[:n])
fields := logrus.Fields{"path": path}
if ver, err := getFileVersion(path); err == nil {
fields["version"] = ver
}
logrus.WithFields(fields).Info("loaded cimwriter.dll")
}
return nil
})
@@ -62,3 +69,31 @@ var load = sync.OnceValue(func() error {
func Supported() bool {
return load() == nil
}
// getFileVersion returns the file version string (e.g. "10.0.26100.1") for the given path.
func getFileVersion(path string) (string, error) {
size, err := windows.GetFileVersionInfoSize(path, nil)
if err != nil {
return "", err
}
data := make([]byte, size)
if err := windows.GetFileVersionInfo(path, 0, size, unsafe.Pointer(&data[0])); err != nil {
return "", err
}
var info *windows.VS_FIXEDFILEINFO
var infoLen uint32
if err := windows.VerQueryValue(unsafe.Pointer(&data[0]), `\`, unsafe.Pointer(&info), &infoLen); err != nil {
return "", err
}
return formatFileVersion(info), nil
}
// formatFileVersion formats the file version from a VS_FIXEDFILEINFO as "major.minor.build.revision".
// See https://learn.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo
func formatFileVersion(info *windows.VS_FIXEDFILEINFO) string {
major := info.FileVersionMS >> 16
minor := info.FileVersionMS & 0xffff
build := info.FileVersionLS >> 16
revision := info.FileVersionLS & 0xffff
return fmt.Sprintf("%d.%d.%d.%d", major, minor, build, revision)
}
+21
View File
@@ -0,0 +1,21 @@
package winapi
// BOOL GetProcessGroupAffinity(
// [in] HANDLE hProcess,
// [in, out] PUSHORT GroupCount,
// [out] PUSHORT GroupArray
// );
//
//sys GetProcessGroupAffinity(process windows.Handle, groupCount *uint16, groupArray *uint16) (err error) = kernel32.GetProcessGroupAffinity
// BOOL GetProcessAffinityMask(
// [in] HANDLE hProcess,
// [out] PDWORD_PTR lpProcessAffinityMask,
// [out] PDWORD_PTR lpSystemAffinityMask
// );
//
//sys GetProcessAffinityMask(process windows.Handle, processAffinityMask *uintptr, systemAffinityMask *uintptr) (err error) = kernel32.GetProcessAffinityMask
// WORD GetActiveProcessorGroupCount();
//
//sys GetActiveProcessorGroupCount() (amount uint16) = kernel32.GetActiveProcessorGroupCount
+20
View File
@@ -98,6 +98,26 @@ type JOBOBJECT_BASIC_PROCESS_ID_LIST struct {
ProcessIdList [1]uintptr
}
// GROUP_AFFINITY specifies a processor group and an affinity mask for that group.
// Mirrors the Win32 _GROUP_AFFINITY structure.
//
// Processor group support was introduced in Windows 7 / Windows Server 2008 R2
// to handle machines with more than 64 logical processors. The structure is used
// with SetInformationJobObject(JobObjectGroupInformationEx) and
// QueryInformationJobObject(JobObjectGroupInformationEx), both available since
// Windows 7 / Windows Server 2008 R2.
//
// For job object silos (containers), multi-processor-group affinity requires
// Windows Server 2022 (build 20348) or later.
//
// https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/miniport/ns-miniport-_group_affinity
// https://learn.microsoft.com/en-us/windows/win32/procthread/processor-groups
type GROUP_AFFINITY struct {
Mask uintptr // KAFFINITY = ULONG_PTR: bitmask of processors in Group
Group uint16 // Processor group number
Reserved [3]uint16 // Must be zero
}
// AllPids returns all the process Ids in the job object.
func (p *JOBOBJECT_BASIC_PROCESS_ID_LIST) AllPids() []uintptr {
return (*[(1 << 27) - 1]uintptr)(unsafe.Pointer(&p.ProcessIdList[0]))[:p.NumberOfProcessIdsInList:p.NumberOfProcessIdsInList]
@@ -63,6 +63,9 @@ var (
procCreatePseudoConsole = modkernel32.NewProc("CreatePseudoConsole")
procCreateRemoteThread = modkernel32.NewProc("CreateRemoteThread")
procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount")
procGetActiveProcessorGroupCount = modkernel32.NewProc("GetActiveProcessorGroupCount")
procGetProcessAffinityMask = modkernel32.NewProc("GetProcessAffinityMask")
procGetProcessGroupAffinity = modkernel32.NewProc("GetProcessGroupAffinity")
procIsProcessInJob = modkernel32.NewProc("IsProcessInJob")
procLocalAlloc = modkernel32.NewProc("LocalAlloc")
procLocalFree = modkernel32.NewProc("LocalFree")
@@ -270,6 +273,28 @@ func GetActiveProcessorCount(groupNumber uint16) (amount uint32) {
return
}
func GetActiveProcessorGroupCount() (amount uint16) {
r0, _, _ := syscall.SyscallN(procGetActiveProcessorGroupCount.Addr())
amount = uint16(r0)
return
}
func GetProcessAffinityMask(process windows.Handle, processAffinityMask *uintptr, systemAffinityMask *uintptr) (err error) {
r1, _, e1 := syscall.SyscallN(procGetProcessAffinityMask.Addr(), uintptr(process), uintptr(unsafe.Pointer(processAffinityMask)), uintptr(unsafe.Pointer(systemAffinityMask)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func GetProcessGroupAffinity(process windows.Handle, groupCount *uint16, groupArray *uint16) (err error) {
r1, _, e1 := syscall.SyscallN(procGetProcessGroupAffinity.Addr(), uintptr(process), uintptr(unsafe.Pointer(groupCount)), uintptr(unsafe.Pointer(groupArray)))
if r1 == 0 {
err = errnoErr(e1)
}
return
}
func IsProcessInJob(procHandle windows.Handle, jobHandle windows.Handle, result *int32) (err error) {
r1, _, e1 := syscall.SyscallN(procIsProcessInJob.Addr(), uintptr(procHandle), uintptr(jobHandle), uintptr(unsafe.Pointer(result)))
if r1 == 0 {
@@ -1,3 +1,11 @@
# v1.7.18 (2026-08-14)
* **Dependency Update**: Update to smithy-go v1.27.8.
# v1.7.17 (2026-08-10)
* **Dependency Update**: Update to smithy-go v1.27.7.
# v1.7.16 (2026-07-31.2)
* **Dependency Update**: Upgrade to smithy-go v1.27.6 to fix various serde issues in HTTP binding services.
Loaded 100 of 635 files, more files were not shown because too many files have changed in this diff. Show more