mirror of
https://github.com/moby/buildkit.git
synced 2026-11-06 05:16:45 +00:00
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:
635 files changed
+31289
-15074
No files matched your search
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Generated
Vendored
+12
-9
@@ -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{
|
||||
|
||||
Generated
Vendored
+3
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"`
|
||||
}
|
||||
Generated
Vendored
+1
-1
@@ -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"`
|
||||
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// HvSocket configuration for a VM
|
||||
// HvSocket configuration for a VM
|
||||
type HvSocket2 struct {
|
||||
HvSocketConfig *HvSocketSystemConfig `json:"HvSocketConfig,omitempty"`
|
||||
}
|
||||
+2
-2
@@ -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"`
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Memory runtime statistics
|
||||
// Memory runtime statistics
|
||||
type MemoryStats struct {
|
||||
MemoryUsageCommitBytes uint64 `json:"MemoryUsageCommitBytes,omitempty"`
|
||||
|
||||
|
||||
+205
@@ -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
@@ -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"`
|
||||
}
|
||||
+1
-1
@@ -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
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Options for HcsPauseComputeSystem
|
||||
// Options for HcsPauseComputeSystem
|
||||
type PauseOptions struct {
|
||||
SuspensionLevel string `json:"SuspensionLevel,omitempty"`
|
||||
|
||||
|
||||
+1
-10
@@ -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"`
|
||||
}
|
||||
+38
@@ -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
|
||||
)
|
||||
+1
-1
@@ -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
@@ -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)
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// CPU runtime statistics
|
||||
// CPU runtime statistics
|
||||
type ProcessorStats struct {
|
||||
TotalRuntime100ns uint64 `json:"TotalRuntime100ns,omitempty"`
|
||||
|
||||
|
||||
+10
@@ -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"`
|
||||
}
|
||||
+5
-1
@@ -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"`
|
||||
}
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Silo job information
|
||||
// Silo job information
|
||||
type SiloProperties struct {
|
||||
Enabled bool `json:"Enabled,omitempty"`
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -9,7 +9,7 @@
|
||||
|
||||
package hcsschema
|
||||
|
||||
// Storage runtime statistics
|
||||
// Storage runtime statistics
|
||||
type StorageStats struct {
|
||||
ReadCountNormalized uint64 `json:"ReadCountNormalized,omitempty"`
|
||||
|
||||
|
||||
+3
-3
@@ -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
@@ -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"`
|
||||
}
|
||||
Generated
Vendored
+4
-4
@@ -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"`
|
||||
}
|
||||
Generated
Vendored
+6
-6
@@ -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"`
|
||||
}
|
||||
+2
-2
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
+5
-5
@@ -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
@@ -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
-7
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
+5
-5
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
+25
@@ -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 {
|
||||
|
||||
+8
@@ -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
Reference in new issue
Block a user