diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 527fb295a31..62941cb32f4 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -28,3 +28,5 @@ jobs: cd $GITHUB_WORKSPACE/src/github.com/aws/amazon-ecs-agent make test-silent make analyze-cover-profile + make test-init + make analyze-cover-profile-init diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0b5c4a48755..776e47a68cb 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -29,6 +29,32 @@ jobs: make get-deps make static-check + init-check: + name: Static Analysis Init + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + path: src/github.com/aws/amazon-ecs-agent + - name: get GO_VERSION + run: | + cd $GITHUB_WORKSPACE/src/github.com/aws/amazon-ecs-agent + echo "GO_VERSION=$(cat GO_VERSION)" >> $GITHUB_ENV + - uses: actions/setup-go@v2 + with: + go-version: ${{ env.GO_VERSION }} + - uses: actions/checkout@v2 + with: + path: src/github.com/aws/amazon-ecs-agent + - name: run static checks + run: | + export GOPATH=$GITHUB_WORKSPACE + export PATH=$PATH:$(go env GOPATH)/bin + export GO111MODULE=auto + cd $GITHUB_WORKSPACE/src/github.com/aws/amazon-ecs-agent + make get-deps-init + make static-check-init + x-platform-build: name: Cross platform build runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 6cdbe76d8ad..27f8b948468 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ _bin/ *.swp *.orig /agent/version/_version.go +/ecs-init/version/version.go .agignore *.sublime-* .DS_Store @@ -20,3 +21,22 @@ _bin/ *.iml cover.out coverprofile.out +/amazon-ecs-init* +/BUILDROOT/ +/x86_64/ +/sources.tar +/ecs-init-* +/ecs.conf +/.deb-done +/.rpm-done +/.srpm-done +/BUILD +/RPMS +/SOURCES +/SRPMS +/ecs-init.spec +/sources.tgz +ecs-agent-*.tar +/ecs.service +*.log +*.DS_Store diff --git a/CHANGELOG.md b/CHANGELOG.md index 27ae02577bb..e8ee0beea92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.60.0 +* Enhancement - Update cgroups library to the latest release [#3126](https://github.com/aws/amazon-ecs-agent/pull/3126) +* Enhancement - Improve log readability [#3134](https://github.com/aws/amazon-ecs-agent/pull/3134) +* Enhancement - Add Host IP to port response for v4 container response [#3136](https://github.com/aws/amazon-ecs-agent/pull/3136) + ## 1.59.0 * Feature - prevent instances in EC2 Autoscaling warm pool from being registered with cluster [#3123](https://github.com/aws/amazon-ecs-agent/pull/3123) * Enhancement - DiscoverPollEndpoint: lengthen cache ttl and improve resiliency [#3109](https://github.com/aws/amazon-ecs-agent/pull/3109) diff --git a/INIT_CHANGELOG.md b/INIT_CHANGELOG.md new file mode 100644 index 00000000000..1b2f0ac5108 --- /dev/null +++ b/INIT_CHANGELOG.md @@ -0,0 +1,444 @@ +# Changelog + +## 1.60.0-1 +* Cache Agent version 1.60.0 +* Add volume plugin to rpm/deb package + +## 1.59.0-1 +* Cache Agent version 1.59.0 +* Log what pre-start is doing + +## 1.58.0-2 +* Cache Agent version 1.58.0 +* Add exec prerequisites to ecs-anywhere installation script + +## 1.57.1-1 +* Cache Agent version 1.57.1 +* Enable AL2 support for ECS-A +* Initialize docker client lazily + +## 1.57.0-1 +* Cache Agent version 1.57.0 + +## 1.56.0-1 +* Cache Agent version 1.56.0 + +## 1.55.5-1 +* Cache Agent version 1.55.5 + +## 1.55.4-1 +* Cache Agent version 1.55.4 +* GPU updates for ECS Anywhere +* Introduce new configuration variable ECS\_OFFHOST\_INTROSPECTION\_NAME to specify the primary network interface name to block offhost agent introspection port access. + +## 1.55.3-1 +* Cache Agent version 1.55.3 + +## 1.55.2-1 +* Cache Agent version 1.55.2 + +## 1.55.1-1 +* Cache Agent version 1.55.1 + +## 1.55.0-1 +* Cache Agent version 1.55.0 + +## 1.54.1-1 +* Cache Agent version 1.54.1 + +## 1.54.0-1 +* Cache Agent version 1.54.0 + +## 1.53.1-1 +* Cache Agent version 1.53.1 + +## 1.53.0-1 +* Cache Agent version 1.53.0 + +## 1.52.2-2 +* Cache Agent version 1.52.2 +* ecs-anywhere-install: fix incorrect download url when running in cn region + +## 1.52.2-1 +* Cache Agent version 1.52.2 +* ecs-anywhere-install: remove dependency on gpg key server +* ecs-anywhere-install: allow sandboxed apt installations + +## 1.52.1-1 +* Cache Agent version 1.52.1 + +## 1.52.0-1 +* Cache Agent version 1.52.0 +* Add support for ECS EXTERNAL launch type (ECS Anywhere) + +## 1.51.0-1 +* Cache Agent version 1.51.0 + +## 1.50.3-1 +* Cache Agent version 1.50.3 + +## 1.50.2-1 +* Cache Agent version 1.50.2 + +## 1.50.1-1 +* Cache Agent version 1.50.1 +* Does not restart ECS Agent when it exits with exit code 5 + +## 1.50.0-1 +* Cache Agent version 1.50.0 +* Allows ECS customers to execute interactive commands inside containers. + +## 1.49.0-1 +* Cache Agent version 1.49.0 +* Removes iptable rule that drops packets to port 51678 unconditionally on ecs service stop + +## 1.48.1-1 +* Cache Agent version 1.48.1 + +## 1.48.0-2 +* Cache Agent version 1.48.0 + +## 1.47.0-1 +* Cache Agent version 1.47.0 + +## 1.46.0-1 +* Cache Agent version 1.46.0 + +## 1.45.0-1 +* Cache Agent version 1.45.0 +* Block offhost access to agent's introspection port by default. Configurable via env ECS\_ALLOW\_OFFHOST\_INTROSPECTION\_ACCESS + +## 1.44.4-1 +* Cache Agent version 1.44.4 + +## 1.44.3-1 +* Cache Agent version 1.44.3 + +## 1.44.2-1 +* Cache Agent version 1.44.2 + +## 1.44.1-1 +* Cache Agent version 1.44.1 + +## 1.44.0-1 +* Cache Agent version 1.44.0 +* Add support for configuring Agent container logs + +## 1.43.0-2 +* Cache Agent version 1.43.0 + +## 1.42.0-1 +* Cache Agent version 1.42.0 +* Add a flag ECS\_SKIP\_LOCALHOST\_TRAFFIC\_FILTER to allow skipping local traffic filtering + +## 1.41.1-2 +* Drop traffic to 127.0.0.1 that isn't originated from the host + +## 1.41.1-1 +* Cache Agent version 1.41.1 + +## 1.41.0-1 +* Cache Agent version 1.41.0 + +## 1.40.0-1 +* Cache Agent version 1.40.0 + +## 1.39.0-2 +* Cache Agent version 1.39.0 +* Ignore IPv6 disable failure if already disabled + +## 1.38.0-1 +* Cache Agent version 1.38.0 +* Adds support for ECS volume plugin +* Disable ipv6 router advertisements for optimization + +## 1.37.0-2 +* Cache Agent version 1.37.0 +* Add '/etc/alternatives' to mounts + +## 1.36.2-1 +* Cache Agent version 1.36.2 +* update sbin mount point to avoid conflict with Docker >= 19.03.5 + +## 1.36.1-1 +* Cache Agent version 1.36.1 + +## 1.36.0-1 +* Cache Agent version 1.36.0 +* capture a fixed tail of container logs when removing a container + +## 1.35.0-1 +* Cache Agent version 1.35.0 +* Fix bug where stopping agent gracefully would still restart ecs-init + +## 1.33.0-1 +* Cache Agent version 1.33.0 +* Fix destination path in docker socket bind mount to match the one specified using DOCKER\_HOST on Amazon Linux 2 + +## 1.32.1-1 +* Cache Agent version 1.32.1 +* Add the ability to set Agent container's labels + +## 1.32.0-1 +* Cache Agent version 1.32.0 + +## 1.31.0-1 +* Cache Agent version 1.31.0 + +## 1.30.0-1 +* Cache Agent version 1.30.0 + +## 1.29.1-1 +* Cache Agent version 1.29.1 + +## 1.29.0-1 +* Cache Agent version 1.29.0 + +## 1.28.1-2 +* Cache Agent version 1.28.1 +* Use exponential backoff when restarting agent + +## 1.28.0-1 +* Cache Agent version 1.28.0 + +## 1.27.0-1 +* Cache Agent version 1.27.0 + +## 1.26.1-1 +* Cache Agent version 1.26.1 + +## 1.26.0-1 +* Cache Agent version 1.26.0 +* Add support for running iptables within agent container + +## 1.25.3-1 +* Cache Agent version 1.25.3 + +## 1.25.2-1 +* Cache Agent version 1.25.2 + +## 1.25.1-1 +* Cache Agent version 1.25.1 +* Update ecr models for private link support + +## 1.25.0-1 +* Cache Agent version 1.25.0 +* Add Nvidia GPU support for p2 and p3 instances + +## 1.24.0-1 +* Cache Agent version 1.24.0 + +## 1.22.0-4 +* Cache ECS agent version 1.22.0 for x86\_64 & ARM +* Support ARM architecture builds + +## 1.22.0-3 +* Rebuild + +## 1.22.0-2 +* Cache Agent version 1.22.0 + +## 1.21.0-1 +* Cache Agent version 1.21.0 +* Support configurable logconfig for Agent container to reduce disk usage +* ECS Agent will use the host's cert store on the Amazon Linux platform + +## 1.20.3-1 +* Cache Agent version 1.20.3 + +## 1.20.2-1 +* Cache Agent version 1.20.2 + +## 1.20.1-1 +* Cache Agent version 1.20.1 + +## 1.20.0-1 +* Cache Agent version 1.20.0 + +## 1.19.1-1 +* Cache Agent version 1.19.1 + +## 1.19.0-1 +* Cache Agent version 1.19.0 + +## 1.18.0-2 +* Spec file cleanups +* Enable builds for both AL1 and AL2 + +## 1.18.0-1 +* Cache Agent version 1.18.0 +* Add support for regional buckets +* Bundle ECS Agent tarball in package +* Download agent based on the partition +* Mount Docker plugin files dir + +## 1.17.3-1 +* Cache Agent version 1.17.3 +* Use s3client instead of httpclient when downloading + +## 1.17.2-1 +* Cache Agent version 1.17.2 + +## 1.17.1-1 +* Cache Agent version 1.17.1 + +## 1.17.0-2 +* Cache Agent version 1.17.0 + +## 1.16.2-1 +* Cache Agent version 1.16.2 +* Add GovCloud endpoint + +## 1.16.1-1 +* Cache Agent version 1.16.1 +* Improve startup behavior when Docker socket doesn't exist yet + +## 1.16.0-1 +* Cache Agent version 1.16.0 + +## 1.15.2-1 +* Cache Agent version 1.15.2 + +## 1.15.1-1 +* Update ECS Agent version + +## 1.15.0-1 +* Update ECS Agent version + +## 1.14.5-1 +* Update ECS Agent version + +## 1.14.4-1 +* Update ECS Agent version + +## 1.14.2-2 +* Cache Agent version 1.14.2 +* Add functionality for running agent with userns=host when Docker has userns-remap enabled +* Add support for Docker 17.03.1ce + +## 1.14.1-1 +* Cache Agent version 1.14.1 + +## 1.14.0-2 +* Add retry-backoff for pinging the Docker socket when creating the Docker client + +## 1.14.0-1 +* Cache Agent version 1.14.0 + +## 1.13.1-2 +* Update Requires to indicate support for docker <= 1.12.6 + +## 1.13.1-1 +* Cache Agent version 1.13.1 + +## 1.13.0-1 +* Cache Agent version 1.13.0 + +## 1.12.2-1 +* Cache Agent version 1.12.2 + +## 1.12.1-1 +* Cache Agent version 1.12.1 + +## 1.12.0-1 +* Cache Agent version 1.12.0 +* Add netfilter rules to support host network reaching credentials proxy + +## 1.11.1-1 +* Cache Agent version 1.11.1 + +## 1.11.0-1 +* Cache Agent version 1.11.0 +* Add support for Docker 1.11.2 +* Modify iptables and netfilter to support credentials proxy +* Eliminate requirement that /tmp and /var/cache be on the same filesystem +* Start agent with host network mode + +## 1.10.0-1 +* Cache Agent version 1.10.0 +* Add support for Docker 1.11.1 + +## 1.9.0-1 +* Cache Agent version 1.9.0 +* Make awslogs driver available by default + +## 1.8.2-1 +* Cache Agent version 1.8.2 + +## 1.8.1-1 +* Cache Agent version 1.8.1 + +## 1.8.0-1 +* Cache Agent version 1.8.0 + +## 1.7.1-1 +* Cache Agent version 1.7.1 + +## 1.7.0-1 +* Cache Agent version 1.7.0 +* Add support for Docker 1.9.1 + +## 1.6.0-1 +* Cache Agent version 1.6.0 +* Updated source dependencies + +## 1.5.0-1 +* Cache Agent version 1.5.0 +* Improved merge strategy for user-supplied environment variables +* Add default supported logging drivers + +## 1.4.0-2 +* Add support for Docker 1.7.1 + +## 1.4.0-1 +* Cache Agent version 1.4.0 + +## 1.3.1-1 +* Cache Agent version 1.3.1 +* Read Docker endpoint from environment variable DOCKER\_HOST if present + +## 1.3.0-1 +* Cache Agent version 1.3.0 + +## 1.2.1-2 +* Cache Agent version 1.2.1 + +## 1.2.0-1 +* Update versioning scheme to match Agent version +* Cache Agent version 1.2.0 +* Mount cgroup and execdriver directories for Telemetry feature + +## 1.0-5 +* Add support for Docker 1.6.2 + +## 1.0-4 +* Properly restart if the ecs-init package is upgraded in isolation + +## 1.0-3 +* Restart on upgrade if already running + +## 1.0-2 +* Cache Agent version 1.1.0 +* Add support for Docker 1.6.0 +* Force cache load on install/upgrade +* Add man page + +## 1.0-1 +* Re-start Agent on non-terminal exit codes +* Enable Agent self-updates +* Cache Agent version 1.0.0 +* Added rollback to cached Agent version for failed updates + +## 0.3-0 +* Migrate to statically-compiled Go binary + +## 0.2-3 +* Test for existing container agent and force remove it + +## 0.2-2 +* Mount data directory for state persistence +* Enable JSON-based configuration + +## 0.2-1 +* Naive update functionality + diff --git a/INIT_README.md b/INIT_README.md new file mode 100644 index 00000000000..02187364592 --- /dev/null +++ b/INIT_README.md @@ -0,0 +1,80 @@ +# Amazon Elastic Container Service RPM + +[![Build Status](https://travis-ci.org/aws/amazon-ecs-init.svg?branch=master)](https://travis-ci.org/aws/amazon-ecs-init) + +The Amazon Elastic Container Service RPM is software developed to support the [Amazon ECS Container +Agent](http://github.com/aws/amazon-ecs-agent). The Amazon ECS RPM is packaged for RPM-based systems that utilize +[Upstart](http://upstart.ubuntu.com) as the init system. + +## Behavior +The upstart script installed by the Amazon ECS RPM runs at the completion of runlevel 3, 4, or 5 as the system starts. +The script will clean up any previous copies of the Amazon ECS Container Agent, and then start a new copy. Logs from +the RPM are available at `/var/log/ecs/ecs-init.log`, while logs from the Amazon ECS Container Agent are available at +`/var/log/ecs/ecs-agent.log`. The Amazon ECS RPM makes the Amazon ECS Container Agent introspection endpoint available +at `http://127.0.0.1:51678/v1`. Configuration for the Amazon ECS Container Agent is read from `/etc/ecs/ecs.config`. +All of the configurations in this file are used as environment variables of the ECS Agent container. Additionally, some +configurations can be used to configure other properties of the ECS Agent container, as described below. + +| Configuration Key | Example Value(s) | Description | Default value | +|:----------------|:----------------------------|:------------|:-----------------------| +| `ECS_AGENT_LABELS` | `{"test.label.1":"value1","test.label.2":"value2"}` | The labels to add to the ECS Agent container. | | + +Additionally, the following environment variable(s) can be used to configure the behavior of the RPM: + +| Environment Variable Name | Example Value(s) | Description | Default value | +|:----------------|:----------------------------|:------------|:-----------------------| +| `ECS_SKIP_LOCALHOST_TRAFFIC_FILTER` | <true | false> | By default, the ecs-init service adds an iptable rule to drop non-local packets to localhost if they're not part of an existing forwarded connection or DNAT, and removes the rule upon stop. If `ECS_SKIP_LOCALHOST_TRAFFIC_FILTER` is set to true, this rule will not be added/removed. | false | +| `ECS_ALLOW_OFFHOST_INTROSPECTION_ACCESS` | <true | false> | By default, the ecs-init service adds an iptable rule to block access to ECS Agent's introspection port from off-host (or containers in awsvpc network mode), and removes the rule upon stop. If `ECS_ALLOW_OFFHOST_INTROSPECTION_ACCESS` is set to true, this rule will not be added/removed. | false | +| `ECS_OFFHOST_INTROSPECTION_INTERFACE_NAME` | `eth0` | Primary network interface name to be used for blocking offhost agent introspection port access. By default, this value is `eth0` | `eth0` | + +The above environment variable(s) can be used in the following way +- On Amazon Linux 1, the flag `ECS_SKIP_LOCALHOST_TRAFFIC_FILTER` can be turned on by adding `env ECS_SKIP_LOCALHOST_TRAFFIC_FILTER=true` to /etc/init/ecs.conf. +- On Amazon Linux 2, the flag `ECS_SKIP_LOCALHOST_TRAFFIC_FILTER` can be turned on by adding `ECS_SKIP_LOCALHOST_TRAFFIC_FILTER=true` to /etc/ecs/ecs.config. + +## Usage +The upstart script installed by the Amazon Elastic Container Service RPM can be started or stopped with the following commands respectively: + +* `sudo start ecs` +* `sudo stop ecs` + +### Updates +Updates to the Amazon ECS Container Agent should be performed through the Amazon ECS Container Agent. In the case where +an update failed and the Amazon ECS Container Agent is no longer functional, a rollback can be initiated as follows: + +1. `sudo stop ecs` +2. `sudo /usr/libexec/amazon-ecs-init reload-cache` +3. `sudo start ecs` + +## Security disclosures +If you think you’ve found a potential security issue, please do not post it in the Issues. Instead, please follow the instructions [here](https://aws.amazon.com/security/vulnerability-reporting/) or [email AWS security directly](mailto:aws-security@amazon.com). + +## Development + +#### Building the RPM for test + +On your local machine, you can use the docker target to generate an rpm: + +``` +make rpm-in-docker +``` + +This rpm can then be installed in an amazon linux ami: + +``` +# send rpm either through s3 or scp +rpm -i rpm-that-you-built.rpm +sudo systemctl enable ecs +sudo systemctl start ecs +``` + +#### Dev dependencies + +Run `make get-deps` to get dependencies for running tests and generating mocks. + +#### Generating mocks + +Mocks can be generated using the `make generate` Makefile target. **NOTE** that this must be run on a linux machine. + +## License + +The Amazon Elastic Container Service RPM is licensed under the Apache 2.0 License. diff --git a/Makefile b/Makefile index 75c3bca8f7f..ff542fdde16 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,6 @@ all: docker gobuild: ./scripts/build false - # create output directories .out-stamp: mkdir -p ./out/test-artifacts ./out/cni-plugins ./out/amazon-ecs-cni-plugins ./out/amazon-vpc-cni-plugins @@ -49,6 +48,9 @@ gobuild: static: ./scripts/build +static-with-pause: + ./scripts/build true "" false true + # Cross-platform build target for static checks xplatform-build: GOOS=linux GOARCH=arm64 ./scripts/build true "" false @@ -119,6 +121,10 @@ gogenerate: go generate -x ./agent/... $(MAKE) goimports +gogenerate-init: + PATH=$(PATH):$(shell pwd)/scripts go generate -x ./ecs-init/... + $(MAKE) goimports + # 'go' may not be on the $PATH for sudo tests GO_EXECUTABLE=$(shell command -v go 2> /dev/null) @@ -140,6 +146,10 @@ test: ${GOTEST} -tags unit -coverprofile cover.out -timeout=60s ./agent/... go tool cover -func cover.out > coverprofile.out +test-init: + go test -count=1 -short -v -coverprofile cover.out ./ecs-init/... + go tool cover -func cover.out > coverprofile-init.out + test-silent: $(eval VERBOSE=) ${GOTEST} -tags unit -coverprofile cover.out -timeout=60s ./agent/... @@ -149,6 +159,10 @@ test-silent: analyze-cover-profile: coverprofile.out ./scripts/analyze-cover-profile +.PHONY: analyze-cover-profile-init +analyze-cover-profile-init: coverprofile-init.out + ./scripts/analyze-cover-profile-init + run-integ-tests: test-registry gremlin container-health-check-image run-sudo-tests ECS_LOGLEVEL=debug ${GOTEST} -tags integration -timeout=30m ./agent/... @@ -158,7 +172,6 @@ run-sudo-tests: benchmark-test: go test -run=XX -bench=. ./agent/... - .PHONY: build-image-for-ecr upload-images replicate-images build-image-for-ecr: netkitten volumes-test image-cleanup-test-images fluentd exec-command-agent-test @@ -223,6 +236,22 @@ cni-plugins: get-cni-sources .out-stamp build-ecs-cni-plugins build-vpc-cni-plug mv $(PWD)/out/amazon-vpc-cni-plugins/* $(PWD)/out/cni-plugins @echo "Built all cni plugins successfully." +# dockerfree build process will build the agent container image from scratch +# and with minimal dependencies +# requires glibc-static +# dockerfree-pause works for both amd64 and arm64 +dockerfree-pause: + ./scripts/build-pause + +# dockerfree-certs works for both amd64 and arm64 +dockerfree-certs: + ./scripts/get-host-certs + +dockerfree-cni-plugins: get-cni-sources + ./scripts/build-cni-plugins + +dockerfree-agent-image: dockerfree-pause dockerfree-certs dockerfree-cni-plugins static-with-pause + ./scripts/build-agent-image .PHONY: codebuild codebuild: .out-stamp @@ -259,7 +288,6 @@ image-cleanup-test-images: container-health-check-image: $(MAKE) -C misc/container-health $(MFLAGS) - # all .go files in the agent, excluding vendor/, model/ and testutils/ directories, and all *_test.go and *_mocks.go files GOFILES:=$(shell go list -f '{{$$p := .}}{{range $$f := .GoFiles}}{{$$p.Dir}}/{{$$f}} {{end}}' ./agent/... \ | grep -v /testutils/ | grep -v _test\.go$ | grep -v _mocks\.go$ | grep -v /model) @@ -286,12 +314,23 @@ gogenerate-check: gogenerate # check that gogenerate does not generate a diff. git diff --exit-code +.PHONY: gogenerate-check-init +gogenerate-check-init: gogenerate-init + # check that gogenerate does not generate a diff. + git diff --exit-code + .PHONY: static-check static-check: gocyclo govet importcheck gogenerate-check # use default checks of staticcheck tool, except style checks (-ST*) and depracation checks (-SA1019) # depracation checks have been left out for now; removing their warnings requires error handling for newer suggested APIs, changes in function signatures and their usages. # https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck - staticcheck -tests=false -checks "inherit,-ST*,-SA1019,-SA9002" ./agent/... + staticcheck -tests=false -checks "inherit,-ST*,-SA1019,-SA9002,-SA4006" ./agent/... + +.PHONY: static-check-init +static-check-init: gocyclo govet importcheck gogenerate-check-init + # use default checks of staticcheck tool, except style checks (-ST*) + # https://github.com/dominikh/go-tools/tree/master/cmd/staticcheck + staticcheck -tests=false -checks "inherit,-ST*" ./ecs-init/... .PHONY: goimports goimports: @@ -309,13 +348,80 @@ GOPATH=$(shell go env GOPATH) get-deps: .get-deps-stamp +get-deps-init: + go get golang.org/x/tools/cover + go get golang.org/x/tools/cmd/cover + go get github.com/golang/mock/mockgen + cd "${GOPATH}/src/github.com/golang/mock/mockgen" && git checkout 1.3.1 && go get ./... && go install ./... && cd - + GO111MODULE=on go get github.com/fzipp/gocyclo/cmd/gocyclo@v0.3.1 + go get golang.org/x/tools/cmd/goimports + go get honnef.co/go/tools/cmd/staticcheck + +.amazon-linux-rpm-integrated-done: + ./scripts/update-version.sh + cp packaging/amazon-linux-ami-integrated/ecs-init.spec ecs-init.spec + cp packaging/amazon-linux-ami-integrated/ecs.conf ecs.conf + cp packaging/amazon-linux-ami-integrated/ecs.service ecs.service + cp packaging/amazon-linux-ami-integrated/amazon-ecs-volume-plugin.conf amazon-ecs-volume-plugin.conf + cp packaging/amazon-linux-ami-integrated/amazon-ecs-volume-plugin.service amazon-ecs-volume-plugin.service + cp packaging/amazon-linux-ami-integrated/amazon-ecs-volume-plugin.socket amazon-ecs-volume-plugin.socket + tar -czf ./sources.tgz ecs-init scripts misc agent amazon-ecs-cni-plugins amazon-vpc-cni-plugins agent-container VERSION + test -e SOURCES || ln -s . SOURCES + rpmbuild --define "%_topdir $(PWD)" -bb ecs-init.spec + find RPMS/ -type f -exec cp {} . \; + touch .amazon-linux-rpm-integrated-done + +amazon-linux-rpm-integrated: .amazon-linux-rpm-integrated-done + +.generic-rpm-integrated-done: + ./scripts/update-version.sh + cp packaging/generic-rpm-integrated/amazon-ecs-init.spec amazon-ecs-init.spec + cp packaging/generic-rpm-integrated/ecs.service ecs.service + cp packaging/generic-rpm-integrated/amazon-ecs-volume-plugin.service amazon-ecs-volume-plugin.service + cp packaging/generic-rpm-integrated/amazon-ecs-volume-plugin.socket amazon-ecs-volume-plugin.socket + tar -czf ./sources.tgz ecs-init scripts misc agent amazon-ecs-cni-plugins amazon-vpc-cni-plugins agent-container VERSION + test -e SOURCES || ln -s . SOURCES + rpmbuild --define "%_topdir $(PWD)" -bb amazon-ecs-init.spec + find RPMS/ -type f -exec cp {} . \; + touch .generic-rpm-integrated-done + +generic-rpm-integrated: .generic-rpm-integrated-done + +.generic-rpm-done: + ./scripts/update-version.sh + cp packaging/generic-rpm/amazon-ecs-init.spec amazon-ecs-init.spec + cp packaging/generic-rpm/ecs.service ecs.service + cp packaging/generic-rpm/amazon-ecs-volume-plugin.service amazon-ecs-volume-plugin.service + cp packaging/generic-rpm/amazon-ecs-volume-plugin.socket amazon-ecs-volume-plugin.socket + tar -czf ./sources.tgz ecs-init scripts + test -e SOURCES || ln -s . SOURCES + rpmbuild --define "%_topdir $(PWD)" -bb amazon-ecs-init.spec + find RPMS/ -type f -exec cp {} . \; + touch .generic-rpm-done + +generic-rpm: .generic-rpm-done + +.deb-done: BUILDROOT/ecs-agent.tar + ./scripts/update-version.sh + tar -czf ./amazon-ecs-init_${VERSION}.orig.tar.gz ecs-init scripts README.md + cp -r packaging/generic-deb/debian ecs-init scripts README.md BUILDROOT + cd BUILDROOT && debuild -uc -us --lintian-opts --suppress-tags bad-distribution-in-changes-file,file-in-unusual-dir + touch .deb-done + +deb: .deb-done + clean: # ensure docker is running and we can talk to it, abort if not: docker ps > /dev/null -docker rmi $(BUILDER_IMAGE) "amazon/amazon-ecs-agent-cleanbuild:make" -docker rmi $(BUILDER_IMAGE) "amazon/amazon-ecs-agent-cleanbuild-windows:make" - rm -f misc/certs/ca-certificates.crt &> /dev/null + rm -f misc/certs/host-certs.crt &> /dev/null + rm -rf misc/pause-container/image/ + rm -rf misc/pause-container/rootfs/ + rm -rf misc/plugins/ + rm -f misc/pause-container/amazon-ecs-pause.tar rm -rf out/ + rm -rf rootfs/ -$(MAKE) -C $(ECS_CNI_REPOSITORY_SRC_DIR) clean -$(MAKE) -C misc/netkitten $(MFLAGS) clean -$(MAKE) -C misc/volumes-test $(MFLAGS) clean @@ -329,4 +435,26 @@ clean: -rm -rf $(PWD)/bin -rm -rf cover.out -rm -rf coverprofile.out - + -rm -rf coverprofile-init.out + # ecs-init & rpm cleanup + -rm -f ecs-init.spec + -rm -f amazon-ecs-init.spec + -rm -f ecs.conf + -rm -f ecs.service + -rm -f amazon-ecs-volume-plugin.conf + -rm -f amazon-ecs-volume-plugin.service + -rm -f amazon-ecs-volume-plugin.socket + -rm -rf ./bin + -rm -f ./sources.tgz + -rm -f ./amazon-ecs-init + -rm -f ./ecs-init/ecs-init + -rm -f ./amazon-ecs-init-*.rpm + -rm -f ./ecs-agent-*.tar + -rm -f ./ecs-init-*.src.rpm + -rm -rf ./ecs-init-* + -rm -rf ./BUILDROOT BUILD RPMS SRPMS SOURCES SPECS + -rm -rf ./x86_64 + -rm -f ./amazon-ecs-init_${VERSION}* + -rm -f .srpm-done .rpm-done .generic-rpm-done + -rm -f .deb-done + -rm -f amazon-ecs-volume-plugin diff --git a/README.md b/README.md index b7d68e4ec95..2db353e26b7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Amazon ECS Container Agent + ![Amazon ECS logo](doc/ecs.png "Amazon ECS") ![Build Status](https://github.com/aws/amazon-ecs-agent/workflows/Build/badge.svg?branch=dev) diff --git a/VERSION b/VERSION index bb120e876c6..4d5fde5bd16 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.59.0 +1.60.0 diff --git a/agent-container/agent-config.json b/agent-container/agent-config.json new file mode 100644 index 00000000000..fc3f1ed1492 --- /dev/null +++ b/agent-container/agent-config.json @@ -0,0 +1 @@ +{"author":"Amazon Web Services, Inc.","config":{"Cmd":["/agent"],"ArgsEscaped":true},"created":"~~timestamp~~","history":[{"created":"~~timestamp~~","author":"Amazon Web Services, Inc.","created_by":"°o°","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:~~digest~~"]}} diff --git a/agent-container/agent-image-VERSION b/agent-container/agent-image-VERSION new file mode 100644 index 00000000000..d3827e75a5c --- /dev/null +++ b/agent-container/agent-image-VERSION @@ -0,0 +1 @@ +1.0 diff --git a/agent-container/agent-manifest.json b/agent-container/agent-manifest.json new file mode 100644 index 00000000000..840d0392d65 --- /dev/null +++ b/agent-container/agent-manifest.json @@ -0,0 +1 @@ +[{"Config":"config.json","RepoTags":["amazon/amazon-ecs-agent:~~agentversion~~"],"Layers":["rootfs/layer.tar"]}] diff --git a/agent-container/agent-repositories b/agent-container/agent-repositories new file mode 100644 index 00000000000..91624061cc3 --- /dev/null +++ b/agent-container/agent-repositories @@ -0,0 +1 @@ +{"amazon/amazon-ecs-agent":{"amazon-ecs":"rootfs"}} diff --git a/agent/acs/client/acs_client_test.go b/agent/acs/client/acs_client_test.go index 6e56e84f55f..9efa8abe454 100644 --- a/agent/acs/client/acs_client_test.go +++ b/agent/acs/client/acs_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/client/acs_error_test.go b/agent/acs/client/acs_error_test.go index c8c631040bf..1ba77736245 100644 --- a/agent/acs/client/acs_error_test.go +++ b/agent/acs/client/acs_error_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/acs_handler_test.go b/agent/acs/handler/acs_handler_test.go index b086a86a869..ed25e268d55 100644 --- a/agent/acs/handler/acs_handler_test.go +++ b/agent/acs/handler/acs_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/attach_eni_handler_common.go b/agent/acs/handler/attach_eni_handler_common.go index c41e05081fd..210d80f2e64 100644 --- a/agent/acs/handler/attach_eni_handler_common.go +++ b/agent/acs/handler/attach_eni_handler_common.go @@ -17,6 +17,9 @@ import ( "fmt" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/aws/amazon-ecs-agent/agent/acs/model/ecsacs" apieni "github.com/aws/amazon-ecs-agent/agent/api/eni" "github.com/aws/amazon-ecs-agent/agent/data" @@ -118,16 +121,26 @@ func addENIAttachmentToState(attachmentType, attachmentARN, taskARN, mac string, switch attachmentType { case apieni.ENIAttachmentTypeTaskENI: - seelog.Infof("Adding task eni attachment info for task '%s' to state, attachment=%s mac=%s", - taskARN, attachmentARN, mac) + taskId, _ := utils.TaskIdFromArn(taskARN) + logger.Info("Adding eni attachment info to state for task", logger.Fields{ + field.TaskID: taskId, + "attachmentARN": attachmentARN, + "mac": mac, + }) case apieni.ENIAttachmentTypeInstanceENI: - seelog.Infof("Adding instance eni attachment info to state, attachment=%s mac=%s", attachmentARN, mac) + logger.Info("Adding instance eni attachment info to state", logger.Fields{ + "attachmentARN": attachmentARN, + "mac": mac, + }) default: return fmt.Errorf("unrecognized eni attachment type: %s", attachmentType) } state.AddENIAttachment(eniAttachment) if err := dataClient.SaveENIAttachment(eniAttachment); err != nil { - seelog.Errorf("Failed to save data for eni attachment %s: %v", eniAttachment.AttachmentARN, err) + logger.Error("Failed to save data for eni attachment", logger.Fields{ + "attachmentARN": attachmentARN, + field.Error: err, + }) } return nil } diff --git a/agent/acs/handler/attach_eni_handler_common_test.go b/agent/acs/handler/attach_eni_handler_common_test.go index 6453ebc002a..fddbf3f8e68 100644 --- a/agent/acs/handler/attach_eni_handler_common_test.go +++ b/agent/acs/handler/attach_eni_handler_common_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/attach_instance_eni_handler_test.go b/agent/acs/handler/attach_instance_eni_handler_test.go index 0a51baefaa3..b834eddbde4 100644 --- a/agent/acs/handler/attach_instance_eni_handler_test.go +++ b/agent/acs/handler/attach_instance_eni_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/attach_task_eni_handler_test.go b/agent/acs/handler/attach_task_eni_handler_test.go index fbe240e7441..cdcda4bdad3 100644 --- a/agent/acs/handler/attach_task_eni_handler_test.go +++ b/agent/acs/handler/attach_task_eni_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/heartbeat_handler_test.go b/agent/acs/handler/heartbeat_handler_test.go index ac3a7eb7343..176de61acb1 100644 --- a/agent/acs/handler/heartbeat_handler_test.go +++ b/agent/acs/handler/heartbeat_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/payload_handler.go b/agent/acs/handler/payload_handler.go index 8d82bdabcf4..0df1b810d6d 100644 --- a/agent/acs/handler/payload_handler.go +++ b/agent/acs/handler/payload_handler.go @@ -16,6 +16,9 @@ import ( "context" "fmt" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/aws/amazon-ecs-agent/agent/acs/model/ecsacs" "github.com/aws/amazon-ecs-agent/agent/api" apiappmesh "github.com/aws/amazon-ecs-agent/agent/api/appmesh" @@ -128,7 +131,10 @@ func (payloadHandler *payloadRequestHandler) ackMessageId(messageID string) { MessageId: aws.String(messageID), }) if err != nil { - seelog.Warnf("Error 'ack'ing request with messageID: %s, error: %v", messageID, err) + logger.Warn("Error ack'ing request", logger.Fields{ + "messageID": messageID, + field.Error: err, + }) } } @@ -198,6 +204,12 @@ func (payloadHandler *payloadRequestHandler) addPayloadTasks(payload *ecsacs.Pay continue } + logger.Info("Received task payload from ACS", logger.Fields{ + field.TaskARN: apiTask.Arn, + "version": apiTask.Version, + field.DesiredStatus: apiTask.GetDesiredStatus(), + }) + if task.RoleCredentials != nil { // The payload from ACS for the task has credentials for the // task. Add those to the credentials manager and set the diff --git a/agent/acs/handler/payload_handler_test.go b/agent/acs/handler/payload_handler_test.go index b265efb9c10..5f96f911bcf 100644 --- a/agent/acs/handler/payload_handler_test.go +++ b/agent/acs/handler/payload_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/refresh_credentials_handler_test.go b/agent/acs/handler/refresh_credentials_handler_test.go index d7fa8f88892..a87df989a20 100644 --- a/agent/acs/handler/refresh_credentials_handler_test.go +++ b/agent/acs/handler/refresh_credentials_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/handler/task_manifest_handler_test.go b/agent/acs/handler/task_manifest_handler_test.go index 545bb46cf5d..cce4b9c24dc 100644 --- a/agent/acs/handler/task_manifest_handler_test.go +++ b/agent/acs/handler/task_manifest_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/acs/update_handler/updater_test.go b/agent/acs/update_handler/updater_test.go index adeff4458ef..48d536215d5 100644 --- a/agent/acs/update_handler/updater_test.go +++ b/agent/acs/update_handler/updater_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/appmesh/appmesh_test.go b/agent/api/appmesh/appmesh_test.go index 846c9036988..9061499609b 100644 --- a/agent/api/appmesh/appmesh_test.go +++ b/agent/api/appmesh/appmesh_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/container_test.go b/agent/api/container/container_test.go index 76d248b1446..5aa8f2a701c 100644 --- a/agent/api/container/container_test.go +++ b/agent/api/container/container_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/container_unix.go b/agent/api/container/container_unix.go index a105be71284..defdaf30970 100644 --- a/agent/api/container/container_unix.go +++ b/agent/api/container/container_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/container_windows.go b/agent/api/container/container_windows.go index 3b81dbb58a6..f481aaabeab 100644 --- a/agent/api/container/container_windows.go +++ b/agent/api/container/container_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/container_windows_test.go b/agent/api/container/container_windows_test.go index 89aa2f08a43..669019ad850 100644 --- a/agent/api/container/container_windows_test.go +++ b/agent/api/container/container_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/containeroverrides_test.go b/agent/api/container/containeroverrides_test.go index c7479c7dc8a..da40ea00c98 100644 --- a/agent/api/container/containeroverrides_test.go +++ b/agent/api/container/containeroverrides_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/containertype_test.go b/agent/api/container/containertype_test.go index 41298acfc1c..5681df63a8b 100644 --- a/agent/api/container/containertype_test.go +++ b/agent/api/container/containertype_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/port_binding_test.go b/agent/api/container/port_binding_test.go index 5648e4f0c8f..603490dd7e1 100644 --- a/agent/api/container/port_binding_test.go +++ b/agent/api/container/port_binding_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/status/containerstatus_test.go b/agent/api/container/status/containerstatus_test.go index 10cd9b94783..0016f1cf19f 100644 --- a/agent/api/container/status/containerstatus_test.go +++ b/agent/api/container/status/containerstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/status/managedagentstatus_test.go b/agent/api/container/status/managedagentstatus_test.go index 151312367a6..332c11d1899 100644 --- a/agent/api/container/status/managedagentstatus_test.go +++ b/agent/api/container/status/managedagentstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/transitiondependency_test.go b/agent/api/container/transitiondependency_test.go index 093f8dbc331..e4466988d1f 100644 --- a/agent/api/container/transitiondependency_test.go +++ b/agent/api/container/transitiondependency_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/container/transport_test.go b/agent/api/container/transport_test.go index 5e230054b6b..2f21240ee8d 100644 --- a/agent/api/container/transport_test.go +++ b/agent/api/container/transport_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/ecsclient/client.go b/agent/api/ecsclient/client.go index cb5c357d5a6..2ff65d9fe12 100644 --- a/agent/api/ecsclient/client.go +++ b/agent/api/ecsclient/client.go @@ -20,6 +20,8 @@ import ( "strings" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/api" apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" apierrors "github.com/aws/amazon-ecs-agent/agent/api/errors" @@ -587,8 +589,11 @@ func (client *APIECSClient) discoverPollEndpoint(containerInstanceArn string) (* if !expired && found { // Cache hit and not expired. Return the output. if output, ok := cachedEndpoint.(*ecs.DiscoverPollEndpointOutput); ok { - seelog.Infof("Using cached DiscoverPollEndpoint. endpoint=%s telemetryEndpoint=%s containerInstanceARN=%s", - aws.StringValue(output.Endpoint), aws.StringValue(output.TelemetryEndpoint), containerInstanceArn) + logger.Info("Using cached DiscoverPollEndpoint", logger.Fields{ + "endpoint": aws.StringValue(output.Endpoint), + "telemetryEndpoint": aws.StringValue(output.TelemetryEndpoint), + "containerInstanceARN": containerInstanceArn, + }) return output, nil } } @@ -604,8 +609,11 @@ func (client *APIECSClient) discoverPollEndpoint(containerInstanceArn string) (* // we have it. if expired { if output, ok := cachedEndpoint.(*ecs.DiscoverPollEndpointOutput); ok { - seelog.Infof("Error calling DiscoverPollEndpoint. Using cached but expired endpoint as a fallback. error=%s endpoint=%s telemetryEndpoint=%s containerInstanceARN=%s", - err, aws.StringValue(output.Endpoint), aws.StringValue(output.TelemetryEndpoint), containerInstanceArn) + logger.Info("Error calling DiscoverPollEndpoint. Using cached-but-expired endpoint as a fallback.", logger.Fields{ + "endpoint": aws.StringValue(output.Endpoint), + "telemetryEndpoint": aws.StringValue(output.TelemetryEndpoint), + "containerInstanceARN": containerInstanceArn, + }) return output, nil } } diff --git a/agent/api/ecsclient/client_test.go b/agent/api/ecsclient/client_test.go index 21fedd0ba82..bd65af02213 100644 --- a/agent/api/ecsclient/client_test.go +++ b/agent/api/ecsclient/client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/ecsclient/retry_handler_test.go b/agent/api/ecsclient/retry_handler_test.go index 24f523a0065..2194355ffb9 100644 --- a/agent/api/ecsclient/retry_handler_test.go +++ b/agent/api/ecsclient/retry_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/ecsclient/utils_amd64_test.go b/agent/api/ecsclient/utils_amd64_test.go index 7ecd0e2b17c..5bb95300c54 100644 --- a/agent/api/ecsclient/utils_amd64_test.go +++ b/agent/api/ecsclient/utils_amd64_test.go @@ -1,4 +1,5 @@ //go:build amd64 && unit +// +build amd64,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/ecsclient/utils_arm64_test.go b/agent/api/ecsclient/utils_arm64_test.go index 37d680ad1b0..1a46f13425b 100644 --- a/agent/api/ecsclient/utils_arm64_test.go +++ b/agent/api/ecsclient/utils_arm64_test.go @@ -1,4 +1,5 @@ //go:build arm64 && unit +// +build arm64,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/eni/eni_test.go b/agent/api/eni/eni_test.go index 11b4a3fe52a..2ed2f0b3b15 100644 --- a/agent/api/eni/eni_test.go +++ b/agent/api/eni/eni_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/eni/eniattachment.go b/agent/api/eni/eniattachment.go index 82c0c38c9ac..dccf34201b2 100644 --- a/agent/api/eni/eniattachment.go +++ b/agent/api/eni/eniattachment.go @@ -18,8 +18,11 @@ import ( "sync" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/aws/amazon-ecs-agent/agent/utils" + "github.com/aws/amazon-ecs-agent/agent/utils/ttime" - "github.com/cihub/seelog" "github.com/pkg/errors" ) @@ -55,6 +58,25 @@ type ENIAttachment struct { guard sync.RWMutex } +func getEniAttachmentLogFields(eni *ENIAttachment, duration time.Duration) logger.Fields { + fields := logger.Fields{ + "duration": duration.String(), + "attachmentARN": eni.AttachmentARN, + "attachmentType": eni.AttachmentType, + "attachmentSent": eni.AttachStatusSent, + "mac": eni.MACAddress, + "status": eni.Status.String(), + "expiresAt": eni.ExpiresAt.Format(time.RFC3339), + } + + if eni.AttachmentType != ENIAttachmentTypeInstanceENI { + taskId, _ := utils.TaskIdFromArn(eni.TaskARN) + fields[field.TaskID] = taskId + } + + return fields +} + // StartTimer starts the ack timer to record the expiration of ENI attachment func (eni *ENIAttachment) StartTimer(timeoutFunc func()) error { eni.guard.Lock() @@ -70,7 +92,7 @@ func (eni *ENIAttachment) StartTimer(timeoutFunc func()) error { return errors.Errorf("eni attachment: timer expiration is in the past; expiration [%s] < now [%s]", eni.ExpiresAt.String(), now.String()) } - seelog.Infof("Starting ENI ack timer with duration=%s, %s", duration.String(), eni.stringUnsafe()) + logger.Info("Starting ENI ack timer", getEniAttachmentLogFields(eni, duration)) eni.ackTimer = time.AfterFunc(duration, timeoutFunc) return nil } @@ -92,7 +114,7 @@ func (eni *ENIAttachment) Initialize(timeoutFunc func()) error { return errors.New("ENI attachment has already expired") } - seelog.Infof("Starting ENI ack timer with duration=%s, %s", duration.String(), eni.stringUnsafe()) + logger.Info("Starting ENI ack timer", getEniAttachmentLogFields(eni, duration)) eni.ackTimer = time.AfterFunc(duration, timeoutFunc) return nil } diff --git a/agent/api/eni/eniattachment_test.go b/agent/api/eni/eniattachment_test.go index 4c188fd56b5..6f46caecabd 100644 --- a/agent/api/eni/eniattachment_test.go +++ b/agent/api/eni/eniattachment_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/eni/enistatus_test.go b/agent/api/eni/enistatus_test.go index c76acc3b4b1..1f42345ae06 100644 --- a/agent/api/eni/enistatus_test.go +++ b/agent/api/eni/enistatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/statechange_test.go b/agent/api/statechange_test.go index 72ed57f027e..42657e16b78 100644 --- a/agent/api/statechange_test.go +++ b/agent/api/statechange_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/association_test.go b/agent/api/task/association_test.go index a3056eae414..0544af0aab6 100644 --- a/agent/api/task/association_test.go +++ b/agent/api/task/association_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/status/statusmapping_test.go b/agent/api/task/status/statusmapping_test.go index a4f345f34bc..0d5c757bc92 100644 --- a/agent/api/task/status/statusmapping_test.go +++ b/agent/api/task/status/statusmapping_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/status/taskstatus_test.go b/agent/api/task/status/taskstatus_test.go index 270223bee9c..4a9938581d6 100644 --- a/agent/api/task/status/taskstatus_test.go +++ b/agent/api/task/status/taskstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/task.go b/agent/api/task/task.go index 96c02bdd2be..93958671e53 100644 --- a/agent/api/task/task.go +++ b/agent/api/task/task.go @@ -28,7 +28,6 @@ import ( "github.com/aws/amazon-ecs-agent/agent/logger/field" "github.com/aws/amazon-ecs-agent/agent/utils/ttime" "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/arn" "github.com/docker/docker/api/types" "github.com/docker/go-connections/nat" @@ -54,7 +53,6 @@ import ( taskresourcevolume "github.com/aws/amazon-ecs-agent/agent/taskresource/volume" "github.com/aws/amazon-ecs-agent/agent/utils" "github.com/aws/aws-sdk-go/private/protocol/json/jsonutil" - "github.com/cihub/seelog" dockercontainer "github.com/docker/docker/api/types/container" "github.com/pkg/errors" ) @@ -83,7 +81,6 @@ const ( ContainerOrderingCreateCondition = "CREATE" ContainerOrderingStartCondition = "START" - arnResourceDelimiter = "/" // networkModeNone specifies the string used to define the `none` docker networking mode networkModeNone = "none" // dockerMappingContainerPrefix specifies the prefix string used for setting the @@ -156,6 +153,8 @@ type TaskOverrides struct{} type Task struct { // Arn is the unique identifier for the task Arn string + // id is the id section of the task ARN + id string // Overrides are the overrides applied to a task Overrides TaskOverrides `json:"-"` // Family is the name of the task definition family @@ -271,6 +270,9 @@ type Task struct { // lock is for protecting all fields in the task struct lock sync.RWMutex + + // setIdOnce is used to set the value of this task's id only the first time GetID is invoked + setIdOnce sync.Once } // TaskFromACS translates ecsacs.Task to apitask.Task by first marshaling the received @@ -330,18 +332,27 @@ func (task *Task) PostUnmarshalTask(cfg *config.Config, task.adjustForPlatform(cfg) if task.MemoryCPULimitsEnabled { if err := task.initializeCgroupResourceSpec(cfg.CgroupPath, cfg.CgroupCPUPeriod, resourceFields); err != nil { - seelog.Errorf("Task [%s]: could not intialize resource: %v", task.Arn, err) + logger.Error("Could not initialize resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } } if err := task.initializeContainerOrderingForVolumes(); err != nil { - seelog.Errorf("Task [%s]: could not initialize volumes dependency for container: %v", task.Arn, err) + logger.Error("Could not initialize volumes dependency for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } if err := task.initializeContainerOrderingForLinks(); err != nil { - seelog.Errorf("Task [%s]: could not initialize links dependency for container: %v", task.Arn, err) + logger.Error("Could not initialize links dependency for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } @@ -356,14 +367,20 @@ func (task *Task) PostUnmarshalTask(cfg *config.Config, } if err := task.addGPUResource(cfg); err != nil { - seelog.Errorf("Task [%s]: could not initialize GPU associations: %v", task.Arn, err) + logger.Error("Could not initialize GPU associations", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } task.initializeContainersV3MetadataEndpoint(utils.NewDynamicUUIDProvider()) task.initializeContainersV4MetadataEndpoint(utils.NewDynamicUUIDProvider()) if err := task.addNetworkResourceProvisioningDependency(cfg); err != nil { - seelog.Errorf("Task [%s]: could not provision network resource: %v", task.Arn, err) + logger.Error("Could not provision network resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } // Adds necessary Pause containers for sharing PID or IPC namespaces @@ -375,13 +392,19 @@ func (task *Task) PostUnmarshalTask(cfg *config.Config, if task.requiresCredentialSpecResource() { if err := task.initializeCredentialSpecResource(cfg, credentialsManager, resourceFields); err != nil { - seelog.Errorf("Task [%s]: could not initialize credentialspec resource: %v", task.Arn, err) + logger.Error("Could not initialize credentialspec resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } } if err := task.initializeEnvfilesResource(cfg, credentialsManager); err != nil { - seelog.Errorf("Task [%s]: could not initialize environment files resource: %v", task.Arn, err) + logger.Error("Could not initialize environment files resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } task.populateTaskARN() @@ -389,14 +412,20 @@ func (task *Task) PostUnmarshalTask(cfg *config.Config, // fsxWindowsFileserver is the product type -- it is technically "agnostic" ie it should apply to both Windows and Linux tasks if task.requiresFSxWindowsFileServerResource() { if err := task.initializeFSxWindowsFileServerResource(cfg, credentialsManager, resourceFields); err != nil { - seelog.Errorf("Task [%s]: could not initialize FSx for Windows File Server resource: %v", task.Arn, err) + logger.Error("Could not initialize FSx for Windows File Server resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return apierrors.NewResourceInitError(task.Arn, err) } } for _, opt := range options { if err := opt(task); err != nil { - seelog.Errorf("Task [%s]: could not apply task option: %v", task.Arn, err) + logger.Error("Could not apply task option", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return err } } @@ -670,8 +699,11 @@ func (task *Task) addSharedVolumes(SharedVolumeMatchFullConfig bool, ctx context if _, ok := volumeMetadata.Error.(*dockerapi.DockerTimeoutError); ok { return volumeMetadata.Error } - - seelog.Infof("initialize volume: Task [%s]: non-autoprovisioned volume not found, adding to task resource %q", task.Arn, vol.Name) + logger.Error("Failed to initialize non-autoprovisioned volume", logger.Fields{ + field.TaskID: task.GetID(), + field.Volume: vol.Name, + field.Error: volumeMetadata.Error, + }) // this resource should be created by agent volumeResource, err := taskresourcevolume.NewVolumeResource( ctx, @@ -690,22 +722,34 @@ func (task *Task) addSharedVolumes(SharedVolumeMatchFullConfig bool, ctx context return nil } - seelog.Infof("initialize volume: Task [%s]: volume [%s] already exists", task.Arn, volumeConfig.DockerVolumeName) + logger.Debug("Volume already exists", logger.Fields{ + field.TaskID: task.GetID(), + field.Volume: volumeConfig.DockerVolumeName, + }) if !SharedVolumeMatchFullConfig { - seelog.Infof("initialize volume: Task [%s]: ECS_SHARED_VOLUME_MATCH_FULL_CONFIG is set to false and volume with name [%s] is found", task.Arn, volumeConfig.DockerVolumeName) + logger.Info("ECS_SHARED_VOLUME_MATCH_FULL_CONFIG is set to false and volume was found", logger.Fields{ + field.TaskID: task.GetID(), + field.Volume: volumeConfig.DockerVolumeName, + }) return nil } // validate all the volume metadata fields match to the configuration if len(volumeMetadata.DockerVolume.Labels) == 0 && len(volumeMetadata.DockerVolume.Labels) == len(volumeConfig.Labels) { - seelog.Infof("labels are both empty or null: Task [%s]: volume [%s]", task.Arn, volumeConfig.DockerVolumeName) + logger.Info("Volume labels are both empty or null", logger.Fields{ + field.TaskID: task.GetID(), + field.Volume: volumeConfig.DockerVolumeName, + }) } else if !reflect.DeepEqual(volumeMetadata.DockerVolume.Labels, volumeConfig.Labels) { return errors.Errorf("intialize volume: non-autoprovisioned volume does not match existing volume labels: existing: %v, expected: %v", volumeMetadata.DockerVolume.Labels, volumeConfig.Labels) } if len(volumeMetadata.DockerVolume.Options) == 0 && len(volumeMetadata.DockerVolume.Options) == len(volumeConfig.DriverOpts) { - seelog.Infof("driver options are both empty or null: Task [%s]: volume [%s]", task.Arn, volumeConfig.DockerVolumeName) + logger.Info("Volume driver options are both empty or null", logger.Fields{ + field.TaskID: task.GetID(), + field.Volume: volumeConfig.DockerVolumeName, + }) } else if !reflect.DeepEqual(volumeMetadata.DockerVolume.Options, volumeConfig.DriverOpts) { return errors.Errorf("initialize volume: non-autoprovisioned volume does not match existing volume options: existing: %v, expected: %v", volumeMetadata.DockerVolume.Options, volumeConfig.DriverOpts) @@ -742,7 +786,9 @@ func (task *Task) initializeCredentialsEndpoint(credentialsManager credentials.M // the id. This should never happen as the payload handler sets // credentialsId for the task after adding credentials to the // credentials manager - seelog.Errorf("Unable to get credentials for task: %s", task.Arn) + logger.Error("Unable to get credentials for task", logger.Fields{ + field.TaskID: task.GetID(), + }) return } @@ -1021,7 +1067,10 @@ func (task *Task) addFirelensContainerDependency() error { if firelensContainer.HasContainerDependencies() { // If firelens container has any container dependency, we don't add internal container dependency that depends // on it in order to be safe (otherwise we need to deal with circular dependency). - seelog.Warnf("Not adding container dependency to let firelens container %s start first, because it has dependency on other containers.", firelensContainer.Name) + logger.Warn("Not adding container dependency to let firelens container start first since it has dependency on other containers.", logger.Fields{ + field.TaskID: task.GetID(), + "firelensContainer": firelensContainer.Name, + }) return nil } @@ -1045,8 +1094,11 @@ func (task *Task) addFirelensContainerDependency() error { // If there's no dependency between the app container and the firelens container, make firelens container // start first to be the default behavior by adding a START container depdendency. if !container.DependsOnContainer(firelensContainer.Name) { - seelog.Infof("Adding a START container dependency on firelens container %s for container %s", - firelensContainer.Name, container.Name) + logger.Info("Adding a START container dependency on firelens for container", logger.Fields{ + field.TaskID: task.GetID(), + "firelensContainer": firelensContainer.Name, + field.Container: container.Name, + }) container.AddContainerDependency(firelensContainer.Name, ContainerOrderingStartCondition) } } @@ -1125,10 +1177,7 @@ func (task *Task) collectFirelensLogEnvOptions(containerToLogOptions map[string] // container's host config. func (task *Task) AddFirelensContainerBindMounts(firelensConfig *apicontainer.FirelensConfig, hostConfig *dockercontainer.HostConfig, config *config.Config) *apierrors.HostConfigError { - taskID, err := task.GetID() - if err != nil { - return &apierrors.HostConfigError{Msg: err.Error()} - } + taskID := task.GetID() var configBind, s3ConfigBind, socketBind string switch firelensConfig.Type { @@ -1220,7 +1269,10 @@ func (task *Task) addNetworkResourceProvisioningDependency(cfg *config.Config) e for _, resource := range task.GetResources() { if resource.DependOnTaskNetwork() { - seelog.Debugf("Task [%s]: adding network pause container dependency to resource [%s]", task.Arn, resource.GetName()) + logger.Debug("Adding network pause container dependency to resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Resource: resource.GetName(), + }) resource.BuildContainerDependency(NetworkPauseContainerName, apicontainerstatus.ContainerResourcesProvisioned, resourcestatus.ResourceStatus(taskresourcevolume.VolumeCreated)) } } @@ -1296,15 +1348,16 @@ func (task *Task) UpdateMountPoints(cont *apicontainer.Container, vols []types.M // there was no change // Invariant: task known status is the minimum of container known status func (task *Task) updateTaskKnownStatus() (newStatus apitaskstatus.TaskStatus) { - seelog.Debugf("api/task: Updating task's known status, task: %s", task.String()) + logger.Debug("Updating task's known status", logger.Fields{ + field.TaskID: task.GetID(), + }) // Set to a large 'impossible' status that can't be the min containerEarliestKnownStatus := apicontainerstatus.ContainerZombie - var earliestKnownStatusContainer *apicontainer.Container - essentialContainerStopped := false + var earliestKnownStatusContainer, essentialContainerStopped *apicontainer.Container for _, container := range task.Containers { containerKnownStatus := container.GetKnownStatus() if containerKnownStatus == apicontainerstatus.ContainerStopped && container.Essential { - essentialContainerStopped = true + essentialContainerStopped = container } if containerKnownStatus < containerEarliestKnownStatus { containerEarliestKnownStatus = containerKnownStatus @@ -1312,19 +1365,25 @@ func (task *Task) updateTaskKnownStatus() (newStatus apitaskstatus.TaskStatus) { } } if earliestKnownStatusContainer == nil { - seelog.Criticalf( - "Impossible state found while updating tasks's known status, earliest state recorded as %s for task [%v]", - containerEarliestKnownStatus.String(), task) + logger.Critical("Impossible state found while updating tasks's known status", logger.Fields{ + field.TaskID: task.GetID(), + "earliestKnownStatus": containerEarliestKnownStatus.String(), + }) return apitaskstatus.TaskStatusNone } - seelog.Debugf("api/task: Container with earliest known container is [%s] for task: %s", - earliestKnownStatusContainer.String(), task.String()) + logger.Debug("Found container with earliest known status", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: earliestKnownStatusContainer.Name, + field.KnownStatus: earliestKnownStatusContainer.GetKnownStatus(), + field.DesiredStatus: earliestKnownStatusContainer.GetDesiredStatus(), + }) // If the essential container is stopped while other containers may be running // don't update the task status until the other containers are stopped. - if earliestKnownStatusContainer.IsKnownSteadyState() && essentialContainerStopped { - seelog.Debugf( - "Essential container is stopped while other containers are running, not updating task status for task: %s", - task.String()) + if earliestKnownStatusContainer.IsKnownSteadyState() && essentialContainerStopped != nil { + logger.Debug("Essential container is stopped while other containers are running, not updating task status", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: essentialContainerStopped.Name, + }) return apitaskstatus.TaskStatusNone } // We can't rely on earliest container known status alone for determining if the @@ -1335,7 +1394,7 @@ func (task *Task) updateTaskKnownStatus() (newStatus apitaskstatus.TaskStatus) { if task.GetKnownStatus() < earliestKnownTaskStatus { task.SetKnownStatus(earliestKnownTaskStatus) logger.Info("Container change also resulted in task change", logger.Fields{ - field.TaskARN: task.Arn, + field.TaskID: task.GetID(), field.Container: earliestKnownStatusContainer.Name, field.RuntimeID: earliestKnownStatusContainer.RuntimeID, field.DesiredStatus: task.GetDesiredStatus().String(), @@ -1350,7 +1409,9 @@ func (task *Task) updateTaskKnownStatus() (newStatus apitaskstatus.TaskStatus) { // based on the known statuses of all containers in the task func (task *Task) getEarliestKnownTaskStatusForContainers() apitaskstatus.TaskStatus { if len(task.Containers) == 0 { - seelog.Criticalf("No containers in the task: %s", task.String()) + logger.Critical("No containers in the task", logger.Fields{ + field.TaskID: task.GetID(), + }) return apitaskstatus.TaskStatusNone } // Set earliest container status to an impossible to reach 'high' task status @@ -1539,13 +1600,21 @@ func (task *Task) overrideContainerRuntime(container *apicontainer.Container, ho if task.NvidiaRuntime == "" { return &apierrors.HostConfigError{Msg: "Runtime is not set for GPU containers"} } - seelog.Debugf("Setting runtime as %s for container %s", task.NvidiaRuntime, container.Name) + logger.Debug("Setting runtime for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "runTime": task.NvidiaRuntime, + }) hostCfg.Runtime = task.NvidiaRuntime } } if cfg.InferentiaSupportEnabled && container.RequireNeuronRuntime() { - seelog.Debugf("Setting runtime as %s for container %s", neuronRuntime, container.Name) + logger.Debug("Setting runtime for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "runTime": neuronRuntime, + }) hostCfg.Runtime = neuronRuntime } return nil @@ -1556,8 +1625,11 @@ func (task *Task) getDockerResources(container *apicontainer.Container, cfg *con // Convert MB to B and set Memory dockerMem := int64(container.Memory * 1024 * 1024) if dockerMem != 0 && dockerMem < apicontainer.DockerContainerMinimumMemoryInBytes { - seelog.Warnf("Task %s container %s memory setting is too low, increasing to %d bytes", - task.Arn, container.Name, apicontainer.DockerContainerMinimumMemoryInBytes) + logger.Warn("Memory setting too low for container, increasing to minimum", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "bytes": apicontainer.DockerContainerMinimumMemoryInBytes, + }) dockerMem = apicontainer.DockerContainerMinimumMemoryInBytes } // Set CPUShares @@ -1607,14 +1679,18 @@ func (task *Task) shouldOverrideNetworkMode(container *apicontainer.Container, d } } if pauseContName == "" { - seelog.Critical("Pause container required, but not found in the task: %s", task.String()) + logger.Critical("Pause container required, but not found in the task", logger.Fields{ + field.TaskID: task.GetID(), + }) return false, "" } pauseContainer, ok := dockerContainerMap[pauseContName] if !ok || pauseContainer == nil { // This should never be the case and implies a code-bug. - seelog.Criticalf("Pause container required, but not found in container map for container: [%s] in task: %s", - container.String(), task.String()) + logger.Critical("Pause container required, but not found in container map", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) return false, "" } return true, dockerMappingContainerPrefix + pauseContainer.DockerID @@ -1704,14 +1780,18 @@ func (task *Task) shouldOverridePIDMode(container *apicontainer.Container, docke case pidModeTask: pauseCont, ok := task.ContainerByName(NamespacePauseContainerName) if !ok { - seelog.Criticalf("Namespace Pause container not found in the task: %s; Setting Task's Desired Status to Stopped", task.Arn) + logger.Critical("Namespace Pause container not found; stopping task", logger.Fields{ + field.TaskID: task.GetID(), + }) task.SetDesiredStatus(apitaskstatus.TaskStopped) return false, "" } pauseDockerID, ok := dockerContainerMap[pauseCont.Name] if !ok || pauseDockerID == nil { // Docker container shouldn't be nil or not exist if the Container definition within task exists; implies code-bug - seelog.Criticalf("Namespace Pause docker container not found in the task: %s; Setting Task's Desired Status to Stopped", task.Arn) + logger.Critical("Namespace Pause docker container not found; stopping task", logger.Fields{ + field.TaskID: task.GetID(), + }) task.SetDesiredStatus(apitaskstatus.TaskStopped) return false, "" } @@ -1757,14 +1837,18 @@ func (task *Task) shouldOverrideIPCMode(container *apicontainer.Container, docke case ipcModeTask: pauseCont, ok := task.ContainerByName(NamespacePauseContainerName) if !ok { - seelog.Criticalf("Namespace Pause container not found in the task: %s; Setting Task's Desired Status to Stopped", task.Arn) + logger.Critical("Namespace Pause container not found; stopping task", logger.Fields{ + field.TaskID: task.GetID(), + }) task.SetDesiredStatus(apitaskstatus.TaskStopped) return false, "" } pauseDockerID, ok := dockerContainerMap[pauseCont.Name] if !ok || pauseDockerID == nil { // Docker container shouldn't be nill or not exist if the Container definition within task exists; implies code-bug - seelog.Criticalf("Namespace Pause container not found in the task: %s; Setting Task's Desired Status to Stopped", task.Arn) + logger.Critical("Namespace Pause container not found; stopping task", logger.Fields{ + field.TaskID: task.GetID(), + }) task.SetDesiredStatus(apitaskstatus.TaskStopped) return false, "" } @@ -1823,8 +1907,11 @@ func (task *Task) dockerLinks(container *apicontainer.Container, dockerContainer if len(linkParts) == 2 { linkAlias = linkParts[1] } else { - seelog.Warnf("Link name [%s] found with no linkalias for container: [%s] in task: [%s]", - linkName, container.String(), task.String()) + logger.Warn("Link name found with no linkalias for container", logger.Fields{ + field.TaskID: task.GetID(), + "link": linkName, + field.Container: container.Name, + }) linkAlias = linkName } @@ -1883,9 +1970,13 @@ func (task *Task) dockerHostBinds(container *apicontainer.Container) ([]string, } if hv.Source() == "" || mountPoint.ContainerPath == "" { - seelog.Errorf( - "Unable to resolve volume mounts for container [%s]; invalid path: [%s]; [%s] -> [%s] in task: [%s]", - container.Name, mountPoint.SourceVolume, hv.Source(), mountPoint.ContainerPath, task.String()) + logger.Error("Unable to resolve volume mounts for container; invalid path", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Volume: mountPoint.SourceVolume, + "path": hv.Source(), + "containerPath": mountPoint.ContainerPath, + }) return []string{}, errors.Errorf("Unable to resolve volume mounts; invalid path: %s %s; %s -> %s", container.Name, mountPoint.SourceVolume, hv.Source(), mountPoint.ContainerPath) } @@ -1922,7 +2013,10 @@ func (task *Task) UpdateDesiredStatus() { // updateTaskDesiredStatusUnsafe determines what status the task should properly be at based on the containers' statuses // Invariant: task desired status must be stopped if any essential container is stopped func (task *Task) updateTaskDesiredStatusUnsafe() { - seelog.Debugf("Updating task: [%s]", task.stringUnsafe()) + logger.Debug("Updating task's desired status", logger.Fields{ + field.TaskID: task.GetID(), + field.KnownStatus: task.KnownStatusUnsafe.String(), + }) // A task's desired status is stopped if any essential container is stopped // Otherwise, the task's desired status is unchanged (typically running, but no need to change) @@ -1931,8 +2025,12 @@ func (task *Task) updateTaskDesiredStatusUnsafe() { break } if cont.Essential && (cont.KnownTerminal() || cont.DesiredTerminal()) { - seelog.Infof("api/task: Updating task desired status to stopped because of container: [%s]; task: [%s]", - cont.Name, task.stringUnsafe()) + logger.Info("Essential container stopped; updating task desired status to stopped", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Name, + field.KnownStatus: task.KnownStatusUnsafe.String(), + field.DesiredStatus: apitaskstatus.TaskStopped.String(), + }) task.DesiredStatusUnsafe = apitaskstatus.TaskStopped } } @@ -2222,22 +2320,19 @@ func (task *Task) stringUnsafe() string { // GetID is used to retrieve the taskID from taskARN // Reference: http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-ecs -func (task *Task) GetID() (string, error) { - // Parse taskARN - parsedARN, err := arn.Parse(task.Arn) - if err != nil { - return "", errors.Wrapf(err, "task get-id: malformed taskARN: %s", task.Arn) - } - - // Get task resource section - resource := parsedARN.Resource - - if !strings.Contains(resource, arnResourceDelimiter) { - return "", errors.Errorf("task get-id: malformed task resource: %s", resource) - } +func (task *Task) GetID() string { + task.setIdOnce.Do(func() { + id, err := utils.TaskIdFromArn(task.Arn) + if err != nil { + logger.Error("Error getting ID for task", logger.Fields{ + field.TaskARN: task.Arn, + field.Error: err, + }) + } + task.id = id + }) - resourceSplit := strings.Split(resource, arnResourceDelimiter) - return resourceSplit[len(resourceSplit)-1], nil + return task.id } // RecordExecutionStoppedAt checks if this is an essential container stopped @@ -2256,8 +2351,11 @@ func (task *Task) RecordExecutionStoppedAt(container *apicontainer.Container) { // ExecutionStoppedAt was already recorded. Nothing to left to do here return } - seelog.Infof("Task [%s]: recording execution stopped time. Essential container [%s] stopped at: %s", - task.Arn, container.Name, now.String()) + logger.Info("Essential container stopped; recording task stopped time", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Time: now.String(), + }) } // GetResources returns the list of task resources from ResourcesMap @@ -2286,10 +2384,11 @@ func (task *Task) AddResource(resourceType string, resource taskresource.TaskRes // SetTerminalReason sets the terminalReason string and this can only be set // once per the task's lifecycle. This field does not accept updates. func (task *Task) SetTerminalReason(reason string) { - seelog.Infof("Task [%s]: attempting to set terminal reason for task [%s]", task.Arn, reason) task.terminalReasonOnce.Do(func() { - seelog.Infof("Task [%s]: setting terminal reason for task [%s]", task.Arn, reason) - + logger.Info("Setting terminal reason for task", logger.Fields{ + field.TaskID: task.GetID(), + field.Reason: reason, + }) // Converts the first letter of terminal reason into capital letter words := strings.Fields(reason) words[0] = strings.Title(words[0]) diff --git a/agent/api/task/task_linux.go b/agent/api/task/task_linux.go index 400162682b6..d85a52ea613 100644 --- a/agent/api/task/task_linux.go +++ b/agent/api/task/task_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -20,6 +21,8 @@ import ( "path/filepath" "time" + "github.com/aws/amazon-ecs-agent/agent/utils" + apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" apieni "github.com/aws/amazon-ecs-agent/agent/api/eni" "github.com/aws/amazon-ecs-agent/agent/config" @@ -78,11 +81,10 @@ func (task *Task) initializeCgroupResourceSpec(cgroupPath string, cGroupCPUPerio // BuildCgroupRoot helps build the task cgroup prefix // Example: /ecs/task-id func (task *Task) BuildCgroupRoot() (string, error) { - taskID, err := task.GetID() + taskID, err := utils.TaskIdFromArn(task.Arn) if err != nil { - return "", errors.Wrapf(err, "task build cgroup root: unable to get task-id from task ARN: %s", task.Arn) + return "", err } - return filepath.Join(config.DefaultTaskCgroupPrefix, taskID), nil } diff --git a/agent/api/task/task_linux_test.go b/agent/api/task/task_linux_test.go index a241ee5d42f..de1c38e9667 100644 --- a/agent/api/task/task_linux_test.go +++ b/agent/api/task/task_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/task_test.go b/agent/api/task/task_test.go index bc80206ef54..2e557d868ef 100644 --- a/agent/api/task/task_test.go +++ b/agent/api/task/task_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -1640,30 +1641,6 @@ func assertSetStructFieldsEqual(t *testing.T, expected, actual interface{}) { } } -// TestGetIDErrorPaths performs table tests on GetID with erroneous taskARNs -func TestGetIDErrorPaths(t *testing.T) { - testCases := []struct { - arn string - name string - }{ - {"", "EmptyString"}, - {"invalidArn", "InvalidARN"}, - {"arn:aws:ecs:region:account-id:task:task-id", "IncorrectSections"}, - {"arn:aws:ecs:region:account-id:task", "IncorrectResourceSections"}, - } - - task := Task{} - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - task.Arn = tc.arn - taskID, err := task.GetID() - assert.Error(t, err, "GetID should return an error") - assert.Empty(t, taskID, "ID should be empty") - }) - } -} - // TestGetIDHappyPath validates the happy path of GetID func TestGetIDHappyPath(t *testing.T) { taskNormalARN := Task{ @@ -1673,14 +1650,11 @@ func TestGetIDHappyPath(t *testing.T) { Arn: "arn:aws:ecs:region:account-id:task/cluster-name/task-id", } - taskID, err := taskNormalARN.GetID() - assert.NoError(t, err) + taskID := taskNormalARN.GetID() assert.Equal(t, "task-id", taskID) - taskID, err = taskLongARN.GetID() - assert.NoError(t, err) + taskID = taskLongARN.GetID() assert.Equal(t, "task-id", taskID) - } // TestTaskGetPrimaryENI tests the eni can be correctly acquired by calling GetTaskPrimaryENI diff --git a/agent/api/task/task_test_utils.go b/agent/api/task/task_test_utils.go index 66707a2b5c1..d8c3ec97012 100644 --- a/agent/api/task/task_test_utils.go +++ b/agent/api/task/task_test_utils.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/task_unsupported.go b/agent/api/task/task_unsupported.go index 33c3636e9ff..8ea6cb31cfe 100644 --- a/agent/api/task/task_unsupported.go +++ b/agent/api/task/task_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/task_windows.go b/agent/api/task/task_windows.go index 766a48555d8..178049dac56 100644 --- a/agent/api/task/task_windows.go +++ b/agent/api/task/task_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/task_windows_test.go b/agent/api/task/task_windows_test.go index cde35b42024..78e8122f933 100644 --- a/agent/api/task/task_windows_test.go +++ b/agent/api/task/task_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/taskvolume_test.go b/agent/api/task/taskvolume_test.go index dac7a2bffaf..737dd8e1342 100644 --- a/agent/api/task/taskvolume_test.go +++ b/agent/api/task/taskvolume_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/taskvolume_windows_test.go b/agent/api/task/taskvolume_windows_test.go index b85bcb44489..2d02669b15d 100644 --- a/agent/api/task/taskvolume_windows_test.go +++ b/agent/api/task/taskvolume_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/types_unmarshal_test.go b/agent/api/task/types_unmarshal_test.go index 04890be8890..bd2c3d069a8 100644 --- a/agent/api/task/types_unmarshal_test.go +++ b/agent/api/task/types_unmarshal_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/task/util_test.go b/agent/api/task/util_test.go index 1b17240e443..8c440971b8b 100644 --- a/agent/api/task/util_test.go +++ b/agent/api/task/util_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/testutils/container_equal_test.go b/agent/api/testutils/container_equal_test.go index b1162560bb0..5e7a90e58b8 100644 --- a/agent/api/testutils/container_equal_test.go +++ b/agent/api/testutils/container_equal_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/api/testutils/task_equal_test.go b/agent/api/testutils/task_equal_test.go index 069e583e0bf..68300334d30 100644 --- a/agent/api/testutils/task_equal_test.go +++ b/agent/api/testutils/task_equal_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent.go b/agent/app/agent.go index bfe71daa52a..91658edcd14 100644 --- a/agent/app/agent.go +++ b/agent/app/agent.go @@ -20,6 +20,9 @@ import ( "fmt" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/aws/amazon-ecs-agent/agent/doctor" "github.com/aws/amazon-ecs-agent/agent/eni/watcher" "github.com/aws/aws-sdk-go/aws/awserr" @@ -151,8 +154,11 @@ func newAgent(blackholeEC2Metadata bool, acceptInsecureCert *bool) (agent, error if blackholeEC2Metadata { ec2MetadataClient = ec2.NewBlackholeEC2MetadataClient() } - - seelog.Info("Loading configuration") + logger.Info("Starting Amazon ECS Agent", logger.Fields{ + "version": version.Version, + "commit": version.GitShortHash, + }) + logger.Info("Loading configuration") cfg, err := config.NewConfig(ec2MetadataClient) if err != nil { // All required config values can be inferred from EC2 Metadata, @@ -165,11 +171,10 @@ func newAgent(blackholeEC2Metadata bool, acceptInsecureCert *bool) (agent, error if cfg.AcceptInsecureCert { seelog.Warn("SSL certificate verification disabled. This is not recommended.") } - seelog.Infof("Amazon ECS agent Version: %s, Commit: %s", version.Version, version.GitShortHash) seelog.Debugf("Loaded config: %s", cfg.String()) if cfg.External.Enabled() { - seelog.Info("Running in external mode.") + logger.Info("ECS Agent is running in external mode.") ec2MetadataClient = ec2.NewBlackholeEC2MetadataClient() cfg.NoIID = true } @@ -179,7 +184,9 @@ func newAgent(blackholeEC2Metadata bool, acceptInsecureCert *bool) (agent, error if err != nil { // This is also non terminal in the current config - seelog.Criticalf("Error creating Docker client: %v", err) + logger.Critical("Error creating Docker client", logger.Fields{ + field.Error: err, + }) cancel() return nil, err } @@ -188,7 +195,9 @@ func newAgent(blackholeEC2Metadata bool, acceptInsecureCert *bool) (agent, error if cfg.Checkpoint.Enabled() { dataClient, err = data.New(cfg.DataDir) if err != nil { - seelog.Criticalf("Error creating data client: %v", err) + logger.Critical("Error creating Docker client", logger.Fields{ + field.Error: err, + }) cancel() return nil, err } @@ -572,11 +581,17 @@ func (agent *ecsAgent) setClusterInConfig(previousCluster string) error { err := clusterMismatchError{ fmt.Errorf(clusterMismatchErrorFormat, previousCluster, configuredCluster), } - seelog.Criticalf("%v", err) + logger.Critical("Error restoring cluster", logger.Fields{ + "previousCluster": previousCluster, + "configuredCluster": configuredCluster, + field.Error: err, + }) return err } agent.cfg.Cluster = previousCluster - seelog.Infof("Restored cluster '%s'", agent.cfg.Cluster) + logger.Info("Cluster was successfully restored", logger.Fields{ + "cluster": agent.cfg.Cluster, + }) return nil } @@ -596,8 +611,9 @@ func (agent *ecsAgent) getEC2InstanceID() string { } } if err != nil { - seelog.Warnf( - "Unable to access EC2 Metadata service to determine EC2 ID: %v", err) + logger.Warn("Unable to access EC2 Metadata service to determine EC2 ID", logger.Fields{ + field.Error: err, + }) } return instanceID } @@ -687,20 +703,27 @@ func (agent *ecsAgent) registerContainerInstance( outpostARN := agent.getoutpostARN() if agent.containerInstanceARN != "" { - seelog.Infof("Restored from checkpoint file. I am running as '%s' in cluster '%s'", agent.containerInstanceARN, agent.cfg.Cluster) + logger.Info("Restored from checkpoint file", logger.Fields{ + "containerInstanceARN": agent.containerInstanceARN, + "cluster": agent.cfg.Cluster, + }) return agent.reregisterContainerInstance(client, capabilities, tags, uuid.New(), platformDevices, outpostARN) } - seelog.Info("Registering Instance with ECS") + logger.Info("Registering Instance with ECS") containerInstanceArn, availabilityZone, err := client.RegisterContainerInstance("", capabilities, tags, uuid.New(), platformDevices, outpostARN) if err != nil { - seelog.Errorf("Error registering: %v", err) + logger.Error("Error registering container instance", logger.Fields{ + field.Error: err, + }) if retriable, ok := err.(apierrors.Retriable); ok && !retriable.Retry() { return err } if utils.IsAWSErrorCodeEqual(err, ecs.ErrCodeInvalidParameterException) { - seelog.Critical("Instance registration attempt with an invalid parameter") + logger.Critical("Instance registration attempt with an invalid parameter", logger.Fields{ + field.Error: err, + }) return err } if _, ok := err.(apierrors.AttributeError); ok { @@ -708,12 +731,17 @@ func (agent *ecsAgent) registerContainerInstance( if len(agent.cfg.InstanceAttributes) > 0 { attributeErrorMsg = customAttributeErrorMessage } - seelog.Critical("Instance registration attempt with invalid attribute(s)." + attributeErrorMsg) + logger.Critical("Instance registration attempt with invalid attribute(s)", logger.Fields{ + field.Error: attributeErrorMsg, + }) return err } return transientError{err} } - seelog.Infof("Registration completed successfully. I am running as '%s' in cluster '%s'", containerInstanceArn, agent.cfg.Cluster) + logger.Info("Instance registration completed successfully", logger.Fields{ + "instanceArn": containerInstanceArn, + "cluster": agent.cfg.Cluster, + }) agent.containerInstanceARN = containerInstanceArn agent.availabilityZone = availabilityZone return nil @@ -733,7 +761,9 @@ func (agent *ecsAgent) reregisterContainerInstance(client api.ECSClient, capabil if err == nil { return nil } - seelog.Errorf("Error re-registering: %v", err) + logger.Error("Error re-registering container instance", logger.Fields{ + field.Error: err, + }) if apierrors.IsInstanceTypeChangedError(err) { seelog.Criticalf(instanceTypeMismatchErrorFormat, err) return err @@ -743,7 +773,9 @@ func (agent *ecsAgent) reregisterContainerInstance(client api.ECSClient, capabil if len(agent.cfg.InstanceAttributes) > 0 { attributeErrorMsg = customAttributeErrorMessage } - seelog.Critical("Instance re-registration attempt with invalid attribute(s)." + attributeErrorMsg) + logger.Critical("Instance re-registration attempt with invalid attribute(s)", logger.Fields{ + field.Error: attributeErrorMsg, + }) return err } return transientError{err} diff --git a/agent/app/agent_capability_test.go b/agent/app/agent_capability_test.go index 0753f3910c7..a0e558e6dae 100644 --- a/agent/app/agent_capability_test.go +++ b/agent/app/agent_capability_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_capability_unix.go b/agent/app/agent_capability_unix.go index b7fed896c07..f7c2b318f5c 100644 --- a/agent/app/agent_capability_unix.go +++ b/agent/app/agent_capability_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_capability_unix_test.go b/agent/app/agent_capability_unix_test.go index 98f281d7c39..fc476506f68 100644 --- a/agent/app/agent_capability_unix_test.go +++ b/agent/app/agent_capability_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_capability_unspecified.go b/agent/app/agent_capability_unspecified.go index 28cfb80d45a..de0c37f8858 100644 --- a/agent/app/agent_capability_unspecified.go +++ b/agent/app/agent_capability_unspecified.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_capability_windows.go b/agent/app/agent_capability_windows.go index 99225922e2a..749b0c3a6a5 100644 --- a/agent/app/agent_capability_windows.go +++ b/agent/app/agent_capability_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_capability_windows_test.go b/agent/app/agent_capability_windows_test.go index 747a4db32f1..c5568537c95 100644 --- a/agent/app/agent_capability_windows_test.go +++ b/agent/app/agent_capability_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_compatibility_linux.go b/agent/app/agent_compatibility_linux.go index 4c493ff1b14..716b91f8db9 100644 --- a/agent/app/agent_compatibility_linux.go +++ b/agent/app/agent_compatibility_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_compatibility_linux_test.go b/agent/app/agent_compatibility_linux_test.go index f20c4af0f9f..d1ef20e9032 100644 --- a/agent/app/agent_compatibility_linux_test.go +++ b/agent/app/agent_compatibility_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_compatibility_unspecified.go b/agent/app/agent_compatibility_unspecified.go index dce18e76689..0911e725f29 100644 --- a/agent/app/agent_compatibility_unspecified.go +++ b/agent/app/agent_compatibility_unspecified.go @@ -1,4 +1,5 @@ //go:build !linux +// +build !linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_integ_test.go b/agent/app/agent_integ_test.go index a158a739b88..416b10771b7 100644 --- a/agent/app/agent_integ_test.go +++ b/agent/app/agent_integ_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_test.go b/agent/app/agent_test.go index 79210cb8569..8b488c3c18d 100644 --- a/agent/app/agent_test.go +++ b/agent/app/agent_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_unix.go b/agent/app/agent_unix.go index 9dda0d1bf50..8858bcee32d 100644 --- a/agent/app/agent_unix.go +++ b/agent/app/agent_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_unix_test.go b/agent/app/agent_unix_test.go index 25933a72653..e67d49f321d 100644 --- a/agent/app/agent_unix_test.go +++ b/agent/app/agent_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_unspecified.go b/agent/app/agent_unspecified.go index 34bf5d351fa..876bfefd6a5 100644 --- a/agent/app/agent_unspecified.go +++ b/agent/app/agent_unspecified.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_windows.go b/agent/app/agent_windows.go index 5f1421e5221..673736a1c04 100644 --- a/agent/app/agent_windows.go +++ b/agent/app/agent_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/agent_windows_test.go b/agent/app/agent_windows_test.go index 55952d01cd6..fa71c244cc1 100644 --- a/agent/app/agent_windows_test.go +++ b/agent/app/agent_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/app/data_test.go b/agent/app/data_test.go index d201f49e2f5..db9c88be865 100644 --- a/agent/app/data_test.go +++ b/agent/app/data_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/asm/asm_test.go b/agent/asm/asm_test.go index d3e18bfd12a..95bb3cfc0cf 100644 --- a/agent/asm/asm_test.go +++ b/agent/asm/asm_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/async/lru_cache_test.go b/agent/async/lru_cache_test.go index 12591307ffc..7e863acd00d 100644 --- a/agent/async/lru_cache_test.go +++ b/agent/async/lru_cache_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/conditional_test.go b/agent/config/conditional_test.go index 601bf94e1fb..e9cda03b300 100644 --- a/agent/config/conditional_test.go +++ b/agent/config/conditional_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/config_test.go b/agent/config/config_test.go index c2d14738364..f6b92f0c036 100644 --- a/agent/config/config_test.go +++ b/agent/config/config_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/config_unix.go b/agent/config/config_unix.go index 506c67f7fa8..f70efc0d0b3 100644 --- a/agent/config/config_unix.go +++ b/agent/config/config_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/config_unix_test.go b/agent/config/config_unix_test.go index d39a0966082..e35d9bbf0e3 100644 --- a/agent/config/config_unix_test.go +++ b/agent/config/config_unix_test.go @@ -1,4 +1,5 @@ //go:build !windows && unit +// +build !windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/config_windows.go b/agent/config/config_windows.go index 181c9545af9..d35ec9606f4 100644 --- a/agent/config/config_windows.go +++ b/agent/config/config_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/config_windows_test.go b/agent/config/config_windows_test.go index f4ad9898178..f2c4a323678 100644 --- a/agent/config/config_windows_test.go +++ b/agent/config/config_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/const_linux.go b/agent/config/const_linux.go index 2b9289e1dde..1ea8885bbbd 100644 --- a/agent/config/const_linux.go +++ b/agent/config/const_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/const_unknown.go b/agent/config/const_unknown.go index 37f31d03e76..53841f47eec 100644 --- a/agent/config/const_unknown.go +++ b/agent/config/const_unknown.go @@ -1,4 +1,5 @@ //go:build !windows && !linux +// +build !windows,!linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/const_windows.go b/agent/config/const_windows.go index 71ab60ced9c..3606476fbaf 100644 --- a/agent/config/const_windows.go +++ b/agent/config/const_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/os_family_windows.go b/agent/config/os_family_windows.go index 5bc773a7ce9..d7b2218d849 100644 --- a/agent/config/os_family_windows.go +++ b/agent/config/os_family_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/os_family_windows_test.go b/agent/config/os_family_windows_test.go index 68e14f16f5c..9b6208cd9bb 100644 --- a/agent/config/os_family_windows_test.go +++ b/agent/config/os_family_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/parse_linux.go b/agent/config/parse_linux.go index 255163decb8..5ab45d3cf1e 100644 --- a/agent/config/parse_linux.go +++ b/agent/config/parse_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/parse_unsupported.go b/agent/config/parse_unsupported.go index 732fae352b3..45d711563a8 100644 --- a/agent/config/parse_unsupported.go +++ b/agent/config/parse_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/parse_windows.go b/agent/config/parse_windows.go index fbdc2ade0ec..6040cb5d27c 100644 --- a/agent/config/parse_windows.go +++ b/agent/config/parse_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/parse_windows_test.go b/agent/config/parse_windows_test.go index 618ae726d0a..d4604840555 100644 --- a/agent/config/parse_windows_test.go +++ b/agent/config/parse_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/sensitive_test.go b/agent/config/sensitive_test.go index a5c00fe66da..f0f13b2a01b 100644 --- a/agent/config/sensitive_test.go +++ b/agent/config/sensitive_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/types_unix.go b/agent/config/types_unix.go index 887e35ea535..164fa4aaaf2 100644 --- a/agent/config/types_unix.go +++ b/agent/config/types_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/config/types_windows.go b/agent/config/types_windows.go index 90ca8b250c6..df04eedac0f 100644 --- a/agent/config/types_windows.go +++ b/agent/config/types_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/manager_test.go b/agent/containermetadata/manager_test.go index cfb1f7b1bed..737dbf55042 100644 --- a/agent/containermetadata/manager_test.go +++ b/agent/containermetadata/manager_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/manager_unix_test.go b/agent/containermetadata/manager_unix_test.go index 2c787e401a0..ad3399ccf35 100644 --- a/agent/containermetadata/manager_unix_test.go +++ b/agent/containermetadata/manager_unix_test.go @@ -1,4 +1,5 @@ //go:build unit && !windows +// +build unit,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/manager_windows_test.go b/agent/containermetadata/manager_windows_test.go index 8174b4a0e07..296f5621341 100644 --- a/agent/containermetadata/manager_windows_test.go +++ b/agent/containermetadata/manager_windows_test.go @@ -1,4 +1,5 @@ //go:build unit && windows +// +build unit,windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/parse_metadata_test.go b/agent/containermetadata/parse_metadata_test.go index 73770de927d..7a3357f7b9b 100644 --- a/agent/containermetadata/parse_metadata_test.go +++ b/agent/containermetadata/parse_metadata_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/types_test.go b/agent/containermetadata/types_test.go index 12b25486d12..5aebbd84bbf 100644 --- a/agent/containermetadata/types_test.go +++ b/agent/containermetadata/types_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/utils_test.go b/agent/containermetadata/utils_test.go index dba39d36984..df3ad60c291 100644 --- a/agent/containermetadata/utils_test.go +++ b/agent/containermetadata/utils_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/write_metadata_test.go b/agent/containermetadata/write_metadata_test.go index b3ab5e0b745..adeeb1c8378 100644 --- a/agent/containermetadata/write_metadata_test.go +++ b/agent/containermetadata/write_metadata_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/write_metadata_unix.go b/agent/containermetadata/write_metadata_unix.go index d3b32ddef94..1c9e799034f 100644 --- a/agent/containermetadata/write_metadata_unix.go +++ b/agent/containermetadata/write_metadata_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/write_metadata_unix_test.go b/agent/containermetadata/write_metadata_unix_test.go index 9603e71f8fa..5d6eb54e90d 100644 --- a/agent/containermetadata/write_metadata_unix_test.go +++ b/agent/containermetadata/write_metadata_unix_test.go @@ -1,4 +1,5 @@ //go:build unit && !windows +// +build unit,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/write_metadata_windows.go b/agent/containermetadata/write_metadata_windows.go index 357ff630657..85efa3c672a 100644 --- a/agent/containermetadata/write_metadata_windows.go +++ b/agent/containermetadata/write_metadata_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/containermetadata/write_metadata_windows_test.go b/agent/containermetadata/write_metadata_windows_test.go index 2e86c31bf3d..3a906b3d768 100644 --- a/agent/containermetadata/write_metadata_windows_test.go +++ b/agent/containermetadata/write_metadata_windows_test.go @@ -1,4 +1,5 @@ //go:build unit && windows +// +build unit,windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/credentials/instancecreds/instancecreds_test.go b/agent/credentials/instancecreds/instancecreds_test.go index 4c4f6428645..7632faa2480 100644 --- a/agent/credentials/instancecreds/instancecreds_test.go +++ b/agent/credentials/instancecreds/instancecreds_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/credentials/manager_test.go b/agent/credentials/manager_test.go index b30284c0980..40f3ca75fc1 100644 --- a/agent/credentials/manager_test.go +++ b/agent/credentials/manager_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/credentials/providers/rotating_shared_credentials_provider_test.go b/agent/credentials/providers/rotating_shared_credentials_provider_test.go index 404701cfec3..246adc669bc 100644 --- a/agent/credentials/providers/rotating_shared_credentials_provider_test.go +++ b/agent/credentials/providers/rotating_shared_credentials_provider_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/client_test.go b/agent/data/client_test.go index 27b8a399139..ab5d0d918cb 100644 --- a/agent/data/client_test.go +++ b/agent/data/client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/container_client_test.go b/agent/data/container_client_test.go index 9d1c325cbe8..cd11908adf8 100644 --- a/agent/data/container_client_test.go +++ b/agent/data/container_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/eniattachment_client_test.go b/agent/data/eniattachment_client_test.go index 58fbd80a56b..cac248e8de1 100644 --- a/agent/data/eniattachment_client_test.go +++ b/agent/data/eniattachment_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/helpers_test.go b/agent/data/helpers_test.go index efae4878b04..fad4799a35b 100644 --- a/agent/data/helpers_test.go +++ b/agent/data/helpers_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/imagestate_client_test.go b/agent/data/imagestate_client_test.go index c5ddaacb5aa..696191314f6 100644 --- a/agent/data/imagestate_client_test.go +++ b/agent/data/imagestate_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/metadata_client_test.go b/agent/data/metadata_client_test.go index 6d5b32721a9..f9a6b754548 100644 --- a/agent/data/metadata_client_test.go +++ b/agent/data/metadata_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/data/task_client_test.go b/agent/data/task_client_test.go index 5134b1edad4..6d72782764c 100644 --- a/agent/data/task_client_test.go +++ b/agent/data/task_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerapi/docker_client.go b/agent/dockerclient/dockerapi/docker_client.go index e014ceaa81b..c5781393666 100644 --- a/agent/dockerclient/dockerapi/docker_client.go +++ b/agent/dockerclient/dockerapi/docker_client.go @@ -28,6 +28,9 @@ import ( "sync/atomic" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" apierrors "github.com/aws/amazon-ecs-agent/agent/api/errors" @@ -1414,7 +1417,9 @@ func (dg *dockerGoClient) Stats(ctx context.Context, id string, inactivityTimeou var resp types.ContainerStats if !dg.config.PollMetrics.Enabled() { // Streaming metrics is the default behavior - seelog.Infof("DockerGoClient: Starting streaming metrics for container %s", id) + logger.Info("Start streaming metrics for container", logger.Fields{ + field.RuntimeID: id, + }) go func() { defer cancelRequest() defer close(statsC) diff --git a/agent/dockerclient/dockerapi/docker_client_test.go b/agent/dockerclient/dockerapi/docker_client_test.go index 49a09232e9f..2442e971266 100644 --- a/agent/dockerclient/dockerapi/docker_client_test.go +++ b/agent/dockerclient/dockerapi/docker_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerapi/docker_events_buffer_test.go b/agent/dockerclient/dockerapi/docker_events_buffer_test.go index 1f9042fdda4..4ca0003f736 100644 --- a/agent/dockerclient/dockerapi/docker_events_buffer_test.go +++ b/agent/dockerclient/dockerapi/docker_events_buffer_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerapi/errors_test.go b/agent/dockerclient/dockerapi/errors_test.go index 6aa593750bf..1bdd65a15fb 100644 --- a/agent/dockerclient/dockerapi/errors_test.go +++ b/agent/dockerclient/dockerapi/errors_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerapi/inactivity_timeout_handler_test.go b/agent/dockerclient/dockerapi/inactivity_timeout_handler_test.go index 4fb9e5b2e06..eaea8ec1bfc 100644 --- a/agent/dockerclient/dockerapi/inactivity_timeout_handler_test.go +++ b/agent/dockerclient/dockerapi/inactivity_timeout_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerapi_compare_versions_test.go b/agent/dockerclient/dockerapi_compare_versions_test.go index 792e4b94992..46e077ef9a3 100644 --- a/agent/dockerclient/dockerapi_compare_versions_test.go +++ b/agent/dockerclient/dockerapi_compare_versions_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerauth/dockerauth_test.go b/agent/dockerclient/dockerauth/dockerauth_test.go index f8fa5072537..f1d9fb01749 100644 --- a/agent/dockerclient/dockerauth/dockerauth_test.go +++ b/agent/dockerclient/dockerauth/dockerauth_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/dockerauth/ecr_test.go b/agent/dockerclient/dockerauth/ecr_test.go index 2f6ca9786a6..d394421dcbe 100644 --- a/agent/dockerclient/dockerauth/ecr_test.go +++ b/agent/dockerclient/dockerauth/ecr_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/sdkclientfactory/sdkclientfactory_test.go b/agent/dockerclient/sdkclientfactory/sdkclientfactory_test.go index e983af5fbe2..bc6664d6d77 100644 --- a/agent/dockerclient/sdkclientfactory/sdkclientfactory_test.go +++ b/agent/dockerclient/sdkclientfactory/sdkclientfactory_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/sdkclientfactory/sdkclientfactory_unix_test.go b/agent/dockerclient/sdkclientfactory/sdkclientfactory_unix_test.go index 82d4732fe93..4c88e87101a 100644 --- a/agent/dockerclient/sdkclientfactory/sdkclientfactory_unix_test.go +++ b/agent/dockerclient/sdkclientfactory/sdkclientfactory_unix_test.go @@ -1,4 +1,5 @@ //go:build unit && !windows +// +build unit,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/sdkclientfactory/sdkclientfactory_windows_test.go b/agent/dockerclient/sdkclientfactory/sdkclientfactory_windows_test.go index 3c0effd4137..23aba519006 100644 --- a/agent/dockerclient/sdkclientfactory/sdkclientfactory_windows_test.go +++ b/agent/dockerclient/sdkclientfactory/sdkclientfactory_windows_test.go @@ -1,4 +1,5 @@ //go:build unit && windows +// +build unit,windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/sdkclientfactory/versionsupport_unix.go b/agent/dockerclient/sdkclientfactory/versionsupport_unix.go index 884dc94c40b..9117a7d7290 100644 --- a/agent/dockerclient/sdkclientfactory/versionsupport_unix.go +++ b/agent/dockerclient/sdkclientfactory/versionsupport_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/dockerclient/sdkclientfactory/versionsupport_windows.go b/agent/dockerclient/sdkclientfactory/versionsupport_windows.go index 5857b085295..afc83054a2b 100644 --- a/agent/dockerclient/sdkclientfactory/versionsupport_windows.go +++ b/agent/dockerclient/sdkclientfactory/versionsupport_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ec2/ec2_client_test.go b/agent/ec2/ec2_client_test.go index 089b487a06b..00ed5d5c92a 100644 --- a/agent/ec2/ec2_client_test.go +++ b/agent/ec2/ec2_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ec2/ec2_metadata_client_test.go b/agent/ec2/ec2_metadata_client_test.go index ed87ad10064..d583e368d9b 100644 --- a/agent/ec2/ec2_metadata_client_test.go +++ b/agent/ec2/ec2_metadata_client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecr/client_test.go b/agent/ecr/client_test.go index d56d833236d..17e729b6cac 100644 --- a/agent/ecr/client_test.go +++ b/agent/ecr/client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecr/factory_test.go b/agent/ecr/factory_test.go index 5eac709a5f6..324ec90e8df 100644 --- a/agent/ecr/factory_test.go +++ b/agent/ecr/factory_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/namespace_helper_linux.go b/agent/ecscni/namespace_helper_linux.go index ff508cfd274..7f4479ef012 100644 --- a/agent/ecscni/namespace_helper_linux.go +++ b/agent/ecscni/namespace_helper_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/namespace_helper_unsupported.go b/agent/ecscni/namespace_helper_unsupported.go index 19d5666de45..bc10fce10eb 100644 --- a/agent/ecscni/namespace_helper_unsupported.go +++ b/agent/ecscni/namespace_helper_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/namespace_helper_windows.go b/agent/ecscni/namespace_helper_windows.go index 763dcc4a306..a552e148738 100644 --- a/agent/ecscni/namespace_helper_windows.go +++ b/agent/ecscni/namespace_helper_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/namespace_helper_windows_test.go b/agent/ecscni/namespace_helper_windows_test.go index 8d4300178b7..a777d39a19b 100644 --- a/agent/ecscni/namespace_helper_windows_test.go +++ b/agent/ecscni/namespace_helper_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/netconfig_linux.go b/agent/ecscni/netconfig_linux.go index b9596d97f5b..283e8a689db 100644 --- a/agent/ecscni/netconfig_linux.go +++ b/agent/ecscni/netconfig_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/netconfig_windows.go b/agent/ecscni/netconfig_windows.go index 2949379f78d..4d266d7e9a1 100644 --- a/agent/ecscni/netconfig_windows.go +++ b/agent/ecscni/netconfig_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/netconfig_windows_test.go b/agent/ecscni/netconfig_windows_test.go index 86a35953dd3..4f81fa9b6fa 100644 --- a/agent/ecscni/netconfig_windows_test.go +++ b/agent/ecscni/netconfig_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_linux.go b/agent/ecscni/plugin_linux.go index df9f86c8c65..aa56d0a6f2a 100644 --- a/agent/ecscni/plugin_linux.go +++ b/agent/ecscni/plugin_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_linux_test.go b/agent/ecscni/plugin_linux_test.go index e7744fa6073..be2e0efcd9c 100644 --- a/agent/ecscni/plugin_linux_test.go +++ b/agent/ecscni/plugin_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_test.go b/agent/ecscni/plugin_test.go index 963b5eebdd1..764220f3a94 100644 --- a/agent/ecscni/plugin_test.go +++ b/agent/ecscni/plugin_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_unsupported.go b/agent/ecscni/plugin_unsupported.go index 67b2ba87548..e156b75c03e 100644 --- a/agent/ecscni/plugin_unsupported.go +++ b/agent/ecscni/plugin_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_windows.go b/agent/ecscni/plugin_windows.go index 948715e9542..4aed39d1b3e 100644 --- a/agent/ecscni/plugin_windows.go +++ b/agent/ecscni/plugin_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/plugin_windows_test.go b/agent/ecscni/plugin_windows_test.go index e82541f7ff5..04420ba7a7b 100644 --- a/agent/ecscni/plugin_windows_test.go +++ b/agent/ecscni/plugin_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/types_linux.go b/agent/ecscni/types_linux.go index 1a07be23e0b..2ad65834acd 100644 --- a/agent/ecscni/types_linux.go +++ b/agent/ecscni/types_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ecscni/types_windows.go b/agent/ecscni/types_windows.go index 61871805a1b..4a2218f255b 100644 --- a/agent/ecscni/types_windows.go +++ b/agent/ecscni/types_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/common_integ_test.go b/agent/engine/common_integ_test.go index 1e6b65ec522..73d9c7e4893 100644 --- a/agent/engine/common_integ_test.go +++ b/agent/engine/common_integ_test.go @@ -1,4 +1,5 @@ //go:build sudo || integration +// +build sudo integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/common_test.go b/agent/engine/common_test.go index b6945e04248..5e160117e50 100644 --- a/agent/engine/common_test.go +++ b/agent/engine/common_test.go @@ -252,7 +252,6 @@ func addTaskToEngine(t *testing.T, taskEngine.AddTask(sleepTask) waitForRunningEvents(t, taskEngine.StateChangeEvents()) - // Wait for all events to be consumed prior to moving it towards stopped; we // don't want to race the below with these or we'll end up with the "going // backwards in state" stop and we haven't 'expect'd for that diff --git a/agent/engine/common_unix_integ_test.go b/agent/engine/common_unix_integ_test.go index 53d81706003..0b83295f7a6 100644 --- a/agent/engine/common_unix_integ_test.go +++ b/agent/engine/common_unix_integ_test.go @@ -1,4 +1,6 @@ //go:build linux && (sudo || integration) +// +build linux +// +build sudo integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/data_test.go b/agent/engine/data_test.go index 7b29e975632..049c190d31e 100644 --- a/agent/engine/data_test.go +++ b/agent/engine/data_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/dependencygraph/graph_test.go b/agent/engine/dependencygraph/graph_test.go index bf3fad7a446..af6d8d218f4 100644 --- a/agent/engine/dependencygraph/graph_test.go +++ b/agent/engine/dependencygraph/graph_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/dependencygraph/graph_unix_test.go b/agent/engine/dependencygraph/graph_unix_test.go index b777d4bec77..0c173e59e0e 100644 --- a/agent/engine/dependencygraph/graph_unix_test.go +++ b/agent/engine/dependencygraph/graph_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_image_manager.go b/agent/engine/docker_image_manager.go index 3031cbbadef..77b8ae94903 100644 --- a/agent/engine/docker_image_manager.go +++ b/agent/engine/docker_image_manager.go @@ -21,6 +21,9 @@ import ( "sync" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/docker/docker/api/types" apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" @@ -102,7 +105,9 @@ func buildImageCleanupExclusionList(cfg *config.Config) []string { config.CachedImageNameAgentContainer, ) for _, image := range excludedImages { - seelog.Infof("Image excluded from cleanup: %s", image) + logger.Info("Image excluded from cleanup", logger.Fields{ + field.Image: image, + }) } return excludedImages } diff --git a/agent/engine/docker_image_manager_data_test.go b/agent/engine/docker_image_manager_data_test.go index 05354ec8ae5..d322d52f16f 100644 --- a/agent/engine/docker_image_manager_data_test.go +++ b/agent/engine/docker_image_manager_data_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_image_manager_integ_test.go b/agent/engine/docker_image_manager_integ_test.go index 1cd64a07e1a..bea1debe9b3 100644 --- a/agent/engine/docker_image_manager_integ_test.go +++ b/agent/engine/docker_image_manager_integ_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_image_manager_test.go b/agent/engine/docker_image_manager_test.go index 06662ea9d59..91ca9a9e601 100644 --- a/agent/engine/docker_image_manager_test.go +++ b/agent/engine/docker_image_manager_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_image_manager_unix_integ_test.go b/agent/engine/docker_image_manager_unix_integ_test.go index 849b9127d04..b9871ebb01e 100644 --- a/agent/engine/docker_image_manager_unix_integ_test.go +++ b/agent/engine/docker_image_manager_unix_integ_test.go @@ -1,4 +1,5 @@ //go:build !windows && integration +// +build !windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_image_manager_windows_integ_test.go b/agent/engine/docker_image_manager_windows_integ_test.go index cade220651e..77a53c7c735 100644 --- a/agent/engine/docker_image_manager_windows_integ_test.go +++ b/agent/engine/docker_image_manager_windows_integ_test.go @@ -1,4 +1,5 @@ //go:build windows && integration +// +build windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_task_engine.go b/agent/engine/docker_task_engine.go index 5bcb48209b6..69d1e2d0d41 100644 --- a/agent/engine/docker_task_engine.go +++ b/agent/engine/docker_task_engine.go @@ -25,6 +25,8 @@ import ( "sync" "time" + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/amazon-ecs-agent/agent/logger" "github.com/aws/amazon-ecs-agent/agent/logger/field" @@ -56,7 +58,6 @@ import ( "github.com/aws/amazon-ecs-agent/agent/utils/ttime" dockercontainer "github.com/docker/docker/api/types/container" - "github.com/cihub/seelog" "github.com/docker/docker/api/types" "github.com/pkg/errors" ) @@ -319,7 +320,10 @@ func (engine *DockerTaskEngine) monitorExecAgentRunning(ctx context.Context, task := mTask.Task dockerID, err := engine.getDockerID(task, c) if err != nil { - seelog.Errorf("Task engine [%s]: Could not retrieve docker id for container", task.Arn) + logger.Error("Could not retrieve docker id for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: c.Name, + }) return } // Sleeping here so that all the containers do not call inspect/start exec agent process @@ -330,7 +334,12 @@ func (engine *DockerTaskEngine) monitorExecAgentRunning(ctx context.Context, time.Sleep(retry.AddJitter(time.Nanosecond, engine.monitorExecAgentsInterval/2)) status, err := engine.execCmdMgr.RestartAgentIfStopped(ctx, engine.client, task, c, dockerID) if err != nil { - seelog.Errorf("Task engine [%s]: Failed to restart ExecCommandAgent Process for container [%s]: %v", task.Arn, dockerID, err) + logger.Error("Failed to restart ExecCommandAgent Process for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: c.Name, + field.DockerId: dockerID, + field.Error: err, + }) mTask.emitManagedAgentEvent(mTask.Task, c, execcmd.ExecuteCommandAgentName, "ExecuteCommandAgent cannot be restarted") } if status == execcmd.Restarted { @@ -357,7 +366,9 @@ func (engine *DockerTaskEngine) MustInit(ctx context.Context) { err := engine.Init(ctx) if err != nil { errorOnce.Do(func() { - seelog.Errorf("Task engine: could not connect to docker daemon: %v", err) + logger.Error("Could not connect to docker daemon", logger.Fields{ + field.Error: err, + }) }) } return err @@ -409,11 +420,19 @@ func (engine *DockerTaskEngine) synchronizeState() { timeoutFunc := func() { eniAttachment, ok := engine.state.ENIByMac(eniAttachment.MACAddress) if !ok { - seelog.Warnf("Ignoring unmanaged ENI attachment with MAC address: %s", eniAttachment.MACAddress) + logger.Warn("Ignoring unmanaged ENI attachment", logger.Fields{ + "macAddress": eniAttachment.MACAddress, + }) return } if !eniAttachment.IsSent() { - seelog.Warnf("Timed out waiting for ENI ack; removing ENI attachment record %s", eniAttachment.String()) + logger.Warn("Timed out waiting for ENI ack; removing ENI attachment record", logger.Fields{ + field.TaskARN: eniAttachment.TaskARN, + field.Status: eniAttachment.Status.String(), + "attachmentArn": eniAttachment.AttachmentARN, + "expiresAt": eniAttachment.ExpiresAt.Format(time.RFC3339), + "type": eniAttachment.AttachmentType, + }) engine.removeENIAttachmentData(eniAttachment.MACAddress) engine.state.RemoveENIAttachment(eniAttachment.MACAddress) } @@ -422,7 +441,13 @@ func (engine *DockerTaskEngine) synchronizeState() { if err != nil { // The only case where we get an error from Initialize is that the attachment has expired. In that case, remove the expired // attachment from state. - seelog.Warnf("ENI attachment has expired. Removing it from state. %s", eniAttachment.String()) + logger.Warn("ENI attachment has expired; removing it from state", logger.Fields{ + field.TaskARN: eniAttachment.TaskARN, + field.Status: eniAttachment.Status.String(), + "attachmentArn": eniAttachment.AttachmentARN, + "expiresAt": eniAttachment.ExpiresAt.Format(time.RFC3339), + "type": eniAttachment.AttachmentType, + }) engine.removeENIAttachmentData(eniAttachment.MACAddress) engine.state.RemoveENIAttachment(eniAttachment.MACAddress) } @@ -509,14 +534,19 @@ func updateContainerMetadata(metadata *dockerapi.DockerContainerMetadata, contai // synchronizeContainerStatus checks and updates the container status with docker func (engine *DockerTaskEngine) synchronizeContainerStatus(container *apicontainer.DockerContainer, task *apitask.Task) { if container.DockerID == "" { - seelog.Debugf("Task engine [%s]: found container potentially created while we were down: %s", - task.Arn, container.DockerName) + logger.Debug("Found container potentially created while we were down", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + }) // Figure out the dockerid describedContainer, err := engine.client.InspectContainer(engine.ctx, container.DockerName, dockerclient.InspectContainerTimeout) if err != nil { - seelog.Warnf("Task engine [%s]: could not find matching container for expected name [%s]: %v", - task.Arn, container.DockerName, err) + logger.Warn("Error getting container with name", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + field.Error: err, + }) } else { // update the container metadata in case the container was created during agent restart metadata := dockerapi.MetadataFromContainer(describedContainer) @@ -528,8 +558,11 @@ func (engine *DockerTaskEngine) synchronizeContainerStatus(container *apicontain engine.state.AddContainer(container, task) err := engine.imageManager.RecordContainerReference(container.Container) if err != nil { - seelog.Warnf("Task engine [%s]: unable to add container reference to image state: %v", - task.Arn, err) + logger.Warn("Unable to add container reference to image state", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + field.Error: err, + }) } } return @@ -540,14 +573,22 @@ func (engine *DockerTaskEngine) synchronizeContainerStatus(container *apicontain currentState = apicontainerstatus.ContainerStopped // If this is a Docker API error if metadata.Error.ErrorName() == dockerapi.CannotDescribeContainerErrorName { - seelog.Warnf("Task engine [%s]: could not describe previously known container [id=%s; name=%s]; assuming dead: %v", - task.Arn, container.DockerID, container.DockerName, metadata.Error) + logger.Warn("Could not describe previously known container; assuming dead", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + field.DockerId: container.DockerID, + field.Error: metadata.Error, + }) if !container.Container.KnownTerminal() { container.Container.ApplyingError = apierrors.NewNamedError(&ContainerVanishedError{}) err := engine.imageManager.RemoveContainerReferenceFromImageState(container.Container) if err != nil { - seelog.Warnf("Task engine [%s]: could not remove container reference for image state %s: %v", - container.Container.Image, err) + logger.Warn("Could not remove container reference from image state", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + "image": container.Container.Image, + field.Error: err, + }) } } } else { @@ -560,8 +601,11 @@ func (engine *DockerTaskEngine) synchronizeContainerStatus(container *apicontain updateContainerMetadata(&metadata, container.Container, task) err := engine.imageManager.RecordContainerReference(container.Container) if err != nil { - seelog.Warnf("Task engine [%s]: unable to add container reference to image state: %v", - task.Arn, err) + logger.Warn("Unable to add container reference to image state", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.DockerName, + field.Error: err, + }) } if engine.cfg.ContainerMetadataEnabled.Enabled() && !container.Container.IsMetadataFileUpdated() { go engine.updateMetadataFile(task, container) @@ -606,8 +650,11 @@ func (engine *DockerTaskEngine) sweepTask(task *apitask.Task) { for _, cont := range task.Containers { err := engine.removeContainer(task, cont) if err != nil { - seelog.Infof("Task engine [%s]: unable to remove old container [%s]: %v", - task.Arn, cont.Name, err) + logger.Error("Unable to remove old container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Name, + field.Error: err, + }) } // Internal container(created by ecs-agent) state isn't recorded if cont.IsInternal() { @@ -615,8 +662,11 @@ func (engine *DockerTaskEngine) sweepTask(task *apitask.Task) { } err = engine.imageManager.RemoveContainerReferenceFromImageState(cont) if err != nil { - seelog.Errorf("Task engine [%s]: Unable to remove container [%s] reference from image state: %v", - task.Arn, cont.Name, err) + logger.Error("Unable to remove container reference from image state", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Name, + field.Error: err, + }) } } @@ -624,7 +674,10 @@ func (engine *DockerTaskEngine) sweepTask(task *apitask.Task) { if engine.cfg.ContainerMetadataEnabled.Enabled() { err := engine.metadataManager.Clean(task.Arn) if err != nil { - seelog.Warnf("Task engine [%s]: clean task metadata failed: %v", task.Arn, err) + logger.Warn("Error cleaning task metadata", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) } } } @@ -635,22 +688,27 @@ func (engine *DockerTaskEngine) deleteTask(task *apitask.Task) { for _, resource := range task.GetResources() { err := resource.Cleanup() if err != nil { - seelog.Warnf("Task engine [%s]: unable to cleanup resource %s: %v", - task.Arn, resource.GetName(), err) + logger.Warn("Unable to cleanup resource", logger.Fields{ + field.TaskID: task.GetID(), + field.Resource: resource.GetName(), + field.Error: err, + }) } else { - seelog.Infof("Task engine [%s]: resource %s cleanup complete", task.Arn, - resource.GetName()) + logger.Info("Resource cleanup complete", logger.Fields{ + field.TaskID: task.GetID(), + field.Resource: resource.GetName(), + }) } } if execcmd.IsExecEnabledTask(task) { // cleanup host exec agent log dirs - if tID, err := task.GetID(); err != nil { - seelog.Warnf("Task Engine[%s]: error getting task ID for ExecAgent logs cleanup: %v", task.Arn, err) - } else { - if err := removeAll(filepath.Join(execcmd.ECSAgentExecLogDir, tID)); err != nil { - seelog.Warnf("Task Engine[%s]: unable to remove ExecAgent host logs for task: %v", task.Arn, err) - } + tID := task.GetID() + if err := removeAll(filepath.Join(execcmd.ECSAgentExecLogDir, tID)); err != nil { + logger.Warn("Unable to remove ExecAgent host logs for task", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) } } @@ -663,20 +721,26 @@ func (engine *DockerTaskEngine) deleteTask(task *apitask.Task) { // ENIs that exist only as logical associations on another interface do not have // attachments that need to be removed. if taskENI.IsStandardENI() { - seelog.Debugf("Task engine [%s]: removing eni %s from agent state", - task.Arn, taskENI.ID) + logger.Debug("Removing ENI from agent state", logger.Fields{ + field.TaskID: task.GetID(), + "eni": taskENI.ID, + }) engine.removeENIAttachmentData(taskENI.MacAddress) engine.state.RemoveENIAttachment(taskENI.MacAddress) } else { - seelog.Debugf("Task engine [%s]: skipping removing logical eni %s from agent state", - task.Arn, taskENI.ID) + logger.Debug("Skipping removing logical ENI from agent state because it's not a standard ENI", logger.Fields{ + field.TaskID: task.GetID(), + "eni": taskENI.ID, + }) } } // Remove task and container data from database. engine.removeTaskData(task) - seelog.Infof("Task engine [%s]: finished removing task data, removing task from managed tasks", task.Arn) + logger.Info("Finished removing task data, removing task from managed tasks", logger.Fields{ + field.TaskID: task.GetID(), + }) delete(engine.managedTasks, task.Arn) engine.tasksLock.Unlock() } @@ -684,11 +748,17 @@ func (engine *DockerTaskEngine) deleteTask(task *apitask.Task) { func (engine *DockerTaskEngine) emitTaskEvent(task *apitask.Task, reason string) { event, err := api.NewTaskStateChangeEvent(task, reason) if err != nil { - seelog.Infof("Task engine [%s]: unable to create task state change event: %v", task.Arn, err) + logger.Error("Unable to create task state change event", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return } - - seelog.Infof("Task engine [%s]: Task engine: sending change event [%s]", task.Arn, event.String()) + logger.Info("Preparing to send change event", logger.Fields{ + field.TaskID: task.GetID(), + field.Status: event.Status.String(), + field.Reason: event.Reason, + }) engine.stateChangeEvents <- event } @@ -745,18 +815,49 @@ func (engine *DockerTaskEngine) handleDockerEvents(ctx context.Context) { // container and placing it in the context of the task to which that container // belongs. func (engine *DockerTaskEngine) handleDockerEvent(event dockerapi.DockerContainerChangeEvent) { - seelog.Debugf("Task engine: handling a docker event: %s", event.String()) + + eventFields := logger.Fields{ + field.DockerId: event.DockerID, + field.Status: event.Status.String(), + "health": event.Health.Status.String(), + } + + if event.ExitCode != nil { + eventFields["exitCode"] = aws.IntValue(event.ExitCode) + } + if len(event.PortBindings) != 0 { + eventFields["portBindings"] = event.PortBindings + } + if event.Error != nil { + eventFields[field.Error] = event.Error + } + if len(event.Volumes) != 0 { + eventFields["volumes"] = event.Volumes + } + if len(event.Labels) != 0 { + eventFields["labels"] = event.Labels + } + if !event.CreatedAt.IsZero() { + eventFields["createdAt"] = event.CreatedAt.String() + } + if !event.StartedAt.IsZero() { + eventFields["startedAt"] = event.StartedAt.String() + } + if !event.FinishedAt.IsZero() { + eventFields["finishedAt"] = event.FinishedAt.String() + } + logger.Debug("Handling a docker event", eventFields) task, ok := engine.state.TaskByID(event.DockerID) if !ok { - seelog.Debugf("Task engine: event for container [%s] not managed, unable to map container id to task", - event.DockerID) + logger.Debug("Unable to map container event to task", eventFields) return } cont, ok := engine.state.ContainerByID(event.DockerID) if !ok { - seelog.Debugf("Task engine: event for container [%s] not managed, unable to map container id to container", - event.DockerID) + logger.Debug("Unable to map container id to container", logger.Fields{ + field.TaskID: task.GetID(), + }, eventFields) return } @@ -764,8 +865,14 @@ func (engine *DockerTaskEngine) handleDockerEvent(event dockerapi.DockerContaine // no need to process this in task manager if event.Type == apicontainer.ContainerHealthEvent { if cont.Container.HealthStatusShouldBeReported() { - seelog.Debugf("Task engine: updating container [%s(%s)] health status: %v", - cont.Container.Name, cont.DockerID, event.DockerContainerMetadata.Health) + logger.Debug("Updating container health status", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Container.Name, + field.DockerId: cont.DockerID, + "status": event.DockerContainerMetadata.Health.Status.String(), + "exitCode": event.DockerContainerMetadata.Health.ExitCode, + "output": event.DockerContainerMetadata.Health.Output, + }) cont.Container.SetHealthStatus(event.DockerContainerMetadata.Health) } return @@ -775,15 +882,18 @@ func (engine *DockerTaskEngine) handleDockerEvent(event dockerapi.DockerContaine managedTask, ok := engine.managedTasks[task.Arn] engine.tasksLock.RUnlock() if !ok { - seelog.Criticalf("Task engine: could not find managed task [%s] corresponding to a docker event: %s", - task.Arn, event.String()) + logger.Critical("Could not find managed task for docker event", logger.Fields{ + field.TaskID: task.GetID(), + }, eventFields) return } - seelog.Debugf("Task engine [%s]: writing docker event to the task: %s", - task.Arn, event.String()) + logger.Debug("Writing docker event to the task", logger.Fields{ + field.TaskID: task.GetID(), + }, eventFields) managedTask.emitDockerContainerChange(dockerContainerChange{container: cont.Container, event: event}) - seelog.Debugf("Task engine [%s]: wrote docker event to the task: %s", - task.Arn, event.String()) + logger.Debug("Wrote docker event to the task", logger.Fields{ + field.TaskID: task.GetID(), + }, eventFields) } // StateChangeEvents returns channels to read task and container state changes. These @@ -799,7 +909,10 @@ func (engine *DockerTaskEngine) AddTask(task *apitask.Task) { err := task.PostUnmarshalTask(engine.cfg, engine.credentialsManager, engine.resourceFields, engine.client, engine.ctx) if err != nil { - seelog.Errorf("Task engine [%s]: unable to add task to the engine: %v", task.Arn, err) + logger.Error("Unable to add task to the engine", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) task.SetKnownStatus(apitaskstatus.TaskStopped) task.SetDesiredStatus(apitaskstatus.TaskStopped) engine.emitTaskEvent(task, err.Error()) @@ -821,7 +934,9 @@ func (engine *DockerTaskEngine) AddTask(task *apitask.Task) { if dependencygraph.ValidDependencies(task, engine.cfg) { engine.startTask(task) } else { - seelog.Errorf("Task engine [%s]: unable to progress task with circular dependencies", task.Arn) + logger.Error("Task has circular dependencies; unable to start", logger.Fields{ + field.TaskID: task.GetID(), + }) task.SetKnownStatus(apitaskstatus.TaskStopped) task.SetDesiredStatus(apitaskstatus.TaskStopped) err := TaskDependencyError{task.Arn} @@ -829,7 +944,6 @@ func (engine *DockerTaskEngine) AddTask(task *apitask.Task) { } return } - // Update task engine.updateTaskUnsafe(existingTask, task) } @@ -851,14 +965,17 @@ func (engine *DockerTaskEngine) pullContainer(task *apitask.Task, container *api return dockerapi.DockerContainerMetadata{} } - if engine.imagePullRequired(engine.cfg.ImagePullBehavior, container, task.Arn) { + if engine.imagePullRequired(engine.cfg.ImagePullBehavior, container, task.GetID()) { // Record the pullStoppedAt timestamp defer func() { timestamp := engine.time().Now() task.SetPullStoppedAt(timestamp) }() - - seelog.Infof("Task engine [%s]: pulling image %s for container %s concurrently", task.Arn, container.Image, container.Name) + logger.Info("Pulling image for container concurrently", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) return engine.concurrentPull(task, container) } @@ -871,7 +988,7 @@ func (engine *DockerTaskEngine) pullContainer(task *apitask.Task, container *api engine.state.AddPulledContainer(dockerContainer, task) // No pull image is required, just update container reference and use cached image. - engine.updateContainerReference(false, container, task.Arn) + engine.updateContainerReference(false, container, task.GetID()) // Return the metadata without any error return dockerapi.DockerContainerMetadata{Error: nil} } @@ -881,7 +998,7 @@ func (engine *DockerTaskEngine) pullContainer(task *apitask.Task, container *api // to make sure the container passed in is not an internal container. func (engine *DockerTaskEngine) imagePullRequired(imagePullBehavior config.ImagePullBehaviorType, container *apicontainer.Container, - taskArn string) bool { + taskId string) bool { switch imagePullBehavior { case config.ImagePullOnceBehavior: // If this image has been pulled successfully before, don't pull the image, @@ -889,8 +1006,11 @@ func (engine *DockerTaskEngine) imagePullRequired(imagePullBehavior config.Image // (the image can be prepopulated with the AMI and never be pulled). imageState, ok := engine.imageManager.GetImageStateFromImageName(container.Image) if ok && imageState.GetPullSucceeded() { - seelog.Infof("Task engine [%s]: image %s for container %s has been pulled once, not pulling it again", - taskArn, container.Image, container.Name) + logger.Info("Image for container already exists, not pulling it again", logger.Fields{ + field.TaskID: taskId, + field.Container: container.Name, + field.Image: container.Image, + }) return false } return true @@ -901,8 +1021,11 @@ func (engine *DockerTaskEngine) imagePullRequired(imagePullBehavior config.Image if err != nil { return true } - seelog.Infof("Task engine [%s]: found cached image %s, use it directly for container %s", - taskArn, container.Image, container.Name) + logger.Info("Found cached image, use it directly for container", logger.Fields{ + field.TaskID: taskId, + field.Container: container.Name, + field.Image: container.Image, + }) return false default: // Need to pull the image for always and default agent pull behavior @@ -911,29 +1034,53 @@ func (engine *DockerTaskEngine) imagePullRequired(imagePullBehavior config.Image } func (engine *DockerTaskEngine) concurrentPull(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata { - seelog.Debugf("Task engine [%s]: attempting to obtain ImagePullDeleteLock to pull image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Debug("Attempting to obtain ImagePullDeleteLock to pull image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) ImagePullDeleteLock.RLock() - seelog.Debugf("Task engine [%s]: acquired ImagePullDeleteLock, start pulling image %s for container %s", - task.Arn, container.Image, container.Name) - defer seelog.Debugf("Task engine [%s]: released ImagePullDeleteLock after pulling image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Debug("Acquired ImagePullDeleteLock, start pulling image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) + defer logger.Debug("Released ImagePullDeleteLock after pulling image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) defer ImagePullDeleteLock.RUnlock() // Record the task pull_started_at timestamp pullStart := engine.time().Now() ok := task.SetPullStartedAt(pullStart) if ok { - seelog.Infof("Task engine [%s]: recording timestamp for starting image pulltime: %s", - task.Arn, pullStart) + logger.Info("Recording start time for image pull", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + "pullStart": pullStart.String(), + }) + } metadata := engine.pullAndUpdateContainerReference(task, container) if metadata.Error == nil { - seelog.Infof("Task engine [%s]: finished pulling image %s for container %s in %s", - task.Arn, container.Image, container.Name, time.Since(pullStart).String()) + elapsed := time.Since(pullStart) + logger.Info("Finished pulling image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + field.Elapsed: elapsed.String(), + "elapsedMs": elapsed.Milliseconds(), + }) } else { - seelog.Errorf("Task engine [%s]: failed to pull image %s for container %s: %v", - task.Arn, container.Image, container.Name, metadata.Error) + logger.Error("Failed to pull image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + field.Error: metadata.Error, + }) } return metadata } @@ -942,8 +1089,11 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta // If a task is blocked here for some time, and before it starts pulling image, // the task's desired status is set to stopped, then don't pull the image if task.GetDesiredStatus() == apitaskstatus.TaskStopped { - seelog.Infof("Task engine [%s]: task's desired status is stopped, skipping pulling image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Warn("Task's desired status is stopped, skipping image pull for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) container.SetDesiredStatus(apicontainerstatus.ContainerStopped) return dockerapi.DockerContainerMetadata{Error: TaskStoppedBeforePullBeginError{task.Arn}} } @@ -952,8 +1102,11 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta if container.ShouldPullWithExecutionRole() { executionCredentials, ok := engine.credentialsManager.GetTaskCredentials(task.GetExecutionCredentialsID()) if !ok { - seelog.Errorf("Task engine [%s]: unable to acquire ECR credentials for image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Error("Unable to acquire ECR credentials to pull image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) return dockerapi.DockerContainerMetadata{ Error: dockerapi.CannotPullECRContainerError{ FromError: errors.New("engine ecr credentials: not found"), @@ -970,8 +1123,12 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta // Apply registry auth data from ASM if required if container.ShouldPullWithASMAuth() { if err := task.PopulateASMAuthData(container); err != nil { - seelog.Errorf("Task engine [%s]: unable to acquire Docker registry credentials for image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Error("Unable to acquire Docker registry credentials to pull image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + field.Error: err, + }) return dockerapi.DockerContainerMetadata{ Error: dockerapi.CannotPullContainerAuthError{ FromError: errors.New("engine docker private registry credentials: not found"), @@ -996,8 +1153,12 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta // search the image in local cached images if engine.cfg.DependentContainersPullUpfront.Enabled() && engine.cfg.ImagePullBehavior != config.ImagePullAlwaysBehavior { if _, err := engine.client.InspectImage(container.Image); err != nil { - seelog.Errorf("Task engine [%s]: failed to find cached image %s for container %s", - task.Arn, container.Image, container.Name) + logger.Error("Failed to find cached image for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + field.Error: err, + }) // Stop the task if the container is an essential container, // and the image is not available in both remote and local caches if container.IsEssential() { @@ -1006,8 +1167,11 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta } return dockerapi.DockerContainerMetadata{Error: metadata.Error} } - seelog.Infof("Task engine [%s]: found cached image %s, use it directly for container %s", - task.Arn, container.Image, container.Name) + logger.Info("Found cached image, use it directly for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Image: container.Image, + }) findCachedImage = true } } @@ -1019,15 +1183,18 @@ func (engine *DockerTaskEngine) pullAndUpdateContainerReference(task *apitask.Ta engine.state.AddPulledContainer(dockerContainer, task) } - engine.updateContainerReference(pullSucceeded, container, task.Arn) + engine.updateContainerReference(pullSucceeded, container, task.GetID()) return metadata } -func (engine *DockerTaskEngine) updateContainerReference(pullSucceeded bool, container *apicontainer.Container, taskArn string) { +func (engine *DockerTaskEngine) updateContainerReference(pullSucceeded bool, container *apicontainer.Container, taskId string) { err := engine.imageManager.RecordContainerReference(container) if err != nil { - seelog.Errorf("Task engine [%s]: unable to add container reference to image state: %v", - taskArn, err) + logger.Error("Unable to add container reference to image state", logger.Fields{ + field.TaskID: taskId, + field.Container: container.Name, + field.Error: err, + }) } imageState, ok := engine.imageManager.GetImageStateFromImageName(container.Image) if ok && pullSucceeded { @@ -1036,8 +1203,12 @@ func (engine *DockerTaskEngine) updateContainerReference(pullSucceeded bool, con imageState.SetPullSucceeded(true) err = engine.dataClient.SaveImageState(imageState) if err != nil { - seelog.Warnf("Task engine [%s]: unable to save image state: %v", - taskArn, err) + logger.Warn("Unable to save image state", logger.Fields{ + field.TaskID: taskId, + field.Container: container.Name, + field.Image: container.Image, + field.Error: err, + }) } } } @@ -1045,7 +1216,10 @@ func (engine *DockerTaskEngine) updateContainerReference(pullSucceeded bool, con } func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata { - seelog.Infof("Task engine [%s]: creating container: %s", task.Arn, container.Name) + logger.Info("Creating container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) client := engine.client if container.DockerConfig.Version != nil { client = client.WithVersion(dockerclient.DockerVersion(*container.DockerConfig.Version)) @@ -1121,7 +1295,7 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a } else if container.GetNetworkModeFromHostConfig() == "" || container.GetNetworkModeFromHostConfig() == apitask.BridgeNetworkMode { ipAddress, ok := getContainerHostIP(task.GetFirelensContainer().GetNetworkSettings()) if !ok { - err := apierrors.DockerClientConfigError{Msg: "unable to get BridgeIP for task in bridge mode"} + err := apierrors.DockerClientConfigError{Msg: "unable to get BridgeIP for task in bridge mode"} return dockerapi.DockerContainerMetadata{Error: apierrors.NamedError(&err)} } container.MergeEnvironmentVariables(map[string]string{ @@ -1145,7 +1319,10 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a // Populate credentialspec resource if container.RequiresCredentialSpec() { - seelog.Debugf("Obtained container %s with credentialspec resource requirement for task %s.", container.Name, task.Arn) + logger.Debug("Obtained container with credentialspec resource requirement for task", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) var credSpecResource *credentialspec.CredentialSpecResource resource, ok := task.GetCredentialSpecResource() if !ok || len(resource) <= 0 { @@ -1164,7 +1341,11 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a } // Inject containers' hostConfig.SecurityOpt with the credentialspec resource - seelog.Infof("Injecting container %s with credentialspec %s.", container.Name, desiredCredSpecInjection) + logger.Info("Injecting container with credentialspec", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "credentialSpec": desiredCredSpecInjection, + }) if len(hostConfig.SecurityOpt) == 0 { hostConfig.SecurityOpt = []string{desiredCredSpecInjection} } else { @@ -1184,21 +1365,24 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a if container.ShouldCreateWithEnvFiles() { err := task.MergeEnvVarsFromEnvfiles(container) if err != nil { - seelog.Errorf("Error populating environment variables from specified files into container %s", container.Name) + logger.Error("Error populating environment variables from specified files into container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: err, + }) return dockerapi.DockerContainerMetadata{Error: apierrors.NamedError(err)} } } if execcmd.IsExecEnabledContainer(container) { - tID, err := task.GetID() + tID := task.GetID() + err := engine.execCmdMgr.InitializeContainer(tID, container, hostConfig) if err != nil { - herr := &apierrors.HostConfigError{Msg: err.Error()} - return dockerapi.DockerContainerMetadata{Error: apierrors.NamedError(herr)} - } - err = engine.execCmdMgr.InitializeContainer(tID, container, hostConfig) - if err != nil { - seelog.Warnf("Exec Agent initialization: %v . Continuing to start container without enabling exec feature.", err) - + logger.Warn("Error initializing ExecCommandAgent; proceeding to start container without exec feature", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: err, + }) // Emit a managedagent state chnage event if exec agent initialization fails engine.tasksLock.RLock() mTask, ok := engine.managedTasks[task.Arn] @@ -1206,7 +1390,11 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a if ok { mTask.emitManagedAgentEvent(mTask.Task, container, execcmd.ExecuteCommandAgentName, fmt.Sprintf("ExecuteCommandAgent Initialization failed - %v", err)) } else { - seelog.Errorf("Task engine [%s]: Failed to update status of ExecCommandAgent Process for container [%s]: managed task not found", task.Arn, container.Name) + logger.Error("Failed to update status of ExecCommandAgent Process for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: "managed task not found", + }) } } } @@ -1240,8 +1428,11 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a DockerName: dockerContainerName, Container: container, }, task) - seelog.Infof("Task engine [%s]: created container name mapping for task: %s -> %s", - task.Arn, container.Name, dockerContainerName) + logger.Info("Created container name mapping for task", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "dockerContainerName": dockerContainerName, + }) } // Create metadata directory and file then populate it with common metadata of all containers of this task @@ -1249,13 +1440,19 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a if engine.cfg.ContainerMetadataEnabled.Enabled() && !container.IsInternal() { info, infoErr := engine.client.Info(engine.ctx, dockerclient.InfoTimeout) if infoErr != nil { - seelog.Warnf("Task engine [%s]: unable to get docker info : %v", - task.Arn, infoErr) + logger.Warn("Unable to get docker info", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: infoErr, + }) } mderr := engine.metadataManager.Create(config, hostConfig, task, container.Name, info.SecurityOptions) if mderr != nil { - seelog.Warnf("Task engine [%s]: unable to create metadata for container %s: %v", - task.Arn, container.Name, mderr) + logger.Warn("Unable to create metadata for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: mderr, + }) } } @@ -1263,8 +1460,6 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a metadata := client.CreateContainer(engine.ctx, config, hostConfig, dockerContainerName, engine.cfg.ContainerCreateTimeout) if metadata.DockerID != "" { - seelog.Infof("Task engine [%s]: created docker container for task: %s -> %s", - task.Arn, container.Name, metadata.DockerID) dockerContainer := &apicontainer.DockerContainer{DockerID: metadata.DockerID, DockerName: dockerContainerName, Container: container} @@ -1272,8 +1467,12 @@ func (engine *DockerTaskEngine) createContainer(task *apitask.Task, container *a engine.saveDockerContainerData(dockerContainer) } container.SetLabels(config.Labels) - seelog.Infof("Task engine [%s]: created docker container for task: %s -> %s, took %s", - task.Arn, container.Name, metadata.DockerID, time.Since(createContainerBegin)) + logger.Info("Created docker container for task", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.DockerId: metadata.DockerID, + field.Elapsed: time.Since(createContainerBegin), + }) container.SetRuntimeID(metadata.DockerID) return metadata } @@ -1294,12 +1493,20 @@ func getFirelensLogConfig(task *apitask.Task, container *apicontainer.Container, if bufferLimitExists { logConfig.Config[logDriverBufferLimit] = bufferLimit } - seelog.Debugf("Applying firelens log config for container %s: %v", container.Name, logConfig) + logger.Debug("Applying firelens log config for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "config": logConfig, + }) return logConfig } func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata { - seelog.Infof("Task engine [%s]: starting container: %s (Runtime ID: %s)", task.Arn, container.Name, container.GetRuntimeID()) + logger.Info("Starting container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: container.GetRuntimeID(), + }) client := engine.client if container.DockerConfig.Version != nil { client = client.WithVersion(dockerclient.DockerVersion(*container.DockerConfig.Version)) @@ -1320,8 +1527,12 @@ func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *ap return dockerContainerMD } - seelog.Infof("Task engine [%s]: started docker container for task: %s -> %s, took %s", - task.Arn, container.Name, dockerContainerMD.DockerID, time.Since(startContainerBegin)) + logger.Info("Started container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: container.GetRuntimeID(), + field.Elapsed: time.Since(startContainerBegin), + }) // Get metadata through container inspection and available task information then write this to the metadata file // Performs this in the background to avoid delaying container start @@ -1331,13 +1542,18 @@ func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *ap go func() { err := engine.metadataManager.Update(engine.ctx, dockerID, task, container.Name) if err != nil { - seelog.Warnf("Task engine [%s]: failed to update metadata file for container %s: %v", - task.Arn, container.Name, err) + logger.Warn("Failed to update metadata file for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: err, + }) return } container.SetMetadataFileUpdated() - seelog.Debugf("Task engine [%s]: updated metadata file for container %s", - task.Arn, container.Name) + logger.Debug("Updated metadata file for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) }() } @@ -1379,7 +1595,11 @@ func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *ap reason := "ExecuteCommandAgent started" if err := engine.execCmdMgr.StartAgent(engine.ctx, engine.client, task, container, dockerID); err != nil { reason = err.Error() - seelog.Errorf("Task engine [%s]: Failed to start ExecCommandAgent Process for container [%s]: %v", task.Arn, container.Name, err) + logger.Error("Failed to start ExecCommandAgent Process for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: err, + }) } engine.tasksLock.RLock() @@ -1390,7 +1610,11 @@ func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *ap if ok { mTask.emitManagedAgentEvent(mTask.Task, container, execcmd.ExecuteCommandAgentName, reason) } else { - seelog.Errorf("Task engine [%s]: Failed to update status of ExecCommandAgent Process for container [%s]: managed task not found", task.Arn, container.Name) + logger.Error("Failed to update status of ExecCommandAgent Process for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: "managed task not found", + }) } } } @@ -1412,8 +1636,10 @@ func (engine *DockerTaskEngine) startContainer(task *apitask.Task, container *ap } func (engine *DockerTaskEngine) provisionContainerResources(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata { - seelog.Infof("Task engine [%s]: setting up container resources for container [%s]", - task.Arn, container.Name) + logger.Info("Setting up container resources for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) containerInspectOutput, err := engine.inspectContainer(task, container) if err != nil { return dockerapi.DockerContainerMetadata{ @@ -1439,8 +1665,10 @@ func (engine *DockerTaskEngine) provisionContainerResources(task *apitask.Task, // Invoke the libcni to config the network namespace for the container result, err := engine.cniClient.SetupNS(engine.ctx, cniConfig, cniSetupTimeout) if err != nil { - seelog.Errorf("Task engine [%s]: unable to configure pause container namespace: %v", - task.Arn, err) + logger.Error("Unable to configure pause container namespace", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return dockerapi.DockerContainerMetadata{ DockerID: cniConfig.ContainerID, Error: ContainerNetworkingError{errors.Wrap(err, @@ -1450,7 +1678,10 @@ func (engine *DockerTaskEngine) provisionContainerResources(task *apitask.Task, // This is the IP of the task assigned on the bridge for IAM Task roles taskIP := result.IPs[0].Address.IP.String() - seelog.Infof("Task engine [%s]: associated with ip address '%s'", task.Arn, taskIP) + logger.Info("Task associated with ip address", logger.Fields{ + field.TaskID: task.GetID(), + "ip": taskIP, + }) engine.state.AddTaskIPAddress(taskIP, task.Arn) task.SetLocalIPAddress(taskIP) engine.saveTaskData(task) @@ -1458,8 +1689,10 @@ func (engine *DockerTaskEngine) provisionContainerResources(task *apitask.Task, // Invoke additional commands required to configure the task namespace routing. err = engine.namespaceHelper.ConfigureTaskNamespaceRouting(engine.ctx, task.GetPrimaryENI(), cniConfig, result) if err != nil { - seelog.Errorf("Task engine [%s]: unable to configure pause container namespace: %v", - task.Arn, err) + logger.Error("Unable to configure pause container namespace", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) return dockerapi.DockerContainerMetadata{ DockerID: cniConfig.ContainerID, Error: ContainerNetworkingError{errors.Wrapf(err, @@ -1485,7 +1718,10 @@ func (engine *DockerTaskEngine) checkTearDownPauseContainer(task *apitask.Task) if container.KnownTerminal() || container.DesiredTerminal() { err := engine.cleanupPauseContainerNetwork(task, container) if err != nil { - seelog.Errorf("Task engine [%s]: unable to cleanup pause container network namespace: %v", task.Arn, err) + logger.Error("Unable to cleanup pause container network namespace", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) } } return @@ -1501,7 +1737,10 @@ func (engine *DockerTaskEngine) cleanupPauseContainerNetwork(task *apitask.Task, } delay := time.Duration(engine.cfg.ENIPauseContainerCleanupDelaySeconds) * time.Second if engine.handleDelay != nil && delay > 0 { - seelog.Infof("Task engine [%s]: waiting %s before cleaning up pause container.", task.Arn, delay) + logger.Info("Waiting before cleaning up pause container", logger.Fields{ + field.TaskID: task.GetID(), + "wait": delay.String(), + }) engine.handleDelay(delay) } containerInspectOutput, err := engine.inspectContainer(task, container) @@ -1509,7 +1748,9 @@ func (engine *DockerTaskEngine) cleanupPauseContainerNetwork(task *apitask.Task, return errors.Wrap(err, "engine: cannot cleanup task network namespace due to error inspecting pause container") } - seelog.Infof("Task engine [%s]: cleaning up the network namespace", task.Arn) + logger.Info("Cleaning up the network namespace", logger.Fields{ + field.TaskID: task.GetID(), + }) cniConfig, err := engine.buildCNIConfigFromTaskContainer(task, containerInspectOutput, false) if err != nil { return errors.Wrapf(err, @@ -1522,7 +1763,9 @@ func (engine *DockerTaskEngine) cleanupPauseContainerNetwork(task *apitask.Task, } container.SetContainerTornDown(true) - seelog.Infof("Task engine [%s]: cleaned pause container network namespace", task.Arn) + logger.Info("Cleaned pause container network namespace", logger.Fields{ + field.TaskID: task.GetID(), + }) return nil } @@ -1577,8 +1820,10 @@ func (engine *DockerTaskEngine) inspectContainer(task *apitask.Task, container * } func (engine *DockerTaskEngine) stopContainer(task *apitask.Task, container *apicontainer.Container) dockerapi.DockerContainerMetadata { - seelog.Infof("Task engine [%s]: stopping container [%s]", task.Arn, container.Name) - + logger.Info("Stopping container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) dockerID, err := engine.getDockerID(task, container) if err != nil { return dockerapi.DockerContainerMetadata{ @@ -1592,8 +1837,10 @@ func (engine *DockerTaskEngine) stopContainer(task *apitask.Task, container *api if container.Type == apicontainer.ContainerCNIPause { err := engine.cleanupPauseContainerNetwork(task, container) if err != nil { - seelog.Errorf("Task engine [%s]: unable to cleanup pause container network namespace: %v", - task.Arn, err) + logger.Error("Unable to cleanup pause container network namespace", logger.Fields{ + field.TaskID: task.GetID(), + field.Error: err, + }) } } @@ -1637,8 +1884,10 @@ func (engine *DockerTaskEngine) stopDockerContainer(dockerID, containerName stri } func (engine *DockerTaskEngine) removeContainer(task *apitask.Task, container *apicontainer.Container) error { - seelog.Infof("Task engine [%s]: removing container: %s", task.Arn, container.Name) - + logger.Info("Removing container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) dockerID, err := engine.getDockerID(task, container) if err != nil { return err @@ -1653,8 +1902,9 @@ func (engine *DockerTaskEngine) removeContainer(task *apitask.Task, container *a func (engine *DockerTaskEngine) updateTaskUnsafe(task *apitask.Task, update *apitask.Task) { managedTask, ok := engine.managedTasks[task.Arn] if !ok { - seelog.Criticalf("Task engine [%s]: ACS message for a task we thought we managed, but don't! Aborting.", - task.Arn) + logger.Critical("ACS message for a task we thought we managed, but don't! Aborting.", logger.Fields{ + field.TaskARN: task.Arn, + }) return } // Keep the lock because sequence numbers cannot be correct unless they are @@ -1662,14 +1912,20 @@ func (engine *DockerTaskEngine) updateTaskUnsafe(task *apitask.Task, update *api // This does block the engine's ability to ingest any new events (including // stops for past tasks, ack!), but this is necessary for correctness updateDesiredStatus := update.GetDesiredStatus() - seelog.Debugf("Task engine [%s]: putting update on the acs channel: [%s] with seqnum [%d]", - task.Arn, updateDesiredStatus.String(), update.StopSequenceNumber) + logger.Debug("Putting update on the acs channel", logger.Fields{ + field.TaskID: task.GetID(), + field.DesiredStatus: updateDesiredStatus.String(), + field.Sequence: update.StopSequenceNumber, + }) managedTask.emitACSTransition(acsTransition{ desiredStatus: updateDesiredStatus, seqnum: update.StopSequenceNumber, }) - seelog.Debugf("Task engine [%s]: update taken off the acs channel: [%s] with seqnum [%d]", - task.Arn, updateDesiredStatus.String(), update.StopSequenceNumber) + logger.Debug("Update taken off the acs channel", logger.Fields{ + field.TaskID: task.GetID(), + field.DesiredStatus: updateDesiredStatus.String(), + field.Sequence: update.StopSequenceNumber, + }) } // transitionContainer calls applyContainerState, and then notifies the managed @@ -1699,17 +1955,30 @@ func (engine *DockerTaskEngine) transitionContainer(task *apitask.Task, containe func (engine *DockerTaskEngine) applyContainerState(task *apitask.Task, container *apicontainer.Container, nextState apicontainerstatus.ContainerStatus) dockerapi.DockerContainerMetadata { transitionFunction, ok := engine.transitionFunctionMap()[nextState] if !ok { - seelog.Criticalf("Task engine [%s]: unsupported desired state transition for container [%s]: %s", - task.Arn, container.Name, nextState.String()) + logger.Critical("Unsupported desired state transition for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + "nextState": nextState.String(), + }) return dockerapi.DockerContainerMetadata{Error: &impossibleTransitionError{nextState}} } metadata := transitionFunction(task, container) if metadata.Error != nil { - seelog.Infof("Task engine [%s]: error transitioning container [%s (Runtime ID: %s)] to [%s]: %v", - task.Arn, container.Name, container.GetRuntimeID(), nextState.String(), metadata.Error) + logger.Error("Error transitioning container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: container.GetRuntimeID(), + "nextState": nextState.String(), + field.Error: metadata.Error, + }) } else { - seelog.Debugf("Task engine [%s]: transitioned container [%s (Runtime ID: %s)] to [%s]", - task.Arn, container.Name, container.GetRuntimeID(), nextState.String()) + logger.Debug("Transitioned container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: container.GetRuntimeID(), + "nextState": nextState.String(), + field.Error: metadata.Error, + }) } return metadata } @@ -1738,12 +2007,17 @@ func (engine *DockerTaskEngine) Version() (string, error) { func (engine *DockerTaskEngine) updateMetadataFile(task *apitask.Task, cont *apicontainer.DockerContainer) { err := engine.metadataManager.Update(engine.ctx, cont.DockerID, task, cont.Container.Name) if err != nil { - seelog.Errorf("Task engine [%s]: failed to update metadata file for container %s: %v", - task.Arn, cont.Container.Name, err) + logger.Error("Failed to update metadata file for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Container.Name, + field.Error: err, + }) } else { cont.Container.SetMetadataFileUpdated() - seelog.Debugf("Task engine [%s]: updated metadata file for container %s", - task.Arn, cont.Container.Name) + logger.Debug("Updated metadata file for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: cont.Container.Name, + }) } } diff --git a/agent/engine/docker_task_engine_linux.go b/agent/engine/docker_task_engine_linux.go index 1d27300f34a..56298a6bac1 100644 --- a/agent/engine/docker_task_engine_linux.go +++ b/agent/engine/docker_task_engine_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_task_engine_linux_test.go b/agent/engine/docker_task_engine_linux_test.go index 120eae89c4e..798b5df04cf 100644 --- a/agent/engine/docker_task_engine_linux_test.go +++ b/agent/engine/docker_task_engine_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -85,8 +86,7 @@ func TestResourceContainerProgression(t *testing.T) { mockControl := mock_control.NewMockControl(ctrl) mockIO := mock_ioutilwrapper.NewMockIOUtil(ctrl) - taskID, err := sleepTask.GetID() - assert.NoError(t, err) + taskID := sleepTask.GetID() cgroupMemoryPath := fmt.Sprintf("/sys/fs/cgroup/memory/ecs/%s/memory.use_hierarchy", taskID) cgroupRoot := fmt.Sprintf("/ecs/%s", taskID) cgroupResource := cgroup.NewCgroupResource(sleepTask.Arn, mockControl, mockIO, cgroupRoot, cgroupMountPath, specs.LinuxResources{}) @@ -94,6 +94,7 @@ func TestResourceContainerProgression(t *testing.T) { sleepTask.ResourcesMapUnsafe = make(map[string][]taskresource.TaskResource) sleepTask.AddResource("cgroup", cgroupResource) eventStream := make(chan dockerapi.DockerContainerChangeEvent) + // containerEventsWG is used to force the test to wait until the container created and started // events are processed containerEventsWG := sync.WaitGroup{} @@ -127,7 +128,6 @@ func TestResourceContainerProgression(t *testing.T) { }() }).Return(dockerapi.DockerContainerMetadata{DockerID: containerID + ":" + sleepContainer.Name}), ) - addTaskToEngine(t, ctx, taskEngine, sleepTask, mockTime, &containerEventsWG) cleanup := make(chan time.Time, 1) @@ -253,8 +253,7 @@ func TestResourceContainerProgressionFailure(t *testing.T) { sleepContainer.BuildResourceDependency("cgroup", resourcestatus.ResourceCreated, apicontainerstatus.ContainerPulled) mockControl := mock_control.NewMockControl(ctrl) - taskID, err := sleepTask.GetID() - assert.NoError(t, err) + taskID := sleepTask.GetID() cgroupRoot := fmt.Sprintf("/ecs/%s", taskID) cgroupResource := cgroup.NewCgroupResource(sleepTask.Arn, mockControl, nil, cgroupRoot, cgroupMountPath, specs.LinuxResources{}) @@ -269,7 +268,7 @@ func TestResourceContainerProgressionFailure(t *testing.T) { ) mockTime.EXPECT().Now().Return(time.Now()).AnyTimes() - err = taskEngine.Init(ctx) + err := taskEngine.Init(ctx) assert.NoError(t, err) taskEngine.AddTask(sleepTask) @@ -330,8 +329,7 @@ func TestTaskCPULimitHappyPath(t *testing.T) { }() mockControl := mock_control.NewMockControl(ctrl) mockIO := mock_ioutilwrapper.NewMockIOUtil(ctrl) - taskID, err := sleepTask.GetID() - assert.NoError(t, err) + taskID := sleepTask.GetID() cgroupMemoryPath := fmt.Sprintf("/sys/fs/cgroup/memory/ecs/%s/memory.use_hierarchy", taskID) if tc.taskCPULimit.Enabled() { // TODO Currently, the resource Setup() method gets invoked multiple diff --git a/agent/engine/docker_task_engine_test.go b/agent/engine/docker_task_engine_test.go index d90fee5c2ed..023aea86f5b 100644 --- a/agent/engine/docker_task_engine_test.go +++ b/agent/engine/docker_task_engine_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_task_engine_unsupported.go b/agent/engine/docker_task_engine_unsupported.go index cebf298524d..c59db83fcfb 100644 --- a/agent/engine/docker_task_engine_unsupported.go +++ b/agent/engine/docker_task_engine_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/docker_task_engine_windows.go b/agent/engine/docker_task_engine_windows.go index 1e64df89271..9afadf22611 100644 --- a/agent/engine/docker_task_engine_windows.go +++ b/agent/engine/docker_task_engine_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -18,9 +19,11 @@ package engine import ( "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" apitask "github.com/aws/amazon-ecs-agent/agent/api/task" - "github.com/cihub/seelog" "github.com/pkg/errors" ) @@ -52,7 +55,11 @@ func (engine *DockerTaskEngine) invokePluginsForContainer(task *apitask.Task, co // Invoke the cni plugin for the container using libcni _, err = engine.cniClient.SetupNS(engine.ctx, cniConfig, cniSetupTimeout) if err != nil { - seelog.Errorf("Task engine [%s]: unable to configure container %v in the pause namespace: %v", task.Arn, container.Name, err) + logger.Error("Unable to configure container in the pause namespace", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.Error: err, + }) return errors.Wrap(err, "failed to connect HNS endpoint to container") } diff --git a/agent/engine/docker_task_engine_windows_test.go b/agent/engine/docker_task_engine_windows_test.go index e11e7e67cdf..4adbe809c75 100644 --- a/agent/engine/docker_task_engine_windows_test.go +++ b/agent/engine/docker_task_engine_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/dockerstate/dockerstate_test.go b/agent/engine/dockerstate/dockerstate_test.go index fc5c94d5be8..7fe6a5ba7b8 100644 --- a/agent/engine/dockerstate/dockerstate_test.go +++ b/agent/engine/dockerstate/dockerstate_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/dockerstate/json_test.go b/agent/engine/dockerstate/json_test.go index 7a1f26ee358..c584c35787a 100644 --- a/agent/engine/dockerstate/json_test.go +++ b/agent/engine/dockerstate/json_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/dockerstate/testutils/json_test.go b/agent/engine/dockerstate/testutils/json_test.go index 6170683aaea..c05710f91fe 100644 --- a/agent/engine/dockerstate/testutils/json_test.go +++ b/agent/engine/dockerstate/testutils/json_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/engine_integ_test.go b/agent/engine/engine_integ_test.go index b6d543a2648..09d4b3840c5 100644 --- a/agent/engine/engine_integ_test.go +++ b/agent/engine/engine_integ_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/engine_sudo_linux_integ_test.go b/agent/engine/engine_sudo_linux_integ_test.go index 2eec610d792..3e434dfc879 100644 --- a/agent/engine/engine_sudo_linux_integ_test.go +++ b/agent/engine/engine_sudo_linux_integ_test.go @@ -1,4 +1,5 @@ //go:build linux && sudo +// +build linux,sudo // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -247,7 +248,7 @@ func TestFirelensFluentbit(t *testing.T) { err = VerifyTaskStatus(apitaskstatus.TaskStopped, testTask.Arn, testEvents, t) assert.NoError(t, err) - taskID, err := testTask.GetID() + taskID := testTask.GetID() //declare a cloudwatch client cwlClient := cloudwatchlogs.New(session.New(), aws.NewConfig().WithRegion(testECSRegion)) diff --git a/agent/engine/engine_unix_integ_test.go b/agent/engine/engine_unix_integ_test.go index 9aa7a25ec09..4e771f3ebeb 100644 --- a/agent/engine/engine_unix_integ_test.go +++ b/agent/engine/engine_unix_integ_test.go @@ -1,4 +1,5 @@ //go:build !windows && integration +// +build !windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/engine_windows_integ_test.go b/agent/engine/engine_windows_integ_test.go index 59bae72ac6f..4f2635050ef 100644 --- a/agent/engine/engine_windows_integ_test.go +++ b/agent/engine/engine_windows_integ_test.go @@ -1,4 +1,5 @@ //go:build windows && integration +// +build windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/execcmd/manager_init_task_linux.go b/agent/engine/execcmd/manager_init_task_linux.go index 6398bf9bb1a..05af1582b1e 100644 --- a/agent/engine/execcmd/manager_init_task_linux.go +++ b/agent/engine/execcmd/manager_init_task_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/execcmd/manager_init_task_linux_test.go b/agent/engine/execcmd/manager_init_task_linux_test.go index cb242d995b2..564e58bada2 100644 --- a/agent/engine/execcmd/manager_init_task_linux_test.go +++ b/agent/engine/execcmd/manager_init_task_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/execcmd/manager_start.go b/agent/engine/execcmd/manager_start.go index b1a46d18684..f9d84ff9718 100644 --- a/agent/engine/execcmd/manager_start.go +++ b/agent/engine/execcmd/manager_start.go @@ -23,7 +23,9 @@ import ( "strconv" "time" - "github.com/cihub/seelog" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/docker/docker/api/types" apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" @@ -42,7 +44,10 @@ import ( // To actually restart the ExecCommandAgent, this function invokes this instance's StartAgent method. func (m *manager) RestartAgentIfStopped(ctx context.Context, client dockerapi.DockerClient, task *apitask.Task, container *apicontainer.Container, containerId string) (RestartStatus, error) { if !IsExecEnabledContainer(container) { - seelog.Warnf("Task engine [%s]: an attempt to restart ExecCommandAgent for a non ExecCommandAgent-enabled container was made; container %s", task.Arn, containerId) + logger.Warn("Attempt to restart ExecCommandAgent for a non ExecCommandAgent-enabled container was made", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + }) return NotRestarted, nil } ma, _ := container.GetManagedAgentByName(ExecuteCommandAgentName) @@ -60,7 +65,12 @@ func (m *manager) RestartAgentIfStopped(ctx context.Context, client dockerapi.Do } // Restart if not running //TODO: [ecs-exec] retry only for certain exit codes? - seelog.Warnf("Task engine [%s]: ExecCommandAgent Process stopped (exitCode=%d) for container %s, restarting...", task.Arn, res.ExitCode, containerId) + logger.Warn("ExecCommandAgent Process stopped for container, restarting...", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: containerId, + "exitCode": res.ExitCode, + }) container.UpdateManagedAgentByName(ExecuteCommandAgentName, apicontainer.ManagedAgentState{ ID: ma.ID, }) @@ -100,7 +110,11 @@ func (m *manager) inspectExecAgentProcess(ctx context.Context, client dockerapi. // If no error is returned, it can be assumed the ExecCommandAgent is started. func (m *manager) StartAgent(ctx context.Context, client dockerapi.DockerClient, task *apitask.Task, container *apicontainer.Container, containerId string) error { if !IsExecEnabledContainer(container) { - seelog.Warnf("Task engine [%s]: an attempt to start ExecCommandAgent for a non ExecCommandAgent-enabled container was made; container %s", task.Arn, containerId) + logger.Warn("An attempt to start ExecCommandAgent for a non ExecCommandAgent-enabled container was made", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: containerId, + }) return nil } ma, _ := container.GetManagedAgentByName(ExecuteCommandAgentName) @@ -112,9 +126,18 @@ func (m *manager) StartAgent(ctx context.Context, client dockerapi.DockerClient, if m.isAgentStarted(ma) { res, err := m.inspectExecAgentProcess(ctx, client, existingMetadata) if err != nil { - seelog.Warnf("Task engine [%s]: could not verify if the ExecCommandAgent was already running for container %s: %v", task.Arn, containerId, err) + logger.Warn("Could not verify if the ExecCommandAgent was already running for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: containerId, + field.Error: err, + }) } else if res.Running { // agent is already running, nothing to do - seelog.Warnf("Task engine [%s]: an attempt was made to start the ExecCommandAgent but it was already running (%s)", task.Arn, containerId) + logger.Warn("An attempt was made to start the ExecCommandAgent but it was already running", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: containerId, + }) return nil } } @@ -128,7 +151,12 @@ func (m *manager) StartAgent(ctx context.Context, client dockerapi.DockerClient, retry.RetryNWithBackoffCtx(ctx, backoff, maxRetries, func() error { execMD, startErr = m.doStartAgent(ctx, client, task, ma, containerId) if startErr != nil { - seelog.Warnf("Task engine [%s]: exec command agent failed to start for container %s: %v. Retrying...", task.Arn, containerId, startErr) + logger.Warn("Exec command agent failed to start for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: container.Name, + field.RuntimeID: containerId, + field.Error: startErr, + }) } return startErr }) @@ -163,20 +191,33 @@ func (m *manager) doStartAgent(ctx context.Context, client dockerapi.DockerClien return newMD, StartError{error: fmt.Errorf("unable to start ExecuteCommandAgent [create]: %v", err), retryable: true} } - seelog.Debugf("Task engine [%s]: created ExecCommandAgent for container: %s -> docker exec id: %s", task.Arn, containerId, execRes.ID) + logger.Debug("Created ExecCommandAgent for container", logger.Fields{ + field.TaskID: task.GetID(), + field.RuntimeID: containerId, + "execResId": execRes.ID, + }) err = client.StartContainerExec(ctx, execRes.ID, types.ExecStartCheck{Detach: true, Tty: false}, dockerclient.ContainerExecStartTimeout) if err != nil { return newMD, StartError{error: fmt.Errorf("unable to start ExecuteCommandAgent [pre-start]: %v", err), retryable: true} } - seelog.Debugf("Task engine [%s]: sent ExecCommandAgent start signal for container: %s -> docker exec id: %s", task.Arn, containerId, execRes.ID) + logger.Debug("Sent ExecCommandAgent start signal for container", logger.Fields{ + field.TaskID: task.GetID(), + field.RuntimeID: containerId, + "execResId": execRes.ID, + }) inspect, err := client.InspectContainerExec(ctx, execRes.ID, dockerclient.ContainerExecInspectTimeout) if err != nil { return newMD, StartError{error: fmt.Errorf("unable to start ExecuteCommandAgent [inspect]: %v", err), retryable: true} } - seelog.Debugf("Task engine [%s]: inspect ExecCommandAgent for container: %s -> pid: %d, exitCode: %d, running:%v, err:%v", - task.Arn, containerId, inspect.Pid, inspect.ExitCode, inspect.Running, err) + logger.Debug("Inspect ExecCommandAgent for container", logger.Fields{ + field.TaskID: task.GetID(), + field.RuntimeID: containerId, + "pid": inspect.Pid, + "exitCode": inspect.ExitCode, + "running": inspect.Running, + }) if !inspect.Running { //TODO: [ecs-exec] retry only for certain exit codes? return newMD, StartError{ @@ -184,7 +225,11 @@ func (m *manager) doStartAgent(ctx context.Context, client dockerapi.DockerClien retryable: true, } } - seelog.Infof("Task engine [%s]: started ExecCommandAgent for container: %s -> docker exec id: %s", task.Arn, containerId, execRes.ID) + logger.Info("Started ExecCommandAgent for container", logger.Fields{ + field.TaskID: task.GetID(), + field.RuntimeID: containerId, + "execResId": inspect.Pid, + }) newMD.PID = strconv.Itoa(inspect.Pid) newMD.DockerExecID = execRes.ID newMD.CMD = execAgentCmd diff --git a/agent/engine/execcmd/manager_start_linux.go b/agent/engine/execcmd/manager_start_linux.go index b98634c856d..774c3435bc7 100644 --- a/agent/engine/execcmd/manager_start_linux.go +++ b/agent/engine/execcmd/manager_start_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/execcmd/manager_start_linux_test.go b/agent/engine/execcmd/manager_start_linux_test.go index 2613f9ab2cd..061617a61c4 100644 --- a/agent/engine/execcmd/manager_start_linux_test.go +++ b/agent/engine/execcmd/manager_start_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/execcmd/manager_unsupported.go b/agent/engine/execcmd/manager_unsupported.go index 4a8124c3b2b..3fed93585c4 100644 --- a/agent/engine/execcmd/manager_unsupported.go +++ b/agent/engine/execcmd/manager_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/image/types.go b/agent/engine/image/types.go index acdb92fc71b..d16438ab363 100644 --- a/agent/engine/image/types.go +++ b/agent/engine/image/types.go @@ -20,8 +20,10 @@ import ( "sync" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" - "github.com/cihub/seelog" ) type Image struct { @@ -55,7 +57,11 @@ type ImageState struct { func (imageState *ImageState) UpdateContainerReference(container *apicontainer.Container) { imageState.lock.Lock() defer imageState.lock.Unlock() - seelog.Infof("Updating container reference %v in Image State - %v", container.Name, imageState.Image.ImageID) + logger.Info("Updating container reference in image state", logger.Fields{ + field.Container: container.Name, + field.Image: container.Image, + "state": imageState.Image.ImageID, + }) imageState.Containers = append(imageState.Containers, container) } @@ -64,7 +70,10 @@ func (imageState *ImageState) AddImageName(imageName string) { imageState.lock.Lock() defer imageState.lock.Unlock() if !imageState.HasImageName(imageName) { - seelog.Infof("Adding image name- %v to Image state- %v", imageName, imageState.Image.ImageID) + logger.Info("Adding image to state", logger.Fields{ + field.Image: imageName, + "state": imageState.Image.ImageID, + }) imageState.Image.Names = append(imageState.Image.Names, imageName) } } @@ -125,7 +134,11 @@ func (imageState *ImageState) RemoveContainerReference(container *apicontainer.C for i := range imageState.Containers { if imageState.Containers[i].Name == container.Name { // Container reference found; hence remove it - seelog.Infof("Removing Container Reference: %v from Image State- %v", container.Name, imageState.Image.ImageID) + logger.Info("Removing container reference from image state", logger.Fields{ + field.Container: container.Name, + field.Image: container.Image, + "state": imageState.Image.ImageID, + }) imageState.Containers = append(imageState.Containers[:i], imageState.Containers[i+1:]...) // Update the last used time for the image imageState.LastUsedAt = time.Now() diff --git a/agent/engine/ordering_integ_test.go b/agent/engine/ordering_integ_test.go index 25e787e3c85..31162998126 100644 --- a/agent/engine/ordering_integ_test.go +++ b/agent/engine/ordering_integ_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/ordering_integ_unix_test.go b/agent/engine/ordering_integ_unix_test.go index 2f8d0a2b3cf..1878e4bdb54 100644 --- a/agent/engine/ordering_integ_unix_test.go +++ b/agent/engine/ordering_integ_unix_test.go @@ -1,4 +1,5 @@ //go:build integration && !windows +// +build integration,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/ordering_integ_windows_test.go b/agent/engine/ordering_integ_windows_test.go index 89a1515cfa2..b411c377177 100644 --- a/agent/engine/ordering_integ_windows_test.go +++ b/agent/engine/ordering_integ_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && integration +// +build windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/task_manager.go b/agent/engine/task_manager.go index bba3b40aca9..a0ea9274b96 100644 --- a/agent/engine/task_manager.go +++ b/agent/engine/task_manager.go @@ -224,7 +224,7 @@ func (mtask *managedTask) overseeTask() { // If we aren't terminal and we aren't steady state, we should be // able to move some containers along. logger.Debug("Task not steady state or terminal; progressing it", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.progressTask() @@ -237,13 +237,13 @@ func (mtask *managedTask) overseeTask() { // We only break out of the above if this task is known to be stopped. Do // onetime cleanup here, including removing the task after a timeout logger.Info("Managed task has reached stopped; waiting for container cleanup", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.engine.checkTearDownPauseContainer(mtask.Task) mtask.cleanupCredentials() if mtask.StopSequenceNumber != 0 { logger.Debug("Marking done for this sequence", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Sequence: mtask.StopSequenceNumber, }) mtask.taskStopWG.Done(mtask.StopSequenceNumber) @@ -286,7 +286,7 @@ func (mtask *managedTask) waitForHostResources() { } logger.Info("Waiting for any previous stops to complete", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Sequence: mtask.StartSequenceNumber, }) @@ -307,7 +307,7 @@ func (mtask *managedTask) waitForHostResources() { } } logger.Info("Wait over; ready to move towards desired status", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.DesiredStatus: mtask.GetDesiredStatus().String(), }) } @@ -316,7 +316,7 @@ func (mtask *managedTask) waitForHostResources() { // event, or a timeout. func (mtask *managedTask) waitSteady() { logger.Info("Managed task at steady state", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.KnownStatus: mtask.GetKnownStatus().String(), }) @@ -329,7 +329,7 @@ func (mtask *managedTask) waitSteady() { if timedOut { logger.Debug("Checking to verify it's still at steady state", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) go mtask.engine.checkTaskState(mtask.Task) } @@ -341,7 +341,7 @@ func (mtask *managedTask) steadyState() bool { select { case <-mtask.ctx.Done(): logger.Info("Task manager exiting", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) return false default: @@ -365,12 +365,14 @@ func (mtask *managedTask) cleanupCredentials() { // return true. func (mtask *managedTask) waitEvent(stopWaiting <-chan struct{}) bool { logger.Debug("Waiting for task event", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) select { case acsTransition := <-mtask.acsMessages: logger.Info("Managed task got acs event", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), + field.DesiredStatus: acsTransition.desiredStatus.String(), + field.Sequence: acsTransition.seqnum, }) mtask.handleDesiredStatusChange(acsTransition.desiredStatus, acsTransition.seqnum) return false @@ -380,7 +382,7 @@ func (mtask *managedTask) waitEvent(stopWaiting <-chan struct{}) bool { case resChange := <-mtask.resourceStateChangeEvent: res := resChange.resource logger.Info("Managed task got resource", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: res.GetName(), field.Status: res.StatusString(resChange.nextState), }) @@ -399,14 +401,14 @@ func (mtask *managedTask) handleDesiredStatusChange(desiredStatus apitaskstatus. // Handle acs message changes this task's desired status to whatever // acs says it should be if it is compatible logger.Info("New acs transition", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.DesiredStatus: desiredStatus.String(), field.Sequence: seqnum, "StopNumber": mtask.StopSequenceNumber, }) if desiredStatus <= mtask.GetDesiredStatus() { - logger.Info("Redundant task transition; ignoring", logger.Fields{ - field.TaskARN: mtask.Arn, + logger.Debug("Redundant task transition; ignoring", logger.Fields{ + field.TaskID: mtask.GetID(), field.DesiredStatus: desiredStatus.String(), field.Sequence: seqnum, "StopNumber": mtask.StopSequenceNumber, @@ -416,7 +418,7 @@ func (mtask *managedTask) handleDesiredStatusChange(desiredStatus apitaskstatus. if desiredStatus == apitaskstatus.TaskStopped && seqnum != 0 && mtask.GetStopSequenceNumber() == 0 { logger.Info("Managed task moving to stopped, adding to stopgroup with sequence number", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Sequence: seqnum, }) mtask.SetStopSequenceNumber(seqnum) @@ -436,22 +438,23 @@ func (mtask *managedTask) handleContainerChange(containerChange dockerContainerC runtimeID := container.GetRuntimeID() event := containerChange.event containerKnownStatus := container.GetKnownStatus() - if event.Status != containerKnownStatus { - logger.Info("Handling container change event", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Container: container.Name, - field.RuntimeID: runtimeID, - field.Status: event.Status.String(), - }) + + eventLogFields := logger.Fields{ + field.TaskID: mtask.GetID(), + field.Container: container.Name, + field.RuntimeID: runtimeID, + field.Status: event.Status.String(), + } + + if event.Status.String() == apicontainerstatus.ContainerStatusNone.String() || + (event.Status == apicontainerstatus.ContainerRunning && containerKnownStatus == apicontainerstatus.ContainerResourcesProvisioned) { + logger.Debug("Handling container change event", eventLogFields) + } else if event.Status != containerKnownStatus { // This prevents noisy docker event logs for pause container + logger.Info("Handling container change event", eventLogFields) } found := mtask.isContainerFound(container) if !found { - logger.Critical("State error; invoked with another task's container!", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Container: container.Name, - field.RuntimeID: runtimeID, - field.Status: event.Status.String(), - }) + logger.Critical("State error; invoked with another task's container!", eventLogFields) return } @@ -459,11 +462,7 @@ func (mtask *managedTask) handleContainerChange(containerChange dockerContainerC // to be known running so it will be stopped. Subsequently ignore these backward transitions mtask.handleStoppedToRunningContainerTransition(event.Status, container) if event.Status <= containerKnownStatus { - logger.Debug("Container change is redundant", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Container: container.Name, - field.RuntimeID: runtimeID, - field.Status: event.Status.String(), + logger.Debug("Container change is redundant", eventLogFields, logger.Fields{ field.KnownStatus: containerKnownStatus.String(), }) @@ -495,20 +494,13 @@ func (mtask *managedTask) handleContainerChange(containerChange dockerContainerC } mtask.RecordExecutionStoppedAt(container) - logger.Debug("Sending container change event to tcs", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Container: container.Name, - field.RuntimeID: runtimeID, - field.Status: event.Status.String(), - }) + logger.Debug("Sending container change event to tcs", eventLogFields) err := mtask.containerChangeEventStream.WriteToEventStream(event) if err != nil { logger.Warn("Failed to write container change event to tcs event stream", + eventLogFields, logger.Fields{ - field.TaskARN: mtask.Arn, - field.Container: container.Name, - field.RuntimeID: runtimeID, - field.Error: err, + field.Error: err, }) } @@ -533,7 +525,7 @@ func (mtask *managedTask) handleResourceStateChange(resChange resourceStateChang if !mtask.isResourceFound(res) { logger.Critical("State error; invoked with another task's resource", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: res.GetName(), }) return @@ -545,7 +537,7 @@ func (mtask *managedTask) handleResourceStateChange(resChange resourceStateChang if status <= currentKnownStatus { logger.Info("Redundant resource state change", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: res.GetName(), field.Status: res.StatusString(status), field.KnownStatus: res.StatusString(currentKnownStatus), @@ -566,15 +558,15 @@ func (mtask *managedTask) handleResourceStateChange(resChange resourceStateChang } if status == res.SteadyState() { // Failed to create resource. - logger.Error("Managed task [%s]: failed to create task resource [%s]: %v", logger.Fields{ - field.TaskARN: mtask.Arn, + logger.Error("Failed to create task resource", logger.Fields{ + field.TaskID: mtask.GetID(), field.Resource: res.GetName(), field.Error: err, }) res.SetKnownStatus(currentKnownStatus) // Set status back to None. logger.Info("Marking task desired status to STOPPED", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.SetDesiredStatus(apitaskstatus.TaskStopped) mtask.Task.SetTerminalReason(res.GetTerminalReason()) @@ -585,7 +577,7 @@ func (mtask *managedTask) emitResourceChange(change resourceStateChange) { select { case <-mtask.ctx.Done(): logger.Info("Unable to emit resource state change due to exit", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) case mtask.resourceStateChangeEvent <- change: } @@ -611,17 +603,25 @@ func getContainerEventLogFields(c api.ContainerStateChange) logger.Fields { } func (mtask *managedTask) emitTaskEvent(task *apitask.Task, reason string) { + taskKnownStatus := task.GetKnownStatus() + if !taskKnownStatus.BackendRecognized() { + logger.Debug("Skipping event emission for task", logger.Fields{ + field.TaskID: mtask.GetID(), + field.Error: "status not recognized by ECS", + }) + return + } event, err := api.NewTaskStateChangeEvent(task, reason) if err != nil { - logger.Debug("Managed task [%s]: skipping emitting event for task [%s]: %v", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Reason: reason, - field.Error: err, + logger.Error("Skipping emitting event for task due to error", logger.Fields{ + field.TaskID: mtask.GetID(), + field.Reason: reason, + field.Error: err, }) return } logger.Debug("Sending task change event", logger.Fields{ - field.TaskARN: task.Arn, + field.TaskID: mtask.GetID(), field.Status: event.Status.String(), field.SentStatus: task.GetSentStatus().String(), field.Event: event.String(), @@ -629,7 +629,7 @@ func (mtask *managedTask) emitTaskEvent(task *apitask.Task, reason string) { select { case <-mtask.ctx.Done(): logger.Info("Unable to send task change event due to exit", logger.Fields{ - field.TaskARN: task.Arn, + field.TaskID: mtask.GetID(), field.Status: event.Status.String(), field.SentStatus: task.GetSentStatus().String(), field.Event: event.String(), @@ -637,8 +637,8 @@ func (mtask *managedTask) emitTaskEvent(task *apitask.Task, reason string) { case mtask.stateChangeEvents <- event: } logger.Debug("Sent task change event", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Event: event.String(), + field.TaskID: mtask.GetID(), + field.Event: event.String(), }) } @@ -649,27 +649,27 @@ func (mtask *managedTask) emitManagedAgentEvent(task *apitask.Task, cont *apicon event, err := api.NewManagedAgentChangeEvent(task, cont, managedAgentName, reason) if err != nil { logger.Error("Skipping emitting ManagedAgent event for task", logger.Fields{ - field.TaskARN: task.Arn, - field.Reason: reason, - field.Error: err, + field.TaskID: mtask.GetID(), + field.Reason: reason, + field.Error: err, }) return } logger.Info("Sending ManagedAgent event", logger.Fields{ - field.TaskARN: task.Arn, - field.Event: event.String(), + field.TaskID: mtask.GetID(), + field.Event: event.String(), }) select { case <-mtask.ctx.Done(): logger.Info("Unable to send managed agent event due to exit", logger.Fields{ - field.TaskARN: task.Arn, - field.Event: event.String(), + field.TaskID: mtask.GetID(), + field.Event: event.String(), }) case mtask.stateChangeEvents <- event: } logger.Info("Sent managed agent event [%s]", logger.Fields{ - field.TaskARN: task.Arn, - field.Event: event.String(), + field.TaskID: mtask.GetID(), + field.Event: event.String(), }) } @@ -679,7 +679,7 @@ func (mtask *managedTask) emitContainerEvent(task *apitask.Task, cont *apicontai event, err := api.NewContainerStateChangeEvent(task, cont, reason) if err != nil { logger.Debug("Skipping emitting event for container", logger.Fields{ - field.TaskARN: task.Arn, + field.TaskID: mtask.GetID(), field.Container: cont.Name, field.Error: err, }) @@ -690,17 +690,17 @@ func (mtask *managedTask) emitContainerEvent(task *apitask.Task, cont *apicontai func (mtask *managedTask) doEmitContainerEvent(event api.ContainerStateChange) { logger.Debug("Sending container change event", getContainerEventLogFields(event), logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) select { case <-mtask.ctx.Done(): logger.Info("Unable to send container change event due to exit", getContainerEventLogFields(event), logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) case mtask.stateChangeEvents <- event: } logger.Debug("Sent container change event", getContainerEventLogFields(event), logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) } @@ -708,7 +708,7 @@ func (mtask *managedTask) emitDockerContainerChange(change dockerContainerChange select { case <-mtask.ctx.Done(): logger.Info("Unable to emit docker container change due to exit", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) case mtask.dockerMessages <- change: } @@ -718,7 +718,7 @@ func (mtask *managedTask) emitACSTransition(transition acsTransition) { select { case <-mtask.ctx.Done(): logger.Info("Unable to emit docker container change due to exit", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) case mtask.acsMessages <- transition: } @@ -750,7 +750,7 @@ func (mtask *managedTask) releaseIPInIPAM() { return } logger.Info("IPAM releasing ip for task eni", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) cfg, err := mtask.BuildCNIConfig(true, &ecscni.Config{ @@ -758,16 +758,16 @@ func (mtask *managedTask) releaseIPInIPAM() { }) if err != nil { logger.Error("Failed to release ip; unable to build cni configuration", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Error: err, + field.TaskID: mtask.GetID(), + field.Error: err, }) return } err = mtask.cniClient.ReleaseIPResource(mtask.ctx, cfg, ipamCleanupTmeout) if err != nil { logger.Error("Failed to release ip; IPAM error", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Error: err, + field.TaskID: mtask.GetID(), + field.Error: err, }) return } @@ -797,7 +797,7 @@ func (mtask *managedTask) handleStoppedToRunningContainerTransition(status apico // update it to 'known running' so that it will be driven back to stopped mtask.unexpectedStart.Do(func() { logger.Warn("Stopped container came back; re-stopping it once", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, }) go mtask.engine.transitionContainer(mtask.Task, container, apicontainerstatus.ContainerStopped) @@ -813,7 +813,7 @@ func (mtask *managedTask) handleManagedAgentStoppedTransition(container *apicont case execcmd.ExecuteCommandAgentName: if !container.UpdateManagedAgentStatus(managedAgentName, apicontainerstatus.ManagedAgentStopped) { logger.Warn("Cannot find ManagedAgent for container", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.ManagedAgent: managedAgentName, }) @@ -822,7 +822,7 @@ func (mtask *managedTask) handleManagedAgentStoppedTransition(container *apicont mtask.emitManagedAgentEvent(mtask.Task, container, managedAgentName, "Received Container Stopped event") default: logger.Warn("Unexpected ManagedAgent in container; unable to process ManagedAgent transition event", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.ManagedAgent: managedAgentName, }) @@ -848,7 +848,7 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange if mtask.cfg.ImagePullBehavior == config.ImagePullAlwaysBehavior || mtask.cfg.ImagePullBehavior == config.ImagePullOnceBehavior { logger.Error("Error while pulling image; moving task to STOPPED", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Image: container.Image, field.Container: container.Name, field.Error: event.Error, @@ -864,7 +864,7 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange // If the agent pull behavior is default, use local image cache directly, // assuming it exists. logger.Error("Error while pulling image; will try to run anyway", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Image: container.Image, field.Container: container.Name, field.Error: event.Error, @@ -879,7 +879,7 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange case apicontainerstatus.ContainerCreated: // No need to explicitly stop containers if this is a * -> NONE/CREATED transition logger.Warn("Error creating container; marking its desired status as STOPPED", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.Error: event.Error, }) @@ -890,7 +890,7 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange // If this is a * -> RUNNING / RESOURCES_PROVISIONED transition, we need to stop // the container. logger.Warn("Error starting/provisioning container[%s (Runtime ID: %s)];", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), field.Error: event.Error, @@ -913,7 +913,7 @@ func (mtask *managedTask) handleEventError(containerChange dockerContainerChange if shouldForceStop { logger.Warn("Forcing container to stop", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), }) @@ -934,7 +934,7 @@ func (mtask *managedTask) handleContainerStoppedTransitionError(event dockerapi. pr := mtask.dockerClient.SystemPing(mtask.ctx, systemPingTimeout) if pr.Error != nil { logger.Info("Error stopping the container, but docker seems to be unresponsive; ignoring state change", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), "ErrorName": event.Error.ErrorName(), @@ -952,7 +952,7 @@ func (mtask *managedTask) handleContainerStoppedTransitionError(event dockerapi. // This can happen in cases where the container we tried to stop // was already stopped or did not exist at all. logger.Warn("Error stopping the container; marking it as stopped anyway", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), "ErrorName": event.Error.ErrorName(), @@ -971,7 +971,7 @@ func (mtask *managedTask) handleContainerStoppedTransitionError(event dockerapi. // Container changes may also prompt the task status to change as well. func (mtask *managedTask) progressTask() { logger.Debug("Progressing containers and resources in task", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) // max number of transitions length to ensure writes will never block on // these and if we exit early transitions can exit the goroutine and it'll @@ -1042,7 +1042,7 @@ func (mtask *managedTask) progressTask() { // update the task status if mtask.UpdateStatus() { logger.Info("Container or resource change also resulted in task change", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) // If knownStatus changed, let it be known @@ -1060,7 +1060,7 @@ func (mtask *managedTask) isWaitingForACSExecutionCredentials(reasons []error) b for _, reason := range reasons { if reason == dependencygraph.CredentialsNotResolvedErr { logger.Info("Waiting for credentials to pull from ECR", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) timeoutCtx, timeoutCancel := context.WithTimeout(mtask.ctx, waitForPullCredentialsTimeout) @@ -1069,7 +1069,7 @@ func (mtask *managedTask) isWaitingForACSExecutionCredentials(reasons []error) b timedOut := mtask.waitEvent(timeoutCtx.Done()) if timedOut { logger.Info("Timed out waiting for acs credentials message", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) } return true @@ -1139,7 +1139,7 @@ func (mtask *managedTask) startResourceTransitions(transitionFunc resourceTransi if knownStatus >= desiredStatus { logger.Debug("Resource has already transitioned to or beyond the desired status", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: res.GetName(), field.KnownStatus: res.StatusString(knownStatus), field.DesiredStatus: res.StatusString(desiredStatus), @@ -1194,7 +1194,7 @@ func (mtask *managedTask) applyResourceState(resource taskresource.TaskResource, err := resource.ApplyTransition(nextState) if err != nil { logger.Info("Error transitioning resource", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: resName, field.FailedStatus: resStatus, field.Error: err, @@ -1203,9 +1203,9 @@ func (mtask *managedTask) applyResourceState(resource taskresource.TaskResource, return err } logger.Info("Transitioned resource", logger.Fields{ - field.TaskARN: mtask.Arn, - field.Resource: resName, - field.FailedStatus: resStatus, + field.TaskID: mtask.GetID(), + field.Resource: resName, + field.Status: resStatus, }) return nil } @@ -1233,7 +1233,7 @@ func (mtask *managedTask) containerNextState(container *apicontainer.Container) if containerKnownStatus == containerDesiredStatus { logger.Debug("Container at desired status", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), field.DesiredStatus: containerDesiredStatus.String(), @@ -1246,8 +1246,8 @@ func (mtask *managedTask) containerNextState(container *apicontainer.Container) } if containerKnownStatus > containerDesiredStatus { - logger.Debug("Managed task [%s]: container [%s (Runtime ID: %s)] has already transitioned beyond desired status(%s): %s", logger.Fields{ - field.TaskARN: mtask.Arn, + logger.Debug("Container has already transitioned beyond desired status", logger.Fields{ + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), field.KnownStatus: containerKnownStatus.String(), @@ -1262,7 +1262,7 @@ func (mtask *managedTask) containerNextState(container *apicontainer.Container) if blocked, err := dependencygraph.DependenciesAreResolved(container, mtask.Containers, mtask.Task.GetExecutionCredentialsID(), mtask.credentialsManager, mtask.GetResources(), mtask.cfg); err != nil { logger.Debug("Can't apply state to container yet due to unresolved dependencies", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Container: container.Name, field.RuntimeID: container.GetRuntimeID(), field.Error: err, @@ -1324,8 +1324,8 @@ func (mtask *managedTask) resourceNextState(resource taskresource.TaskResource) resDesiredStatus := resource.GetDesiredStatus() if resKnownStatus >= resDesiredStatus { - logger.Debug("Managed task [%s]: task resource [%s] has already transitioned to or beyond desired status(%s): %s", logger.Fields{ - field.TaskARN: mtask.Arn, + logger.Debug("Task resource has already transitioned to or beyond desired status", logger.Fields{ + field.TaskID: mtask.GetID(), field.Resource: resource.GetName(), field.KnownStatus: resource.StatusString(resKnownStatus), field.DesiredStatus: resource.StatusString(resDesiredStatus), @@ -1340,7 +1340,7 @@ func (mtask *managedTask) resourceNextState(resource taskresource.TaskResource) if err := dependencygraph.TaskResourceDependenciesAreResolved(resource, mtask.Containers); err != nil { logger.Debug("Can't apply state to resource yet due to unresolved dependencies", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.Resource: resource.GetName(), field.Error: err, }) @@ -1371,21 +1371,21 @@ func (mtask *managedTask) resourceNextState(resource taskresource.TaskResource) func (mtask *managedTask) handleContainersUnableToTransitionState() { logger.Critical("Task in a bad state; it's not steady state but no containers want to transition", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) if mtask.GetDesiredStatus().Terminal() { // Ack, really bad. We want it to stop but the containers don't think // that's possible. let's just break out and hope for the best! logger.Critical("The state is so bad that we're just giving up on it", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.SetKnownStatus(apitaskstatus.TaskStopped) mtask.emitTaskEvent(mtask.Task, taskUnableToTransitionToStoppedReason) // TODO we should probably panic here } else { logger.Critical("Moving task to stopped due to bad state", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.handleDesiredStatusChange(apitaskstatus.TaskStopped, 0) } @@ -1399,18 +1399,18 @@ func (mtask *managedTask) waitForTransition(transitions map[string]string, // progressTask call. This is done by waiting for one transition/acs/docker message. if !mtask.waitEvent(transition) { logger.Debug("Received non-transition events", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) return } transitionedEntity := <-transitionChangeEntity - logger.Debug("Managed task [%s]: transition for [%s] finished", logger.Fields{ - field.TaskARN: mtask.Arn, + logger.Debug("Transition finished", logger.Fields{ + field.TaskID: mtask.GetID(), "TransitionedEntity": transitionedEntity, }) delete(transitions, transitionedEntity) logger.Debug("Task still waiting for: %v", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), "TransitionedEntity": fmt.Sprintf("%v", transitions), }) } @@ -1430,7 +1430,7 @@ func (mtask *managedTask) cleanupTask(taskStoppedDuration time.Duration) { cleanupTime := make(<-chan time.Time) if cleanupTimeDuration < 0 { logger.Info("Cleanup Duration has been exceeded; starting cleanup now", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) cleanupTime = mtask.time().After(time.Nanosecond) } else { @@ -1449,14 +1449,14 @@ func (mtask *managedTask) cleanupTask(taskStoppedDuration time.Duration) { ok := mtask.waitForStopReported() if !ok { logger.Error("Aborting cleanup for task as it is not reported as stopped", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.SentStatus: mtask.GetSentStatus().String(), }) return } logger.Info("Cleaning up task's containers and data", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) // For the duration of this, simply discard any task events; this ensures the @@ -1469,7 +1469,7 @@ func (mtask *managedTask) cleanupTask(taskStoppedDuration time.Duration) { // Remove TaskExecutionCredentials from credentialsManager if taskExecutionCredentialsID != "" { logger.Info("Cleaning up task's execution credentials", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), }) mtask.credentialsManager.RemoveCredentials(taskExecutionCredentialsID) } @@ -1505,7 +1505,7 @@ func (mtask *managedTask) waitForStopReported() bool { break } logger.Warn("Blocking cleanup until the task has been reported stopped", logger.Fields{ - field.TaskARN: mtask.Arn, + field.TaskID: mtask.GetID(), field.SentStatus: sentStatus.String(), "Attempt": i + 1, "MaxAttempts": _maxStoppedWaitTimes, diff --git a/agent/engine/task_manager_data_test.go b/agent/engine/task_manager_data_test.go index a60ebaa64e6..f6726d7b3f2 100644 --- a/agent/engine/task_manager_data_test.go +++ b/agent/engine/task_manager_data_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/task_manager_test.go b/agent/engine/task_manager_test.go index 1ab79ddfcc2..4b4f0838e6f 100644 --- a/agent/engine/task_manager_test.go +++ b/agent/engine/task_manager_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/engine/task_manager_unix_test.go b/agent/engine/task_manager_unix_test.go index 476656553de..a3510571879 100644 --- a/agent/engine/task_manager_unix_test.go +++ b/agent/engine/task_manager_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -428,7 +429,7 @@ func TestCleanupExecEnabledTask(t *testing.T) { dockerContainer := &apicontainer.DockerContainer{ DockerName: "dockerContainer", } - tID, _ := mTask.Task.GetID() + tID := mTask.Task.GetID() removeAll = func(path string) error { assert.Equal(t, fmt.Sprintf("/log/exec/%s", tID), path) return nil diff --git a/agent/eni/iphelperwrapper/iphelper_windows.go b/agent/eni/iphelperwrapper/iphelper_windows.go index 1c77ff19154..6bf45de2096 100644 --- a/agent/eni/iphelperwrapper/iphelper_windows.go +++ b/agent/eni/iphelperwrapper/iphelper_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/iphelperwrapper/iphelper_windows_test.go b/agent/eni/iphelperwrapper/iphelper_windows_test.go index d0628291db5..adbd8aa42a5 100644 --- a/agent/eni/iphelperwrapper/iphelper_windows_test.go +++ b/agent/eni/iphelperwrapper/iphelper_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/iphelperwrapper/mibIpInterfaceRow_windows.go b/agent/eni/iphelperwrapper/mibIpInterfaceRow_windows.go index c27c5beedd1..1112094b416 100644 --- a/agent/eni/iphelperwrapper/mibIpInterfaceRow_windows.go +++ b/agent/eni/iphelperwrapper/mibIpInterfaceRow_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/netlinkwrapper/netlink_linux.go b/agent/eni/netlinkwrapper/netlink_linux.go index 54f14be1baf..74713472d98 100644 --- a/agent/eni/netlinkwrapper/netlink_linux.go +++ b/agent/eni/netlinkwrapper/netlink_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/networkutils/utils_linux.go b/agent/eni/networkutils/utils_linux.go index 9a04d2c56dd..10a7a21262f 100644 --- a/agent/eni/networkutils/utils_linux.go +++ b/agent/eni/networkutils/utils_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/networkutils/utils_linux_test.go b/agent/eni/networkutils/utils_linux_test.go index f94e12426d5..39e5f771c4b 100644 --- a/agent/eni/networkutils/utils_linux_test.go +++ b/agent/eni/networkutils/utils_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/networkutils/utils_windows.go b/agent/eni/networkutils/utils_windows.go index 402e4a39916..4c4e68d3d91 100644 --- a/agent/eni/networkutils/utils_windows.go +++ b/agent/eni/networkutils/utils_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/networkutils/utils_windows_test.go b/agent/eni/networkutils/utils_windows_test.go index 352cccc7a49..755ccb353cd 100644 --- a/agent/eni/networkutils/utils_windows_test.go +++ b/agent/eni/networkutils/utils_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/error_test.go b/agent/eni/pause/error_test.go index 5a7cad12aae..72de9f05460 100644 --- a/agent/eni/pause/error_test.go +++ b/agent/eni/pause/error_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/load_test.go b/agent/eni/pause/load_test.go index 32a88e0ccf0..3203a923922 100644 --- a/agent/eni/pause/load_test.go +++ b/agent/eni/pause/load_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/pause_linux.go b/agent/eni/pause/pause_linux.go index c983c24a9f9..cb983ccc9b0 100644 --- a/agent/eni/pause/pause_linux.go +++ b/agent/eni/pause/pause_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/pause_linux_test.go b/agent/eni/pause/pause_linux_test.go index 6cb7725176a..00ad512fdbf 100644 --- a/agent/eni/pause/pause_linux_test.go +++ b/agent/eni/pause/pause_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/pause_unsupported.go b/agent/eni/pause/pause_unsupported.go index bc5eafd7bf2..8616f5fb8ae 100644 --- a/agent/eni/pause/pause_unsupported.go +++ b/agent/eni/pause/pause_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/pause/pause_windows.go b/agent/eni/pause/pause_windows.go index 9f640857e8d..05eac21383e 100644 --- a/agent/eni/pause/pause_windows.go +++ b/agent/eni/pause/pause_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/udevwrapper/udev_linux.go b/agent/eni/udevwrapper/udev_linux.go index 32cf01f4105..9d696c9fddc 100644 --- a/agent/eni/udevwrapper/udev_linux.go +++ b/agent/eni/udevwrapper/udev_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/udevwrapper/udev_unsupported.go b/agent/eni/udevwrapper/udev_unsupported.go index 09c70ab73ea..452edf7a639 100644 --- a/agent/eni/udevwrapper/udev_unsupported.go +++ b/agent/eni/udevwrapper/udev_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux +// +build !linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/watcher/watcher_linux.go b/agent/eni/watcher/watcher_linux.go index 795bf91c5fc..f055fec79d5 100644 --- a/agent/eni/watcher/watcher_linux.go +++ b/agent/eni/watcher/watcher_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -20,6 +21,9 @@ import ( "strings" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + log "github.com/cihub/seelog" "github.com/deniswernert/udev" "github.com/pkg/errors" @@ -109,7 +113,9 @@ func (eniWatcher *ENIWatcher) reconcileOnce(withRetry bool) error { if withRetry { go func(ctx context.Context, macAddress string, timeout time.Duration) { if err := eniWatcher.sendENIStateChangeWithRetries(ctx, macAddress, timeout); err != nil { - log.Infof("ENI watcher event-handler: unable to send state change: %v", err) + logger.Error("Unable to send state ENI change", logger.Fields{ + field.Error: err, + }) } }(eniWatcher.ctx, mac, sendENIStateChangeRetryTimeout) continue @@ -119,9 +125,13 @@ func (eniWatcher *ENIWatcher) reconcileOnce(withRetry bool) error { if strings.Contains(err.Error(), eniStatusSentMsg) { continue } else if _, ok := err.(*unmanagedENIError); ok { - log.Debugf("ENI watcher reconciliation: unable to send state change: %v", err) + logger.Debug("Unable to send state ENI change", logger.Fields{ + field.Error: err, + }) } else { - log.Warnf("ENI watcher reconciliation: unable to send state change: %v", err) + logger.Warn("Unable to send state ENI change", logger.Fields{ + field.Error: err, + }) } } } diff --git a/agent/eni/watcher/watcher_linux_test.go b/agent/eni/watcher/watcher_linux_test.go index ce17f13b8af..469555b4f55 100644 --- a/agent/eni/watcher/watcher_linux_test.go +++ b/agent/eni/watcher/watcher_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/watcher/watcher_test.go b/agent/eni/watcher/watcher_test.go index 9fda7494e30..9bd90c170bb 100644 --- a/agent/eni/watcher/watcher_test.go +++ b/agent/eni/watcher/watcher_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/watcher/watcher_unsupported.go b/agent/eni/watcher/watcher_unsupported.go index 222653c87ab..7adae3c5979 100644 --- a/agent/eni/watcher/watcher_unsupported.go +++ b/agent/eni/watcher/watcher_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/watcher/watcher_windows.go b/agent/eni/watcher/watcher_windows.go index 3a712955761..04e6a1fddba 100644 --- a/agent/eni/watcher/watcher_windows.go +++ b/agent/eni/watcher/watcher_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eni/watcher/watcher_windows_test.go b/agent/eni/watcher/watcher_windows_test.go index 97d5c772a0f..8313d07e8b2 100644 --- a/agent/eni/watcher/watcher_windows_test.go +++ b/agent/eni/watcher/watcher_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eventhandler/attachment_handler_test.go b/agent/eventhandler/attachment_handler_test.go index 3ddadb7f8f5..3a5303e0cf4 100644 --- a/agent/eventhandler/attachment_handler_test.go +++ b/agent/eventhandler/attachment_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eventhandler/handler_test.go b/agent/eventhandler/handler_test.go index 1698b3724f1..1d85fa99e0e 100644 --- a/agent/eventhandler/handler_test.go +++ b/agent/eventhandler/handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eventhandler/task_handler_test.go b/agent/eventhandler/task_handler_test.go index 4c9ded191f4..ba1277e0d83 100644 --- a/agent/eventhandler/task_handler_test.go +++ b/agent/eventhandler/task_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eventhandler/task_handler_types.go b/agent/eventhandler/task_handler_types.go index f7559c2c032..4df3eedfb3b 100644 --- a/agent/eventhandler/task_handler_types.go +++ b/agent/eventhandler/task_handler_types.go @@ -18,6 +18,9 @@ import ( "fmt" "sync" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/aws/amazon-ecs-agent/agent/api" apicontainer "github.com/aws/amazon-ecs-agent/agent/api/container" apicontainerstatus "github.com/aws/amazon-ecs-agent/agent/api/container/status" @@ -149,18 +152,27 @@ func (event *sendableEvent) send( backoff retry.Backoff, taskEvents *taskSendableEvents) error { - seelog.Infof("TaskHandler: Sending %s change: %s", eventType, event.toString()) + logger.Info("Sending state change to ECS", logger.Fields{ + "eventType": eventType, + "eventData": event.toString(), + }) // Try submitting the change to ECS if err := sendStatusToECS(client, event); err != nil { - seelog.Errorf("TaskHandler: Unretriable error submitting %s state change [%s]: %v", - eventType, event.toString(), err) + logger.Error("Unretriable error sending state change to ECS", logger.Fields{ + "eventType": eventType, + "eventData": event.toString(), + field.Error: err, + }) return err } // submitted; ensure we don't retry it event.setSent() // Mark event as sent setChangeSent(event, dataClient) - seelog.Debugf("TaskHandler: Submitted task state change: %s", event.toString()) + logger.Debug("Submitted state change to ECS", logger.Fields{ + "eventType": eventType, + "eventData": event.toString(), + }) taskEvents.events.Remove(eventToSubmit) backoff.Reset() return nil diff --git a/agent/eventhandler/task_handler_types_test.go b/agent/eventhandler/task_handler_types_test.go index e745249ea43..b9bad21c6bb 100644 --- a/agent/eventhandler/task_handler_types_test.go +++ b/agent/eventhandler/task_handler_types_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/eventstream/eventstream_test.go b/agent/eventstream/eventstream_test.go index 032e10f39d1..1b9e5768ae3 100644 --- a/agent/eventstream/eventstream_test.go +++ b/agent/eventstream/eventstream_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/fsx/fsx_test.go b/agent/fsx/fsx_test.go index c298744337b..e7e9349bcc8 100644 --- a/agent/fsx/fsx_test.go +++ b/agent/fsx/fsx_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/go.mod b/agent/go.mod index 1fa1ac850fe..327aabe84f5 100644 --- a/agent/go.mod +++ b/agent/go.mod @@ -7,7 +7,7 @@ require ( github.com/aws/aws-sdk-go v1.36.0 github.com/awslabs/go-config-generator-for-fluentd-and-fluentbit v0.0.0-20190829210224-55d4fd2e6f35 github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 - github.com/containerd/cgroups v0.0.0-20170627184340-c3fc2b77b568 + github.com/containerd/cgroups v1.0.3 github.com/containerd/containerd v1.4.12 // indirect github.com/containerd/continuity v0.0.0-20181023183536-c220ac4f01b8 // indirect github.com/containernetworking/cni v0.7.1 @@ -18,7 +18,6 @@ require ( github.com/docker/docker v0.0.0-20200531234253-77e06fda0c94 github.com/docker/go-connections v0.4.0 github.com/docker/go-units v0.4.0 - github.com/godbus/dbus v4.1.0+incompatible // indirect github.com/golang/mock v1.1.1 github.com/google/go-cmp v0.5.6 // indirect github.com/gorilla/mux v1.8.0 @@ -28,20 +27,20 @@ require ( github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0-rc1 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect - github.com/opencontainers/runtime-spec v0.0.0-20170627113742-d349388c43b0 + github.com/opencontainers/runtime-spec v1.0.2 github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pborman/uuid v0.0.0-20150603214016-ca53cad383ca github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v0.9.4 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 - github.com/stretchr/testify v1.5.1 + github.com/stretchr/testify v1.7.0 github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf go.etcd.io/bbolt v1.3.6 golang.org/x/net v0.0.0-20210525063256-abc453219eb5 - golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 golang.org/x/text v0.3.6 // indirect golang.org/x/time v0.0.0-20170927054726-6dc17368e09b // indirect - golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 + golang.org/x/tools v0.1.5 google.golang.org/grpc v1.38.0 // indirect gotest.tools v2.2.0+incompatible // indirect ) diff --git a/agent/go.sum b/agent/go.sum index bca4eb16205..dc2051bfad0 100644 --- a/agent/go.sum +++ b/agent/go.sum @@ -20,10 +20,11 @@ github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/containerd/cgroups v0.0.0-20170627184340-c3fc2b77b568 h1:rBkGdqk6go6dea4ckU92hpJeHBD3n6wXJLANgiS90eo= -github.com/containerd/cgroups v0.0.0-20170627184340-c3fc2b77b568/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= github.com/containerd/containerd v1.4.12 h1:V+SHzYmhng/iju6M5nFrpTTusrhidoxKTwdwLw+u4c4= github.com/containerd/containerd v1.4.12/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/continuity v0.0.0-20181023183536-c220ac4f01b8 h1:lJeDcldQnYskl7krc3lTppg8NKomoQkmQg1AzOXtQbA= @@ -35,6 +36,10 @@ github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHV github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-systemd v0.0.0-20170731111925-d21964639418 h1:0QH6fTJVDpblGjjozilaO++YRbnQNnTYh3yuFJHH0o8= github.com/coreos/go-systemd v0.0.0-20170731111925-d21964639418/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= @@ -57,13 +62,17 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF 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.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus v4.1.0+incompatible h1:WqqLRTsQic3apZUK9qC5sGNfXthmPXzUZ7nQPrNITa4= github.com/godbus/dbus v4.1.0+incompatible/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 h1:tT8iWCYw4uOem71yYA3htfH+LNopJvcqZQshm56G5L4= github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -72,6 +81,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= 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.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -86,9 +96,15 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5i github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -105,8 +121,8 @@ github.com/opencontainers/go-digest v1.0.0-rc1 h1:WzifXhOVOEOuFYOJAW6aQqW0TooG2i github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runtime-spec v0.0.0-20170627113742-d349388c43b0 h1:SggLMhCQwg4mVOVBrl6klF2lsB7jaqJjYe4VV/t5Ogw= -github.com/opencontainers/runtime-spec v0.0.0-20170627113742-d349388c43b0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= github.com/pborman/uuid v0.0.0-20150603214016-ca53cad383ca h1:dKRMHfduZ/ZqOHuYGk/0kkTIUbnyorkAfzLOp6Ts8pU= @@ -126,23 +142,28 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.1.1 h1:VzGj7lhU7KEB9e9gMpAV/v5XT2NVSvLJhJLCWbnkgXg= github.com/sirupsen/logrus v1.1.1/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/vishvananda/netlink v0.0.0-20170220200719-fe3b5664d23a h1:fLfXW2a8XEPPiZe2s99Smaa1v3TmcN9d/COofb13o2A= github.com/vishvananda/netlink v0.0.0-20170220200719-fe3b5664d23a/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936 h1:J9gO8RJCAFlln1jsvRba/CWVUnMHwObklfxxjErl1uk= github.com/vishvananda/netns v0.0.0-20171111001504-be1fbeda1936/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3 h1:f4/ZD59VsBOaJmWeI2yqtHvJhmRRPzi73C88ZtfhAIk= golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a h1:+HHJiFUXVOIS9mr1ThqkQD1N8vpFCfCShqADBM12KTc= golang.org/x/net v0.0.0-20191204025024-5ee1b9f4859a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -179,8 +200,10 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= 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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/agent/gogenerate/awssdk.go b/agent/gogenerate/awssdk.go index fee08b8d51f..fbd8706aed7 100644 --- a/agent/gogenerate/awssdk.go +++ b/agent/gogenerate/awssdk.go @@ -1,4 +1,5 @@ //go:build codegen +// +build codegen // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/gpu/generate_mocks.go b/agent/gpu/generate_mocks.go index 26dadfa72b5..f609d8ff1a5 100644 --- a/agent/gpu/generate_mocks.go +++ b/agent/gpu/generate_mocks.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/gpu/nvidia_gpu_manager_unix.go b/agent/gpu/nvidia_gpu_manager_unix.go index 9c5b385e31c..c18d6d20140 100644 --- a/agent/gpu/nvidia_gpu_manager_unix.go +++ b/agent/gpu/nvidia_gpu_manager_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/gpu/nvidia_gpu_manager_unix_test.go b/agent/gpu/nvidia_gpu_manager_unix_test.go index 70b674a8e3e..ededb252214 100644 --- a/agent/gpu/nvidia_gpu_manager_unix_test.go +++ b/agent/gpu/nvidia_gpu_manager_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/introspection_server_setup_test.go b/agent/handlers/introspection_server_setup_test.go index d8a90bbf5b9..e6d0b4c3dee 100644 --- a/agent/handlers/introspection_server_setup_test.go +++ b/agent/handlers/introspection_server_setup_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/task_server_setup_test.go b/agent/handlers/task_server_setup_test.go index 46ae12d87d4..b0e62e07ec5 100644 --- a/agent/handlers/task_server_setup_test.go +++ b/agent/handlers/task_server_setup_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/utils/helpers_test.go b/agent/handlers/utils/helpers_test.go index 1b691a8297b..7be7c9c5d0d 100644 --- a/agent/handlers/utils/helpers_test.go +++ b/agent/handlers/utils/helpers_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/v1/license_handler_test.go b/agent/handlers/v1/license_handler_test.go index 51c7b94e373..13812bd9cb0 100644 --- a/agent/handlers/v1/license_handler_test.go +++ b/agent/handlers/v1/license_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/v1/response.go b/agent/handlers/v1/response.go index bba57fcc1d9..069cf400159 100644 --- a/agent/handlers/v1/response.go +++ b/agent/handlers/v1/response.go @@ -67,6 +67,7 @@ type PortResponse struct { ContainerPort uint16 `json:"ContainerPort,omitempty"` Protocol string `json:"Protocol,omitempty"` HostPort uint16 `json:"HostPort,omitempty"` + HostIp string `json:"HostIp,omitempty"` } // NewTaskResponse creates a TaskResponse for a task. diff --git a/agent/handlers/v1/response_test.go b/agent/handlers/v1/response_test.go index 34bfff87431..2d6ac6def6b 100644 --- a/agent/handlers/v1/response_test.go +++ b/agent/handlers/v1/response_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/v2/response.go b/agent/handlers/v2/response.go index 812031cd0d2..d97c77d88f3 100644 --- a/agent/handlers/v2/response.go +++ b/agent/handlers/v2/response.go @@ -281,6 +281,9 @@ func NewContainerResponse( } else { port.HostPort = port.ContainerPort } + if includeV4Metadata { + port.HostIp = binding.BindIP + } resp.Ports = append(resp.Ports, port) } diff --git a/agent/handlers/v2/response_test.go b/agent/handlers/v2/response_test.go index 718dcd74e5c..19d89f2c573 100644 --- a/agent/handlers/v2/response_test.go +++ b/agent/handlers/v2/response_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -54,6 +55,7 @@ const ( volDestination = "/volume" availabilityZone = "us-west-2b" containerInstanceArn = "containerInstance-test" + hostIp = "0.0.0.0" ) func TestTaskResponse(t *testing.T) { @@ -462,6 +464,19 @@ func TestTaskResponseMarshal(t *testing.T) { } func TestContainerResponseMarshal(t *testing.T) { + testCases := []struct { + description string + includeV4Metadata bool + }{ + { + "task container response without v4 metadata", + false, + }, + { + "task container response with v4 metadata", + true, + }, + } timeRFC3339, _ := time.Parse(time.RFC3339, "2014-11-12T11:45:26Z") expectedContainerResponseMap := map[string]interface{}{ @@ -549,20 +564,28 @@ func TestContainerResponseMarshal(t *testing.T) { }, }, } - gomock.InOrder( - state.EXPECT().ContainerByID(containerID).Return(dockerContainer, true), - state.EXPECT().TaskByID(containerID).Return(task, true), - ) - containerResponse, err := NewContainerResponseFromState(containerID, state, false) - assert.NoError(t, err) + for _, tc := range testCases { + t.Run(tc.description, func(t *testing.T) { + gomock.InOrder( + state.EXPECT().ContainerByID(containerID).Return(dockerContainer, true), + state.EXPECT().TaskByID(containerID).Return(task, true), + ) + if tc.includeV4Metadata { + container.KnownPortBindingsUnsafe[0].BindIP = hostIp + expectedContainerResponseMap["Ports"].([]interface{})[0].(map[string]interface{})["HostIp"] = hostIp + } + containerResponse, err := NewContainerResponseFromState(containerID, state, tc.includeV4Metadata) + assert.NoError(t, err) - containerResponseJSON, err := json.Marshal(containerResponse) - assert.NoError(t, err) + containerResponseJSON, err := json.Marshal(containerResponse) + assert.NoError(t, err) - containerResponseMap := make(map[string]interface{}) - json.Unmarshal(containerResponseJSON, &containerResponseMap) - assert.Equal(t, expectedContainerResponseMap, containerResponseMap) + containerResponseMap := make(map[string]interface{}) + json.Unmarshal(containerResponseJSON, &containerResponseMap) + assert.Equal(t, expectedContainerResponseMap, containerResponseMap) + }) + } } func TestTaskResponseWithV4TagsError(t *testing.T) { diff --git a/agent/handlers/v2/stats_response_test.go b/agent/handlers/v2/stats_response_test.go index b3ca475b097..b1d2635dbc8 100644 --- a/agent/handlers/v2/stats_response_test.go +++ b/agent/handlers/v2/stats_response_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/v3/response_test.go b/agent/handlers/v3/response_test.go index 3039a57aff5..38d5b27845b 100644 --- a/agent/handlers/v3/response_test.go +++ b/agent/handlers/v3/response_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/handlers/v4/response_test.go b/agent/handlers/v4/response_test.go index e99b52435df..103eaf6a3bc 100644 --- a/agent/handlers/v4/response_test.go +++ b/agent/handlers/v4/response_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/httpclient/httpclient_test.go b/agent/httpclient/httpclient_test.go index 362722da25c..e8967718c28 100644 --- a/agent/httpclient/httpclient_test.go +++ b/agent/httpclient/httpclient_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/audit/audit_log_test.go b/agent/logger/audit/audit_log_test.go index f2a6b53045d..c88ea4ee643 100644 --- a/agent/logger/audit/audit_log_test.go +++ b/agent/logger/audit/audit_log_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/buffer_pool_test.go b/agent/logger/buffer_pool_test.go index 9cca77e8e66..9eeb97971b2 100644 --- a/agent/logger/buffer_pool_test.go +++ b/agent/logger/buffer_pool_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/eventlog_windows.go b/agent/logger/eventlog_windows.go index f920da0c26f..f72539c1271 100644 --- a/agent/logger/eventlog_windows.go +++ b/agent/logger/eventlog_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/field/constants.go b/agent/logger/field/constants.go index a056689c8da..18b79d38a99 100644 --- a/agent/logger/field/constants.go +++ b/agent/logger/field/constants.go @@ -14,19 +14,25 @@ package field const ( + TaskID = "task" TaskARN = "taskARN" Container = "container" + DockerId = "dockerId" ManagedAgent = "managedAgent" KnownStatus = "knownStatus" + KnownSent = "knownSent" DesiredStatus = "desiredStatus" SentStatus = "sentStatus" FailedStatus = "failedStatus" - Sequence = "sequence" + Sequence = "seqnum" Reason = "reason" Status = "status" RuntimeID = "runtimeID" + Elapsed = "elapsed" Resource = "resource" Error = "error" Event = "event" Image = "image" + Volume = "volume" + Time = "time" ) diff --git a/agent/logger/format_test.go b/agent/logger/format_test.go index 80e43d58d3a..91445da5f1b 100644 --- a/agent/logger/format_test.go +++ b/agent/logger/format_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/global_test.go b/agent/logger/global_test.go index 032a9691afe..05435114080 100644 --- a/agent/logger/global_test.go +++ b/agent/logger/global_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/log_init_test.go b/agent/logger/log_init_test.go index 0148f1dbd09..496c1b07757 100644 --- a/agent/logger/log_init_test.go +++ b/agent/logger/log_init_test.go @@ -1,4 +1,5 @@ //go:build unit || integration +// +build unit integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/log_test.go b/agent/logger/log_test.go index 61e6747a1f6..8d25cd434ea 100644 --- a/agent/logger/log_test.go +++ b/agent/logger/log_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/log_unix_test.go b/agent/logger/log_unix_test.go index 64be35cff4a..0b063d1837b 100644 --- a/agent/logger/log_unix_test.go +++ b/agent/logger/log_unix_test.go @@ -1,4 +1,5 @@ //go:build !windows && unit +// +build !windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/log_windows_test.go b/agent/logger/log_windows_test.go index 9f2fe12ce78..c763d595ac8 100644 --- a/agent/logger/log_windows_test.go +++ b/agent/logger/log_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/platform_unix.go b/agent/logger/platform_unix.go index 8b8ef812649..85cb4385906 100644 --- a/agent/logger/platform_unix.go +++ b/agent/logger/platform_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/logger/structured_logger_test.go b/agent/logger/structured_logger_test.go index d51c2a76178..94e1bd8dd3c 100644 --- a/agent/logger/structured_logger_test.go +++ b/agent/logger/structured_logger_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/metrics/metrics_test.go b/agent/metrics/metrics_test.go index 6f454da97f2..e9271853db8 100644 --- a/agent/metrics/metrics_test.go +++ b/agent/metrics/metrics_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/s3/s3_test.go b/agent/s3/s3_test.go index 636bd8cc146..b44a221651c 100644 --- a/agent/s3/s3_test.go +++ b/agent/s3/s3_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/sighandlers/debug_handler.go b/agent/sighandlers/debug_handler.go index cdb15a47704..790e61b11a9 100644 --- a/agent/sighandlers/debug_handler.go +++ b/agent/sighandlers/debug_handler.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/sighandlers/debug_handler_windows.go b/agent/sighandlers/debug_handler_windows.go index 27f383055ca..2c414848ad1 100644 --- a/agent/sighandlers/debug_handler_windows.go +++ b/agent/sighandlers/debug_handler_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/sighandlers/termination_handler_test.go b/agent/sighandlers/termination_handler_test.go index 86369e272fb..610ae69b327 100644 --- a/agent/sighandlers/termination_handler_test.go +++ b/agent/sighandlers/termination_handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/ssm/ssm_test.go b/agent/ssm/ssm_test.go index 4028b8c5450..2699083beac 100644 --- a/agent/ssm/ssm_test.go +++ b/agent/ssm/ssm_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/dependencies/dependencies_windows.go b/agent/statemanager/dependencies/dependencies_windows.go index 7d920a24f01..709bcf0d021 100644 --- a/agent/statemanager/dependencies/dependencies_windows.go +++ b/agent/statemanager/dependencies/dependencies_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/helper_unix_test.go b/agent/statemanager/helper_unix_test.go index f141753b8ea..9c164e1f26f 100644 --- a/agent/statemanager/helper_unix_test.go +++ b/agent/statemanager/helper_unix_test.go @@ -1,4 +1,5 @@ //go:build !windows && unit +// +build !windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/helper_windows_test.go b/agent/statemanager/helper_windows_test.go index 4d4539c71f9..178cc6b03cc 100644 --- a/agent/statemanager/helper_windows_test.go +++ b/agent/statemanager/helper_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_test.go b/agent/statemanager/state_manager_test.go index bec7cec51d7..b4d297ca26a 100644 --- a/agent/statemanager/state_manager_test.go +++ b/agent/statemanager/state_manager_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_unix.go b/agent/statemanager/state_manager_unix.go index 7bd207fec03..ddf9ebfebd9 100644 --- a/agent/statemanager/state_manager_unix.go +++ b/agent/statemanager/state_manager_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_unix_test.go b/agent/statemanager/state_manager_unix_test.go index 209422b4e87..0b72687df03 100644 --- a/agent/statemanager/state_manager_unix_test.go +++ b/agent/statemanager/state_manager_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_win_test.go b/agent/statemanager/state_manager_win_test.go index 68bf2a182e9..33abcdccac3 100644 --- a/agent/statemanager/state_manager_win_test.go +++ b/agent/statemanager/state_manager_win_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_windows.go b/agent/statemanager/state_manager_windows.go index cc79d16007f..09362c5fe25 100644 --- a/agent/statemanager/state_manager_windows.go +++ b/agent/statemanager/state_manager_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/statemanager/state_manager_windows_test.go b/agent/statemanager/state_manager_windows_test.go index b347501f404..0d31c4b8f76 100644 --- a/agent/statemanager/state_manager_windows_test.go +++ b/agent/statemanager/state_manager_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/common_unix_test.go b/agent/stats/common_unix_test.go index fe488de2613..928364211d6 100644 --- a/agent/stats/common_unix_test.go +++ b/agent/stats/common_unix_test.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/common_windows_test.go b/agent/stats/common_windows_test.go index 349aec3fa61..e818904ad6e 100644 --- a/agent/stats/common_windows_test.go +++ b/agent/stats/common_windows_test.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/container_test.go b/agent/stats/container_test.go index 9adfb90e9ea..bba649b0f62 100644 --- a/agent/stats/container_test.go +++ b/agent/stats/container_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/engine.go b/agent/stats/engine.go index ef19761c482..7b5ce54dd9e 100644 --- a/agent/stats/engine.go +++ b/agent/stats/engine.go @@ -22,6 +22,9 @@ import ( "sync" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + "github.com/cihub/seelog" "github.com/pborman/uuid" "github.com/pkg/errors" @@ -165,7 +168,10 @@ func (engine *DockerStatsEngine) addAndStartStatsContainer(containerID string) { defer engine.lock.Unlock() statsContainer, statsTaskContainer, err := engine.addContainerUnsafe(containerID) if err != nil { - seelog.Debugf("Adding container to stats watch list failed, container: %s, err: %v", containerID, err) + logger.Debug("Adding container to stats watchlist failed", logger.Fields{ + field.Container: containerID, + field.Error: err, + }) return } @@ -182,7 +188,10 @@ func (engine *DockerStatsEngine) addAndStartStatsContainer(containerID string) { dockerContainer, errResolveContainer := engine.resolver.ResolveContainer(containerID) if errResolveContainer != nil { - seelog.Debugf("Could not map container ID to container, container: %s, err: %s", containerID, err) + logger.Debug("Could not map container ID to container", logger.Fields{ + field.Container: containerID, + field.Error: err, + }) return } @@ -191,7 +200,9 @@ func (engine *DockerStatsEngine) addAndStartStatsContainer(containerID string) { if statsTaskContainer != nil && dockerContainer.Container.Type == apicontainer.ContainerCNIPause { statsTaskContainer.StartStatsCollection() } else { - seelog.Debugf("stats task container is nil, cannot start task stats collection") + logger.Debug("Stats task container is nil, cannot start task stats collection", logger.Fields{ + field.Container: containerID, + }) } } @@ -204,7 +215,7 @@ func (engine *DockerStatsEngine) MustInit(ctx context.Context, taskEngine ecseng engine.ctx = derivedCtx // TODO ensure that this is done only once per engine object - seelog.Info("Initializing stats engine") + logger.Info("Initializing stats engine") engine.cluster = cluster engine.containerInstanceArn = containerInstanceArn @@ -221,7 +232,9 @@ func (engine *DockerStatsEngine) MustInit(ctx context.Context, taskEngine ecseng } err = engine.synchronizeState() if err != nil { - seelog.Warnf("Synchronize the container state failed, err: %v", err) + logger.Warn("Synchronize the container state failed", logger.Fields{ + field.Error: err, + }) } go engine.waitToStop() @@ -243,7 +256,7 @@ func (engine *DockerStatsEngine) Disable() { func (engine *DockerStatsEngine) waitToStop() { // Waiting for the event stream to close <-engine.containerChangeEventStream.Context().Done() - seelog.Debug("Event stream closed, stop listening to the event stream") + logger.Debug("Event stream closed, stop listening to the event stream") engine.containerChangeEventStream.Unsubscribe(containerChangeHandler) engine.removeAll() } @@ -280,7 +293,7 @@ func (engine *DockerStatsEngine) addToStatsTaskMapUnsafe(task *apitask.Task, doc return } containerpid := strconv.Itoa(containerInspect.State.Pid) - statsTaskContainer, err = newStatsTaskContainer(task.Arn, containerpid, numberOfContainers, + statsTaskContainer, err = newStatsTaskContainer(task.Arn, task.GetID(), containerpid, numberOfContainers, engine.resolver, engine.config.PollingMetricsWaitDuration, task.ENIs) if err != nil { return @@ -494,13 +507,18 @@ func (engine *DockerStatsEngine) stopTrackingContainerUnsafe(container *StatsCon // docker task engine. If the docker task engine has already removed // the container from its state, there's no point in stats engine tracking the // container. So, clean-up anyway. - seelog.Warnf("Error determining if the container %s is terminal, removing from stats, err: %v", container.containerMetadata.DockerID, err) + logger.Warn("Error determining if the container is terminal, removing from stats", logger.Fields{ + field.Container: container.containerMetadata.DockerID, + field.Error: err, + }) engine.doRemoveContainerUnsafe(container, taskARN) return true } if terminal { // Container is in known terminal state. Stop collection metrics. - seelog.Infof("Container %s is terminal, removing from stats", container.containerMetadata.DockerID) + logger.Info("Container is terminal, removing from stats", logger.Fields{ + field.Container: container.containerMetadata.DockerID, + }) engine.doRemoveContainerUnsafe(container, taskARN) return true } @@ -657,12 +675,18 @@ func (engine *DockerStatsEngine) taskContainerMetricsUnsafe(taskArn string) ([]* // CPU and Memory are both critical, so skip the container if either of these fail. cpuStatsSet, err := container.statsQueue.GetCPUStatsSet() if err != nil { - seelog.Infof("cloudwatch metrics for container %v not collected, reason (cpu): %v", dockerID, err) + logger.Error("Error collecting cloudwatch metrics for container", logger.Fields{ + field.Container: dockerID, + field.Error: err, + }) continue } memoryStatsSet, err := container.statsQueue.GetMemoryStatsSet() if err != nil { - seelog.Infof("cloudwatch metrics for container %v not collected, reason (memory): %v", dockerID, err) + logger.Error("Error collecting cloudwatch metrics for container", logger.Fields{ + field.Container: dockerID, + field.Error: err, + }) continue } @@ -674,14 +698,20 @@ func (engine *DockerStatsEngine) taskContainerMetricsUnsafe(taskArn string) ([]* storageStatsSet, err := container.statsQueue.GetStorageStatsSet() if err != nil { - seelog.Warnf("Error getting storage stats, err: %v, container: %v", err, dockerID) + logger.Warn("Error getting storage stats for container", logger.Fields{ + field.Container: dockerID, + field.Error: err, + }) } else { containerMetric.StorageStatsSet = storageStatsSet } task, err := engine.resolver.ResolveTask(dockerID) if err != nil { - seelog.Warnf("Task not found for container ID: %s", dockerID) + logger.Warn("Task not found for container", logger.Fields{ + field.Container: dockerID, + field.Error: err, + }) } else { // send network stats for default/bridge/nat/awsvpc network modes if !task.IsNetworkModeAWSVPC() && container.containerMetadata.NetworkMode != hostNetworkMode && @@ -689,7 +719,10 @@ func (engine *DockerStatsEngine) taskContainerMetricsUnsafe(taskArn string) ([]* networkStatsSet, err := container.statsQueue.GetNetworkStatsSet() if err != nil { // we log the error and still continue to publish cpu, memory stats - seelog.Warnf("Error getting network stats: %v, container: %v", err, dockerID) + logger.Warn("Error getting network stats for container", logger.Fields{ + field.Container: dockerID, + field.Error: err, + }) } else { containerMetric.NetworkStatsSet = networkStatsSet } @@ -705,7 +738,11 @@ func (engine *DockerStatsEngine) taskContainerMetricsUnsafe(taskArn string) ([]* if dockerContainer.Container.Type != apicontainer.ContainerCNIPause { networkStats, err := taskStatsMap.StatsQueue.GetNetworkStatsSet() if err != nil { - seelog.Warnf("error getting network stats: %v, task: %v", err, taskArn) + logger.Warn("Error getting network stats for container", logger.Fields{ + field.TaskARN: taskArn, + field.Container: dockerContainer.DockerID, + field.Error: err, + }) } else { containerMetric.NetworkStatsSet = networkStats } @@ -788,7 +825,11 @@ func (engine *DockerStatsEngine) ContainerDockerStats(taskARN string, containerI } containerNetworkRateStats = taskStats.StatsQueue.GetLastNetworkStatPerSec() } else { - seelog.Warnf("Network stats not found for container %s", containerID) + logger.Warn("Network stats not found for container", logger.Fields{ + field.TaskID: task.GetID(), + field.Container: containerID, + field.Error: err, + }) } } diff --git a/agent/stats/engine_integ_test.go b/agent/stats/engine_integ_test.go index fa344c9bcbc..05918a3b40f 100644 --- a/agent/stats/engine_integ_test.go +++ b/agent/stats/engine_integ_test.go @@ -1,4 +1,5 @@ //go:build integration +// +build integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/engine_test.go b/agent/stats/engine_test.go index 00a03076eaf..cafe17ea461 100644 --- a/agent/stats/engine_test.go +++ b/agent/stats/engine_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/engine_unix_integ_test.go b/agent/stats/engine_unix_integ_test.go index 578e571979c..152b1d918d3 100644 --- a/agent/stats/engine_unix_integ_test.go +++ b/agent/stats/engine_unix_integ_test.go @@ -1,4 +1,5 @@ //go:build !windows && integration +// +build !windows,integration // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/engine_unix_test.go b/agent/stats/engine_unix_test.go index 657c9999ec5..073f51951a3 100644 --- a/agent/stats/engine_unix_test.go +++ b/agent/stats/engine_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/queue_test.go b/agent/stats/queue_test.go index d727b7746ee..919c5a35032 100644 --- a/agent/stats/queue_test.go +++ b/agent/stats/queue_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/task.go b/agent/stats/task.go index b8cdea6fcbd..fb692c03ae5 100644 --- a/agent/stats/task.go +++ b/agent/stats/task.go @@ -18,12 +18,14 @@ import ( "fmt" "time" + "github.com/aws/amazon-ecs-agent/agent/logger" + "github.com/aws/amazon-ecs-agent/agent/logger/field" + apitaskstatus "github.com/aws/amazon-ecs-agent/agent/api/task/status" "github.com/aws/amazon-ecs-agent/agent/config" "github.com/aws/amazon-ecs-agent/agent/stats/resolver" "github.com/aws/amazon-ecs-agent/agent/utils/retry" - "github.com/cihub/seelog" "github.com/docker/docker/api/types" dockerstats "github.com/docker/docker/api/types" ) @@ -51,31 +53,40 @@ func (taskStat *StatsTask) StopStatsCollection() { } func (taskStat *StatsTask) collect() { - taskArn := taskStat.TaskMetadata.TaskArn + taskId := taskStat.TaskMetadata.TaskId backoff := retry.NewExponentialBackoff(time.Second*1, time.Second*10, 0.5, 2) for { err := taskStat.processStatsStream() select { case <-taskStat.Ctx.Done(): - seelog.Debugf("Stopping stats collection for taskStat %s", taskArn) + logger.Debug("Stopping stats collection for taskStat", logger.Fields{ + field.TaskID: taskId, + }) return default: if err != nil { d := backoff.Duration() time.Sleep(d) - seelog.Debugf("Error querying stats for task %s: %v", taskArn, err) + logger.Debug("Error querying stats for task", logger.Fields{ + field.TaskID: taskId, + field.Error: err, + }) } // We were disconnected from the stats stream. // Check if the task is terminal. If it is, stop collecting metrics. terminal, err := taskStat.terminal() if err != nil { // Error determining if the task is terminal. clean-up anyway. - seelog.Warnf("Error determining if the task %s is terminal, stopping stats collection: %v", - taskArn, err) + logger.Warn("Error determining if the task is terminal, stopping stats collection", logger.Fields{ + field.TaskID: taskId, + field.Error: err, + }) taskStat.StopStatsCollection() } else if terminal { - seelog.Infof("Task %s is terminal, stopping stats collection", taskArn) + logger.Warn("Task is terminal, stopping stats collection", logger.Fields{ + field.TaskID: taskId, + }) taskStat.StopStatsCollection() } } @@ -83,18 +94,22 @@ func (taskStat *StatsTask) collect() { } func (taskStat *StatsTask) processStatsStream() error { - taskArn := taskStat.TaskMetadata.TaskArn + taskId := taskStat.TaskMetadata.TaskId awsvpcNetworkStats, errC := taskStat.getAWSVPCNetworkStats() returnError := false for { select { case <-taskStat.Ctx.Done(): - seelog.Info("task context is done") + logger.Info("Task context is done", logger.Fields{ + field.TaskID: taskId, + }) return nil case err := <-errC: - seelog.Warnf("Error encountered processing metrics stream from host, this may affect "+ - "cloudwatch metric accuracy: %s", err) + logger.Warn("Error encountered processing metrics stream from host, this may affect cloudwatch metric accuracy", logger.Fields{ + field.TaskID: taskId, + field.Error: err, + }) returnError = true case rawStat, ok := <-awsvpcNetworkStats: if !ok { @@ -104,7 +119,10 @@ func (taskStat *StatsTask) processStatsStream() error { return nil } if err := taskStat.StatsQueue.Add(rawStat); err != nil { - seelog.Warnf("Task [%s]: error converting stats: %v", taskArn, err) + logger.Warn("Error converting task stats", logger.Fields{ + field.TaskID: taskId, + field.Error: err, + }) } } diff --git a/agent/stats/task_linux.go b/agent/stats/task_linux.go index ca07c3a7571..7baa4a0fdda 100644 --- a/agent/stats/task_linux.go +++ b/agent/stats/task_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -48,7 +49,7 @@ type StatsTask struct { netlinkinterface netlinkwrapper.NetLink } -func newStatsTaskContainer(taskARN string, containerPID string, numberOfContainers int, +func newStatsTaskContainer(taskARN, taskId, containerPID string, numberOfContainers int, resolver resolver.ContainerMetadataResolver, publishInterval time.Duration, _ task.TaskENIs) (*StatsTask, error) { nsAgent := nswrapper.NewNS() netlinkclient := netlinkwrapper.New() @@ -58,6 +59,7 @@ func newStatsTaskContainer(taskARN string, containerPID string, numberOfContaine statsTaskCommon: &statsTaskCommon{ TaskMetadata: &TaskMetadata{ TaskArn: taskARN, + TaskId: taskId, ContainerPID: containerPID, NumberContainers: numberOfContainers, }, diff --git a/agent/stats/task_linux_test.go b/agent/stats/task_linux_test.go index 05997589126..1ebedf665dd 100644 --- a/agent/stats/task_linux_test.go +++ b/agent/stats/task_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/task_unspecified.go b/agent/stats/task_unspecified.go index c7ed848c4ad..cd96cdeb47c 100644 --- a/agent/stats/task_unspecified.go +++ b/agent/stats/task_unspecified.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -31,7 +32,7 @@ type StatsTask struct { *statsTaskCommon } -func newStatsTaskContainer(taskARN string, containerPID string, numberOfContainers int, +func newStatsTaskContainer(taskARN, taskId, containerPID string, numberOfContainers int, resolver resolver.ContainerMetadataResolver, publishInterval time.Duration, _ task.TaskENIs) (*StatsTask, error) { return nil, errors.New("Unsupported platform") } diff --git a/agent/stats/task_windows.go b/agent/stats/task_windows.go index 4bbc84fbaa9..165cab6ca02 100644 --- a/agent/stats/task_windows.go +++ b/agent/stats/task_windows.go @@ -68,7 +68,7 @@ type StatsTask struct { *statsTaskCommon } -func newStatsTaskContainer(taskARN string, containerPID string, numberOfContainers int, +func newStatsTaskContainer(taskARN, taskId, containerPID string, numberOfContainers int, resolver resolver.ContainerMetadataResolver, publishInterval time.Duration, taskENIs task.TaskENIs) (*StatsTask, error) { ctx, cancel := context.WithCancel(context.Background()) diff --git a/agent/stats/types.go b/agent/stats/types.go index 113a4213fac..bc1540149ce 100644 --- a/agent/stats/types.go +++ b/agent/stats/types.go @@ -70,6 +70,7 @@ type ContainerMetadata struct { // TaskMetadata contains meta-data information for a task. type TaskMetadata struct { TaskArn string `json:"-"` + TaskId string `json:"-"` // ContainerPID is the PID of the pause container in the awsvpc task. ContainerPID string `json:"-"` DeviceName []string `json:"-"` diff --git a/agent/stats/utils_test.go b/agent/stats/utils_test.go index 3210c0eed8e..bdca0e169a4 100644 --- a/agent/stats/utils_test.go +++ b/agent/stats/utils_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/utils_unix.go b/agent/stats/utils_unix.go index c89bf5af6cf..28dbcc5fa0e 100644 --- a/agent/stats/utils_unix.go +++ b/agent/stats/utils_unix.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/utils_unix_test.go b/agent/stats/utils_unix_test.go index 84fa3a83a8e..414554cb7fd 100644 --- a/agent/stats/utils_unix_test.go +++ b/agent/stats/utils_unix_test.go @@ -1,4 +1,5 @@ //go:build !windows && unit +// +build !windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/utils_windows.go b/agent/stats/utils_windows.go index b8b202ffa6f..9e0545720ea 100644 --- a/agent/stats/utils_windows.go +++ b/agent/stats/utils_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/stats/utils_windows_test.go b/agent/stats/utils_windows_test.go index 792c500e8e4..6d611bb2fe9 100644 --- a/agent/stats/utils_windows_test.go +++ b/agent/stats/utils_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/asmauth/asmauth_test.go b/agent/taskresource/asmauth/asmauth_test.go index 09c032e9a60..73f14fbae36 100644 --- a/agent/taskresource/asmauth/asmauth_test.go +++ b/agent/taskresource/asmauth/asmauth_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/asmauth/asmauthstatus_test.go b/agent/taskresource/asmauth/asmauthstatus_test.go index 54882cb7940..e35218bfcdf 100644 --- a/agent/taskresource/asmauth/asmauthstatus_test.go +++ b/agent/taskresource/asmauth/asmauthstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/asmsecret/asmsecret.go b/agent/taskresource/asmsecret/asmsecret.go index 8ace7eb21c1..f8fcd3ac66f 100644 --- a/agent/taskresource/asmsecret/asmsecret.go +++ b/agent/taskresource/asmsecret/asmsecret.go @@ -269,7 +269,7 @@ func (secret *ASMSecretResource) Create() error { // Get the maximum number of errors to be returned, which will be one error per goroutine errorEvents := make(chan error, len(secret.requiredSecrets)) - seelog.Infof("ASM secret resource: retrieving secrets for containers in task: [%s]", secret.taskARN) + seelog.Debugf("ASM secret resource: retrieving secrets for containers in task: [%s]", secret.taskARN) secret.secretData = make(map[string]string) for _, asmsecret := range secret.getRequiredSecrets() { @@ -300,7 +300,7 @@ func (secret *ASMSecretResource) retrieveASMSecretValue(apiSecret apicontainer.S defer wg.Done() asmClient := secret.asmClientCreator.NewASMClient(apiSecret.Region, iamCredentials) - seelog.Infof("ASM secret resource: retrieving resource for secret %v in region %s for task: [%s]", apiSecret.ValueFrom, apiSecret.Region, secret.taskARN) + seelog.Debugf("ASM secret resource: retrieving resource for secret %v in region %s for task: [%s]", apiSecret.ValueFrom, apiSecret.Region, secret.taskARN) input, jsonKey, err := getASMParametersFromInput(apiSecret.ValueFrom) if err != nil { errorEvents <- fmt.Errorf("trying to retrieve secret with value %s resulted in error: %v", apiSecret.ValueFrom, err) diff --git a/agent/taskresource/asmsecret/asmsecret_test.go b/agent/taskresource/asmsecret/asmsecret_test.go index 59fbd0128ff..d1b093a53a6 100644 --- a/agent/taskresource/asmsecret/asmsecret_test.go +++ b/agent/taskresource/asmsecret/asmsecret_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/asmsecret/asmsecretstatus_test.go b/agent/taskresource/asmsecret/asmsecretstatus_test.go index dac469c84fe..b779aea9785 100644 --- a/agent/taskresource/asmsecret/asmsecretstatus_test.go +++ b/agent/taskresource/asmsecret/asmsecretstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/cgroup.go b/agent/taskresource/cgroup/cgroup.go index e4ebcdc78ee..6fe0a82054f 100644 --- a/agent/taskresource/cgroup/cgroup.go +++ b/agent/taskresource/cgroup/cgroup.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/cgroup_test.go b/agent/taskresource/cgroup/cgroup_test.go index 7aa409a5e33..f37accd6a5c 100644 --- a/agent/taskresource/cgroup/cgroup_test.go +++ b/agent/taskresource/cgroup/cgroup_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/cgroup_unsupported.go b/agent/taskresource/cgroup/cgroup_unsupported.go index 6208687b7b0..544130a606c 100644 --- a/agent/taskresource/cgroup/cgroup_unsupported.go +++ b/agent/taskresource/cgroup/cgroup_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux +// +build !linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/cgroupstatus.go b/agent/taskresource/cgroup/cgroupstatus.go index 156e7ac6788..6e6e0df8c50 100644 --- a/agent/taskresource/cgroup/cgroupstatus.go +++ b/agent/taskresource/cgroup/cgroupstatus.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/cgroupstatus_test.go b/agent/taskresource/cgroup/cgroupstatus_test.go index 482e4535104..065b3df2456 100644 --- a/agent/taskresource/cgroup/cgroupstatus_test.go +++ b/agent/taskresource/cgroup/cgroupstatus_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/cgroup_controller_linux.go b/agent/taskresource/cgroup/control/cgroup_controller_linux.go index 915363b1a6f..18542c35174 100644 --- a/agent/taskresource/cgroup/control/cgroup_controller_linux.go +++ b/agent/taskresource/cgroup/control/cgroup_controller_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/cgroup_controller_linux_test.go b/agent/taskresource/cgroup/control/cgroup_controller_linux_test.go index 027f5912e29..9e46dfa3ead 100644 --- a/agent/taskresource/cgroup/control/cgroup_controller_linux_test.go +++ b/agent/taskresource/cgroup/control/cgroup_controller_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/factory/factory_linux.go b/agent/taskresource/cgroup/control/factory/factory_linux.go index 6e9e3f895d3..6ce587e7ec5 100644 --- a/agent/taskresource/cgroup/control/factory/factory_linux.go +++ b/agent/taskresource/cgroup/control/factory/factory_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/factory/generate_mocks_linux.go b/agent/taskresource/cgroup/control/factory/generate_mocks_linux.go index 31143cc3e8b..e36c74e54f7 100644 --- a/agent/taskresource/cgroup/control/factory/generate_mocks_linux.go +++ b/agent/taskresource/cgroup/control/factory/generate_mocks_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/factory/mock/mock_cgroups_linux.go b/agent/taskresource/cgroup/control/factory/mock/mock_cgroups_linux.go index e66882973bc..7cf7559b4fd 100644 --- a/agent/taskresource/cgroup/control/factory/mock/mock_cgroups_linux.go +++ b/agent/taskresource/cgroup/control/factory/mock/mock_cgroups_linux.go @@ -22,6 +22,7 @@ import ( reflect "reflect" cgroups "github.com/containerd/cgroups" + v1 "github.com/containerd/cgroups/stats/v1" gomock "github.com/golang/mock/gomock" specs_go "github.com/opencontainers/runtime-spec/specs-go" ) @@ -50,17 +51,60 @@ func (m *MockCgroup) EXPECT() *MockCgroupMockRecorder { } // Add mocks base method -func (m *MockCgroup) Add(arg0 cgroups.Process) error { +func (m *MockCgroup) Add(arg0 cgroups.Process, arg1 ...cgroups.Name) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Add", arg0) + varargs := []interface{}{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Add", varargs...) ret0, _ := ret[0].(error) return ret0 } // Add indicates an expected call of Add -func (mr *MockCgroupMockRecorder) Add(arg0 interface{}) *gomock.Call { +func (mr *MockCgroupMockRecorder) Add(arg0 interface{}, arg1 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockCgroup)(nil).Add), varargs...) +} + +// AddProc mocks base method +func (m *MockCgroup) AddProc(arg0 uint64, arg1 ...cgroups.Name) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AddProc", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddProc indicates an expected call of AddProc +func (mr *MockCgroupMockRecorder) AddProc(arg0 interface{}, arg1 ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddProc", reflect.TypeOf((*MockCgroup)(nil).AddProc), varargs...) +} + +// AddTask mocks base method +func (m *MockCgroup) AddTask(arg0 cgroups.Process, arg1 ...cgroups.Name) error { + m.ctrl.T.Helper() + varargs := []interface{}{arg0} + for _, a := range arg1 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "AddTask", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// AddTask indicates an expected call of AddTask +func (mr *MockCgroupMockRecorder) AddTask(arg0 interface{}, arg1 ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Add", reflect.TypeOf((*MockCgroup)(nil).Add), arg0) + varargs := append([]interface{}{arg0}, arg1...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddTask", reflect.TypeOf((*MockCgroup)(nil).AddTask), varargs...) } // Delete mocks base method @@ -150,15 +194,30 @@ func (mr *MockCgroupMockRecorder) Processes(arg0, arg1 interface{}) *gomock.Call return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Processes", reflect.TypeOf((*MockCgroup)(nil).Processes), arg0, arg1) } +// RegisterMemoryEvent mocks base method +func (m *MockCgroup) RegisterMemoryEvent(arg0 cgroups.MemoryEvent) (uintptr, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RegisterMemoryEvent", arg0) + ret0, _ := ret[0].(uintptr) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RegisterMemoryEvent indicates an expected call of RegisterMemoryEvent +func (mr *MockCgroupMockRecorder) RegisterMemoryEvent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RegisterMemoryEvent", reflect.TypeOf((*MockCgroup)(nil).RegisterMemoryEvent), arg0) +} + // Stat mocks base method -func (m *MockCgroup) Stat(arg0 ...cgroups.ErrorHandler) (*cgroups.Stats, error) { +func (m *MockCgroup) Stat(arg0 ...cgroups.ErrorHandler) (*v1.Metrics, error) { m.ctrl.T.Helper() varargs := []interface{}{} for _, a := range arg0 { varargs = append(varargs, a) } ret := m.ctrl.Call(m, "Stat", varargs...) - ret0, _ := ret[0].(*cgroups.Stats) + ret0, _ := ret[0].(*v1.Metrics) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -197,6 +256,21 @@ func (mr *MockCgroupMockRecorder) Subsystems() *gomock.Call { return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Subsystems", reflect.TypeOf((*MockCgroup)(nil).Subsystems)) } +// Tasks mocks base method +func (m *MockCgroup) Tasks(arg0 cgroups.Name, arg1 bool) ([]cgroups.Process, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Tasks", arg0, arg1) + ret0, _ := ret[0].([]cgroups.Process) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Tasks indicates an expected call of Tasks +func (mr *MockCgroupMockRecorder) Tasks(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tasks", reflect.TypeOf((*MockCgroup)(nil).Tasks), arg0, arg1) +} + // Thaw mocks base method func (m *MockCgroup) Thaw() error { m.ctrl.T.Helper() diff --git a/agent/taskresource/cgroup/control/generate_mocks_linux.go b/agent/taskresource/cgroup/control/generate_mocks_linux.go index 38219dc0189..7b7a341acaa 100644 --- a/agent/taskresource/cgroup/control/generate_mocks_linux.go +++ b/agent/taskresource/cgroup/control/generate_mocks_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/init_linux.go b/agent/taskresource/cgroup/control/init_linux.go index f06a15ca302..a3380896e15 100644 --- a/agent/taskresource/cgroup/control/init_linux.go +++ b/agent/taskresource/cgroup/control/init_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -17,14 +18,16 @@ package control import ( "github.com/aws/amazon-ecs-agent/agent/config" + "github.com/aws/amazon-ecs-agent/agent/logger" - "github.com/cihub/seelog" specs "github.com/opencontainers/runtime-spec/specs-go" ) // Init is used to setup the cgroup root for ecs func (c *control) Init() error { - seelog.Infof("Creating root ecs cgroup: %s", config.DefaultTaskCgroupPrefix) + logger.Info("Creating root ecs cgroup", logger.Fields{ + "cgroup": config.DefaultTaskCgroupPrefix, + }) // Build cgroup spec cgroupSpec := &Spec{ diff --git a/agent/taskresource/cgroup/control/init_linux_test.go b/agent/taskresource/cgroup/control/init_linux_test.go index fc218362e8a..6d0a3d27095 100644 --- a/agent/taskresource/cgroup/control/init_linux_test.go +++ b/agent/taskresource/cgroup/control/init_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/cgroup/control/types_linux.go b/agent/taskresource/cgroup/control/types_linux.go index d6c0842609a..50a6a6df5bd 100644 --- a/agent/taskresource/cgroup/control/types_linux.go +++ b/agent/taskresource/cgroup/control/types_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/credentialspec/credentialspec_unsupported.go b/agent/taskresource/credentialspec/credentialspec_unsupported.go index fc48ea5ecdb..62ac255561e 100644 --- a/agent/taskresource/credentialspec/credentialspec_unsupported.go +++ b/agent/taskresource/credentialspec/credentialspec_unsupported.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/credentialspec/credentialspec_windows.go b/agent/taskresource/credentialspec/credentialspec_windows.go index 72ac9d2216c..b7b69d92267 100644 --- a/agent/taskresource/credentialspec/credentialspec_windows.go +++ b/agent/taskresource/credentialspec/credentialspec_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/credentialspec/credentialspec_windows_test.go b/agent/taskresource/credentialspec/credentialspec_windows_test.go index dfe6a49aa8c..3741dca27e9 100644 --- a/agent/taskresource/credentialspec/credentialspec_windows_test.go +++ b/agent/taskresource/credentialspec/credentialspec_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/envFiles/envfile_test.go b/agent/taskresource/envFiles/envfile_test.go index ad7943c14e4..6e15702de62 100644 --- a/agent/taskresource/envFiles/envfile_test.go +++ b/agent/taskresource/envFiles/envfile_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/envFiles/envfilestatus_test.go b/agent/taskresource/envFiles/envfilestatus_test.go index 1bbbb7a0ad8..2c87ad70c39 100644 --- a/agent/taskresource/envFiles/envfilestatus_test.go +++ b/agent/taskresource/envFiles/envfilestatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelens_unimplemented.go b/agent/taskresource/firelens/firelens_unimplemented.go index b6a69a67485..36adcf28a68 100644 --- a/agent/taskresource/firelens/firelens_unimplemented.go +++ b/agent/taskresource/firelens/firelens_unimplemented.go @@ -1,4 +1,5 @@ //go:build !linux +// +build !linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelens_unix.go b/agent/taskresource/firelens/firelens_unix.go index 1646ed71eb3..7c53139fdf8 100644 --- a/agent/taskresource/firelens/firelens_unix.go +++ b/agent/taskresource/firelens/firelens_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelens_unix_test.go b/agent/taskresource/firelens/firelens_unix_test.go index a4573152c24..d7cf8624897 100644 --- a/agent/taskresource/firelens/firelens_unix_test.go +++ b/agent/taskresource/firelens/firelens_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelensconfig_unix.go b/agent/taskresource/firelens/firelensconfig_unix.go index 1ed4d75be95..dbc1709d98c 100644 --- a/agent/taskresource/firelens/firelensconfig_unix.go +++ b/agent/taskresource/firelens/firelensconfig_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelensconfig_unix_test.go b/agent/taskresource/firelens/firelensconfig_unix_test.go index 9fed0fae327..1a18f0cf49c 100644 --- a/agent/taskresource/firelens/firelensconfig_unix_test.go +++ b/agent/taskresource/firelens/firelensconfig_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/firelensstatus_test.go b/agent/taskresource/firelens/firelensstatus_test.go index d128f54af82..5a171aa56db 100644 --- a/agent/taskresource/firelens/firelensstatus_test.go +++ b/agent/taskresource/firelens/firelensstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/json_unix.go b/agent/taskresource/firelens/json_unix.go index 8ee89d2c55d..ba3d8c6be24 100644 --- a/agent/taskresource/firelens/json_unix.go +++ b/agent/taskresource/firelens/json_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/firelens/json_unix_test.go b/agent/taskresource/firelens/json_unix_test.go index 4cd5ba12775..dec3cdbfed1 100644 --- a/agent/taskresource/firelens/json_unix_test.go +++ b/agent/taskresource/firelens/json_unix_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go index 6d45f55dc8b..1e2bee5ea2f 100644 --- a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_unsupported.go @@ -1,4 +1,5 @@ //go:build !windows +// +build !windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go index 1350d52098b..cd2175c5d26 100644 --- a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go index 0d369c76509..e55116ad3ed 100644 --- a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserver_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go index 276d29e326e..0f9e0bce848 100644 --- a/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go +++ b/agent/taskresource/fsxwindowsfileserver/fsxwindowsfileserverstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/ssmsecret/ssmsecret.go b/agent/taskresource/ssmsecret/ssmsecret.go index 7a921832a52..d9ff06a52c2 100644 --- a/agent/taskresource/ssmsecret/ssmsecret.go +++ b/agent/taskresource/ssmsecret/ssmsecret.go @@ -335,7 +335,7 @@ func (secret *SSMSecretResource) retrieveSSMSecretValues(region string, names [] defer wg.Done() ssmClient := secret.ssmClientCreator.NewSSMClient(region, iamCredentials) - seelog.Infof("ssm secret resource: retrieving resource for secrets %v in region [%s] in task: [%s]", names, region, secret.taskARN) + seelog.Debugf("ssm secret resource: retrieving resource for secrets %v in region [%s] in task: [%s]", names, region, secret.taskARN) secValueMap, err := ssm.GetSecretsFromSSM(names, ssmClient) if err != nil { errorEvents <- fmt.Errorf("fetching secret data from SSM Parameter Store in %s: %v", region, err) diff --git a/agent/taskresource/ssmsecret/ssmsecret_test.go b/agent/taskresource/ssmsecret/ssmsecret_test.go index 8c530bc0be2..de1f13f4c22 100644 --- a/agent/taskresource/ssmsecret/ssmsecret_test.go +++ b/agent/taskresource/ssmsecret/ssmsecret_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/ssmsecret/ssmsecretstatus_test.go b/agent/taskresource/ssmsecret/ssmsecretstatus_test.go index 3e1722fb906..4a86aea20e1 100644 --- a/agent/taskresource/ssmsecret/ssmsecretstatus_test.go +++ b/agent/taskresource/ssmsecret/ssmsecretstatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/types/types_linux_test.go b/agent/taskresource/types/types_linux_test.go index 7f3a683a482..a5facfa1a0e 100644 --- a/agent/taskresource/types/types_linux_test.go +++ b/agent/taskresource/types/types_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/types/types_test.go b/agent/taskresource/types/types_test.go index f90c47540c1..98553b83905 100644 --- a/agent/taskresource/types/types_test.go +++ b/agent/taskresource/types/types_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/types_unix.go b/agent/taskresource/types_unix.go index bf9489b828f..a509a9d99ef 100644 --- a/agent/taskresource/types_unix.go +++ b/agent/taskresource/types_unix.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/types_unsupported.go b/agent/taskresource/types_unsupported.go index 106d78d493c..749ff5b85d9 100644 --- a/agent/taskresource/types_unsupported.go +++ b/agent/taskresource/types_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/types_windows.go b/agent/taskresource/types_windows.go index f189f2318ed..810f57f39ad 100644 --- a/agent/taskresource/types_windows.go +++ b/agent/taskresource/types_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/volume/dockervolume_test.go b/agent/taskresource/volume/dockervolume_test.go index 2b7b5f2990b..952c0774346 100644 --- a/agent/taskresource/volume/dockervolume_test.go +++ b/agent/taskresource/volume/dockervolume_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/taskresource/volume/volumestatus_test.go b/agent/taskresource/volume/volumestatus_test.go index f2bbc093f23..4fb1fc92132 100644 --- a/agent/taskresource/volume/volumestatus_test.go +++ b/agent/taskresource/volume/volumestatus_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/tcs/client/client_test.go b/agent/tcs/client/client_test.go index 883b8c82add..17a6110ead5 100644 --- a/agent/tcs/client/client_test.go +++ b/agent/tcs/client/client_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/tcs/handler/handler_test.go b/agent/tcs/handler/handler_test.go index e815b148530..3d5278fadc0 100644 --- a/agent/tcs/handler/handler_test.go +++ b/agent/tcs/handler/handler_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/tcs/handler/types_test.go b/agent/tcs/handler/types_test.go index 98ac4a09a58..6879f5c1bff 100644 --- a/agent/tcs/handler/types_test.go +++ b/agent/tcs/handler/types_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/tools.go b/agent/tools.go index bb248e6b6dc..4a6061cdfdd 100644 --- a/agent/tools.go +++ b/agent/tools.go @@ -1,4 +1,5 @@ //go:build tools +// +build tools // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/arn.go b/agent/utils/arn.go new file mode 100644 index 00000000000..96a8a01318b --- /dev/null +++ b/agent/utils/arn.go @@ -0,0 +1,33 @@ +package utils + +import ( + "strings" + + "github.com/aws/aws-sdk-go/aws/arn" + "github.com/pkg/errors" +) + +const ( + arnResourceDelimiter = "/" +) + +// TaskIdFromArn derives the task id from the task arn +// Reference: http://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-ecs +func TaskIdFromArn(taskArn string) (string, error) { + // Parse taskARN + parsedARN, err := arn.Parse(taskArn) + if err != nil { + return "", err + } + + // Get task resource section + resource := parsedARN.Resource + + if !strings.Contains(resource, arnResourceDelimiter) { + return "", errors.New("malformed task ARN resource") + } + + resourceSplit := strings.Split(resource, arnResourceDelimiter) + + return resourceSplit[len(resourceSplit)-1], nil +} diff --git a/agent/utils/compare_versions_test.go b/agent/utils/compare_versions_test.go index d9b7883d467..b00b10b1889 100644 --- a/agent/utils/compare_versions_test.go +++ b/agent/utils/compare_versions_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/cpuinfo.go b/agent/utils/cpuinfo.go index 390768043d5..0fa8f845de9 100644 --- a/agent/utils/cpuinfo.go +++ b/agent/utils/cpuinfo.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/cpuinfo_test.go b/agent/utils/cpuinfo_test.go index bf86ee282d6..d629ec94ca3 100644 --- a/agent/utils/cpuinfo_test.go +++ b/agent/utils/cpuinfo_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/json_test.go b/agent/utils/json_test.go index 6e4c6803835..b9746c2e677 100644 --- a/agent/utils/json_test.go +++ b/agent/utils/json_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/license_test.go b/agent/utils/license_test.go index d66f674db4c..7403ce2747a 100644 --- a/agent/utils/license_test.go +++ b/agent/utils/license_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/nswrapper/ns_linux.go b/agent/utils/nswrapper/ns_linux.go index 03e7b2f6285..630adfc5666 100644 --- a/agent/utils/nswrapper/ns_linux.go +++ b/agent/utils/nswrapper/ns_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/retry/backoff_test.go b/agent/utils/retry/backoff_test.go index 232349650ce..d68ccde8aef 100644 --- a/agent/utils/retry/backoff_test.go +++ b/agent/utils/retry/backoff_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/retry/exponential_backoff_test.go b/agent/utils/retry/exponential_backoff_test.go index 7583eb9f2ef..5571f49051b 100644 --- a/agent/utils/retry/exponential_backoff_test.go +++ b/agent/utils/retry/exponential_backoff_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/retry/retry.go b/agent/utils/retry/retry.go index f8acac21a17..bbb77cbf4d2 100644 --- a/agent/utils/retry/retry.go +++ b/agent/utils/retry/retry.go @@ -14,9 +14,10 @@ package retry import ( + "context" + apierrors "github.com/aws/amazon-ecs-agent/agent/api/errors" "github.com/aws/amazon-ecs-agent/agent/utils/ttime" - "golang.org/x/net/context" ) var _time ttime.Time = &ttime.DefaultTime{} diff --git a/agent/utils/retry/retry_test.go b/agent/utils/retry/retry_test.go index 4a5546bc7e7..ae602f787e5 100644 --- a/agent/utils/retry/retry_test.go +++ b/agent/utils/retry/retry_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // @@ -16,6 +17,7 @@ package retry import ( + "context" "errors" "testing" "time" @@ -25,7 +27,6 @@ import ( mock_ttime "github.com/aws/amazon-ecs-agent/agent/utils/ttime/mocks" "github.com/golang/mock/gomock" "github.com/stretchr/testify/assert" - "golang.org/x/net/context" ) func TestRetryWithBackoff(t *testing.T) { diff --git a/agent/utils/sync/sequential_waitgroup_test.go b/agent/utils/sync/sequential_waitgroup_test.go index 31f713e2395..ff289f364c6 100644 --- a/agent/utils/sync/sequential_waitgroup_test.go +++ b/agent/utils/sync/sequential_waitgroup_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/ticker_test.go b/agent/utils/ticker_test.go index 535eb629b5e..6dc65e89b9e 100644 --- a/agent/utils/ticker_test.go +++ b/agent/utils/ticker_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_linux.go b/agent/utils/utils_linux.go index 281f413527d..aaa2931a15e 100644 --- a/agent/utils/utils_linux.go +++ b/agent/utils/utils_linux.go @@ -1,4 +1,5 @@ //go:build linux +// +build linux // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_linux_test.go b/agent/utils/utils_linux_test.go index 73b24be11e0..ea369097c94 100644 --- a/agent/utils/utils_linux_test.go +++ b/agent/utils/utils_linux_test.go @@ -1,4 +1,5 @@ //go:build linux && unit +// +build linux,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_test.go b/agent/utils/utils_test.go index 1e477b6bfd9..6ed9a076bdd 100644 --- a/agent/utils/utils_test.go +++ b/agent/utils/utils_test.go @@ -1,4 +1,5 @@ //go:build unit +// +build unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_unsupported.go b/agent/utils/utils_unsupported.go index 6109dff49d1..cc93b15e9bd 100644 --- a/agent/utils/utils_unsupported.go +++ b/agent/utils/utils_unsupported.go @@ -1,4 +1,5 @@ //go:build !linux && !windows +// +build !linux,!windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_windows.go b/agent/utils/utils_windows.go index 072df48b470..938db186bf8 100644 --- a/agent/utils/utils_windows.go +++ b/agent/utils/utils_windows.go @@ -1,4 +1,5 @@ //go:build windows +// +build windows // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/utils/utils_windows_test.go b/agent/utils/utils_windows_test.go index ad22e500fc3..6b09d902bce 100644 --- a/agent/utils/utils_windows_test.go +++ b/agent/utils/utils_windows_test.go @@ -1,4 +1,5 @@ //go:build windows && unit +// +build windows,unit // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // diff --git a/agent/vendor/github.com/containerd/cgroups/.gitignore b/agent/vendor/github.com/containerd/cgroups/.gitignore index 528cd5b39b7..3465c14cf77 100644 --- a/agent/vendor/github.com/containerd/cgroups/.gitignore +++ b/agent/vendor/github.com/containerd/cgroups/.gitignore @@ -1 +1,2 @@ example/example +cmd/cgctl/cgctl diff --git a/agent/vendor/github.com/containerd/cgroups/Makefile b/agent/vendor/github.com/containerd/cgroups/Makefile new file mode 100644 index 00000000000..19e6607561d --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/Makefile @@ -0,0 +1,24 @@ +# Copyright The containerd Authors. + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at + +# http://www.apache.org/licenses/LICENSE-2.0 + +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +PACKAGES=$(shell go list ./... | grep -v /vendor/) + +all: cgutil + go build -v + +cgutil: + cd cmd/cgctl && go build -v + +proto: + protobuild --quiet ${PACKAGES} diff --git a/agent/vendor/github.com/containerd/cgroups/Protobuild.toml b/agent/vendor/github.com/containerd/cgroups/Protobuild.toml new file mode 100644 index 00000000000..1c4c802fe12 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/Protobuild.toml @@ -0,0 +1,46 @@ +version = "unstable" +generator = "gogoctrd" +plugins = ["grpc"] + +# Control protoc include paths. Below are usually some good defaults, but feel +# free to try it without them if it works for your project. +[includes] + # Include paths that will be added before all others. Typically, you want to + # treat the root of the project as an include, but this may not be necessary. + # before = ["."] + + # Paths that should be treated as include roots in relation to the vendor + # directory. These will be calculated with the vendor directory nearest the + # target package. + # vendored = ["github.com/gogo/protobuf"] + packages = ["github.com/gogo/protobuf"] + + # Paths that will be added untouched to the end of the includes. We use + # `/usr/local/include` to pickup the common install location of protobuf. + # This is the default. + after = ["/usr/local/include", "/usr/include"] + +# This section maps protobuf imports to Go packages. These will become +# `-M` directives in the call to the go protobuf generator. +[packages] + "gogoproto/gogo.proto" = "github.com/gogo/protobuf/gogoproto" + "google/protobuf/any.proto" = "github.com/gogo/protobuf/types" + "google/protobuf/descriptor.proto" = "github.com/gogo/protobuf/protoc-gen-gogo/descriptor" + "google/protobuf/field_mask.proto" = "github.com/gogo/protobuf/types" + "google/protobuf/timestamp.proto" = "github.com/gogo/protobuf/types" + +# Aggregrate the API descriptors to lock down API changes. +[[descriptors]] +prefix = "github.com/containerd/cgroups/stats/v1" +target = "stats/v1/metrics.pb.txt" +ignore_files = [ + "google/protobuf/descriptor.proto", + "gogoproto/gogo.proto" +] +[[descriptors]] +prefix = "github.com/containerd/cgroups/v2/stats" +target = "v2/stats/metrics.pb.txt" +ignore_files = [ + "google/protobuf/descriptor.proto", + "gogoproto/gogo.proto" +] diff --git a/agent/vendor/github.com/containerd/cgroups/README.md b/agent/vendor/github.com/containerd/cgroups/README.md index 89007ebbb7b..fc2c7a9be4d 100644 --- a/agent/vendor/github.com/containerd/cgroups/README.md +++ b/agent/vendor/github.com/containerd/cgroups/README.md @@ -1,8 +1,9 @@ # cgroups -[![Build Status](https://travis-ci.org/containerd/cgroups.svg?branch=master)](https://travis-ci.org/containerd/cgroups) - -[![codecov](https://codecov.io/gh/containerd/cgroups/branch/master/graph/badge.svg)](https://codecov.io/gh/containerd/cgroups) +[![Build Status](https://github.com/containerd/cgroups/workflows/CI/badge.svg)](https://github.com/containerd/cgroups/actions?query=workflow%3ACI) +[![codecov](https://codecov.io/gh/containerd/cgroups/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/cgroups) +[![GoDoc](https://godoc.org/github.com/containerd/cgroups?status.svg)](https://godoc.org/github.com/containerd/cgroups) +[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/cgroups)](https://goreportcard.com/report/github.com/containerd/cgroups) Go package for creating, managing, inspecting, and destroying cgroups. The resources format for settings on the cgroup uses the OCI runtime-spec found @@ -64,7 +65,7 @@ To update the resources applied in the cgroup ```go shares = uint64(200) if err := control.Update(&specs.LinuxResources{ - CPU: &specs.CPU{ + CPU: &specs.LinuxCPU{ Shares: &shares, }, }); err != nil { @@ -92,6 +93,11 @@ processes, err := control.Processes(cgroups.Devices, recursive) stats, err := control.Stat() ``` +By adding `cgroups.IgnoreNotExist` all non-existent files will be ignored, e.g. swap memory stats without swap enabled +```go +stats, err := control.Stat(cgroups.IgnoreNotExist) +``` + ### Move process across cgroups This allows you to take processes from one cgroup and move them to another. @@ -105,3 +111,39 @@ err := control.MoveTo(destination) ```go subCgroup, err := control.New("child", resources) ``` + +### Registering for memory events + +This allows you to get notified by an eventfd for v1 memory cgroups events. + +```go +event := cgroups.MemoryThresholdEvent(50 * 1024 * 1024, false) +efd, err := control.RegisterMemoryEvent(event) +``` + +```go +event := cgroups.MemoryPressureEvent(cgroups.MediumPressure, cgroups.DefaultMode) +efd, err := control.RegisterMemoryEvent(event) +``` + +```go +efd, err := control.OOMEventFD() +// or by using RegisterMemoryEvent +event := cgroups.OOMEvent() +efd, err := control.RegisterMemoryEvent(event) +``` + +### Attention + +All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name + +## Project details + +Cgroups is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). +As a containerd sub-project, you will find the: + + * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), + * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), + * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) + +information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/agent/vendor/github.com/containerd/cgroups/Vagrantfile b/agent/vendor/github.com/containerd/cgroups/Vagrantfile new file mode 100644 index 00000000000..4596ad8a7d4 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/Vagrantfile @@ -0,0 +1,46 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| +# Fedora box is used for testing cgroup v2 support + config.vm.box = "fedora/32-cloud-base" + config.vm.provider :virtualbox do |v| + v.memory = 2048 + v.cpus = 2 + end + config.vm.provider :libvirt do |v| + v.memory = 2048 + v.cpus = 2 + end + config.vm.provision "shell", inline: <<-SHELL + set -eux -o pipefail + # configuration + GO_VERSION="1.15" + + # install gcc and Golang + dnf -y install gcc + curl -fsSL "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" | tar Cxz /usr/local + + # setup env vars + cat >> /etc/profile.d/sh.local < /test.sh < 0 { + return nil + } + + // Even the kernel is compiled with the CFQ scheduler, the cgroup may not use + // block devices with the CFQ scheduler. If so, we should fallback to throttle.* files. + settings = []blkioStatSettings{ + { + name: "throttle.io_serviced", + entry: &stats.Blkio.IoServicedRecursive, + }, + { + name: "throttle.io_service_bytes", + entry: &stats.Blkio.IoServiceBytesRecursive, + }, + } for _, t := range settings { if err := b.readEntry(devices, path, t.name, t.entry); err != nil { return err @@ -119,25 +172,22 @@ func (b *blkioController) Stat(path string, stats *Stats) error { return nil } -func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]BlkioEntry) error { - f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name))) +func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*v1.BlkIOEntry) error { + f, err := os.Open(filepath.Join(b.Path(path), "blkio."+name)) if err != nil { return err } defer f.Close() sc := bufio.NewScanner(f) for sc.Scan() { - if err := sc.Err(); err != nil { - return err - } // format: dev type amount - fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine) + fields := strings.FieldsFunc(sc.Text(), splitBlkIOStatLine) if len(fields) < 3 { if len(fields) == 2 && fields[0] == "Total" { // skip total line continue } else { - return fmt.Errorf("Invalid line found while parsing %s: %s", path, sc.Text()) + return fmt.Errorf("invalid line found while parsing %s: %s", path, sc.Text()) } } major, err := strconv.ParseUint(fields[0], 10, 64) @@ -158,7 +208,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str if err != nil { return err } - *entry = append(*entry, BlkioEntry{ + *entry = append(*entry, &v1.BlkIOEntry{ Device: devices[deviceKey{major, minor}], Major: major, Minor: minor, @@ -166,35 +216,46 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str Value: v, }) } - return nil + return sc.Err() } func createBlkioSettings(blkio *specs.LinuxBlockIO) []blkioSettings { - settings := []blkioSettings{ - { - name: "weight", - value: blkio.Weight, - format: uintf, - }, - { - name: "leaf_weight", - value: blkio.LeafWeight, - format: uintf, - }, - } - for _, wd := range blkio.WeightDevice { + settings := []blkioSettings{} + + if blkio.Weight != nil { settings = append(settings, blkioSettings{ - name: "weight_device", - value: wd, - format: weightdev, - }, + name: "weight", + value: blkio.Weight, + format: uintf, + }) + } + if blkio.LeafWeight != nil { + settings = append(settings, blkioSettings{ - name: "leaf_weight_device", - value: wd, - format: weightleafdev, + name: "leaf_weight", + value: blkio.LeafWeight, + format: uintf, }) } + for _, wd := range blkio.WeightDevice { + if wd.Weight != nil { + settings = append(settings, + blkioSettings{ + name: "weight_device", + value: wd, + format: weightdev, + }) + } + if wd.LeafWeight != nil { + settings = append(settings, + blkioSettings{ + name: "leaf_weight_device", + value: wd, + format: weightleafdev, + }) + } + } for _, t := range []struct { name string list []specs.LinuxThrottleDevice @@ -235,7 +296,7 @@ type blkioSettings struct { type blkioStatSettings struct { name string - entry *[]BlkioEntry + entry *[]*v1.BlkIOEntry } func uintf(v interface{}) []byte { @@ -244,12 +305,12 @@ func uintf(v interface{}) []byte { func weightdev(v interface{}) []byte { wd := v.(specs.LinuxWeightDevice) - return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, wd.Weight)) + return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, *wd.Weight)) } func weightleafdev(v interface{}) []byte { wd := v.(specs.LinuxWeightDevice) - return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, wd.LeafWeight)) + return []byte(fmt.Sprintf("%d:%d %d", wd.Major, wd.Minor, *wd.LeafWeight)) } func throttleddev(v interface{}) []byte { @@ -257,7 +318,7 @@ func throttleddev(v interface{}) []byte { return []byte(fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate)) } -func splitBlkioStatLine(r rune) bool { +func splitBlkIOStatLine(r rune) bool { return r == ' ' || r == ':' } @@ -268,56 +329,33 @@ type deviceKey struct { // getDevices makes a best effort attempt to read all the devices into a map // keyed by major and minor number. Since devices may be mapped multiple times, // we err on taking the first occurrence. -func getDevices(path string) (map[deviceKey]string, error) { - // TODO(stevvooe): We are ignoring lots of errors. It might be kind of - // challenging to debug this if we aren't mapping devices correctly. - // Consider logging these errors. - devices := map[deviceKey]string{} - if err := filepath.Walk(path, func(p string, fi os.FileInfo, err error) error { +func getDevices(r io.Reader) (map[deviceKey]string, error) { + + var ( + s = bufio.NewScanner(r) + devices = make(map[deviceKey]string) + ) + for i := 0; s.Scan(); i++ { + if i < 2 { + continue + } + fields := strings.Fields(s.Text()) + major, err := strconv.Atoi(fields[0]) if err != nil { - return err + return nil, err } - switch { - case fi.IsDir(): - switch fi.Name() { - case "pts", "shm", "fd", "mqueue", ".lxc", ".lxd-mounts": - return filepath.SkipDir - default: - return nil - } - case fi.Name() == "console": - return nil - default: - if fi.Mode()&os.ModeDevice == 0 { - // skip non-devices - return nil - } - - st, ok := fi.Sys().(*syscall.Stat_t) - if !ok { - return fmt.Errorf("%s: unable to convert to system stat", p) - } - - key := deviceKey{major(st.Rdev), minor(st.Rdev)} - if _, ok := devices[key]; ok { - return nil // skip it if we have already populated the path. - } - - devices[key] = p + minor, err := strconv.Atoi(fields[1]) + if err != nil { + return nil, err } - - return nil - }); err != nil { - return nil, err + key := deviceKey{ + major: uint64(major), + minor: uint64(minor), + } + if _, ok := devices[key]; ok { + continue + } + devices[key] = filepath.Join("/dev", fields[3]) } - - return devices, nil -} - -func major(devNumber uint64) uint64 { - return (devNumber >> 8) & 0xfff -} - -func minor(devNumber uint64) uint64 { - return (devNumber & 0xff) | ((devNumber >> 12) & 0xfff00) + return devices, s.Err() } diff --git a/agent/vendor/github.com/containerd/cgroups/cgroup.go b/agent/vendor/github.com/containerd/cgroups/cgroup.go index 0aea83222dc..0fab1cecfe2 100644 --- a/agent/vendor/github.com/containerd/cgroups/cgroup.go +++ b/agent/vendor/github.com/containerd/cgroups/cgroup.go @@ -1,56 +1,119 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( + "errors" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" "strings" "sync" - specs "github.com/opencontainers/runtime-spec/specs-go" + v1 "github.com/containerd/cgroups/stats/v1" + + "github.com/opencontainers/runtime-spec/specs-go" ) // New returns a new control via the cgroup cgroups interface -func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources) (Cgroup, error) { +func New(hierarchy Hierarchy, path Path, resources *specs.LinuxResources, opts ...InitOpts) (Cgroup, error) { + config := newInitConfig() + for _, o := range opts { + if err := o(config); err != nil { + return nil, err + } + } subsystems, err := hierarchy() if err != nil { return nil, err } + var active []Subsystem for _, s := range subsystems { + // check if subsystem exists if err := initializeSubsystem(s, path, resources); err != nil { + if err == ErrControllerNotActive { + if config.InitCheck != nil { + if skerr := config.InitCheck(s, path, err); skerr != nil { + if skerr != ErrIgnoreSubsystem { + return nil, skerr + } + } + } + continue + } return nil, err } + active = append(active, s) } return &cgroup{ path: path, - subsystems: subsystems, + subsystems: active, }, nil } // Load will load an existing cgroup and allow it to be controlled -func Load(hierarchy Hierarchy, path Path) (Cgroup, error) { +// All static path should not include `/sys/fs/cgroup/` prefix, it should start with your own cgroups name +func Load(hierarchy Hierarchy, path Path, opts ...InitOpts) (Cgroup, error) { + config := newInitConfig() + for _, o := range opts { + if err := o(config); err != nil { + return nil, err + } + } + var activeSubsystems []Subsystem subsystems, err := hierarchy() if err != nil { return nil, err } - // check the the subsystems still exist + // check that the subsystems still exist, and keep only those that actually exist for _, s := range pathers(subsystems) { p, err := path(s.Name()) if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil, ErrCgroupDeleted + } + if err == ErrControllerNotActive { + if config.InitCheck != nil { + if skerr := config.InitCheck(s, path, err); skerr != nil { + if skerr != ErrIgnoreSubsystem { + return nil, skerr + } + } + } + continue + } return nil, err } if _, err := os.Lstat(s.Path(p)); err != nil { if os.IsNotExist(err) { - return nil, ErrCgroupDeleted + continue } return nil, err } + activeSubsystems = append(activeSubsystems, s) + } + // if we do not have any active systems then the cgroup is deleted + if len(activeSubsystems) == 0 { + return nil, ErrCgroupDeleted } return &cgroup{ path: path, - subsystems: subsystems, + subsystems: activeSubsystems, }, nil } @@ -87,8 +150,50 @@ func (c *cgroup) Subsystems() []Subsystem { return c.subsystems } -// Add moves the provided process into the new cgroup -func (c *cgroup) Add(process Process) error { +func (c *cgroup) subsystemsFilter(subsystems ...Name) []Subsystem { + if len(subsystems) == 0 { + return c.subsystems + } + + var filteredSubsystems = []Subsystem{} + for _, s := range c.subsystems { + for _, f := range subsystems { + if s.Name() == f { + filteredSubsystems = append(filteredSubsystems, s) + break + } + } + } + + return filteredSubsystems +} + +// Add moves the provided process into the new cgroup. +// Without additional arguments, the process is added to all the cgroup subsystems. +// When giving Add a list of subsystem names, the process is only added to those +// subsystems, provided that they are active in the targeted cgroup. +func (c *cgroup) Add(process Process, subsystems ...Name) error { + return c.add(process, cgroupProcs, subsystems...) +} + +// AddProc moves the provided process id into the new cgroup. +// Without additional arguments, the process with the given id is added to all +// the cgroup subsystems. When giving AddProc a list of subsystem names, the process +// id is only added to those subsystems, provided that they are active in the targeted +// cgroup. +func (c *cgroup) AddProc(pid uint64, subsystems ...Name) error { + return c.add(Process{Pid: int(pid)}, cgroupProcs, subsystems...) +} + +// AddTask moves the provided tasks (threads) into the new cgroup. +// Without additional arguments, the task is added to all the cgroup subsystems. +// When giving AddTask a list of subsystem names, the task is only added to those +// subsystems, provided that they are active in the targeted cgroup. +func (c *cgroup) AddTask(process Process, subsystems ...Name) error { + return c.add(process, cgroupTasks, subsystems...) +} + +func (c *cgroup) add(process Process, pType procType, subsystems ...Name) error { if process.Pid <= 0 { return ErrInvalidPid } @@ -97,20 +202,17 @@ func (c *cgroup) Add(process Process) error { if c.err != nil { return c.err } - return c.add(process) -} - -func (c *cgroup) add(process Process) error { - for _, s := range pathers(c.subsystems) { + for _, s := range pathers(c.subsystemsFilter(subsystems...)) { p, err := c.path(s.Name()) if err != nil { return err } - if err := ioutil.WriteFile( - filepath.Join(s.Path(p), cgroupProcs), + err = retryingWriteFile( + filepath.Join(s.Path(p), pType), []byte(strconv.Itoa(process.Pid)), defaultFilePerm, - ); err != nil { + ) + if err != nil { return err } } @@ -124,7 +226,7 @@ func (c *cgroup) Delete() error { if c.err != nil { return c.err } - var errors []string + var errs []string for _, s := range c.subsystems { if d, ok := s.(deleter); ok { sp, err := c.path(s.Name()) @@ -132,7 +234,7 @@ func (c *cgroup) Delete() error { return err } if err := d.Delete(sp); err != nil { - errors = append(errors, string(s.Name())) + errs = append(errs, string(s.Name())) } continue } @@ -143,19 +245,19 @@ func (c *cgroup) Delete() error { } path := p.Path(sp) if err := remove(path); err != nil { - errors = append(errors, path) + errs = append(errs, path) } } } - if len(errors) > 0 { - return fmt.Errorf("cgroups: unable to remove paths %s", strings.Join(errors, ", ")) + if len(errs) > 0 { + return fmt.Errorf("cgroups: unable to remove paths %s", strings.Join(errs, ", ")) } c.err = ErrCgroupDeleted return nil } -// Stat returns the current stats for the cgroup -func (c *cgroup) Stat(handlers ...ErrorHandler) (*Stats, error) { +// Stat returns the current metrics for the cgroup +func (c *cgroup) Stat(handlers ...ErrorHandler) (*v1.Metrics, error) { c.mu.Lock() defer c.mu.Unlock() if c.err != nil { @@ -165,9 +267,14 @@ func (c *cgroup) Stat(handlers ...ErrorHandler) (*Stats, error) { handlers = append(handlers, errPassthrough) } var ( - stats = &Stats{} - wg = &sync.WaitGroup{} - errs = make(chan error, len(c.subsystems)) + stats = &v1.Metrics{ + CPU: &v1.CPUStat{ + Throttling: &v1.Throttle{}, + Usage: &v1.CPUUsage{}, + }, + } + wg = &sync.WaitGroup{} + errs = make(chan error, len(c.subsystems)) ) for _, s := range c.subsystems { if ss, ok := s.(stater); ok { @@ -229,15 +336,29 @@ func (c *cgroup) Processes(subsystem Name, recursive bool) ([]Process, error) { if c.err != nil { return nil, c.err } - return c.processes(subsystem, recursive) + return c.processes(subsystem, recursive, cgroupProcs) +} + +// Tasks returns the tasks running inside the cgroup along +// with the subsystem used, pid, and path +func (c *cgroup) Tasks(subsystem Name, recursive bool) ([]Task, error) { + c.mu.Lock() + defer c.mu.Unlock() + if c.err != nil { + return nil, c.err + } + return c.processes(subsystem, recursive, cgroupTasks) } -func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) { +func (c *cgroup) processes(subsystem Name, recursive bool, pType procType) ([]Process, error) { s := c.getSubsystem(subsystem) sp, err := c.path(subsystem) if err != nil { return nil, err } + if s == nil { + return nil, fmt.Errorf("cgroups: %s doesn't exist in %s subsystem", sp, subsystem) + } path := s.(pather).Path(sp) var processes []Process err = filepath.Walk(path, func(p string, info os.FileInfo, err error) error { @@ -245,13 +366,16 @@ func (c *cgroup) processes(subsystem Name, recursive bool) ([]Process, error) { return err } if !recursive && info.IsDir() { + if p == path { + return nil + } return filepath.SkipDir } dir, name := filepath.Split(p) - if name != cgroupProcs { + if name != pType { return nil } - procs, err := readPids(dir, subsystem) + procs, err := readPids(dir, subsystem, pType) if err != nil { return err } @@ -298,7 +422,8 @@ func (c *cgroup) Thaw() error { } // OOMEventFD returns the memory cgroup's out of memory event fd that triggers -// when processes inside the cgroup receive an oom event +// when processes inside the cgroup receive an oom event. Returns +// ErrMemoryNotSupported if memory cgroups is not supported. func (c *cgroup) OOMEventFD() (uintptr, error) { c.mu.Lock() defer c.mu.Unlock() @@ -313,7 +438,26 @@ func (c *cgroup) OOMEventFD() (uintptr, error) { if err != nil { return 0, err } - return s.(*memoryController).OOMEventFD(sp) + return s.(*memoryController).memoryEvent(sp, OOMEvent()) +} + +// RegisterMemoryEvent allows the ability to register for all v1 memory cgroups +// notifications. +func (c *cgroup) RegisterMemoryEvent(event MemoryEvent) (uintptr, error) { + c.mu.Lock() + defer c.mu.Unlock() + if c.err != nil { + return 0, c.err + } + s := c.getSubsystem(Memory) + if s == nil { + return 0, ErrMemoryNotSupported + } + sp, err := c.path(Memory) + if err != nil { + return 0, err + } + return s.(*memoryController).memoryEvent(sp, event) } // State returns the state of the cgroup and its processes @@ -348,12 +492,15 @@ func (c *cgroup) MoveTo(destination Cgroup) error { return c.err } for _, s := range c.subsystems { - processes, err := c.processes(s.Name(), true) + processes, err := c.processes(s.Name(), true, cgroupProcs) if err != nil { return err } for _, p := range processes { if err := destination.Add(p); err != nil { + if strings.Contains(err.Error(), "no such process") { + continue + } return err } } diff --git a/agent/vendor/github.com/containerd/cgroups/control.go b/agent/vendor/github.com/containerd/cgroups/control.go index c83b2417f48..5fcaac6d056 100644 --- a/agent/vendor/github.com/containerd/cgroups/control.go +++ b/agent/vendor/github.com/containerd/cgroups/control.go @@ -1,14 +1,34 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "os" + v1 "github.com/containerd/cgroups/stats/v1" specs "github.com/opencontainers/runtime-spec/specs-go" ) +type procType = string + const ( - cgroupProcs = "cgroup.procs" - defaultDirPerm = 0755 + cgroupProcs procType = "cgroup.procs" + cgroupTasks procType = "tasks" + defaultDirPerm = 0755 ) // defaultFilePerm is a var so that the test framework can change the filemode @@ -19,38 +39,59 @@ const ( var defaultFilePerm = os.FileMode(0) type Process struct { - // Subsystem is the name of the subsystem that the process is in + // Subsystem is the name of the subsystem that the process / task is in. Subsystem Name - // Pid is the process id of the process + // Pid is the process id of the process / task. Pid int - // Path is the full path of the subsystem and location that the process is in + // Path is the full path of the subsystem and location that the process / task is in. Path string } +type Task = Process + // Cgroup handles interactions with the individual groups to perform // actions on them as them main interface to this cgroup package type Cgroup interface { // New creates a new cgroup under the calling cgroup New(string, *specs.LinuxResources) (Cgroup, error) - // Add adds a process to the cgroup - Add(Process) error + // Add adds a process to the cgroup (cgroup.procs). Without additional arguments, + // the process is added to all the cgroup subsystems. When giving Add a list of + // subsystem names, the process is only added to those subsystems, provided that + // they are active in the targeted cgroup. + Add(Process, ...Name) error + // AddProc adds the process with the given id to the cgroup (cgroup.procs). + // Without additional arguments, the process with the given id is added to all + // the cgroup subsystems. When giving AddProc a list of subsystem names, the process + // id is only added to those subsystems, provided that they are active in the targeted + // cgroup. + AddProc(uint64, ...Name) error + // AddTask adds a process to the cgroup (tasks). Without additional arguments, the + // task is added to all the cgroup subsystems. When giving AddTask a list of subsystem + // names, the task is only added to those subsystems, provided that they are active in + // the targeted cgroup. + AddTask(Process, ...Name) error // Delete removes the cgroup as a whole Delete() error // MoveTo moves all the processes under the calling cgroup to the provided one // subsystems are moved one at a time MoveTo(Cgroup) error // Stat returns the stats for all subsystems in the cgroup - Stat(...ErrorHandler) (*Stats, error) + Stat(...ErrorHandler) (*v1.Metrics, error) // Update updates all the subsystems with the provided resource changes Update(resources *specs.LinuxResources) error // Processes returns all the processes in a select subsystem for the cgroup Processes(Name, bool) ([]Process, error) + // Tasks returns all the tasks in a select subsystem for the cgroup + Tasks(Name, bool) ([]Task, error) // Freeze freezes or pauses all processes inside the cgroup Freeze() error // Thaw thaw or resumes all processes inside the cgroup Thaw() error // OOMEventFD returns the memory subsystem's event fd for OOM events OOMEventFD() (uintptr, error) + // RegisterMemoryEvent returns the memory subsystems event fd for whatever memory event was + // registered for. Can alternatively register for the oom event with this method. + RegisterMemoryEvent(MemoryEvent) (uintptr, error) // State returns the cgroups current state State() State // Subsystems returns all the subsystems in the cgroup diff --git a/agent/vendor/github.com/containerd/cgroups/cpu.go b/agent/vendor/github.com/containerd/cgroups/cpu.go index 036bb8fd0e5..27024f17b82 100644 --- a/agent/vendor/github.com/containerd/cgroups/cpu.go +++ b/agent/vendor/github.com/containerd/cgroups/cpu.go @@ -1,13 +1,28 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "bufio" - "fmt" - "io/ioutil" "os" "path/filepath" "strconv" + v1 "github.com/containerd/cgroups/stats/v1" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -67,8 +82,8 @@ func (c *cpuController) Create(path string, resources *specs.LinuxResources) err value = []byte(strconv.FormatInt(*t.ivalue, 10)) } if value != nil { - if err := ioutil.WriteFile( - filepath.Join(c.Path(path), fmt.Sprintf("cpu.%s", t.name)), + if err := retryingWriteFile( + filepath.Join(c.Path(path), "cpu."+t.name), value, defaultFilePerm, ); err != nil { @@ -84,37 +99,27 @@ func (c *cpuController) Update(path string, resources *specs.LinuxResources) err return c.Create(path, resources) } -func (c *cpuController) Stat(path string, stats *Stats) error { +func (c *cpuController) Stat(path string, stats *v1.Metrics) error { f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat")) if err != nil { return err } defer f.Close() // get or create the cpu field because cpuacct can also set values on this struct - stats.cpuMu.Lock() - cpu := stats.Cpu - if cpu == nil { - cpu = &CpuStat{} - stats.Cpu = cpu - } - stats.cpuMu.Unlock() sc := bufio.NewScanner(f) for sc.Scan() { - if err := sc.Err(); err != nil { - return err - } key, v, err := parseKV(sc.Text()) if err != nil { return err } switch key { case "nr_periods": - cpu.Throttling.Periods = v + stats.CPU.Throttling.Periods = v case "nr_throttled": - cpu.Throttling.ThrottledPeriods = v + stats.CPU.Throttling.ThrottledPeriods = v case "throttled_time": - cpu.Throttling.ThrottledTime = v + stats.CPU.Throttling.ThrottledTime = v } } - return nil + return sc.Err() } diff --git a/agent/vendor/github.com/containerd/cgroups/cpuacct.go b/agent/vendor/github.com/containerd/cgroups/cpuacct.go index 329234887a5..e5fc864bd75 100644 --- a/agent/vendor/github.com/containerd/cgroups/cpuacct.go +++ b/agent/vendor/github.com/containerd/cgroups/cpuacct.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -6,6 +22,8 @@ import ( "path/filepath" "strconv" "strings" + + v1 "github.com/containerd/cgroups/stats/v1" ) const nanosecondsInSecond = 1000000000 @@ -30,7 +48,7 @@ func (c *cpuacctController) Path(path string) string { return filepath.Join(c.root, path) } -func (c *cpuacctController) Stat(path string, stats *Stats) error { +func (c *cpuacctController) Stat(path string, stats *v1.Metrics) error { user, kernel, err := c.getUsage(path) if err != nil { return err @@ -43,17 +61,10 @@ func (c *cpuacctController) Stat(path string, stats *Stats) error { if err != nil { return err } - stats.cpuMu.Lock() - cpu := stats.Cpu - if cpu == nil { - cpu = &CpuStat{} - stats.Cpu = cpu - } - stats.cpuMu.Unlock() - cpu.Usage.Total = total - cpu.Usage.User = user - cpu.Usage.Kernel = kernel - cpu.Usage.PerCpu = percpu + stats.CPU.Usage.Total = total + stats.CPU.Usage.User = user + stats.CPU.Usage.Kernel = kernel + stats.CPU.Usage.PerCPU = percpu return nil } diff --git a/agent/vendor/github.com/containerd/cgroups/cpuset.go b/agent/vendor/github.com/containerd/cgroups/cpuset.go index c5bed1d15d5..3cae173bdd1 100644 --- a/agent/vendor/github.com/containerd/cgroups/cpuset.go +++ b/agent/vendor/github.com/containerd/cgroups/cpuset.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -10,7 +26,7 @@ import ( specs "github.com/opencontainers/runtime-spec/specs-go" ) -func NewCputset(root string) *cpusetController { +func NewCpuset(root string) *cpusetController { return &cpusetController{ root: filepath.Join(root, string(Cpuset)), } @@ -41,21 +57,21 @@ func (c *cpusetController) Create(path string, resources *specs.LinuxResources) if resources.CPU != nil { for _, t := range []struct { name string - value *string + value string }{ { name: "cpus", - value: &resources.CPU.Cpus, + value: resources.CPU.Cpus, }, { name: "mems", - value: &resources.CPU.Mems, + value: resources.CPU.Mems, }, } { - if t.value != nil { - if err := ioutil.WriteFile( - filepath.Join(c.Path(path), fmt.Sprintf("cpuset.%s", t.name)), - []byte(*t.value), + if t.value != "" { + if err := retryingWriteFile( + filepath.Join(c.Path(path), "cpuset."+t.name), + []byte(t.value), defaultFilePerm, ); err != nil { return err @@ -66,6 +82,10 @@ func (c *cpusetController) Create(path string, resources *specs.LinuxResources) return nil } +func (c *cpusetController) Update(path string, resources *specs.LinuxResources) error { + return c.Create(path, resources) +} + func (c *cpusetController) getValues(path string) (cpus []byte, mems []byte, err error) { if cpus, err = ioutil.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil && !os.IsNotExist(err) { return @@ -84,15 +104,14 @@ func (c *cpusetController) ensureParent(current, root string) error { if _, err := filepath.Rel(root, parent); err != nil { return nil } - if cleanPath(parent) == root { - return nil - } // Avoid infinite recursion. if parent == current { return fmt.Errorf("cpuset: cgroup parent path outside cgroup root") } - if err := c.ensureParent(parent, root); err != nil { - return err + if cleanPath(parent) != root { + if err := c.ensureParent(parent, root); err != nil { + return err + } } if err := os.MkdirAll(current, defaultDirPerm); err != nil { return err @@ -115,7 +134,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error { return err } if isEmpty(currentCpus) { - if err := ioutil.WriteFile( + if err := retryingWriteFile( filepath.Join(current, "cpuset.cpus"), parentCpus, defaultFilePerm, @@ -124,7 +143,7 @@ func (c *cpusetController) copyIfNeeded(current, parent string) error { } } if isEmpty(currentMems) { - if err := ioutil.WriteFile( + if err := retryingWriteFile( filepath.Join(current, "cpuset.mems"), parentMems, defaultFilePerm, diff --git a/agent/vendor/github.com/containerd/cgroups/devices.go b/agent/vendor/github.com/containerd/cgroups/devices.go index f0dca5c546d..7792566d5ee 100644 --- a/agent/vendor/github.com/containerd/cgroups/devices.go +++ b/agent/vendor/github.com/containerd/cgroups/devices.go @@ -1,8 +1,23 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -42,7 +57,10 @@ func (d *devicesController) Create(path string, resources *specs.LinuxResources) if device.Allow { file = allowDeviceFile } - if err := ioutil.WriteFile( + if device.Type == "" { + device.Type = "a" + } + if err := retryingWriteFile( filepath.Join(d.Path(path), file), []byte(deviceString(device)), defaultFilePerm, @@ -58,11 +76,11 @@ func (d *devicesController) Update(path string, resources *specs.LinuxResources) } func deviceString(device specs.LinuxDeviceCgroup) string { - return fmt.Sprintf("%c %s:%s %s", - &device.Type, + return fmt.Sprintf("%s %s:%s %s", + device.Type, deviceNumber(device.Major), deviceNumber(device.Minor), - &device.Access, + device.Access, ) } diff --git a/agent/vendor/github.com/containerd/cgroups/errors.go b/agent/vendor/github.com/containerd/cgroups/errors.go index d18b4b1df68..f1ad8315c81 100644 --- a/agent/vendor/github.com/containerd/cgroups/errors.go +++ b/agent/vendor/github.com/containerd/cgroups/errors.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -12,7 +28,7 @@ var ( ErrFreezerNotSupported = errors.New("cgroups: freezer cgroup not supported on this system") ErrMemoryNotSupported = errors.New("cgroups: memory cgroup not supported on this system") ErrCgroupDeleted = errors.New("cgroups: cgroup deleted") - ErrNoCgroupMountDestination = errors.New("cgroups: cannot found cgroup mount destination") + ErrNoCgroupMountDestination = errors.New("cgroups: cannot find cgroup mount destination") ) // ErrorHandler is a function that handles and acts on errors diff --git a/agent/vendor/github.com/containerd/cgroups/freezer.go b/agent/vendor/github.com/containerd/cgroups/freezer.go index f53430b51d1..59a7e712836 100644 --- a/agent/vendor/github.com/containerd/cgroups/freezer.go +++ b/agent/vendor/github.com/containerd/cgroups/freezer.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -26,21 +42,15 @@ func (f *freezerController) Path(path string) string { } func (f *freezerController) Freeze(path string) error { - if err := f.changeState(path, Frozen); err != nil { - return err - } return f.waitState(path, Frozen) } func (f *freezerController) Thaw(path string) error { - if err := f.changeState(path, Thawed); err != nil { - return err - } return f.waitState(path, Thawed) } func (f *freezerController) changeState(path string, state State) error { - return ioutil.WriteFile( + return retryingWriteFile( filepath.Join(f.root, path, "freezer.state"), []byte(strings.ToUpper(string(state))), defaultFilePerm, @@ -57,6 +67,9 @@ func (f *freezerController) state(path string) (State, error) { func (f *freezerController) waitState(path string, state State) error { for { + if err := f.changeState(path, state); err != nil { + return err + } current, err := f.state(path) if err != nil { return err diff --git a/agent/vendor/github.com/containerd/cgroups/go.mod b/agent/vendor/github.com/containerd/cgroups/go.mod new file mode 100644 index 00000000000..80d3f6ea630 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/go.mod @@ -0,0 +1,18 @@ +module github.com/containerd/cgroups + +go 1.16 + +require ( + github.com/cilium/ebpf v0.4.0 + github.com/coreos/go-systemd/v22 v22.3.2 + github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect + github.com/docker/go-units v0.4.0 + github.com/godbus/dbus/v5 v5.0.4 + github.com/gogo/protobuf v1.3.2 + github.com/opencontainers/runtime-spec v1.0.2 + github.com/sirupsen/logrus v1.8.1 + github.com/stretchr/testify v1.7.0 + github.com/urfave/cli v1.22.2 + go.uber.org/goleak v1.1.12 + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 +) diff --git a/agent/vendor/github.com/containerd/cgroups/go.sum b/agent/vendor/github.com/containerd/cgroups/go.sum new file mode 100644 index 00000000000..cda30b49f6c --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/go.sum @@ -0,0 +1,98 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/cilium/ebpf v0.4.0 h1:QlHdikaxALkqWasW8hAC1mfR0jdmvbfaBdBPFmRSglA= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/opencontainers/runtime-spec v1.0.2 h1:UfAcuLBJB9Coz72x1hgl8O5RVzTdNiaglX6v2DM6FI0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/agent/vendor/github.com/containerd/cgroups/hierarchy.go b/agent/vendor/github.com/containerd/cgroups/hierarchy.go index b61660d4131..ca3f1b9380b 100644 --- a/agent/vendor/github.com/containerd/cgroups/hierarchy.go +++ b/agent/vendor/github.com/containerd/cgroups/hierarchy.go @@ -1,4 +1,20 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups -// Hierarchy enableds both unified and split hierarchy for cgroups +// Hierarchy enables both unified and split hierarchy for cgroups type Hierarchy func() ([]Subsystem, error) diff --git a/agent/vendor/github.com/containerd/cgroups/hugetlb.go b/agent/vendor/github.com/containerd/cgroups/hugetlb.go index 650bb069f49..c0eb03b24da 100644 --- a/agent/vendor/github.com/containerd/cgroups/hugetlb.go +++ b/agent/vendor/github.com/containerd/cgroups/hugetlb.go @@ -1,12 +1,28 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( - "io/ioutil" "os" "path/filepath" "strconv" "strings" + v1 "github.com/containerd/cgroups/stats/v1" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -40,7 +56,7 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources) return err } for _, limit := range resources.HugepageLimits { - if err := ioutil.WriteFile( + if err := retryingWriteFile( filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", limit.Pagesize, "limit_in_bytes"}, ".")), []byte(strconv.FormatUint(limit.Limit, 10)), defaultFilePerm, @@ -51,20 +67,21 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources) return nil } -func (h *hugetlbController) Stat(path string, stats *Stats) error { - stats.Hugetlb = make(map[string]HugetlbStat) +func (h *hugetlbController) Stat(path string, stats *v1.Metrics) error { for _, size := range h.sizes { s, err := h.readSizeStat(path, size) if err != nil { return err } - stats.Hugetlb[size] = s + stats.Hugetlb = append(stats.Hugetlb, s) } return nil } -func (h *hugetlbController) readSizeStat(path, size string) (HugetlbStat, error) { - var s HugetlbStat +func (h *hugetlbController) readSizeStat(path, size string) (*v1.HugetlbStat, error) { + s := v1.HugetlbStat{ + Pagesize: size, + } for _, t := range []struct { name string value *uint64 @@ -84,9 +101,9 @@ func (h *hugetlbController) readSizeStat(path, size string) (HugetlbStat, error) } { v, err := readUint(filepath.Join(h.Path(path), strings.Join([]string{"hugetlb", size, t.name}, "."))) if err != nil { - return s, err + return nil, err } *t.value = v } - return s, nil + return &s, nil } diff --git a/agent/vendor/github.com/containerd/cgroups/memory.go b/agent/vendor/github.com/containerd/cgroups/memory.go index 45c87962c70..e271866ef94 100644 --- a/agent/vendor/github.com/containerd/cgroups/memory.go +++ b/agent/vendor/github.com/containerd/cgroups/memory.go @@ -1,29 +1,194 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "bufio" "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" "strings" - "syscall" + v1 "github.com/containerd/cgroups/stats/v1" + specs "github.com/opencontainers/runtime-spec/specs-go" "golang.org/x/sys/unix" +) - specs "github.com/opencontainers/runtime-spec/specs-go" +// MemoryEvent is an interface that V1 memory Cgroup notifications implement. Arg returns the +// file name whose fd should be written to "cgroups.event_control". EventFile returns the name of +// the file that supports the notification api e.g. "memory.usage_in_bytes". +type MemoryEvent interface { + Arg() string + EventFile() string +} + +type memoryThresholdEvent struct { + threshold uint64 + swap bool +} + +// MemoryThresholdEvent returns a new memory threshold event to be used with RegisterMemoryEvent. +// If swap is true, the event will be registered using memory.memsw.usage_in_bytes +func MemoryThresholdEvent(threshold uint64, swap bool) MemoryEvent { + return &memoryThresholdEvent{ + threshold, + swap, + } +} + +func (m *memoryThresholdEvent) Arg() string { + return strconv.FormatUint(m.threshold, 10) +} + +func (m *memoryThresholdEvent) EventFile() string { + if m.swap { + return "memory.memsw.usage_in_bytes" + } + return "memory.usage_in_bytes" +} + +type oomEvent struct{} + +// OOMEvent returns a new oom event to be used with RegisterMemoryEvent. +func OOMEvent() MemoryEvent { + return &oomEvent{} +} + +func (oom *oomEvent) Arg() string { + return "" +} + +func (oom *oomEvent) EventFile() string { + return "memory.oom_control" +} + +type memoryPressureEvent struct { + pressureLevel MemoryPressureLevel + hierarchy EventNotificationMode +} + +// MemoryPressureEvent returns a new memory pressure event to be used with RegisterMemoryEvent. +func MemoryPressureEvent(pressureLevel MemoryPressureLevel, hierarchy EventNotificationMode) MemoryEvent { + return &memoryPressureEvent{ + pressureLevel, + hierarchy, + } +} + +func (m *memoryPressureEvent) Arg() string { + return string(m.pressureLevel) + "," + string(m.hierarchy) +} + +func (m *memoryPressureEvent) EventFile() string { + return "memory.pressure_level" +} + +// MemoryPressureLevel corresponds to the memory pressure levels defined +// for memory cgroups. +type MemoryPressureLevel string + +// The three memory pressure levels are as follows. +// - The "low" level means that the system is reclaiming memory for new +// allocations. Monitoring this reclaiming activity might be useful for +// maintaining cache level. Upon notification, the program (typically +// "Activity Manager") might analyze vmstat and act in advance (i.e. +// prematurely shutdown unimportant services). +// - The "medium" level means that the system is experiencing medium memory +// pressure, the system might be making swap, paging out active file caches, +// etc. Upon this event applications may decide to further analyze +// vmstat/zoneinfo/memcg or internal memory usage statistics and free any +// resources that can be easily reconstructed or re-read from a disk. +// - The "critical" level means that the system is actively thrashing, it is +// about to out of memory (OOM) or even the in-kernel OOM killer is on its +// way to trigger. Applications should do whatever they can to help the +// system. It might be too late to consult with vmstat or any other +// statistics, so it is advisable to take an immediate action. +// "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11 +const ( + LowPressure MemoryPressureLevel = "low" + MediumPressure MemoryPressureLevel = "medium" + CriticalPressure MemoryPressureLevel = "critical" ) -func NewMemory(root string) *memoryController { - return &memoryController{ - root: filepath.Join(root, string(Memory)), +// EventNotificationMode corresponds to the notification modes +// for the memory cgroups pressure level notifications. +type EventNotificationMode string + +// There are three optional modes that specify different propagation behavior: +// - "default": this is the default behavior specified above. This mode is the +// same as omitting the optional mode parameter, preserved by backwards +// compatibility. +// - "hierarchy": events always propagate up to the root, similar to the default +// behavior, except that propagation continues regardless of whether there are +// event listeners at each level, with the "hierarchy" mode. In the above +// example, groups A, B, and C will receive notification of memory pressure. +// - "local": events are pass-through, i.e. they only receive notifications when +// memory pressure is experienced in the memcg for which the notification is +// registered. In the above example, group C will receive notification if +// registered for "local" notification and the group experiences memory +// pressure. However, group B will never receive notification, regardless if +// there is an event listener for group C or not, if group B is registered for +// local notification. +// "https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt" Section 11 +const ( + DefaultMode EventNotificationMode = "default" + LocalMode EventNotificationMode = "local" + HierarchyMode EventNotificationMode = "hierarchy" +) + +// NewMemory returns a Memory controller given the root folder of cgroups. +// It may optionally accept other configuration options, such as IgnoreModules(...) +func NewMemory(root string, options ...func(*memoryController)) *memoryController { + mc := &memoryController{ + root: filepath.Join(root, string(Memory)), + ignored: map[string]struct{}{}, + } + for _, opt := range options { + opt(mc) + } + return mc +} + +// IgnoreModules configure the memory controller to not read memory metrics for some +// module names (e.g. passing "memsw" would avoid all the memory.memsw.* entries) +func IgnoreModules(names ...string) func(*memoryController) { + return func(mc *memoryController) { + for _, name := range names { + mc.ignored[name] = struct{}{} + } + } +} + +// OptionalSwap allows the memory controller to not fail if cgroups is not accounting +// Swap memory (there are no memory.memsw.* entries) +func OptionalSwap() func(*memoryController) { + return func(mc *memoryController) { + _, err := os.Stat(filepath.Join(mc.root, "memory.memsw.usage_in_bytes")) + if os.IsNotExist(err) { + mc.ignored["memsw"] = struct{}{} + } } } type memoryController struct { - root string + root string + ignored map[string]struct{} } func (m *memoryController) Name() Name { @@ -41,21 +206,6 @@ func (m *memoryController) Create(path string, resources *specs.LinuxResources) if resources.Memory == nil { return nil } - if resources.Memory.Kernel != nil { - // Check if kernel memory is enabled - // We have to limit the kernel memory here as it won't be accounted at all - // until a limit is set on the cgroup and limit cannot be set once the - // cgroup has children, or if there are already tasks in the cgroup. - for _, i := range []int64{1, -1} { - if err := ioutil.WriteFile( - filepath.Join(m.Path(path), "memory.kmem.limit_in_bytes"), - []byte(strconv.FormatInt(i, 10)), - defaultFilePerm, - ); err != nil { - return checkEBUSY(err) - } - } - } return m.set(path, getMemorySettings(resources)) } @@ -81,37 +231,55 @@ func (m *memoryController) Update(path string, resources *specs.LinuxResources) return m.set(path, settings) } -func (m *memoryController) Stat(path string, stats *Stats) error { - f, err := os.Open(filepath.Join(m.Path(path), "memory.stat")) +func (m *memoryController) Stat(path string, stats *v1.Metrics) error { + fMemStat, err := os.Open(filepath.Join(m.Path(path), "memory.stat")) if err != nil { return err } - defer f.Close() - stats.Memory = &MemoryStat{} - if err := m.parseStats(f, stats.Memory); err != nil { + defer fMemStat.Close() + stats.Memory = &v1.MemoryStat{ + Usage: &v1.MemoryEntry{}, + Swap: &v1.MemoryEntry{}, + Kernel: &v1.MemoryEntry{}, + KernelTCP: &v1.MemoryEntry{}, + } + if err := m.parseStats(fMemStat, stats.Memory); err != nil { + return err + } + + fMemOomControl, err := os.Open(filepath.Join(m.Path(path), "memory.oom_control")) + if err != nil { + return err + } + defer fMemOomControl.Close() + stats.MemoryOomControl = &v1.MemoryOomControl{} + if err := m.parseOomControlStats(fMemOomControl, stats.MemoryOomControl); err != nil { return err } for _, t := range []struct { module string - entry *MemoryEntry + entry *v1.MemoryEntry }{ { module: "", - entry: &stats.Memory.Usage, + entry: stats.Memory.Usage, }, { module: "memsw", - entry: &stats.Memory.Swap, + entry: stats.Memory.Swap, }, { module: "kmem", - entry: &stats.Memory.Kernel, + entry: stats.Memory.Kernel, }, { module: "kmem.tcp", - entry: &stats.Memory.KernelTCP, + entry: stats.Memory.KernelTCP, }, } { + if _, ok := m.ignored[t.module]; ok { + continue + } for _, tt := range []struct { name string value *uint64 @@ -148,44 +316,13 @@ func (m *memoryController) Stat(path string, stats *Stats) error { return nil } -func (m *memoryController) OOMEventFD(path string) (uintptr, error) { - root := m.Path(path) - f, err := os.Open(filepath.Join(root, "memory.oom_control")) - if err != nil { - return 0, err - } - defer f.Close() - fd, _, serr := unix.RawSyscall(unix.SYS_EVENTFD2, 0, unix.FD_CLOEXEC, 0) - if serr != 0 { - return 0, serr - } - if err := writeEventFD(root, f.Fd(), fd); err != nil { - unix.Close(int(fd)) - return 0, err - } - return fd, nil -} - -func writeEventFD(root string, cfd, efd uintptr) error { - f, err := os.OpenFile(filepath.Join(root, "cgroup.event_control"), os.O_WRONLY, 0) - if err != nil { - return err - } - _, err = f.WriteString(fmt.Sprintf("%d %d", efd, cfd)) - f.Close() - return err -} - -func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error { +func (m *memoryController) parseStats(r io.Reader, stat *v1.MemoryStat) error { var ( raw = make(map[string]uint64) sc = bufio.NewScanner(r) line int ) for sc.Scan() { - if err := sc.Err(); err != nil { - return err - } key, v, err := parseKV(sc.Text()) if err != nil { return fmt.Errorf("%d: %v", line, err) @@ -193,6 +330,9 @@ func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error { raw[key] = v line++ } + if err := sc.Err(); err != nil { + return err + } stat.Cache = raw["cache"] stat.RSS = raw["rss"] stat.RSSHuge = raw["rss_huge"] @@ -228,11 +368,34 @@ func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error { return nil } +func (m *memoryController) parseOomControlStats(r io.Reader, stat *v1.MemoryOomControl) error { + var ( + raw = make(map[string]uint64) + sc = bufio.NewScanner(r) + line int + ) + for sc.Scan() { + key, v, err := parseKV(sc.Text()) + if err != nil { + return fmt.Errorf("%d: %v", line, err) + } + raw[key] = v + line++ + } + if err := sc.Err(); err != nil { + return err + } + stat.OomKillDisable = raw["oom_kill_disable"] + stat.UnderOom = raw["under_oom"] + stat.OomKill = raw["oom_kill"] + return nil +} + func (m *memoryController) set(path string, settings []memorySettings) error { for _, t := range settings { if t.value != nil { - if err := ioutil.WriteFile( - filepath.Join(m.Path(path), fmt.Sprintf("memory.%s", t.name)), + if err := retryingWriteFile( + filepath.Join(m.Path(path), "memory."+t.name), []byte(strconv.FormatInt(*t.value, 10)), defaultFilePerm, ); err != nil { @@ -260,6 +423,10 @@ func getMemorySettings(resources *specs.LinuxResources) []memorySettings { name: "limit_in_bytes", value: mem.Limit, }, + { + name: "soft_limit_in_bytes", + value: mem.Reservation, + }, { name: "memsw.limit_in_bytes", value: mem.Swap, @@ -274,7 +441,7 @@ func getMemorySettings(resources *specs.LinuxResources) []memorySettings { }, { name: "oom_control", - value: getOomControlValue(resources), + value: getOomControlValue(mem), }, { name: "swappiness", @@ -283,22 +450,31 @@ func getMemorySettings(resources *specs.LinuxResources) []memorySettings { } } -func checkEBUSY(err error) error { - if pathErr, ok := err.(*os.PathError); ok { - if errNo, ok := pathErr.Err.(syscall.Errno); ok { - if errNo == unix.EBUSY { - return fmt.Errorf( - "failed to set memory.kmem.limit_in_bytes, because either tasks have already joined this cgroup or it has children") - } - } - } - return err -} - -func getOomControlValue(resources *specs.LinuxResources) *int64 { - if resources.DisableOOMKiller != nil && *resources.DisableOOMKiller { +func getOomControlValue(mem *specs.LinuxMemory) *int64 { + if mem.DisableOOMKiller != nil && *mem.DisableOOMKiller { i := int64(1) return &i } return nil } + +func (m *memoryController) memoryEvent(path string, event MemoryEvent) (uintptr, error) { + root := m.Path(path) + efd, err := unix.Eventfd(0, unix.EFD_CLOEXEC) + if err != nil { + return 0, err + } + evtFile, err := os.Open(filepath.Join(root, event.EventFile())) + if err != nil { + unix.Close(efd) + return 0, err + } + defer evtFile.Close() + data := fmt.Sprintf("%d %d %s", efd, evtFile.Fd(), event.Arg()) + evctlPath := filepath.Join(root, "cgroup.event_control") + if err := retryingWriteFile(evctlPath, []byte(data), 0700); err != nil { + unix.Close(efd) + return 0, err + } + return uintptr(efd), nil +} diff --git a/agent/vendor/github.com/containerd/cgroups/named.go b/agent/vendor/github.com/containerd/cgroups/named.go index f0fbf018ef4..06b16c3b157 100644 --- a/agent/vendor/github.com/containerd/cgroups/named.go +++ b/agent/vendor/github.com/containerd/cgroups/named.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import "path/filepath" diff --git a/agent/vendor/github.com/containerd/cgroups/net_cls.go b/agent/vendor/github.com/containerd/cgroups/net_cls.go index b5a4802d3b9..839b06de080 100644 --- a/agent/vendor/github.com/containerd/cgroups/net_cls.go +++ b/agent/vendor/github.com/containerd/cgroups/net_cls.go @@ -1,7 +1,22 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( - "io/ioutil" "os" "path/filepath" "strconv" @@ -32,11 +47,15 @@ func (n *netclsController) Create(path string, resources *specs.LinuxResources) return err } if resources.Network != nil && resources.Network.ClassID != nil && *resources.Network.ClassID > 0 { - return ioutil.WriteFile( - filepath.Join(n.Path(path), "net_cls_classid_u"), + return retryingWriteFile( + filepath.Join(n.Path(path), "net_cls.classid"), []byte(strconv.FormatUint(uint64(*resources.Network.ClassID), 10)), defaultFilePerm, ) } return nil } + +func (n *netclsController) Update(path string, resources *specs.LinuxResources) error { + return n.Create(path, resources) +} diff --git a/agent/vendor/github.com/containerd/cgroups/net_prio.go b/agent/vendor/github.com/containerd/cgroups/net_prio.go index 0959b8e70fb..6362fd084f7 100644 --- a/agent/vendor/github.com/containerd/cgroups/net_prio.go +++ b/agent/vendor/github.com/containerd/cgroups/net_prio.go @@ -1,8 +1,23 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "fmt" - "io/ioutil" "os" "path/filepath" @@ -33,8 +48,8 @@ func (n *netprioController) Create(path string, resources *specs.LinuxResources) } if resources.Network != nil { for _, prio := range resources.Network.Priorities { - if err := ioutil.WriteFile( - filepath.Join(n.Path(path), "net_prio_ifpriomap"), + if err := retryingWriteFile( + filepath.Join(n.Path(path), "net_prio.ifpriomap"), formatPrio(prio.Name, prio.Priority), defaultFilePerm, ); err != nil { diff --git a/agent/vendor/github.com/containerd/cgroups/opts.go b/agent/vendor/github.com/containerd/cgroups/opts.go new file mode 100644 index 00000000000..1e428d04807 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/opts.go @@ -0,0 +1,61 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cgroups + +import ( + "errors" +) + +var ( + // ErrIgnoreSubsystem allows the specific subsystem to be skipped + ErrIgnoreSubsystem = errors.New("skip subsystem") + // ErrDevicesRequired is returned when the devices subsystem is required but + // does not exist or is not active + ErrDevicesRequired = errors.New("devices subsystem is required") +) + +// InitOpts allows configuration for the creation or loading of a cgroup +type InitOpts func(*InitConfig) error + +// InitConfig provides configuration options for the creation +// or loading of a cgroup and its subsystems +type InitConfig struct { + // InitCheck can be used to check initialization errors from the subsystem + InitCheck InitCheck +} + +func newInitConfig() *InitConfig { + return &InitConfig{ + InitCheck: RequireDevices, + } +} + +// InitCheck allows subsystems errors to be checked when initialized or loaded +type InitCheck func(Subsystem, Path, error) error + +// AllowAny allows any subsystem errors to be skipped +func AllowAny(_ Subsystem, _ Path, _ error) error { + return ErrIgnoreSubsystem +} + +// RequireDevices requires the device subsystem but no others +func RequireDevices(s Subsystem, _ Path, _ error) error { + if s.Name() == Devices { + return ErrDevicesRequired + } + return ErrIgnoreSubsystem +} diff --git a/agent/vendor/github.com/containerd/cgroups/paths.go b/agent/vendor/github.com/containerd/cgroups/paths.go index 63ac270fb62..bddc4e9cdcd 100644 --- a/agent/vendor/github.com/containerd/cgroups/paths.go +++ b/agent/vendor/github.com/containerd/cgroups/paths.go @@ -1,13 +1,30 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( + "errors" "fmt" "path/filepath" ) type Path func(subsystem Name) (string, error) -func RootPath(subsysem Name) (string, error) { +func RootPath(subsystem Name) (string, error) { return "/", nil } @@ -21,7 +38,7 @@ func StaticPath(path string) Path { // NestedPath will nest the cgroups based on the calling processes cgroup // placing its child processes inside its own path func NestedPath(suffix string) Path { - paths, err := parseCgroupFile("/proc/self/cgroup") + paths, err := ParseCgroupFile("/proc/self/cgroup") if err != nil { return errorPath(err) } @@ -31,17 +48,21 @@ func NestedPath(suffix string) Path { // PidPath will return the correct cgroup paths for an existing process running inside a cgroup // This is commonly used for the Load function to restore an existing container func PidPath(pid int) Path { - paths, err := parseCgroupFile(fmt.Sprintf("/proc/%d/cgroup", pid)) + p := fmt.Sprintf("/proc/%d/cgroup", pid) + paths, err := ParseCgroupFile(p) if err != nil { - return errorPath(err) + return errorPath(fmt.Errorf("parse cgroup file %s: %w", p, err)) } return existingPath(paths, "") } +// ErrControllerNotActive is returned when a controller is not supported or enabled +var ErrControllerNotActive = errors.New("controller is not supported") + func existingPath(paths map[string]string, suffix string) Path { // localize the paths based on the root mount dest for nested cgroups for n, p := range paths { - dest, err := getCgroupDestination(string(n)) + dest, err := getCgroupDestination(n) if err != nil { return errorPath(err) } @@ -57,8 +78,8 @@ func existingPath(paths map[string]string, suffix string) Path { return func(name Name) (string, error) { root, ok := paths[string(name)] if !ok { - if root, ok = paths[fmt.Sprintf("name=%s", name)]; !ok { - return "", fmt.Errorf("unable to find %q in controller set", name) + if root, ok = paths["name="+string(name)]; !ok { + return "", ErrControllerNotActive } } if suffix != "" { diff --git a/agent/vendor/github.com/containerd/cgroups/perf_event.go b/agent/vendor/github.com/containerd/cgroups/perf_event.go index 0fa43ec1f68..648786db68f 100644 --- a/agent/vendor/github.com/containerd/cgroups/perf_event.go +++ b/agent/vendor/github.com/containerd/cgroups/perf_event.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import "path/filepath" diff --git a/agent/vendor/github.com/containerd/cgroups/pids.go b/agent/vendor/github.com/containerd/cgroups/pids.go index bdcc10a9071..ce78e44c189 100644 --- a/agent/vendor/github.com/containerd/cgroups/pids.go +++ b/agent/vendor/github.com/containerd/cgroups/pids.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -7,6 +23,7 @@ import ( "strconv" "strings" + v1 "github.com/containerd/cgroups/stats/v1" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -33,7 +50,7 @@ func (p *pidsController) Create(path string, resources *specs.LinuxResources) er return err } if resources.Pids != nil && resources.Pids.Limit > 0 { - return ioutil.WriteFile( + return retryingWriteFile( filepath.Join(p.Path(path), "pids.max"), []byte(strconv.FormatInt(resources.Pids.Limit, 10)), defaultFilePerm, @@ -46,7 +63,7 @@ func (p *pidsController) Update(path string, resources *specs.LinuxResources) er return p.Create(path, resources) } -func (p *pidsController) Stat(path string, stats *Stats) error { +func (p *pidsController) Stat(path string, stats *v1.Metrics) error { current, err := readUint(filepath.Join(p.Path(path), "pids.current")) if err != nil { return err @@ -61,7 +78,7 @@ func (p *pidsController) Stat(path string, stats *Stats) error { return err } } - stats.Pids = &PidsStat{ + stats.Pids = &v1.PidsStat{ Current: current, Limit: max, } diff --git a/agent/vendor/github.com/containerd/cgroups/rdma.go b/agent/vendor/github.com/containerd/cgroups/rdma.go new file mode 100644 index 00000000000..3b59b107142 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/rdma.go @@ -0,0 +1,155 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package cgroups + +import ( + "io/ioutil" + "math" + "os" + "path/filepath" + "strconv" + "strings" + + v1 "github.com/containerd/cgroups/stats/v1" + specs "github.com/opencontainers/runtime-spec/specs-go" +) + +type rdmaController struct { + root string +} + +func (p *rdmaController) Name() Name { + return Rdma +} + +func (p *rdmaController) Path(path string) string { + return filepath.Join(p.root, path) +} + +func NewRdma(root string) *rdmaController { + return &rdmaController{ + root: filepath.Join(root, string(Rdma)), + } +} + +func createCmdString(device string, limits *specs.LinuxRdma) string { + var cmdString string + + cmdString = device + if limits.HcaHandles != nil { + cmdString = cmdString + " " + "hca_handle=" + strconv.FormatUint(uint64(*limits.HcaHandles), 10) + } + + if limits.HcaObjects != nil { + cmdString = cmdString + " " + "hca_object=" + strconv.FormatUint(uint64(*limits.HcaObjects), 10) + } + return cmdString +} + +func (p *rdmaController) Create(path string, resources *specs.LinuxResources) error { + if err := os.MkdirAll(p.Path(path), defaultDirPerm); err != nil { + return err + } + + for device, limit := range resources.Rdma { + if device != "" && (limit.HcaHandles != nil || limit.HcaObjects != nil) { + limit := limit + return retryingWriteFile( + filepath.Join(p.Path(path), "rdma.max"), + []byte(createCmdString(device, &limit)), + defaultFilePerm, + ) + } + } + return nil +} + +func (p *rdmaController) Update(path string, resources *specs.LinuxResources) error { + return p.Create(path, resources) +} + +func parseRdmaKV(raw string, entry *v1.RdmaEntry) { + var value uint64 + var err error + + parts := strings.Split(raw, "=") + switch len(parts) { + case 2: + if parts[1] == "max" { + value = math.MaxUint32 + } else { + value, err = parseUint(parts[1], 10, 32) + if err != nil { + return + } + } + if parts[0] == "hca_handle" { + entry.HcaHandles = uint32(value) + } else if parts[0] == "hca_object" { + entry.HcaObjects = uint32(value) + } + } +} + +func toRdmaEntry(strEntries []string) []*v1.RdmaEntry { + var rdmaEntries []*v1.RdmaEntry + for i := range strEntries { + parts := strings.Fields(strEntries[i]) + switch len(parts) { + case 3: + entry := new(v1.RdmaEntry) + entry.Device = parts[0] + parseRdmaKV(parts[1], entry) + parseRdmaKV(parts[2], entry) + + rdmaEntries = append(rdmaEntries, entry) + default: + continue + } + } + return rdmaEntries +} + +func (p *rdmaController) Stat(path string, stats *v1.Metrics) error { + + currentData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.current")) + if err != nil { + return err + } + currentPerDevices := strings.Split(string(currentData), "\n") + + maxData, err := ioutil.ReadFile(filepath.Join(p.Path(path), "rdma.max")) + if err != nil { + return err + } + maxPerDevices := strings.Split(string(maxData), "\n") + + // If device got removed between reading two files, ignore returning + // stats. + if len(currentPerDevices) != len(maxPerDevices) { + return nil + } + + currentEntries := toRdmaEntry(currentPerDevices) + maxEntries := toRdmaEntry(maxPerDevices) + + stats.Rdma = &v1.RdmaStat{ + Current: currentEntries, + Limit: maxEntries, + } + return nil +} diff --git a/agent/vendor/github.com/containerd/cgroups/state.go b/agent/vendor/github.com/containerd/cgroups/state.go index f1d7b7b6081..cfeabbbc60b 100644 --- a/agent/vendor/github.com/containerd/cgroups/state.go +++ b/agent/vendor/github.com/containerd/cgroups/state.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups // State is a type that represents the state of the current cgroup diff --git a/agent/vendor/github.com/containerd/cgroups/stats/v1/doc.go b/agent/vendor/github.com/containerd/cgroups/stats/v1/doc.go new file mode 100644 index 00000000000..23f3cdd4b37 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/stats/v1/doc.go @@ -0,0 +1,17 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package v1 diff --git a/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go new file mode 100644 index 00000000000..6d2d41770b9 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.go @@ -0,0 +1,6125 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: github.com/containerd/cgroups/stats/v1/metrics.proto + +package v1 + +import ( + fmt "fmt" + _ "github.com/gogo/protobuf/gogoproto" + proto "github.com/gogo/protobuf/proto" + io "io" + math "math" + math_bits "math/bits" + reflect "reflect" + strings "strings" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +type Metrics struct { + Hugetlb []*HugetlbStat `protobuf:"bytes,1,rep,name=hugetlb,proto3" json:"hugetlb,omitempty"` + Pids *PidsStat `protobuf:"bytes,2,opt,name=pids,proto3" json:"pids,omitempty"` + CPU *CPUStat `protobuf:"bytes,3,opt,name=cpu,proto3" json:"cpu,omitempty"` + Memory *MemoryStat `protobuf:"bytes,4,opt,name=memory,proto3" json:"memory,omitempty"` + Blkio *BlkIOStat `protobuf:"bytes,5,opt,name=blkio,proto3" json:"blkio,omitempty"` + Rdma *RdmaStat `protobuf:"bytes,6,opt,name=rdma,proto3" json:"rdma,omitempty"` + Network []*NetworkStat `protobuf:"bytes,7,rep,name=network,proto3" json:"network,omitempty"` + CgroupStats *CgroupStats `protobuf:"bytes,8,opt,name=cgroup_stats,json=cgroupStats,proto3" json:"cgroup_stats,omitempty"` + MemoryOomControl *MemoryOomControl `protobuf:"bytes,9,opt,name=memory_oom_control,json=memoryOomControl,proto3" json:"memory_oom_control,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Metrics) Reset() { *m = Metrics{} } +func (*Metrics) ProtoMessage() {} +func (*Metrics) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{0} +} +func (m *Metrics) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Metrics) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Metrics.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Metrics) XXX_Merge(src proto.Message) { + xxx_messageInfo_Metrics.Merge(m, src) +} +func (m *Metrics) XXX_Size() int { + return m.Size() +} +func (m *Metrics) XXX_DiscardUnknown() { + xxx_messageInfo_Metrics.DiscardUnknown(m) +} + +var xxx_messageInfo_Metrics proto.InternalMessageInfo + +type HugetlbStat struct { + Usage uint64 `protobuf:"varint,1,opt,name=usage,proto3" json:"usage,omitempty"` + Max uint64 `protobuf:"varint,2,opt,name=max,proto3" json:"max,omitempty"` + Failcnt uint64 `protobuf:"varint,3,opt,name=failcnt,proto3" json:"failcnt,omitempty"` + Pagesize string `protobuf:"bytes,4,opt,name=pagesize,proto3" json:"pagesize,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *HugetlbStat) Reset() { *m = HugetlbStat{} } +func (*HugetlbStat) ProtoMessage() {} +func (*HugetlbStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{1} +} +func (m *HugetlbStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *HugetlbStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_HugetlbStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *HugetlbStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_HugetlbStat.Merge(m, src) +} +func (m *HugetlbStat) XXX_Size() int { + return m.Size() +} +func (m *HugetlbStat) XXX_DiscardUnknown() { + xxx_messageInfo_HugetlbStat.DiscardUnknown(m) +} + +var xxx_messageInfo_HugetlbStat proto.InternalMessageInfo + +type PidsStat struct { + Current uint64 `protobuf:"varint,1,opt,name=current,proto3" json:"current,omitempty"` + Limit uint64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PidsStat) Reset() { *m = PidsStat{} } +func (*PidsStat) ProtoMessage() {} +func (*PidsStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{2} +} +func (m *PidsStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PidsStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PidsStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PidsStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_PidsStat.Merge(m, src) +} +func (m *PidsStat) XXX_Size() int { + return m.Size() +} +func (m *PidsStat) XXX_DiscardUnknown() { + xxx_messageInfo_PidsStat.DiscardUnknown(m) +} + +var xxx_messageInfo_PidsStat proto.InternalMessageInfo + +type CPUStat struct { + Usage *CPUUsage `protobuf:"bytes,1,opt,name=usage,proto3" json:"usage,omitempty"` + Throttling *Throttle `protobuf:"bytes,2,opt,name=throttling,proto3" json:"throttling,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CPUStat) Reset() { *m = CPUStat{} } +func (*CPUStat) ProtoMessage() {} +func (*CPUStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{3} +} +func (m *CPUStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CPUStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CPUStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CPUStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_CPUStat.Merge(m, src) +} +func (m *CPUStat) XXX_Size() int { + return m.Size() +} +func (m *CPUStat) XXX_DiscardUnknown() { + xxx_messageInfo_CPUStat.DiscardUnknown(m) +} + +var xxx_messageInfo_CPUStat proto.InternalMessageInfo + +type CPUUsage struct { + // values in nanoseconds + Total uint64 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` + Kernel uint64 `protobuf:"varint,2,opt,name=kernel,proto3" json:"kernel,omitempty"` + User uint64 `protobuf:"varint,3,opt,name=user,proto3" json:"user,omitempty"` + PerCPU []uint64 `protobuf:"varint,4,rep,packed,name=per_cpu,json=perCpu,proto3" json:"per_cpu,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CPUUsage) Reset() { *m = CPUUsage{} } +func (*CPUUsage) ProtoMessage() {} +func (*CPUUsage) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{4} +} +func (m *CPUUsage) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CPUUsage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CPUUsage.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CPUUsage) XXX_Merge(src proto.Message) { + xxx_messageInfo_CPUUsage.Merge(m, src) +} +func (m *CPUUsage) XXX_Size() int { + return m.Size() +} +func (m *CPUUsage) XXX_DiscardUnknown() { + xxx_messageInfo_CPUUsage.DiscardUnknown(m) +} + +var xxx_messageInfo_CPUUsage proto.InternalMessageInfo + +type Throttle struct { + Periods uint64 `protobuf:"varint,1,opt,name=periods,proto3" json:"periods,omitempty"` + ThrottledPeriods uint64 `protobuf:"varint,2,opt,name=throttled_periods,json=throttledPeriods,proto3" json:"throttled_periods,omitempty"` + ThrottledTime uint64 `protobuf:"varint,3,opt,name=throttled_time,json=throttledTime,proto3" json:"throttled_time,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Throttle) Reset() { *m = Throttle{} } +func (*Throttle) ProtoMessage() {} +func (*Throttle) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{5} +} +func (m *Throttle) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Throttle) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Throttle.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Throttle) XXX_Merge(src proto.Message) { + xxx_messageInfo_Throttle.Merge(m, src) +} +func (m *Throttle) XXX_Size() int { + return m.Size() +} +func (m *Throttle) XXX_DiscardUnknown() { + xxx_messageInfo_Throttle.DiscardUnknown(m) +} + +var xxx_messageInfo_Throttle proto.InternalMessageInfo + +type MemoryStat struct { + Cache uint64 `protobuf:"varint,1,opt,name=cache,proto3" json:"cache,omitempty"` + RSS uint64 `protobuf:"varint,2,opt,name=rss,proto3" json:"rss,omitempty"` + RSSHuge uint64 `protobuf:"varint,3,opt,name=rss_huge,json=rssHuge,proto3" json:"rss_huge,omitempty"` + MappedFile uint64 `protobuf:"varint,4,opt,name=mapped_file,json=mappedFile,proto3" json:"mapped_file,omitempty"` + Dirty uint64 `protobuf:"varint,5,opt,name=dirty,proto3" json:"dirty,omitempty"` + Writeback uint64 `protobuf:"varint,6,opt,name=writeback,proto3" json:"writeback,omitempty"` + PgPgIn uint64 `protobuf:"varint,7,opt,name=pg_pg_in,json=pgPgIn,proto3" json:"pg_pg_in,omitempty"` + PgPgOut uint64 `protobuf:"varint,8,opt,name=pg_pg_out,json=pgPgOut,proto3" json:"pg_pg_out,omitempty"` + PgFault uint64 `protobuf:"varint,9,opt,name=pg_fault,json=pgFault,proto3" json:"pg_fault,omitempty"` + PgMajFault uint64 `protobuf:"varint,10,opt,name=pg_maj_fault,json=pgMajFault,proto3" json:"pg_maj_fault,omitempty"` + InactiveAnon uint64 `protobuf:"varint,11,opt,name=inactive_anon,json=inactiveAnon,proto3" json:"inactive_anon,omitempty"` + ActiveAnon uint64 `protobuf:"varint,12,opt,name=active_anon,json=activeAnon,proto3" json:"active_anon,omitempty"` + InactiveFile uint64 `protobuf:"varint,13,opt,name=inactive_file,json=inactiveFile,proto3" json:"inactive_file,omitempty"` + ActiveFile uint64 `protobuf:"varint,14,opt,name=active_file,json=activeFile,proto3" json:"active_file,omitempty"` + Unevictable uint64 `protobuf:"varint,15,opt,name=unevictable,proto3" json:"unevictable,omitempty"` + HierarchicalMemoryLimit uint64 `protobuf:"varint,16,opt,name=hierarchical_memory_limit,json=hierarchicalMemoryLimit,proto3" json:"hierarchical_memory_limit,omitempty"` + HierarchicalSwapLimit uint64 `protobuf:"varint,17,opt,name=hierarchical_swap_limit,json=hierarchicalSwapLimit,proto3" json:"hierarchical_swap_limit,omitempty"` + TotalCache uint64 `protobuf:"varint,18,opt,name=total_cache,json=totalCache,proto3" json:"total_cache,omitempty"` + TotalRSS uint64 `protobuf:"varint,19,opt,name=total_rss,json=totalRss,proto3" json:"total_rss,omitempty"` + TotalRSSHuge uint64 `protobuf:"varint,20,opt,name=total_rss_huge,json=totalRssHuge,proto3" json:"total_rss_huge,omitempty"` + TotalMappedFile uint64 `protobuf:"varint,21,opt,name=total_mapped_file,json=totalMappedFile,proto3" json:"total_mapped_file,omitempty"` + TotalDirty uint64 `protobuf:"varint,22,opt,name=total_dirty,json=totalDirty,proto3" json:"total_dirty,omitempty"` + TotalWriteback uint64 `protobuf:"varint,23,opt,name=total_writeback,json=totalWriteback,proto3" json:"total_writeback,omitempty"` + TotalPgPgIn uint64 `protobuf:"varint,24,opt,name=total_pg_pg_in,json=totalPgPgIn,proto3" json:"total_pg_pg_in,omitempty"` + TotalPgPgOut uint64 `protobuf:"varint,25,opt,name=total_pg_pg_out,json=totalPgPgOut,proto3" json:"total_pg_pg_out,omitempty"` + TotalPgFault uint64 `protobuf:"varint,26,opt,name=total_pg_fault,json=totalPgFault,proto3" json:"total_pg_fault,omitempty"` + TotalPgMajFault uint64 `protobuf:"varint,27,opt,name=total_pg_maj_fault,json=totalPgMajFault,proto3" json:"total_pg_maj_fault,omitempty"` + TotalInactiveAnon uint64 `protobuf:"varint,28,opt,name=total_inactive_anon,json=totalInactiveAnon,proto3" json:"total_inactive_anon,omitempty"` + TotalActiveAnon uint64 `protobuf:"varint,29,opt,name=total_active_anon,json=totalActiveAnon,proto3" json:"total_active_anon,omitempty"` + TotalInactiveFile uint64 `protobuf:"varint,30,opt,name=total_inactive_file,json=totalInactiveFile,proto3" json:"total_inactive_file,omitempty"` + TotalActiveFile uint64 `protobuf:"varint,31,opt,name=total_active_file,json=totalActiveFile,proto3" json:"total_active_file,omitempty"` + TotalUnevictable uint64 `protobuf:"varint,32,opt,name=total_unevictable,json=totalUnevictable,proto3" json:"total_unevictable,omitempty"` + Usage *MemoryEntry `protobuf:"bytes,33,opt,name=usage,proto3" json:"usage,omitempty"` + Swap *MemoryEntry `protobuf:"bytes,34,opt,name=swap,proto3" json:"swap,omitempty"` + Kernel *MemoryEntry `protobuf:"bytes,35,opt,name=kernel,proto3" json:"kernel,omitempty"` + KernelTCP *MemoryEntry `protobuf:"bytes,36,opt,name=kernel_tcp,json=kernelTcp,proto3" json:"kernel_tcp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MemoryStat) Reset() { *m = MemoryStat{} } +func (*MemoryStat) ProtoMessage() {} +func (*MemoryStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{6} +} +func (m *MemoryStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MemoryStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MemoryStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MemoryStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_MemoryStat.Merge(m, src) +} +func (m *MemoryStat) XXX_Size() int { + return m.Size() +} +func (m *MemoryStat) XXX_DiscardUnknown() { + xxx_messageInfo_MemoryStat.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryStat proto.InternalMessageInfo + +type MemoryEntry struct { + Limit uint64 `protobuf:"varint,1,opt,name=limit,proto3" json:"limit,omitempty"` + Usage uint64 `protobuf:"varint,2,opt,name=usage,proto3" json:"usage,omitempty"` + Max uint64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` + Failcnt uint64 `protobuf:"varint,4,opt,name=failcnt,proto3" json:"failcnt,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MemoryEntry) Reset() { *m = MemoryEntry{} } +func (*MemoryEntry) ProtoMessage() {} +func (*MemoryEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{7} +} +func (m *MemoryEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MemoryEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MemoryEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MemoryEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_MemoryEntry.Merge(m, src) +} +func (m *MemoryEntry) XXX_Size() int { + return m.Size() +} +func (m *MemoryEntry) XXX_DiscardUnknown() { + xxx_messageInfo_MemoryEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryEntry proto.InternalMessageInfo + +type MemoryOomControl struct { + OomKillDisable uint64 `protobuf:"varint,1,opt,name=oom_kill_disable,json=oomKillDisable,proto3" json:"oom_kill_disable,omitempty"` + UnderOom uint64 `protobuf:"varint,2,opt,name=under_oom,json=underOom,proto3" json:"under_oom,omitempty"` + OomKill uint64 `protobuf:"varint,3,opt,name=oom_kill,json=oomKill,proto3" json:"oom_kill,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *MemoryOomControl) Reset() { *m = MemoryOomControl{} } +func (*MemoryOomControl) ProtoMessage() {} +func (*MemoryOomControl) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{8} +} +func (m *MemoryOomControl) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *MemoryOomControl) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_MemoryOomControl.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *MemoryOomControl) XXX_Merge(src proto.Message) { + xxx_messageInfo_MemoryOomControl.Merge(m, src) +} +func (m *MemoryOomControl) XXX_Size() int { + return m.Size() +} +func (m *MemoryOomControl) XXX_DiscardUnknown() { + xxx_messageInfo_MemoryOomControl.DiscardUnknown(m) +} + +var xxx_messageInfo_MemoryOomControl proto.InternalMessageInfo + +type BlkIOStat struct { + IoServiceBytesRecursive []*BlkIOEntry `protobuf:"bytes,1,rep,name=io_service_bytes_recursive,json=ioServiceBytesRecursive,proto3" json:"io_service_bytes_recursive,omitempty"` + IoServicedRecursive []*BlkIOEntry `protobuf:"bytes,2,rep,name=io_serviced_recursive,json=ioServicedRecursive,proto3" json:"io_serviced_recursive,omitempty"` + IoQueuedRecursive []*BlkIOEntry `protobuf:"bytes,3,rep,name=io_queued_recursive,json=ioQueuedRecursive,proto3" json:"io_queued_recursive,omitempty"` + IoServiceTimeRecursive []*BlkIOEntry `protobuf:"bytes,4,rep,name=io_service_time_recursive,json=ioServiceTimeRecursive,proto3" json:"io_service_time_recursive,omitempty"` + IoWaitTimeRecursive []*BlkIOEntry `protobuf:"bytes,5,rep,name=io_wait_time_recursive,json=ioWaitTimeRecursive,proto3" json:"io_wait_time_recursive,omitempty"` + IoMergedRecursive []*BlkIOEntry `protobuf:"bytes,6,rep,name=io_merged_recursive,json=ioMergedRecursive,proto3" json:"io_merged_recursive,omitempty"` + IoTimeRecursive []*BlkIOEntry `protobuf:"bytes,7,rep,name=io_time_recursive,json=ioTimeRecursive,proto3" json:"io_time_recursive,omitempty"` + SectorsRecursive []*BlkIOEntry `protobuf:"bytes,8,rep,name=sectors_recursive,json=sectorsRecursive,proto3" json:"sectors_recursive,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlkIOStat) Reset() { *m = BlkIOStat{} } +func (*BlkIOStat) ProtoMessage() {} +func (*BlkIOStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{9} +} +func (m *BlkIOStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlkIOStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlkIOStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BlkIOStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlkIOStat.Merge(m, src) +} +func (m *BlkIOStat) XXX_Size() int { + return m.Size() +} +func (m *BlkIOStat) XXX_DiscardUnknown() { + xxx_messageInfo_BlkIOStat.DiscardUnknown(m) +} + +var xxx_messageInfo_BlkIOStat proto.InternalMessageInfo + +type BlkIOEntry struct { + Op string `protobuf:"bytes,1,opt,name=op,proto3" json:"op,omitempty"` + Device string `protobuf:"bytes,2,opt,name=device,proto3" json:"device,omitempty"` + Major uint64 `protobuf:"varint,3,opt,name=major,proto3" json:"major,omitempty"` + Minor uint64 `protobuf:"varint,4,opt,name=minor,proto3" json:"minor,omitempty"` + Value uint64 `protobuf:"varint,5,opt,name=value,proto3" json:"value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BlkIOEntry) Reset() { *m = BlkIOEntry{} } +func (*BlkIOEntry) ProtoMessage() {} +func (*BlkIOEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{10} +} +func (m *BlkIOEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BlkIOEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BlkIOEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BlkIOEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_BlkIOEntry.Merge(m, src) +} +func (m *BlkIOEntry) XXX_Size() int { + return m.Size() +} +func (m *BlkIOEntry) XXX_DiscardUnknown() { + xxx_messageInfo_BlkIOEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_BlkIOEntry proto.InternalMessageInfo + +type RdmaStat struct { + Current []*RdmaEntry `protobuf:"bytes,1,rep,name=current,proto3" json:"current,omitempty"` + Limit []*RdmaEntry `protobuf:"bytes,2,rep,name=limit,proto3" json:"limit,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RdmaStat) Reset() { *m = RdmaStat{} } +func (*RdmaStat) ProtoMessage() {} +func (*RdmaStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{11} +} +func (m *RdmaStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RdmaStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RdmaStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RdmaStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_RdmaStat.Merge(m, src) +} +func (m *RdmaStat) XXX_Size() int { + return m.Size() +} +func (m *RdmaStat) XXX_DiscardUnknown() { + xxx_messageInfo_RdmaStat.DiscardUnknown(m) +} + +var xxx_messageInfo_RdmaStat proto.InternalMessageInfo + +type RdmaEntry struct { + Device string `protobuf:"bytes,1,opt,name=device,proto3" json:"device,omitempty"` + HcaHandles uint32 `protobuf:"varint,2,opt,name=hca_handles,json=hcaHandles,proto3" json:"hca_handles,omitempty"` + HcaObjects uint32 `protobuf:"varint,3,opt,name=hca_objects,json=hcaObjects,proto3" json:"hca_objects,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *RdmaEntry) Reset() { *m = RdmaEntry{} } +func (*RdmaEntry) ProtoMessage() {} +func (*RdmaEntry) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{12} +} +func (m *RdmaEntry) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *RdmaEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_RdmaEntry.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *RdmaEntry) XXX_Merge(src proto.Message) { + xxx_messageInfo_RdmaEntry.Merge(m, src) +} +func (m *RdmaEntry) XXX_Size() int { + return m.Size() +} +func (m *RdmaEntry) XXX_DiscardUnknown() { + xxx_messageInfo_RdmaEntry.DiscardUnknown(m) +} + +var xxx_messageInfo_RdmaEntry proto.InternalMessageInfo + +type NetworkStat struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + RxBytes uint64 `protobuf:"varint,2,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"` + RxPackets uint64 `protobuf:"varint,3,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"` + RxErrors uint64 `protobuf:"varint,4,opt,name=rx_errors,json=rxErrors,proto3" json:"rx_errors,omitempty"` + RxDropped uint64 `protobuf:"varint,5,opt,name=rx_dropped,json=rxDropped,proto3" json:"rx_dropped,omitempty"` + TxBytes uint64 `protobuf:"varint,6,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"` + TxPackets uint64 `protobuf:"varint,7,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"` + TxErrors uint64 `protobuf:"varint,8,opt,name=tx_errors,json=txErrors,proto3" json:"tx_errors,omitempty"` + TxDropped uint64 `protobuf:"varint,9,opt,name=tx_dropped,json=txDropped,proto3" json:"tx_dropped,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *NetworkStat) Reset() { *m = NetworkStat{} } +func (*NetworkStat) ProtoMessage() {} +func (*NetworkStat) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{13} +} +func (m *NetworkStat) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *NetworkStat) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_NetworkStat.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *NetworkStat) XXX_Merge(src proto.Message) { + xxx_messageInfo_NetworkStat.Merge(m, src) +} +func (m *NetworkStat) XXX_Size() int { + return m.Size() +} +func (m *NetworkStat) XXX_DiscardUnknown() { + xxx_messageInfo_NetworkStat.DiscardUnknown(m) +} + +var xxx_messageInfo_NetworkStat proto.InternalMessageInfo + +// CgroupStats exports per-cgroup statistics. +type CgroupStats struct { + // number of tasks sleeping + NrSleeping uint64 `protobuf:"varint,1,opt,name=nr_sleeping,json=nrSleeping,proto3" json:"nr_sleeping,omitempty"` + // number of tasks running + NrRunning uint64 `protobuf:"varint,2,opt,name=nr_running,json=nrRunning,proto3" json:"nr_running,omitempty"` + // number of tasks in stopped state + NrStopped uint64 `protobuf:"varint,3,opt,name=nr_stopped,json=nrStopped,proto3" json:"nr_stopped,omitempty"` + // number of tasks in uninterruptible state + NrUninterruptible uint64 `protobuf:"varint,4,opt,name=nr_uninterruptible,json=nrUninterruptible,proto3" json:"nr_uninterruptible,omitempty"` + // number of tasks waiting on IO + NrIoWait uint64 `protobuf:"varint,5,opt,name=nr_io_wait,json=nrIoWait,proto3" json:"nr_io_wait,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *CgroupStats) Reset() { *m = CgroupStats{} } +func (*CgroupStats) ProtoMessage() {} +func (*CgroupStats) Descriptor() ([]byte, []int) { + return fileDescriptor_a17b2d87c332bfaa, []int{14} +} +func (m *CgroupStats) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *CgroupStats) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_CgroupStats.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *CgroupStats) XXX_Merge(src proto.Message) { + xxx_messageInfo_CgroupStats.Merge(m, src) +} +func (m *CgroupStats) XXX_Size() int { + return m.Size() +} +func (m *CgroupStats) XXX_DiscardUnknown() { + xxx_messageInfo_CgroupStats.DiscardUnknown(m) +} + +var xxx_messageInfo_CgroupStats proto.InternalMessageInfo + +func init() { + proto.RegisterType((*Metrics)(nil), "io.containerd.cgroups.v1.Metrics") + proto.RegisterType((*HugetlbStat)(nil), "io.containerd.cgroups.v1.HugetlbStat") + proto.RegisterType((*PidsStat)(nil), "io.containerd.cgroups.v1.PidsStat") + proto.RegisterType((*CPUStat)(nil), "io.containerd.cgroups.v1.CPUStat") + proto.RegisterType((*CPUUsage)(nil), "io.containerd.cgroups.v1.CPUUsage") + proto.RegisterType((*Throttle)(nil), "io.containerd.cgroups.v1.Throttle") + proto.RegisterType((*MemoryStat)(nil), "io.containerd.cgroups.v1.MemoryStat") + proto.RegisterType((*MemoryEntry)(nil), "io.containerd.cgroups.v1.MemoryEntry") + proto.RegisterType((*MemoryOomControl)(nil), "io.containerd.cgroups.v1.MemoryOomControl") + proto.RegisterType((*BlkIOStat)(nil), "io.containerd.cgroups.v1.BlkIOStat") + proto.RegisterType((*BlkIOEntry)(nil), "io.containerd.cgroups.v1.BlkIOEntry") + proto.RegisterType((*RdmaStat)(nil), "io.containerd.cgroups.v1.RdmaStat") + proto.RegisterType((*RdmaEntry)(nil), "io.containerd.cgroups.v1.RdmaEntry") + proto.RegisterType((*NetworkStat)(nil), "io.containerd.cgroups.v1.NetworkStat") + proto.RegisterType((*CgroupStats)(nil), "io.containerd.cgroups.v1.CgroupStats") +} + +func init() { + proto.RegisterFile("github.com/containerd/cgroups/stats/v1/metrics.proto", fileDescriptor_a17b2d87c332bfaa) +} + +var fileDescriptor_a17b2d87c332bfaa = []byte{ + // 1749 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x58, 0xcd, 0x72, 0xe3, 0xc6, + 0x11, 0x36, 0x45, 0x48, 0x24, 0x9a, 0x92, 0x56, 0x9a, 0xfd, 0x83, 0xe4, 0xb5, 0x28, 0x53, 0xbb, + 0x89, 0xe2, 0xad, 0x48, 0x65, 0x27, 0xb5, 0x95, 0x75, 0xec, 0x4a, 0x59, 0x5a, 0xbb, 0x76, 0xcb, + 0x51, 0x44, 0x83, 0x52, 0xd9, 0x39, 0xa1, 0x40, 0x70, 0x16, 0x9c, 0x15, 0x80, 0x81, 0x07, 0x03, + 0x89, 0xca, 0x29, 0x87, 0x54, 0xe5, 0x94, 0x07, 0xca, 0x1b, 0xf8, 0x98, 0x4b, 0x52, 0xc9, 0x45, + 0x15, 0xf3, 0x49, 0x52, 0x33, 0x3d, 0xf8, 0xa1, 0xbc, 0x5a, 0x85, 0x37, 0x76, 0xcf, 0xd7, 0x5f, + 0xf7, 0x34, 0xbe, 0x19, 0x34, 0x08, 0xbf, 0x0e, 0x99, 0x1c, 0xe7, 0xc3, 0xbd, 0x80, 0xc7, 0xfb, + 0x01, 0x4f, 0xa4, 0xcf, 0x12, 0x2a, 0x46, 0xfb, 0x41, 0x28, 0x78, 0x9e, 0x66, 0xfb, 0x99, 0xf4, + 0x65, 0xb6, 0x7f, 0xfe, 0xf1, 0x7e, 0x4c, 0xa5, 0x60, 0x41, 0xb6, 0x97, 0x0a, 0x2e, 0x39, 0x71, + 0x18, 0xdf, 0xab, 0xd0, 0x7b, 0x06, 0xbd, 0x77, 0xfe, 0xf1, 0xe6, 0xbd, 0x90, 0x87, 0x5c, 0x83, + 0xf6, 0xd5, 0x2f, 0xc4, 0xf7, 0xfe, 0x65, 0x41, 0xeb, 0x08, 0x19, 0xc8, 0xef, 0xa0, 0x35, 0xce, + 0x43, 0x2a, 0xa3, 0xa1, 0xd3, 0xd8, 0x6e, 0xee, 0x76, 0x3e, 0x79, 0xb2, 0x77, 0x13, 0xdb, 0xde, + 0x4b, 0x04, 0x0e, 0xa4, 0x2f, 0xdd, 0x22, 0x8a, 0x3c, 0x03, 0x2b, 0x65, 0xa3, 0xcc, 0x59, 0xd8, + 0x6e, 0xec, 0x76, 0x3e, 0xe9, 0xdd, 0x1c, 0xdd, 0x67, 0xa3, 0x4c, 0x87, 0x6a, 0x3c, 0xf9, 0x0c, + 0x9a, 0x41, 0x9a, 0x3b, 0x4d, 0x1d, 0xf6, 0xe1, 0xcd, 0x61, 0x87, 0xfd, 0x53, 0x15, 0x75, 0xd0, + 0x9a, 0x5e, 0x75, 0x9b, 0x87, 0xfd, 0x53, 0x57, 0x85, 0x91, 0xcf, 0x60, 0x29, 0xa6, 0x31, 0x17, + 0x97, 0x8e, 0xa5, 0x09, 0x1e, 0xdf, 0x4c, 0x70, 0xa4, 0x71, 0x3a, 0xb3, 0x89, 0x21, 0xcf, 0x61, + 0x71, 0x18, 0x9d, 0x31, 0xee, 0x2c, 0xea, 0xe0, 0x9d, 0x9b, 0x83, 0x0f, 0xa2, 0xb3, 0x57, 0xc7, + 0x3a, 0x16, 0x23, 0xd4, 0x76, 0xc5, 0x28, 0xf6, 0x9d, 0xa5, 0xdb, 0xb6, 0xeb, 0x8e, 0x62, 0x1f, + 0xb7, 0xab, 0xf0, 0xaa, 0xcf, 0x09, 0x95, 0x17, 0x5c, 0x9c, 0x39, 0xad, 0xdb, 0xfa, 0xfc, 0x07, + 0x04, 0x62, 0x9f, 0x4d, 0x14, 0x79, 0x09, 0xcb, 0x08, 0xf1, 0xb4, 0x0a, 0x9c, 0xb6, 0x2e, 0xe0, + 0x1d, 0x2c, 0x87, 0xfa, 0xa7, 0x22, 0xc9, 0xdc, 0x4e, 0x50, 0x19, 0xe4, 0x3b, 0x20, 0xd8, 0x07, + 0x8f, 0xf3, 0xd8, 0x53, 0xc1, 0x82, 0x47, 0x8e, 0xad, 0xf9, 0x3e, 0xba, 0xad, 0x8f, 0xc7, 0x3c, + 0x3e, 0xc4, 0x08, 0x77, 0x2d, 0xbe, 0xe6, 0xe9, 0x9d, 0x41, 0xa7, 0xa6, 0x11, 0x72, 0x0f, 0x16, + 0xf3, 0xcc, 0x0f, 0xa9, 0xd3, 0xd8, 0x6e, 0xec, 0x5a, 0x2e, 0x1a, 0x64, 0x0d, 0x9a, 0xb1, 0x3f, + 0xd1, 0x7a, 0xb1, 0x5c, 0xf5, 0x93, 0x38, 0xd0, 0x7a, 0xed, 0xb3, 0x28, 0x48, 0xa4, 0x96, 0x83, + 0xe5, 0x16, 0x26, 0xd9, 0x84, 0x76, 0xea, 0x87, 0x34, 0x63, 0x7f, 0xa2, 0xfa, 0x41, 0xdb, 0x6e, + 0x69, 0xf7, 0x3e, 0x85, 0x76, 0x21, 0x29, 0xc5, 0x10, 0xe4, 0x42, 0xd0, 0x44, 0x9a, 0x5c, 0x85, + 0xa9, 0x6a, 0x88, 0x58, 0xcc, 0xa4, 0xc9, 0x87, 0x46, 0xef, 0xaf, 0x0d, 0x68, 0x19, 0x61, 0x91, + 0xdf, 0xd4, 0xab, 0x7c, 0xe7, 0x23, 0x3d, 0xec, 0x9f, 0x9e, 0x2a, 0x64, 0xb1, 0x93, 0x03, 0x00, + 0x39, 0x16, 0x5c, 0xca, 0x88, 0x25, 0xe1, 0xed, 0x07, 0xe0, 0x04, 0xb1, 0xd4, 0xad, 0x45, 0xf5, + 0xbe, 0x87, 0x76, 0x41, 0xab, 0x6a, 0x95, 0x5c, 0xfa, 0x51, 0xd1, 0x2f, 0x6d, 0x90, 0x07, 0xb0, + 0x74, 0x46, 0x45, 0x42, 0x23, 0xb3, 0x05, 0x63, 0x11, 0x02, 0x56, 0x9e, 0x51, 0x61, 0x5a, 0xa6, + 0x7f, 0x93, 0x1d, 0x68, 0xa5, 0x54, 0x78, 0xea, 0x60, 0x59, 0xdb, 0xcd, 0x5d, 0xeb, 0x00, 0xa6, + 0x57, 0xdd, 0xa5, 0x3e, 0x15, 0xea, 0xe0, 0x2c, 0xa5, 0x54, 0x1c, 0xa6, 0x79, 0x6f, 0x02, 0xed, + 0xa2, 0x14, 0xd5, 0xb8, 0x94, 0x0a, 0xc6, 0x47, 0x59, 0xd1, 0x38, 0x63, 0x92, 0xa7, 0xb0, 0x6e, + 0xca, 0xa4, 0x23, 0xaf, 0xc0, 0x60, 0x05, 0x6b, 0xe5, 0x42, 0xdf, 0x80, 0x9f, 0xc0, 0x6a, 0x05, + 0x96, 0x2c, 0xa6, 0xa6, 0xaa, 0x95, 0xd2, 0x7b, 0xc2, 0x62, 0xda, 0xfb, 0x4f, 0x07, 0xa0, 0x3a, + 0x8e, 0x6a, 0xbf, 0x81, 0x1f, 0x8c, 0x4b, 0x7d, 0x68, 0x83, 0x6c, 0x40, 0x53, 0x64, 0x26, 0x15, + 0x9e, 0x7a, 0x77, 0x30, 0x70, 0x95, 0x8f, 0xfc, 0x0c, 0xda, 0x22, 0xcb, 0x3c, 0x75, 0xf5, 0x60, + 0x82, 0x83, 0xce, 0xf4, 0xaa, 0xdb, 0x72, 0x07, 0x03, 0x25, 0x3b, 0xb7, 0x25, 0xb2, 0x4c, 0xfd, + 0x20, 0x5d, 0xe8, 0xc4, 0x7e, 0x9a, 0xd2, 0x91, 0xf7, 0x9a, 0x45, 0xa8, 0x1c, 0xcb, 0x05, 0x74, + 0x7d, 0xc5, 0x22, 0xdd, 0xe9, 0x11, 0x13, 0xf2, 0x52, 0x5f, 0x00, 0x96, 0x8b, 0x06, 0x79, 0x04, + 0xf6, 0x85, 0x60, 0x92, 0x0e, 0xfd, 0xe0, 0x4c, 0x1f, 0x70, 0xcb, 0xad, 0x1c, 0xc4, 0x81, 0x76, + 0x1a, 0x7a, 0x69, 0xe8, 0xb1, 0xc4, 0x69, 0xe1, 0x93, 0x48, 0xc3, 0x7e, 0xf8, 0x2a, 0x21, 0x9b, + 0x60, 0xe3, 0x0a, 0xcf, 0xa5, 0x3e, 0x97, 0xaa, 0x8d, 0x61, 0x3f, 0x3c, 0xce, 0x25, 0xd9, 0xd0, + 0x51, 0xaf, 0xfd, 0x3c, 0x92, 0xfa, 0x88, 0xe9, 0xa5, 0xaf, 0x94, 0x49, 0xb6, 0x61, 0x39, 0x0d, + 0xbd, 0xd8, 0x7f, 0x63, 0x96, 0x01, 0xcb, 0x4c, 0xc3, 0x23, 0xff, 0x0d, 0x22, 0x76, 0x60, 0x85, + 0x25, 0x7e, 0x20, 0xd9, 0x39, 0xf5, 0xfc, 0x84, 0x27, 0x4e, 0x47, 0x43, 0x96, 0x0b, 0xe7, 0x17, + 0x09, 0x4f, 0xd4, 0x66, 0xeb, 0x90, 0x65, 0x64, 0xa9, 0x01, 0xea, 0x2c, 0xba, 0x1f, 0x2b, 0xb3, + 0x2c, 0xba, 0x23, 0x15, 0x8b, 0x86, 0xac, 0xd6, 0x59, 0x34, 0x60, 0x1b, 0x3a, 0x79, 0x42, 0xcf, + 0x59, 0x20, 0xfd, 0x61, 0x44, 0x9d, 0x3b, 0x1a, 0x50, 0x77, 0x91, 0x4f, 0x61, 0x63, 0xcc, 0xa8, + 0xf0, 0x45, 0x30, 0x66, 0x81, 0x1f, 0x79, 0xe6, 0x92, 0xc1, 0xe3, 0xb7, 0xa6, 0xf1, 0x0f, 0xeb, + 0x00, 0x54, 0xc2, 0xef, 0xd5, 0x32, 0x79, 0x06, 0x33, 0x4b, 0x5e, 0x76, 0xe1, 0xa7, 0x26, 0x72, + 0x5d, 0x47, 0xde, 0xaf, 0x2f, 0x0f, 0x2e, 0xfc, 0x14, 0xe3, 0xba, 0xd0, 0xd1, 0xa7, 0xc4, 0x43, + 0x21, 0x11, 0x2c, 0x5b, 0xbb, 0x0e, 0xb5, 0x9a, 0x7e, 0x01, 0x36, 0x02, 0x94, 0xa6, 0xee, 0x6a, + 0xcd, 0x2c, 0x4f, 0xaf, 0xba, 0xed, 0x13, 0xe5, 0x54, 0xc2, 0x6a, 0xeb, 0x65, 0x37, 0xcb, 0xc8, + 0x33, 0x58, 0x2d, 0xa1, 0xa8, 0xb1, 0x7b, 0x1a, 0xbf, 0x36, 0xbd, 0xea, 0x2e, 0x17, 0x78, 0x2d, + 0xb4, 0xe5, 0x22, 0x46, 0xab, 0xed, 0x23, 0x58, 0xc7, 0xb8, 0xba, 0xe6, 0xee, 0xeb, 0x4a, 0xee, + 0xe8, 0x85, 0xa3, 0x4a, 0x78, 0x65, 0xbd, 0x28, 0xbf, 0x07, 0xb5, 0x7a, 0x5f, 0x68, 0x0d, 0xfe, + 0x1c, 0x30, 0xc6, 0xab, 0x94, 0xf8, 0x50, 0x83, 0xb0, 0xb6, 0x6f, 0x4b, 0x39, 0xee, 0x14, 0xd5, + 0x96, 0xa2, 0x74, 0xf0, 0x91, 0x68, 0x6f, 0x1f, 0x95, 0xf9, 0xa4, 0x60, 0xab, 0xf4, 0xb9, 0x81, + 0x0f, 0xbf, 0x44, 0x29, 0x91, 0x3e, 0xae, 0x71, 0xa1, 0x16, 0x37, 0x67, 0x50, 0xa8, 0xc6, 0xa7, + 0x40, 0x4a, 0x54, 0xa5, 0xda, 0xf7, 0x6b, 0x1b, 0xed, 0x57, 0xd2, 0xdd, 0x83, 0xbb, 0x08, 0x9e, + 0x15, 0xf0, 0x23, 0x8d, 0xc6, 0x7e, 0xbd, 0xaa, 0xab, 0xb8, 0x6c, 0x62, 0x1d, 0xfd, 0x41, 0x8d, + 0xfb, 0x8b, 0x0a, 0xfb, 0x53, 0x6e, 0xdd, 0xf2, 0xad, 0xb7, 0x70, 0xeb, 0xa6, 0x5f, 0xe7, 0xd6, + 0xe8, 0xee, 0x4f, 0xb8, 0x35, 0xf6, 0x69, 0x81, 0xad, 0x8b, 0x7d, 0xdb, 0x5c, 0x7b, 0x6a, 0xe1, + 0xb4, 0xa6, 0xf8, 0xdf, 0x16, 0xaf, 0x8e, 0x0f, 0x6f, 0x7b, 0x19, 0xa3, 0xd6, 0xbf, 0x4c, 0xa4, + 0xb8, 0x2c, 0xde, 0x1e, 0xcf, 0xc1, 0x52, 0x2a, 0x77, 0x7a, 0xf3, 0xc4, 0xea, 0x10, 0xf2, 0x79, + 0xf9, 0x4a, 0xd8, 0x99, 0x27, 0xb8, 0x78, 0x73, 0x0c, 0x00, 0xf0, 0x97, 0x27, 0x83, 0xd4, 0x79, + 0x3c, 0x07, 0xc5, 0xc1, 0xca, 0xf4, 0xaa, 0x6b, 0x7f, 0xad, 0x83, 0x4f, 0x0e, 0xfb, 0xae, 0x8d, + 0x3c, 0x27, 0x41, 0xda, 0xa3, 0xd0, 0xa9, 0x01, 0xab, 0xf7, 0x6e, 0xa3, 0xf6, 0xde, 0xad, 0x26, + 0x82, 0x85, 0xb7, 0x4c, 0x04, 0xcd, 0xb7, 0x4e, 0x04, 0xd6, 0xcc, 0x44, 0xd0, 0x93, 0xb0, 0x76, + 0x7d, 0x10, 0x21, 0xbb, 0xb0, 0xa6, 0x26, 0x99, 0x33, 0x16, 0xa9, 0x73, 0x95, 0xe9, 0x47, 0x86, + 0x69, 0x57, 0x39, 0x8f, 0xbf, 0x66, 0x51, 0xf4, 0x02, 0xbd, 0xe4, 0x7d, 0xb0, 0xf3, 0x64, 0x44, + 0x85, 0x9a, 0x7c, 0x4c, 0x0d, 0x6d, 0xed, 0x38, 0xe6, 0xb1, 0xba, 0xaa, 0x0b, 0x9a, 0x62, 0x0e, + 0x31, 0xe1, 0xbd, 0x7f, 0x2e, 0x82, 0x5d, 0x8e, 0x82, 0xc4, 0x87, 0x4d, 0xc6, 0xbd, 0x8c, 0x8a, + 0x73, 0x16, 0x50, 0x6f, 0x78, 0x29, 0x69, 0xe6, 0x09, 0x1a, 0xe4, 0x22, 0x63, 0xe7, 0xd4, 0x8c, + 0xd1, 0x8f, 0x6f, 0x99, 0x29, 0xf1, 0x89, 0x3c, 0x64, 0x7c, 0x80, 0x34, 0x07, 0x8a, 0xc5, 0x2d, + 0x48, 0xc8, 0x77, 0x70, 0xbf, 0x4a, 0x31, 0xaa, 0xb1, 0x2f, 0xcc, 0xc1, 0x7e, 0xb7, 0x64, 0x1f, + 0x55, 0xcc, 0x27, 0x70, 0x97, 0x71, 0xef, 0xfb, 0x9c, 0xe6, 0x33, 0xbc, 0xcd, 0x39, 0x78, 0xd7, + 0x19, 0xff, 0x46, 0xc7, 0x57, 0xac, 0x1e, 0x6c, 0xd4, 0x5a, 0xa2, 0x26, 0x80, 0x1a, 0xb7, 0x35, + 0x07, 0xf7, 0x83, 0xb2, 0x66, 0x35, 0x31, 0x54, 0x09, 0xfe, 0x08, 0x0f, 0x18, 0xf7, 0x2e, 0x7c, + 0x26, 0xaf, 0xb3, 0x2f, 0xce, 0xd7, 0x91, 0x6f, 0x7d, 0x26, 0x67, 0xa9, 0xb1, 0x23, 0x31, 0x15, + 0xe1, 0x4c, 0x47, 0x96, 0xe6, 0xeb, 0xc8, 0x91, 0x8e, 0xaf, 0x58, 0xfb, 0xb0, 0xce, 0xf8, 0xf5, + 0x5a, 0x5b, 0x73, 0x70, 0xde, 0x61, 0x7c, 0xb6, 0xce, 0x6f, 0x60, 0x3d, 0xa3, 0x81, 0xe4, 0xa2, + 0xae, 0xb6, 0xf6, 0x1c, 0x8c, 0x6b, 0x26, 0xbc, 0xa4, 0xec, 0x9d, 0x03, 0x54, 0xeb, 0x64, 0x15, + 0x16, 0x78, 0xaa, 0x4f, 0x8e, 0xed, 0x2e, 0xf0, 0x54, 0x4d, 0x9e, 0x23, 0x75, 0xd9, 0xe1, 0x71, + 0xb5, 0x5d, 0x63, 0xa9, 0x53, 0x1c, 0xfb, 0x6f, 0x78, 0x31, 0x7a, 0xa2, 0xa1, 0xbd, 0x2c, 0xe1, + 0xc2, 0x9c, 0x58, 0x34, 0x94, 0xf7, 0xdc, 0x8f, 0x72, 0x5a, 0x4c, 0x5a, 0xda, 0xe8, 0xfd, 0xa5, + 0x01, 0xed, 0xe2, 0x03, 0x89, 0x7c, 0x5e, 0x1f, 0xde, 0x9b, 0xef, 0xfe, 0x1e, 0x53, 0x41, 0xb8, + 0x99, 0x72, 0xc2, 0x7f, 0x5e, 0x4d, 0xf8, 0xff, 0x77, 0xb0, 0xf9, 0x0c, 0xa0, 0x60, 0x97, 0xbe, + 0xda, 0x6e, 0x1b, 0x33, 0xbb, 0xed, 0x42, 0x67, 0x1c, 0xf8, 0xde, 0xd8, 0x4f, 0x46, 0x11, 0xc5, + 0xb9, 0x74, 0xc5, 0x85, 0x71, 0xe0, 0xbf, 0x44, 0x4f, 0x01, 0xe0, 0xc3, 0x37, 0x34, 0x90, 0x99, + 0x6e, 0x0a, 0x02, 0x8e, 0xd1, 0xd3, 0xfb, 0xdb, 0x02, 0x74, 0x6a, 0xdf, 0x74, 0x6a, 0x72, 0x4f, + 0xfc, 0xb8, 0xc8, 0xa3, 0x7f, 0xab, 0xcb, 0x47, 0x4c, 0xf0, 0x2e, 0x31, 0x17, 0x53, 0x4b, 0x4c, + 0xf4, 0xa5, 0x40, 0x3e, 0x00, 0x10, 0x13, 0x2f, 0xf5, 0x83, 0x33, 0x6a, 0xe8, 0x2d, 0xd7, 0x16, + 0x93, 0x3e, 0x3a, 0xd4, 0x9d, 0x26, 0x26, 0x1e, 0x15, 0x82, 0x8b, 0xcc, 0xf4, 0xbe, 0x2d, 0x26, + 0x5f, 0x6a, 0xdb, 0xc4, 0x8e, 0x04, 0x57, 0x13, 0x88, 0x79, 0x06, 0xb6, 0x98, 0xbc, 0x40, 0x87, + 0xca, 0x2a, 0x8b, 0xac, 0x38, 0xf0, 0xb6, 0x64, 0x95, 0x55, 0x56, 0x59, 0x71, 0xe0, 0xb5, 0x65, + 0x3d, 0xab, 0x2c, 0xb3, 0xe2, 0xcc, 0xdb, 0x96, 0xb5, 0xac, 0xb2, 0xca, 0x6a, 0x17, 0xb1, 0x26, + 0x6b, 0xef, 0xef, 0x0d, 0xe8, 0xd4, 0xbe, 0x4e, 0x55, 0x03, 0x13, 0xe1, 0x65, 0x11, 0xa5, 0xa9, + 0xfa, 0x90, 0xc2, 0xab, 0x1b, 0x12, 0x31, 0x30, 0x1e, 0xc5, 0x97, 0x08, 0x4f, 0xe4, 0x49, 0x52, + 0x7c, 0x68, 0x59, 0xae, 0x9d, 0x08, 0x17, 0x1d, 0x66, 0x39, 0x93, 0x98, 0xae, 0x59, 0x2c, 0x0f, + 0xd0, 0x41, 0x7e, 0x09, 0x24, 0x11, 0x5e, 0x9e, 0xb0, 0x44, 0x52, 0x21, 0xf2, 0x54, 0xb2, 0x61, + 0xf9, 0x51, 0xb0, 0x9e, 0x88, 0xd3, 0xd9, 0x05, 0xf2, 0x48, 0xb3, 0x99, 0xcb, 0xc6, 0xb4, 0xac, + 0x9d, 0x88, 0x57, 0xfa, 0xe6, 0x38, 0x70, 0x7e, 0xf8, 0x71, 0xeb, 0xbd, 0x7f, 0xff, 0xb8, 0xf5, + 0xde, 0x9f, 0xa7, 0x5b, 0x8d, 0x1f, 0xa6, 0x5b, 0x8d, 0x7f, 0x4c, 0xb7, 0x1a, 0xff, 0x9d, 0x6e, + 0x35, 0x86, 0x4b, 0xfa, 0xcf, 0x95, 0x5f, 0xfd, 0x2f, 0x00, 0x00, 0xff, 0xff, 0xc4, 0x4e, 0x24, + 0x22, 0xc4, 0x11, 0x00, 0x00, +} + +func (m *Metrics) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Metrics) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Metrics) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.MemoryOomControl != nil { + { + size, err := m.MemoryOomControl.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x4a + } + if m.CgroupStats != nil { + { + size, err := m.CgroupStats.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + if len(m.Network) > 0 { + for iNdEx := len(m.Network) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Network[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if m.Rdma != nil { + { + size, err := m.Rdma.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + if m.Blkio != nil { + { + size, err := m.Blkio.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if m.Memory != nil { + { + size, err := m.Memory.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.CPU != nil { + { + size, err := m.CPU.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.Pids != nil { + { + size, err := m.Pids.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Hugetlb) > 0 { + for iNdEx := len(m.Hugetlb) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Hugetlb[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *HugetlbStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HugetlbStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *HugetlbStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Pagesize) > 0 { + i -= len(m.Pagesize) + copy(dAtA[i:], m.Pagesize) + i = encodeVarintMetrics(dAtA, i, uint64(len(m.Pagesize))) + i-- + dAtA[i] = 0x22 + } + if m.Failcnt != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) + i-- + dAtA[i] = 0x18 + } + if m.Max != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) + i-- + dAtA[i] = 0x10 + } + if m.Usage != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *PidsStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PidsStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PidsStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Limit != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x10 + } + if m.Current != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Current)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *CPUStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CPUStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CPUStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Throttling != nil { + { + size, err := m.Throttling.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Usage != nil { + { + size, err := m.Usage.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CPUUsage) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CPUUsage) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CPUUsage) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.PerCPU) > 0 { + dAtA11 := make([]byte, len(m.PerCPU)*10) + var j10 int + for _, num := range m.PerCPU { + for num >= 1<<7 { + dAtA11[j10] = uint8(uint64(num)&0x7f | 0x80) + num >>= 7 + j10++ + } + dAtA11[j10] = uint8(num) + j10++ + } + i -= j10 + copy(dAtA[i:], dAtA11[:j10]) + i = encodeVarintMetrics(dAtA, i, uint64(j10)) + i-- + dAtA[i] = 0x22 + } + if m.User != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.User)) + i-- + dAtA[i] = 0x18 + } + if m.Kernel != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Kernel)) + i-- + dAtA[i] = 0x10 + } + if m.Total != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Total)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Throttle) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Throttle) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Throttle) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.ThrottledTime != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledTime)) + i-- + dAtA[i] = 0x18 + } + if m.ThrottledPeriods != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.ThrottledPeriods)) + i-- + dAtA[i] = 0x10 + } + if m.Periods != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Periods)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MemoryStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemoryStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.KernelTCP != nil { + { + size, err := m.KernelTCP.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0xa2 + } + if m.Kernel != nil { + { + size, err := m.Kernel.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x9a + } + if m.Swap != nil { + { + size, err := m.Swap.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x92 + } + if m.Usage != nil { + { + size, err := m.Usage.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x8a + } + if m.TotalUnevictable != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalUnevictable)) + i-- + dAtA[i] = 0x2 + i-- + dAtA[i] = 0x80 + } + if m.TotalActiveFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveFile)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf8 + } + if m.TotalInactiveFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveFile)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xf0 + } + if m.TotalActiveAnon != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalActiveAnon)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe8 + } + if m.TotalInactiveAnon != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalInactiveAnon)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xe0 + } + if m.TotalPgMajFault != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgMajFault)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd8 + } + if m.TotalPgFault != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgFault)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xd0 + } + if m.TotalPgPgOut != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgOut)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc8 + } + if m.TotalPgPgIn != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalPgPgIn)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xc0 + } + if m.TotalWriteback != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalWriteback)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb8 + } + if m.TotalDirty != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalDirty)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xb0 + } + if m.TotalMappedFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalMappedFile)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa8 + } + if m.TotalRSSHuge != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSSHuge)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa0 + } + if m.TotalRSS != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalRSS)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x98 + } + if m.TotalCache != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TotalCache)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x90 + } + if m.HierarchicalSwapLimit != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalSwapLimit)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x88 + } + if m.HierarchicalMemoryLimit != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.HierarchicalMemoryLimit)) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x80 + } + if m.Unevictable != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Unevictable)) + i-- + dAtA[i] = 0x78 + } + if m.ActiveFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveFile)) + i-- + dAtA[i] = 0x70 + } + if m.InactiveFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveFile)) + i-- + dAtA[i] = 0x68 + } + if m.ActiveAnon != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.ActiveAnon)) + i-- + dAtA[i] = 0x60 + } + if m.InactiveAnon != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.InactiveAnon)) + i-- + dAtA[i] = 0x58 + } + if m.PgMajFault != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.PgMajFault)) + i-- + dAtA[i] = 0x50 + } + if m.PgFault != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.PgFault)) + i-- + dAtA[i] = 0x48 + } + if m.PgPgOut != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgOut)) + i-- + dAtA[i] = 0x40 + } + if m.PgPgIn != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.PgPgIn)) + i-- + dAtA[i] = 0x38 + } + if m.Writeback != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Writeback)) + i-- + dAtA[i] = 0x30 + } + if m.Dirty != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Dirty)) + i-- + dAtA[i] = 0x28 + } + if m.MappedFile != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.MappedFile)) + i-- + dAtA[i] = 0x20 + } + if m.RSSHuge != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RSSHuge)) + i-- + dAtA[i] = 0x18 + } + if m.RSS != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RSS)) + i-- + dAtA[i] = 0x10 + } + if m.Cache != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Cache)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MemoryEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemoryEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Failcnt != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Failcnt)) + i-- + dAtA[i] = 0x20 + } + if m.Max != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Max)) + i-- + dAtA[i] = 0x18 + } + if m.Usage != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Usage)) + i-- + dAtA[i] = 0x10 + } + if m.Limit != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *MemoryOomControl) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *MemoryOomControl) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *MemoryOomControl) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.OomKill != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.OomKill)) + i-- + dAtA[i] = 0x18 + } + if m.UnderOom != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.UnderOom)) + i-- + dAtA[i] = 0x10 + } + if m.OomKillDisable != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.OomKillDisable)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *BlkIOStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlkIOStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlkIOStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.SectorsRecursive) > 0 { + for iNdEx := len(m.SectorsRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SectorsRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } + if len(m.IoTimeRecursive) > 0 { + for iNdEx := len(m.IoTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x3a + } + } + if len(m.IoMergedRecursive) > 0 { + for iNdEx := len(m.IoMergedRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoMergedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x32 + } + } + if len(m.IoWaitTimeRecursive) > 0 { + for iNdEx := len(m.IoWaitTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoWaitTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + } + if len(m.IoServiceTimeRecursive) > 0 { + for iNdEx := len(m.IoServiceTimeRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoServiceTimeRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + if len(m.IoQueuedRecursive) > 0 { + for iNdEx := len(m.IoQueuedRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoQueuedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if len(m.IoServicedRecursive) > 0 { + for iNdEx := len(m.IoServicedRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoServicedRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.IoServiceBytesRecursive) > 0 { + for iNdEx := len(m.IoServiceBytesRecursive) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.IoServiceBytesRecursive[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *BlkIOEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BlkIOEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BlkIOEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Value != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Value)) + i-- + dAtA[i] = 0x28 + } + if m.Minor != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Minor)) + i-- + dAtA[i] = 0x20 + } + if m.Major != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.Major)) + i-- + dAtA[i] = 0x18 + } + if len(m.Device) > 0 { + i -= len(m.Device) + copy(dAtA[i:], m.Device) + i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) + i-- + dAtA[i] = 0x12 + } + if len(m.Op) > 0 { + i -= len(m.Op) + copy(dAtA[i:], m.Op) + i = encodeVarintMetrics(dAtA, i, uint64(len(m.Op))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RdmaStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RdmaStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Limit) > 0 { + for iNdEx := len(m.Limit) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Limit[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + } + if len(m.Current) > 0 { + for iNdEx := len(m.Current) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Current[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintMetrics(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *RdmaEntry) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RdmaEntry) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *RdmaEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.HcaObjects != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.HcaObjects)) + i-- + dAtA[i] = 0x18 + } + if m.HcaHandles != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.HcaHandles)) + i-- + dAtA[i] = 0x10 + } + if len(m.Device) > 0 { + i -= len(m.Device) + copy(dAtA[i:], m.Device) + i = encodeVarintMetrics(dAtA, i, uint64(len(m.Device))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *NetworkStat) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *NetworkStat) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *NetworkStat) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.TxDropped != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TxDropped)) + i-- + dAtA[i] = 0x48 + } + if m.TxErrors != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TxErrors)) + i-- + dAtA[i] = 0x40 + } + if m.TxPackets != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TxPackets)) + i-- + dAtA[i] = 0x38 + } + if m.TxBytes != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.TxBytes)) + i-- + dAtA[i] = 0x30 + } + if m.RxDropped != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RxDropped)) + i-- + dAtA[i] = 0x28 + } + if m.RxErrors != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RxErrors)) + i-- + dAtA[i] = 0x20 + } + if m.RxPackets != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RxPackets)) + i-- + dAtA[i] = 0x18 + } + if m.RxBytes != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.RxBytes)) + i-- + dAtA[i] = 0x10 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintMetrics(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *CgroupStats) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *CgroupStats) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *CgroupStats) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.NrIoWait != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.NrIoWait)) + i-- + dAtA[i] = 0x28 + } + if m.NrUninterruptible != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.NrUninterruptible)) + i-- + dAtA[i] = 0x20 + } + if m.NrStopped != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.NrStopped)) + i-- + dAtA[i] = 0x18 + } + if m.NrRunning != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.NrRunning)) + i-- + dAtA[i] = 0x10 + } + if m.NrSleeping != 0 { + i = encodeVarintMetrics(dAtA, i, uint64(m.NrSleeping)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintMetrics(dAtA []byte, offset int, v uint64) int { + offset -= sovMetrics(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *Metrics) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Hugetlb) > 0 { + for _, e := range m.Hugetlb { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if m.Pids != nil { + l = m.Pids.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.CPU != nil { + l = m.CPU.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.Memory != nil { + l = m.Memory.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.Blkio != nil { + l = m.Blkio.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.Rdma != nil { + l = m.Rdma.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if len(m.Network) > 0 { + for _, e := range m.Network { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if m.CgroupStats != nil { + l = m.CgroupStats.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.MemoryOomControl != nil { + l = m.MemoryOomControl.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *HugetlbStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Usage != 0 { + n += 1 + sovMetrics(uint64(m.Usage)) + } + if m.Max != 0 { + n += 1 + sovMetrics(uint64(m.Max)) + } + if m.Failcnt != 0 { + n += 1 + sovMetrics(uint64(m.Failcnt)) + } + l = len(m.Pagesize) + if l > 0 { + n += 1 + l + sovMetrics(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *PidsStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Current != 0 { + n += 1 + sovMetrics(uint64(m.Current)) + } + if m.Limit != 0 { + n += 1 + sovMetrics(uint64(m.Limit)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CPUStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Usage != nil { + l = m.Usage.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.Throttling != nil { + l = m.Throttling.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CPUUsage) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Total != 0 { + n += 1 + sovMetrics(uint64(m.Total)) + } + if m.Kernel != 0 { + n += 1 + sovMetrics(uint64(m.Kernel)) + } + if m.User != 0 { + n += 1 + sovMetrics(uint64(m.User)) + } + if len(m.PerCPU) > 0 { + l = 0 + for _, e := range m.PerCPU { + l += sovMetrics(uint64(e)) + } + n += 1 + sovMetrics(uint64(l)) + l + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Throttle) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Periods != 0 { + n += 1 + sovMetrics(uint64(m.Periods)) + } + if m.ThrottledPeriods != 0 { + n += 1 + sovMetrics(uint64(m.ThrottledPeriods)) + } + if m.ThrottledTime != 0 { + n += 1 + sovMetrics(uint64(m.ThrottledTime)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MemoryStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Cache != 0 { + n += 1 + sovMetrics(uint64(m.Cache)) + } + if m.RSS != 0 { + n += 1 + sovMetrics(uint64(m.RSS)) + } + if m.RSSHuge != 0 { + n += 1 + sovMetrics(uint64(m.RSSHuge)) + } + if m.MappedFile != 0 { + n += 1 + sovMetrics(uint64(m.MappedFile)) + } + if m.Dirty != 0 { + n += 1 + sovMetrics(uint64(m.Dirty)) + } + if m.Writeback != 0 { + n += 1 + sovMetrics(uint64(m.Writeback)) + } + if m.PgPgIn != 0 { + n += 1 + sovMetrics(uint64(m.PgPgIn)) + } + if m.PgPgOut != 0 { + n += 1 + sovMetrics(uint64(m.PgPgOut)) + } + if m.PgFault != 0 { + n += 1 + sovMetrics(uint64(m.PgFault)) + } + if m.PgMajFault != 0 { + n += 1 + sovMetrics(uint64(m.PgMajFault)) + } + if m.InactiveAnon != 0 { + n += 1 + sovMetrics(uint64(m.InactiveAnon)) + } + if m.ActiveAnon != 0 { + n += 1 + sovMetrics(uint64(m.ActiveAnon)) + } + if m.InactiveFile != 0 { + n += 1 + sovMetrics(uint64(m.InactiveFile)) + } + if m.ActiveFile != 0 { + n += 1 + sovMetrics(uint64(m.ActiveFile)) + } + if m.Unevictable != 0 { + n += 1 + sovMetrics(uint64(m.Unevictable)) + } + if m.HierarchicalMemoryLimit != 0 { + n += 2 + sovMetrics(uint64(m.HierarchicalMemoryLimit)) + } + if m.HierarchicalSwapLimit != 0 { + n += 2 + sovMetrics(uint64(m.HierarchicalSwapLimit)) + } + if m.TotalCache != 0 { + n += 2 + sovMetrics(uint64(m.TotalCache)) + } + if m.TotalRSS != 0 { + n += 2 + sovMetrics(uint64(m.TotalRSS)) + } + if m.TotalRSSHuge != 0 { + n += 2 + sovMetrics(uint64(m.TotalRSSHuge)) + } + if m.TotalMappedFile != 0 { + n += 2 + sovMetrics(uint64(m.TotalMappedFile)) + } + if m.TotalDirty != 0 { + n += 2 + sovMetrics(uint64(m.TotalDirty)) + } + if m.TotalWriteback != 0 { + n += 2 + sovMetrics(uint64(m.TotalWriteback)) + } + if m.TotalPgPgIn != 0 { + n += 2 + sovMetrics(uint64(m.TotalPgPgIn)) + } + if m.TotalPgPgOut != 0 { + n += 2 + sovMetrics(uint64(m.TotalPgPgOut)) + } + if m.TotalPgFault != 0 { + n += 2 + sovMetrics(uint64(m.TotalPgFault)) + } + if m.TotalPgMajFault != 0 { + n += 2 + sovMetrics(uint64(m.TotalPgMajFault)) + } + if m.TotalInactiveAnon != 0 { + n += 2 + sovMetrics(uint64(m.TotalInactiveAnon)) + } + if m.TotalActiveAnon != 0 { + n += 2 + sovMetrics(uint64(m.TotalActiveAnon)) + } + if m.TotalInactiveFile != 0 { + n += 2 + sovMetrics(uint64(m.TotalInactiveFile)) + } + if m.TotalActiveFile != 0 { + n += 2 + sovMetrics(uint64(m.TotalActiveFile)) + } + if m.TotalUnevictable != 0 { + n += 2 + sovMetrics(uint64(m.TotalUnevictable)) + } + if m.Usage != nil { + l = m.Usage.Size() + n += 2 + l + sovMetrics(uint64(l)) + } + if m.Swap != nil { + l = m.Swap.Size() + n += 2 + l + sovMetrics(uint64(l)) + } + if m.Kernel != nil { + l = m.Kernel.Size() + n += 2 + l + sovMetrics(uint64(l)) + } + if m.KernelTCP != nil { + l = m.KernelTCP.Size() + n += 2 + l + sovMetrics(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MemoryEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Limit != 0 { + n += 1 + sovMetrics(uint64(m.Limit)) + } + if m.Usage != 0 { + n += 1 + sovMetrics(uint64(m.Usage)) + } + if m.Max != 0 { + n += 1 + sovMetrics(uint64(m.Max)) + } + if m.Failcnt != 0 { + n += 1 + sovMetrics(uint64(m.Failcnt)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *MemoryOomControl) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.OomKillDisable != 0 { + n += 1 + sovMetrics(uint64(m.OomKillDisable)) + } + if m.UnderOom != 0 { + n += 1 + sovMetrics(uint64(m.UnderOom)) + } + if m.OomKill != 0 { + n += 1 + sovMetrics(uint64(m.OomKill)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *BlkIOStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.IoServiceBytesRecursive) > 0 { + for _, e := range m.IoServiceBytesRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoServicedRecursive) > 0 { + for _, e := range m.IoServicedRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoQueuedRecursive) > 0 { + for _, e := range m.IoQueuedRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoServiceTimeRecursive) > 0 { + for _, e := range m.IoServiceTimeRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoWaitTimeRecursive) > 0 { + for _, e := range m.IoWaitTimeRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoMergedRecursive) > 0 { + for _, e := range m.IoMergedRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.IoTimeRecursive) > 0 { + for _, e := range m.IoTimeRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.SectorsRecursive) > 0 { + for _, e := range m.SectorsRecursive { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *BlkIOEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Op) + if l > 0 { + n += 1 + l + sovMetrics(uint64(l)) + } + l = len(m.Device) + if l > 0 { + n += 1 + l + sovMetrics(uint64(l)) + } + if m.Major != 0 { + n += 1 + sovMetrics(uint64(m.Major)) + } + if m.Minor != 0 { + n += 1 + sovMetrics(uint64(m.Minor)) + } + if m.Value != 0 { + n += 1 + sovMetrics(uint64(m.Value)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RdmaStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Current) > 0 { + for _, e := range m.Current { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if len(m.Limit) > 0 { + for _, e := range m.Limit { + l = e.Size() + n += 1 + l + sovMetrics(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *RdmaEntry) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Device) + if l > 0 { + n += 1 + l + sovMetrics(uint64(l)) + } + if m.HcaHandles != 0 { + n += 1 + sovMetrics(uint64(m.HcaHandles)) + } + if m.HcaObjects != 0 { + n += 1 + sovMetrics(uint64(m.HcaObjects)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *NetworkStat) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovMetrics(uint64(l)) + } + if m.RxBytes != 0 { + n += 1 + sovMetrics(uint64(m.RxBytes)) + } + if m.RxPackets != 0 { + n += 1 + sovMetrics(uint64(m.RxPackets)) + } + if m.RxErrors != 0 { + n += 1 + sovMetrics(uint64(m.RxErrors)) + } + if m.RxDropped != 0 { + n += 1 + sovMetrics(uint64(m.RxDropped)) + } + if m.TxBytes != 0 { + n += 1 + sovMetrics(uint64(m.TxBytes)) + } + if m.TxPackets != 0 { + n += 1 + sovMetrics(uint64(m.TxPackets)) + } + if m.TxErrors != 0 { + n += 1 + sovMetrics(uint64(m.TxErrors)) + } + if m.TxDropped != 0 { + n += 1 + sovMetrics(uint64(m.TxDropped)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *CgroupStats) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NrSleeping != 0 { + n += 1 + sovMetrics(uint64(m.NrSleeping)) + } + if m.NrRunning != 0 { + n += 1 + sovMetrics(uint64(m.NrRunning)) + } + if m.NrStopped != 0 { + n += 1 + sovMetrics(uint64(m.NrStopped)) + } + if m.NrUninterruptible != 0 { + n += 1 + sovMetrics(uint64(m.NrUninterruptible)) + } + if m.NrIoWait != 0 { + n += 1 + sovMetrics(uint64(m.NrIoWait)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovMetrics(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozMetrics(x uint64) (n int) { + return sovMetrics(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (this *Metrics) String() string { + if this == nil { + return "nil" + } + repeatedStringForHugetlb := "[]*HugetlbStat{" + for _, f := range this.Hugetlb { + repeatedStringForHugetlb += strings.Replace(f.String(), "HugetlbStat", "HugetlbStat", 1) + "," + } + repeatedStringForHugetlb += "}" + repeatedStringForNetwork := "[]*NetworkStat{" + for _, f := range this.Network { + repeatedStringForNetwork += strings.Replace(f.String(), "NetworkStat", "NetworkStat", 1) + "," + } + repeatedStringForNetwork += "}" + s := strings.Join([]string{`&Metrics{`, + `Hugetlb:` + repeatedStringForHugetlb + `,`, + `Pids:` + strings.Replace(this.Pids.String(), "PidsStat", "PidsStat", 1) + `,`, + `CPU:` + strings.Replace(this.CPU.String(), "CPUStat", "CPUStat", 1) + `,`, + `Memory:` + strings.Replace(this.Memory.String(), "MemoryStat", "MemoryStat", 1) + `,`, + `Blkio:` + strings.Replace(this.Blkio.String(), "BlkIOStat", "BlkIOStat", 1) + `,`, + `Rdma:` + strings.Replace(this.Rdma.String(), "RdmaStat", "RdmaStat", 1) + `,`, + `Network:` + repeatedStringForNetwork + `,`, + `CgroupStats:` + strings.Replace(this.CgroupStats.String(), "CgroupStats", "CgroupStats", 1) + `,`, + `MemoryOomControl:` + strings.Replace(this.MemoryOomControl.String(), "MemoryOomControl", "MemoryOomControl", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *HugetlbStat) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&HugetlbStat{`, + `Usage:` + fmt.Sprintf("%v", this.Usage) + `,`, + `Max:` + fmt.Sprintf("%v", this.Max) + `,`, + `Failcnt:` + fmt.Sprintf("%v", this.Failcnt) + `,`, + `Pagesize:` + fmt.Sprintf("%v", this.Pagesize) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *PidsStat) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PidsStat{`, + `Current:` + fmt.Sprintf("%v", this.Current) + `,`, + `Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CPUStat) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CPUStat{`, + `Usage:` + strings.Replace(this.Usage.String(), "CPUUsage", "CPUUsage", 1) + `,`, + `Throttling:` + strings.Replace(this.Throttling.String(), "Throttle", "Throttle", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CPUUsage) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CPUUsage{`, + `Total:` + fmt.Sprintf("%v", this.Total) + `,`, + `Kernel:` + fmt.Sprintf("%v", this.Kernel) + `,`, + `User:` + fmt.Sprintf("%v", this.User) + `,`, + `PerCPU:` + fmt.Sprintf("%v", this.PerCPU) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *Throttle) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&Throttle{`, + `Periods:` + fmt.Sprintf("%v", this.Periods) + `,`, + `ThrottledPeriods:` + fmt.Sprintf("%v", this.ThrottledPeriods) + `,`, + `ThrottledTime:` + fmt.Sprintf("%v", this.ThrottledTime) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *MemoryStat) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MemoryStat{`, + `Cache:` + fmt.Sprintf("%v", this.Cache) + `,`, + `RSS:` + fmt.Sprintf("%v", this.RSS) + `,`, + `RSSHuge:` + fmt.Sprintf("%v", this.RSSHuge) + `,`, + `MappedFile:` + fmt.Sprintf("%v", this.MappedFile) + `,`, + `Dirty:` + fmt.Sprintf("%v", this.Dirty) + `,`, + `Writeback:` + fmt.Sprintf("%v", this.Writeback) + `,`, + `PgPgIn:` + fmt.Sprintf("%v", this.PgPgIn) + `,`, + `PgPgOut:` + fmt.Sprintf("%v", this.PgPgOut) + `,`, + `PgFault:` + fmt.Sprintf("%v", this.PgFault) + `,`, + `PgMajFault:` + fmt.Sprintf("%v", this.PgMajFault) + `,`, + `InactiveAnon:` + fmt.Sprintf("%v", this.InactiveAnon) + `,`, + `ActiveAnon:` + fmt.Sprintf("%v", this.ActiveAnon) + `,`, + `InactiveFile:` + fmt.Sprintf("%v", this.InactiveFile) + `,`, + `ActiveFile:` + fmt.Sprintf("%v", this.ActiveFile) + `,`, + `Unevictable:` + fmt.Sprintf("%v", this.Unevictable) + `,`, + `HierarchicalMemoryLimit:` + fmt.Sprintf("%v", this.HierarchicalMemoryLimit) + `,`, + `HierarchicalSwapLimit:` + fmt.Sprintf("%v", this.HierarchicalSwapLimit) + `,`, + `TotalCache:` + fmt.Sprintf("%v", this.TotalCache) + `,`, + `TotalRSS:` + fmt.Sprintf("%v", this.TotalRSS) + `,`, + `TotalRSSHuge:` + fmt.Sprintf("%v", this.TotalRSSHuge) + `,`, + `TotalMappedFile:` + fmt.Sprintf("%v", this.TotalMappedFile) + `,`, + `TotalDirty:` + fmt.Sprintf("%v", this.TotalDirty) + `,`, + `TotalWriteback:` + fmt.Sprintf("%v", this.TotalWriteback) + `,`, + `TotalPgPgIn:` + fmt.Sprintf("%v", this.TotalPgPgIn) + `,`, + `TotalPgPgOut:` + fmt.Sprintf("%v", this.TotalPgPgOut) + `,`, + `TotalPgFault:` + fmt.Sprintf("%v", this.TotalPgFault) + `,`, + `TotalPgMajFault:` + fmt.Sprintf("%v", this.TotalPgMajFault) + `,`, + `TotalInactiveAnon:` + fmt.Sprintf("%v", this.TotalInactiveAnon) + `,`, + `TotalActiveAnon:` + fmt.Sprintf("%v", this.TotalActiveAnon) + `,`, + `TotalInactiveFile:` + fmt.Sprintf("%v", this.TotalInactiveFile) + `,`, + `TotalActiveFile:` + fmt.Sprintf("%v", this.TotalActiveFile) + `,`, + `TotalUnevictable:` + fmt.Sprintf("%v", this.TotalUnevictable) + `,`, + `Usage:` + strings.Replace(this.Usage.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, + `Swap:` + strings.Replace(this.Swap.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, + `Kernel:` + strings.Replace(this.Kernel.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, + `KernelTCP:` + strings.Replace(this.KernelTCP.String(), "MemoryEntry", "MemoryEntry", 1) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *MemoryEntry) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MemoryEntry{`, + `Limit:` + fmt.Sprintf("%v", this.Limit) + `,`, + `Usage:` + fmt.Sprintf("%v", this.Usage) + `,`, + `Max:` + fmt.Sprintf("%v", this.Max) + `,`, + `Failcnt:` + fmt.Sprintf("%v", this.Failcnt) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *MemoryOomControl) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&MemoryOomControl{`, + `OomKillDisable:` + fmt.Sprintf("%v", this.OomKillDisable) + `,`, + `UnderOom:` + fmt.Sprintf("%v", this.UnderOom) + `,`, + `OomKill:` + fmt.Sprintf("%v", this.OomKill) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *BlkIOStat) String() string { + if this == nil { + return "nil" + } + repeatedStringForIoServiceBytesRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoServiceBytesRecursive { + repeatedStringForIoServiceBytesRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoServiceBytesRecursive += "}" + repeatedStringForIoServicedRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoServicedRecursive { + repeatedStringForIoServicedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoServicedRecursive += "}" + repeatedStringForIoQueuedRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoQueuedRecursive { + repeatedStringForIoQueuedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoQueuedRecursive += "}" + repeatedStringForIoServiceTimeRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoServiceTimeRecursive { + repeatedStringForIoServiceTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoServiceTimeRecursive += "}" + repeatedStringForIoWaitTimeRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoWaitTimeRecursive { + repeatedStringForIoWaitTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoWaitTimeRecursive += "}" + repeatedStringForIoMergedRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoMergedRecursive { + repeatedStringForIoMergedRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoMergedRecursive += "}" + repeatedStringForIoTimeRecursive := "[]*BlkIOEntry{" + for _, f := range this.IoTimeRecursive { + repeatedStringForIoTimeRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForIoTimeRecursive += "}" + repeatedStringForSectorsRecursive := "[]*BlkIOEntry{" + for _, f := range this.SectorsRecursive { + repeatedStringForSectorsRecursive += strings.Replace(f.String(), "BlkIOEntry", "BlkIOEntry", 1) + "," + } + repeatedStringForSectorsRecursive += "}" + s := strings.Join([]string{`&BlkIOStat{`, + `IoServiceBytesRecursive:` + repeatedStringForIoServiceBytesRecursive + `,`, + `IoServicedRecursive:` + repeatedStringForIoServicedRecursive + `,`, + `IoQueuedRecursive:` + repeatedStringForIoQueuedRecursive + `,`, + `IoServiceTimeRecursive:` + repeatedStringForIoServiceTimeRecursive + `,`, + `IoWaitTimeRecursive:` + repeatedStringForIoWaitTimeRecursive + `,`, + `IoMergedRecursive:` + repeatedStringForIoMergedRecursive + `,`, + `IoTimeRecursive:` + repeatedStringForIoTimeRecursive + `,`, + `SectorsRecursive:` + repeatedStringForSectorsRecursive + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *BlkIOEntry) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&BlkIOEntry{`, + `Op:` + fmt.Sprintf("%v", this.Op) + `,`, + `Device:` + fmt.Sprintf("%v", this.Device) + `,`, + `Major:` + fmt.Sprintf("%v", this.Major) + `,`, + `Minor:` + fmt.Sprintf("%v", this.Minor) + `,`, + `Value:` + fmt.Sprintf("%v", this.Value) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *RdmaStat) String() string { + if this == nil { + return "nil" + } + repeatedStringForCurrent := "[]*RdmaEntry{" + for _, f := range this.Current { + repeatedStringForCurrent += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," + } + repeatedStringForCurrent += "}" + repeatedStringForLimit := "[]*RdmaEntry{" + for _, f := range this.Limit { + repeatedStringForLimit += strings.Replace(f.String(), "RdmaEntry", "RdmaEntry", 1) + "," + } + repeatedStringForLimit += "}" + s := strings.Join([]string{`&RdmaStat{`, + `Current:` + repeatedStringForCurrent + `,`, + `Limit:` + repeatedStringForLimit + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *RdmaEntry) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&RdmaEntry{`, + `Device:` + fmt.Sprintf("%v", this.Device) + `,`, + `HcaHandles:` + fmt.Sprintf("%v", this.HcaHandles) + `,`, + `HcaObjects:` + fmt.Sprintf("%v", this.HcaObjects) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *NetworkStat) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NetworkStat{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `RxBytes:` + fmt.Sprintf("%v", this.RxBytes) + `,`, + `RxPackets:` + fmt.Sprintf("%v", this.RxPackets) + `,`, + `RxErrors:` + fmt.Sprintf("%v", this.RxErrors) + `,`, + `RxDropped:` + fmt.Sprintf("%v", this.RxDropped) + `,`, + `TxBytes:` + fmt.Sprintf("%v", this.TxBytes) + `,`, + `TxPackets:` + fmt.Sprintf("%v", this.TxPackets) + `,`, + `TxErrors:` + fmt.Sprintf("%v", this.TxErrors) + `,`, + `TxDropped:` + fmt.Sprintf("%v", this.TxDropped) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func (this *CgroupStats) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&CgroupStats{`, + `NrSleeping:` + fmt.Sprintf("%v", this.NrSleeping) + `,`, + `NrRunning:` + fmt.Sprintf("%v", this.NrRunning) + `,`, + `NrStopped:` + fmt.Sprintf("%v", this.NrStopped) + `,`, + `NrUninterruptible:` + fmt.Sprintf("%v", this.NrUninterruptible) + `,`, + `NrIoWait:` + fmt.Sprintf("%v", this.NrIoWait) + `,`, + `XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`, + `}`, + }, "") + return s +} +func valueToStringMetrics(v interface{}) string { + rv := reflect.ValueOf(v) + if rv.IsNil() { + return "nil" + } + pv := reflect.Indirect(rv).Interface() + return fmt.Sprintf("*%v", pv) +} +func (m *Metrics) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Metrics: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Metrics: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hugetlb", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hugetlb = append(m.Hugetlb, &HugetlbStat{}) + if err := m.Hugetlb[len(m.Hugetlb)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pids", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pids == nil { + m.Pids = &PidsStat{} + } + if err := m.Pids.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CPU", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CPU == nil { + m.CPU = &CPUStat{} + } + if err := m.CPU.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Memory", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Memory == nil { + m.Memory = &MemoryStat{} + } + if err := m.Memory.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blkio", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Blkio == nil { + m.Blkio = &BlkIOStat{} + } + if err := m.Blkio.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rdma", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rdma == nil { + m.Rdma = &RdmaStat{} + } + if err := m.Rdma.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Network", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Network = append(m.Network, &NetworkStat{}) + if err := m.Network[len(m.Network)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field CgroupStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.CgroupStats == nil { + m.CgroupStats = &CgroupStats{} + } + if err := m.CgroupStats.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field MemoryOomControl", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.MemoryOomControl == nil { + m.MemoryOomControl = &MemoryOomControl{} + } + if err := m.MemoryOomControl.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HugetlbStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HugetlbStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HugetlbStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) + } + m.Usage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Usage |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) + } + m.Max = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Max |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Failcnt", wireType) + } + m.Failcnt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Failcnt |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagesize", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Pagesize = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PidsStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PidsStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PidsStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) + } + m.Current = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Current |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CPUStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CPUStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CPUStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Usage == nil { + m.Usage = &CPUUsage{} + } + if err := m.Usage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Throttling", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Throttling == nil { + m.Throttling = &Throttle{} + } + if err := m.Throttling.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CPUUsage) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CPUUsage: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CPUUsage: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Total", wireType) + } + m.Total = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Total |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Kernel", wireType) + } + m.Kernel = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Kernel |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + m.User = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.User |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType == 0 { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PerCPU = append(m.PerCPU, v) + } else if wireType == 2 { + var packedLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + packedLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if packedLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + packedLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + var elementCount int + var count int + for _, integer := range dAtA[iNdEx:postIndex] { + if integer < 128 { + count++ + } + } + elementCount = count + if elementCount != 0 && len(m.PerCPU) == 0 { + m.PerCPU = make([]uint64, 0, elementCount) + } + for iNdEx < postIndex { + var v uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.PerCPU = append(m.PerCPU, v) + } + } else { + return fmt.Errorf("proto: wrong wireType = %d for field PerCPU", wireType) + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Throttle) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Throttle: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Throttle: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Periods", wireType) + } + m.Periods = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Periods |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ThrottledPeriods", wireType) + } + m.ThrottledPeriods = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ThrottledPeriods |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ThrottledTime", wireType) + } + m.ThrottledTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ThrottledTime |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MemoryStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MemoryStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MemoryStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Cache", wireType) + } + m.Cache = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Cache |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RSS", wireType) + } + m.RSS = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RSS |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RSSHuge", wireType) + } + m.RSSHuge = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RSSHuge |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field MappedFile", wireType) + } + m.MappedFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.MappedFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Dirty", wireType) + } + m.Dirty = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Dirty |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Writeback", wireType) + } + m.Writeback = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Writeback |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PgPgIn", wireType) + } + m.PgPgIn = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PgPgIn |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PgPgOut", wireType) + } + m.PgPgOut = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PgPgOut |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PgFault", wireType) + } + m.PgFault = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PgFault |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field PgMajFault", wireType) + } + m.PgMajFault = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.PgMajFault |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InactiveAnon", wireType) + } + m.InactiveAnon = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InactiveAnon |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveAnon", wireType) + } + m.ActiveAnon = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ActiveAnon |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field InactiveFile", wireType) + } + m.InactiveFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.InactiveFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveFile", wireType) + } + m.ActiveFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ActiveFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 15: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Unevictable", wireType) + } + m.Unevictable = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Unevictable |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 16: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HierarchicalMemoryLimit", wireType) + } + m.HierarchicalMemoryLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HierarchicalMemoryLimit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 17: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HierarchicalSwapLimit", wireType) + } + m.HierarchicalSwapLimit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HierarchicalSwapLimit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 18: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalCache", wireType) + } + m.TotalCache = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalCache |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 19: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalRSS", wireType) + } + m.TotalRSS = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalRSS |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 20: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalRSSHuge", wireType) + } + m.TotalRSSHuge = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalRSSHuge |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 21: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalMappedFile", wireType) + } + m.TotalMappedFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalMappedFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 22: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalDirty", wireType) + } + m.TotalDirty = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalDirty |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 23: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalWriteback", wireType) + } + m.TotalWriteback = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalWriteback |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 24: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPgPgIn", wireType) + } + m.TotalPgPgIn = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPgPgIn |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 25: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPgPgOut", wireType) + } + m.TotalPgPgOut = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPgPgOut |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 26: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPgFault", wireType) + } + m.TotalPgFault = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPgFault |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 27: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalPgMajFault", wireType) + } + m.TotalPgMajFault = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalPgMajFault |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 28: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalInactiveAnon", wireType) + } + m.TotalInactiveAnon = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalInactiveAnon |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 29: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalActiveAnon", wireType) + } + m.TotalActiveAnon = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalActiveAnon |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 30: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalInactiveFile", wireType) + } + m.TotalInactiveFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalInactiveFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 31: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalActiveFile", wireType) + } + m.TotalActiveFile = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalActiveFile |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 32: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TotalUnevictable", wireType) + } + m.TotalUnevictable = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TotalUnevictable |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 33: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Usage == nil { + m.Usage = &MemoryEntry{} + } + if err := m.Usage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 34: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Swap", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Swap == nil { + m.Swap = &MemoryEntry{} + } + if err := m.Swap.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 35: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kernel", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Kernel == nil { + m.Kernel = &MemoryEntry{} + } + if err := m.Kernel.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 36: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KernelTCP", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.KernelTCP == nil { + m.KernelTCP = &MemoryEntry{} + } + if err := m.KernelTCP.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MemoryEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MemoryEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MemoryEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Usage", wireType) + } + m.Usage = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Usage |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Max", wireType) + } + m.Max = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Max |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Failcnt", wireType) + } + m.Failcnt = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Failcnt |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *MemoryOomControl) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: MemoryOomControl: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: MemoryOomControl: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OomKillDisable", wireType) + } + m.OomKillDisable = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OomKillDisable |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field UnderOom", wireType) + } + m.UnderOom = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.UnderOom |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field OomKill", wireType) + } + m.OomKill = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.OomKill |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlkIOStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlkIOStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlkIOStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoServiceBytesRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoServiceBytesRecursive = append(m.IoServiceBytesRecursive, &BlkIOEntry{}) + if err := m.IoServiceBytesRecursive[len(m.IoServiceBytesRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoServicedRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoServicedRecursive = append(m.IoServicedRecursive, &BlkIOEntry{}) + if err := m.IoServicedRecursive[len(m.IoServicedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoQueuedRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoQueuedRecursive = append(m.IoQueuedRecursive, &BlkIOEntry{}) + if err := m.IoQueuedRecursive[len(m.IoQueuedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoServiceTimeRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoServiceTimeRecursive = append(m.IoServiceTimeRecursive, &BlkIOEntry{}) + if err := m.IoServiceTimeRecursive[len(m.IoServiceTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoWaitTimeRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoWaitTimeRecursive = append(m.IoWaitTimeRecursive, &BlkIOEntry{}) + if err := m.IoWaitTimeRecursive[len(m.IoWaitTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoMergedRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoMergedRecursive = append(m.IoMergedRecursive, &BlkIOEntry{}) + if err := m.IoMergedRecursive[len(m.IoMergedRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field IoTimeRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.IoTimeRecursive = append(m.IoTimeRecursive, &BlkIOEntry{}) + if err := m.IoTimeRecursive[len(m.IoTimeRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SectorsRecursive", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SectorsRecursive = append(m.SectorsRecursive, &BlkIOEntry{}) + if err := m.SectorsRecursive[len(m.SectorsRecursive)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *BlkIOEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BlkIOEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BlkIOEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Op", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Op = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Device = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Major", wireType) + } + m.Major = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Major |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Minor", wireType) + } + m.Minor = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Minor |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Value", wireType) + } + m.Value = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Value |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RdmaStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RdmaStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RdmaStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Current", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Current = append(m.Current, &RdmaEntry{}) + if err := m.Current[len(m.Current)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Limit = append(m.Limit, &RdmaEntry{}) + if err := m.Limit[len(m.Limit)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RdmaEntry) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RdmaEntry: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RdmaEntry: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Device", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Device = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HcaHandles", wireType) + } + m.HcaHandles = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HcaHandles |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field HcaObjects", wireType) + } + m.HcaObjects = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.HcaObjects |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *NetworkStat) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NetworkStat: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NetworkStat: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthMetrics + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthMetrics + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RxBytes", wireType) + } + m.RxBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RxBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RxPackets", wireType) + } + m.RxPackets = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RxPackets |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RxErrors", wireType) + } + m.RxErrors = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RxErrors |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RxDropped", wireType) + } + m.RxDropped = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RxDropped |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxBytes", wireType) + } + m.TxBytes = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxBytes |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxPackets", wireType) + } + m.TxPackets = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxPackets |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxErrors", wireType) + } + m.TxErrors = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxErrors |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field TxDropped", wireType) + } + m.TxDropped = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.TxDropped |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *CgroupStats) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: CgroupStats: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: CgroupStats: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NrSleeping", wireType) + } + m.NrSleeping = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NrSleeping |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NrRunning", wireType) + } + m.NrRunning = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NrRunning |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NrStopped", wireType) + } + m.NrStopped = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NrStopped |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NrUninterruptible", wireType) + } + m.NrUninterruptible = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NrUninterruptible |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NrIoWait", wireType) + } + m.NrIoWait = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowMetrics + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NrIoWait |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := skipMetrics(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthMetrics + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipMetrics(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMetrics + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMetrics + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowMetrics + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthMetrics + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupMetrics + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthMetrics + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthMetrics = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowMetrics = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupMetrics = fmt.Errorf("proto: unexpected end of group") +) diff --git a/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt new file mode 100644 index 00000000000..e476cea6412 --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.pb.txt @@ -0,0 +1,790 @@ +file { + name: "github.com/containerd/cgroups/stats/v1/metrics.proto" + package: "io.containerd.cgroups.v1" + dependency: "gogoproto/gogo.proto" + message_type { + name: "Metrics" + field { + name: "hugetlb" + number: 1 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.HugetlbStat" + json_name: "hugetlb" + } + field { + name: "pids" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.PidsStat" + json_name: "pids" + } + field { + name: "cpu" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.CPUStat" + options { + 65004: "CPU" + } + json_name: "cpu" + } + field { + name: "memory" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryStat" + json_name: "memory" + } + field { + name: "blkio" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOStat" + json_name: "blkio" + } + field { + name: "rdma" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.RdmaStat" + json_name: "rdma" + } + field { + name: "network" + number: 7 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.NetworkStat" + json_name: "network" + } + field { + name: "cgroup_stats" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.CgroupStats" + json_name: "cgroupStats" + } + field { + name: "memory_oom_control" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryOomControl" + json_name: "memoryOomControl" + } + } + message_type { + name: "HugetlbStat" + field { + name: "usage" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "usage" + } + field { + name: "max" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "max" + } + field { + name: "failcnt" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "failcnt" + } + field { + name: "pagesize" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "pagesize" + } + } + message_type { + name: "PidsStat" + field { + name: "current" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "current" + } + field { + name: "limit" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "limit" + } + } + message_type { + name: "CPUStat" + field { + name: "usage" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.CPUUsage" + json_name: "usage" + } + field { + name: "throttling" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.Throttle" + json_name: "throttling" + } + } + message_type { + name: "CPUUsage" + field { + name: "total" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "total" + } + field { + name: "kernel" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "kernel" + } + field { + name: "user" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "user" + } + field { + name: "per_cpu" + number: 4 + label: LABEL_REPEATED + type: TYPE_UINT64 + options { + 65004: "PerCPU" + } + json_name: "perCpu" + } + } + message_type { + name: "Throttle" + field { + name: "periods" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "periods" + } + field { + name: "throttled_periods" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "throttledPeriods" + } + field { + name: "throttled_time" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "throttledTime" + } + } + message_type { + name: "MemoryStat" + field { + name: "cache" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "cache" + } + field { + name: "rss" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + options { + 65004: "RSS" + } + json_name: "rss" + } + field { + name: "rss_huge" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + options { + 65004: "RSSHuge" + } + json_name: "rssHuge" + } + field { + name: "mapped_file" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "mappedFile" + } + field { + name: "dirty" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "dirty" + } + field { + name: "writeback" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "writeback" + } + field { + name: "pg_pg_in" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "pgPgIn" + } + field { + name: "pg_pg_out" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "pgPgOut" + } + field { + name: "pg_fault" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "pgFault" + } + field { + name: "pg_maj_fault" + number: 10 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "pgMajFault" + } + field { + name: "inactive_anon" + number: 11 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "inactiveAnon" + } + field { + name: "active_anon" + number: 12 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "activeAnon" + } + field { + name: "inactive_file" + number: 13 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "inactiveFile" + } + field { + name: "active_file" + number: 14 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "activeFile" + } + field { + name: "unevictable" + number: 15 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "unevictable" + } + field { + name: "hierarchical_memory_limit" + number: 16 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "hierarchicalMemoryLimit" + } + field { + name: "hierarchical_swap_limit" + number: 17 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "hierarchicalSwapLimit" + } + field { + name: "total_cache" + number: 18 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalCache" + } + field { + name: "total_rss" + number: 19 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + options { + 65004: "TotalRSS" + } + json_name: "totalRss" + } + field { + name: "total_rss_huge" + number: 20 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + options { + 65004: "TotalRSSHuge" + } + json_name: "totalRssHuge" + } + field { + name: "total_mapped_file" + number: 21 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalMappedFile" + } + field { + name: "total_dirty" + number: 22 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalDirty" + } + field { + name: "total_writeback" + number: 23 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalWriteback" + } + field { + name: "total_pg_pg_in" + number: 24 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalPgPgIn" + } + field { + name: "total_pg_pg_out" + number: 25 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalPgPgOut" + } + field { + name: "total_pg_fault" + number: 26 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalPgFault" + } + field { + name: "total_pg_maj_fault" + number: 27 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalPgMajFault" + } + field { + name: "total_inactive_anon" + number: 28 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalInactiveAnon" + } + field { + name: "total_active_anon" + number: 29 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalActiveAnon" + } + field { + name: "total_inactive_file" + number: 30 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalInactiveFile" + } + field { + name: "total_active_file" + number: 31 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalActiveFile" + } + field { + name: "total_unevictable" + number: 32 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "totalUnevictable" + } + field { + name: "usage" + number: 33 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryEntry" + json_name: "usage" + } + field { + name: "swap" + number: 34 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryEntry" + json_name: "swap" + } + field { + name: "kernel" + number: 35 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryEntry" + json_name: "kernel" + } + field { + name: "kernel_tcp" + number: 36 + label: LABEL_OPTIONAL + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.MemoryEntry" + options { + 65004: "KernelTCP" + } + json_name: "kernelTcp" + } + } + message_type { + name: "MemoryEntry" + field { + name: "limit" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "limit" + } + field { + name: "usage" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "usage" + } + field { + name: "max" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "max" + } + field { + name: "failcnt" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "failcnt" + } + } + message_type { + name: "MemoryOomControl" + field { + name: "oom_kill_disable" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "oomKillDisable" + } + field { + name: "under_oom" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "underOom" + } + field { + name: "oom_kill" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "oomKill" + } + } + message_type { + name: "BlkIOStat" + field { + name: "io_service_bytes_recursive" + number: 1 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioServiceBytesRecursive" + } + field { + name: "io_serviced_recursive" + number: 2 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioServicedRecursive" + } + field { + name: "io_queued_recursive" + number: 3 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioQueuedRecursive" + } + field { + name: "io_service_time_recursive" + number: 4 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioServiceTimeRecursive" + } + field { + name: "io_wait_time_recursive" + number: 5 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioWaitTimeRecursive" + } + field { + name: "io_merged_recursive" + number: 6 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioMergedRecursive" + } + field { + name: "io_time_recursive" + number: 7 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "ioTimeRecursive" + } + field { + name: "sectors_recursive" + number: 8 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.BlkIOEntry" + json_name: "sectorsRecursive" + } + } + message_type { + name: "BlkIOEntry" + field { + name: "op" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "op" + } + field { + name: "device" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "device" + } + field { + name: "major" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "major" + } + field { + name: "minor" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "minor" + } + field { + name: "value" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "value" + } + } + message_type { + name: "RdmaStat" + field { + name: "current" + number: 1 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.RdmaEntry" + json_name: "current" + } + field { + name: "limit" + number: 2 + label: LABEL_REPEATED + type: TYPE_MESSAGE + type_name: ".io.containerd.cgroups.v1.RdmaEntry" + json_name: "limit" + } + } + message_type { + name: "RdmaEntry" + field { + name: "device" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "device" + } + field { + name: "hca_handles" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + json_name: "hcaHandles" + } + field { + name: "hca_objects" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT32 + json_name: "hcaObjects" + } + } + message_type { + name: "NetworkStat" + field { + name: "name" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_STRING + json_name: "name" + } + field { + name: "rx_bytes" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "rxBytes" + } + field { + name: "rx_packets" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "rxPackets" + } + field { + name: "rx_errors" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "rxErrors" + } + field { + name: "rx_dropped" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "rxDropped" + } + field { + name: "tx_bytes" + number: 6 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "txBytes" + } + field { + name: "tx_packets" + number: 7 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "txPackets" + } + field { + name: "tx_errors" + number: 8 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "txErrors" + } + field { + name: "tx_dropped" + number: 9 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "txDropped" + } + } + message_type { + name: "CgroupStats" + field { + name: "nr_sleeping" + number: 1 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "nrSleeping" + } + field { + name: "nr_running" + number: 2 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "nrRunning" + } + field { + name: "nr_stopped" + number: 3 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "nrStopped" + } + field { + name: "nr_uninterruptible" + number: 4 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "nrUninterruptible" + } + field { + name: "nr_io_wait" + number: 5 + label: LABEL_OPTIONAL + type: TYPE_UINT64 + json_name: "nrIoWait" + } + } + syntax: "proto3" +} diff --git a/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto new file mode 100644 index 00000000000..b3f6cc37d8c --- /dev/null +++ b/agent/vendor/github.com/containerd/cgroups/stats/v1/metrics.proto @@ -0,0 +1,158 @@ +syntax = "proto3"; + +package io.containerd.cgroups.v1; + +import "gogoproto/gogo.proto"; + +message Metrics { + repeated HugetlbStat hugetlb = 1; + PidsStat pids = 2; + CPUStat cpu = 3 [(gogoproto.customname) = "CPU"]; + MemoryStat memory = 4; + BlkIOStat blkio = 5; + RdmaStat rdma = 6; + repeated NetworkStat network = 7; + CgroupStats cgroup_stats = 8; + MemoryOomControl memory_oom_control = 9; +} + +message HugetlbStat { + uint64 usage = 1; + uint64 max = 2; + uint64 failcnt = 3; + string pagesize = 4; +} + +message PidsStat { + uint64 current = 1; + uint64 limit = 2; +} + +message CPUStat { + CPUUsage usage = 1; + Throttle throttling = 2; +} + +message CPUUsage { + // values in nanoseconds + uint64 total = 1; + uint64 kernel = 2; + uint64 user = 3; + repeated uint64 per_cpu = 4 [(gogoproto.customname) = "PerCPU"]; + +} + +message Throttle { + uint64 periods = 1; + uint64 throttled_periods = 2; + uint64 throttled_time = 3; +} + +message MemoryStat { + uint64 cache = 1; + uint64 rss = 2 [(gogoproto.customname) = "RSS"]; + uint64 rss_huge = 3 [(gogoproto.customname) = "RSSHuge"]; + uint64 mapped_file = 4; + uint64 dirty = 5; + uint64 writeback = 6; + uint64 pg_pg_in = 7; + uint64 pg_pg_out = 8; + uint64 pg_fault = 9; + uint64 pg_maj_fault = 10; + uint64 inactive_anon = 11; + uint64 active_anon = 12; + uint64 inactive_file = 13; + uint64 active_file = 14; + uint64 unevictable = 15; + uint64 hierarchical_memory_limit = 16; + uint64 hierarchical_swap_limit = 17; + uint64 total_cache = 18; + uint64 total_rss = 19 [(gogoproto.customname) = "TotalRSS"]; + uint64 total_rss_huge = 20 [(gogoproto.customname) = "TotalRSSHuge"]; + uint64 total_mapped_file = 21; + uint64 total_dirty = 22; + uint64 total_writeback = 23; + uint64 total_pg_pg_in = 24; + uint64 total_pg_pg_out = 25; + uint64 total_pg_fault = 26; + uint64 total_pg_maj_fault = 27; + uint64 total_inactive_anon = 28; + uint64 total_active_anon = 29; + uint64 total_inactive_file = 30; + uint64 total_active_file = 31; + uint64 total_unevictable = 32; + MemoryEntry usage = 33; + MemoryEntry swap = 34; + MemoryEntry kernel = 35; + MemoryEntry kernel_tcp = 36 [(gogoproto.customname) = "KernelTCP"]; + +} + +message MemoryEntry { + uint64 limit = 1; + uint64 usage = 2; + uint64 max = 3; + uint64 failcnt = 4; +} + +message MemoryOomControl { + uint64 oom_kill_disable = 1; + uint64 under_oom = 2; + uint64 oom_kill = 3; +} + +message BlkIOStat { + repeated BlkIOEntry io_service_bytes_recursive = 1; + repeated BlkIOEntry io_serviced_recursive = 2; + repeated BlkIOEntry io_queued_recursive = 3; + repeated BlkIOEntry io_service_time_recursive = 4; + repeated BlkIOEntry io_wait_time_recursive = 5; + repeated BlkIOEntry io_merged_recursive = 6; + repeated BlkIOEntry io_time_recursive = 7; + repeated BlkIOEntry sectors_recursive = 8; +} + +message BlkIOEntry { + string op = 1; + string device = 2; + uint64 major = 3; + uint64 minor = 4; + uint64 value = 5; +} + +message RdmaStat { + repeated RdmaEntry current = 1; + repeated RdmaEntry limit = 2; +} + +message RdmaEntry { + string device = 1; + uint32 hca_handles = 2; + uint32 hca_objects = 3; +} + +message NetworkStat { + string name = 1; + uint64 rx_bytes = 2; + uint64 rx_packets = 3; + uint64 rx_errors = 4; + uint64 rx_dropped = 5; + uint64 tx_bytes = 6; + uint64 tx_packets = 7; + uint64 tx_errors = 8; + uint64 tx_dropped = 9; +} + +// CgroupStats exports per-cgroup statistics. +message CgroupStats { + // number of tasks sleeping + uint64 nr_sleeping = 1; + // number of tasks running + uint64 nr_running = 2; + // number of tasks in stopped state + uint64 nr_stopped = 3; + // number of tasks in uninterruptible state + uint64 nr_uninterruptible = 4; + // number of tasks waiting on IO + uint64 nr_io_wait = 5; +} diff --git a/agent/vendor/github.com/containerd/cgroups/subsystem.go b/agent/vendor/github.com/containerd/cgroups/subsystem.go index aab403b8a47..b2f41854d2c 100644 --- a/agent/vendor/github.com/containerd/cgroups/subsystem.go +++ b/agent/vendor/github.com/containerd/cgroups/subsystem.go @@ -1,8 +1,26 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "fmt" + "os" + v1 "github.com/containerd/cgroups/stats/v1" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -22,13 +40,13 @@ const ( Cpuacct Name = "cpuacct" Memory Name = "memory" Blkio Name = "blkio" + Rdma Name = "rdma" ) // Subsystems returns a complete list of the default cgroups -// avaliable on most linux systems +// available on most linux systems func Subsystems() []Name { n := []Name{ - Hugetlb, Freezer, Pids, NetCLS, @@ -39,10 +57,14 @@ func Subsystems() []Name { Cpuacct, Memory, Blkio, + Rdma, } - if !isUserNS { + if !RunningInUserNS() { n = append(n, Devices) } + if _, err := os.Stat("/sys/kernel/mm/hugepages"); err == nil { + n = append(n, Hugetlb) + } return n } @@ -67,7 +89,7 @@ type deleter interface { type stater interface { Subsystem - Stat(path string, stats *Stats) error + Stat(path string, stats *v1.Metrics) error } type updater interface { diff --git a/agent/vendor/github.com/containerd/cgroups/systemd.go b/agent/vendor/github.com/containerd/cgroups/systemd.go index 5e052a82188..4da57cb4b00 100644 --- a/agent/vendor/github.com/containerd/cgroups/systemd.go +++ b/agent/vendor/github.com/containerd/cgroups/systemd.go @@ -1,13 +1,29 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( - "fmt" + "context" "path/filepath" "strings" "sync" - systemdDbus "github.com/coreos/go-systemd/dbus" - "github.com/godbus/dbus" + systemdDbus "github.com/coreos/go-systemd/v22/dbus" + "github.com/godbus/dbus/v5" specs "github.com/opencontainers/runtime-spec/specs-go" ) @@ -16,6 +32,11 @@ const ( defaultSlice = "system.slice" ) +var ( + canDelegate bool + once sync.Once +) + func Systemd() ([]Subsystem, error) { root, err := v1MountPoint() if err != nil { @@ -38,24 +59,18 @@ func Slice(slice, name string) Path { slice = defaultSlice } return func(subsystem Name) (string, error) { - return filepath.Join(slice, unitName(name)), nil + return filepath.Join(slice, name), nil } } func NewSystemd(root string) (*SystemdController, error) { - conn, err := systemdDbus.New() - if err != nil { - return nil, err - } return &SystemdController{ root: root, - conn: conn, }, nil } type SystemdController struct { mu sync.Mutex - conn *systemdDbus.Conn root string } @@ -63,25 +78,71 @@ func (s *SystemdController) Name() Name { return SystemdDbus } -func (s *SystemdController) Create(path string, resources *specs.LinuxResources) error { +func (s *SystemdController) Create(path string, _ *specs.LinuxResources) error { + ctx := context.TODO() + conn, err := systemdDbus.NewWithContext(ctx) + if err != nil { + return err + } + defer conn.Close() slice, name := splitName(path) + // We need to see if systemd can handle the delegate property + // Systemd will return an error if it cannot handle delegate regardless + // of its bool setting. + checkDelegate := func() { + canDelegate = true + dlSlice := newProperty("Delegate", true) + if _, err := conn.StartTransientUnitContext(ctx, slice, "testdelegate", []systemdDbus.Property{dlSlice}, nil); err != nil { + if dbusError, ok := err.(dbus.Error); ok { + // Starting with systemd v237, Delegate is not even a property of slices anymore, + // so the D-Bus call fails with "InvalidArgs" error. + if strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.PropertyReadOnly") || strings.Contains(dbusError.Name, "org.freedesktop.DBus.Error.InvalidArgs") { + canDelegate = false + } + } + } + + _, _ = conn.StopUnitContext(ctx, slice, "testDelegate", nil) + } + once.Do(checkDelegate) properties := []systemdDbus.Property{ - systemdDbus.PropDescription(fmt.Sprintf("cgroup %s", name)), + systemdDbus.PropDescription("cgroup " + name), systemdDbus.PropWants(slice), newProperty("DefaultDependencies", false), - newProperty("Delegate", true), newProperty("MemoryAccounting", true), newProperty("CPUAccounting", true), newProperty("BlockIOAccounting", true), } - _, err := s.conn.StartTransientUnit(name, "replace", properties, nil) - return err + + // If we can delegate, we add the property back in + if canDelegate { + properties = append(properties, newProperty("Delegate", true)) + } + + ch := make(chan string) + _, err = conn.StartTransientUnitContext(ctx, name, "replace", properties, ch) + if err != nil { + return err + } + <-ch + return nil } func (s *SystemdController) Delete(path string) error { + ctx := context.TODO() + conn, err := systemdDbus.NewWithContext(ctx) + if err != nil { + return err + } + defer conn.Close() _, name := splitName(path) - _, err := s.conn.StopUnit(name, "replace", nil) - return err + ch := make(chan string) + _, err = conn.StopUnitContext(ctx, name, "replace", ch) + if err != nil { + return err + } + <-ch + return nil } func newProperty(name string, units interface{}) systemdDbus.Property { @@ -91,10 +152,6 @@ func newProperty(name string, units interface{}) systemdDbus.Property { } } -func unitName(name string) string { - return fmt.Sprintf("%s.slice", name) -} - func splitName(path string) (slice string, unit string) { slice, unit = filepath.Split(path) return strings.TrimSuffix(slice, "/"), unit diff --git a/agent/vendor/github.com/containerd/cgroups/ticks.go b/agent/vendor/github.com/containerd/cgroups/ticks.go index e907ab364ed..84dc38d0cc3 100644 --- a/agent/vendor/github.com/containerd/cgroups/ticks.go +++ b/agent/vendor/github.com/containerd/cgroups/ticks.go @@ -1,5 +1,26 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups func getClockTicks() uint64 { + // The value comes from `C.sysconf(C._SC_CLK_TCK)`, and + // on Linux it's a constant which is safe to be hard coded, + // so we can avoid using cgo here. + // See https://github.com/containerd/cgroups/pull/12 for + // more details. return 100 } diff --git a/agent/vendor/github.com/containerd/cgroups/utils.go b/agent/vendor/github.com/containerd/cgroups/utils.go index 823568b900a..2297980d93c 100644 --- a/agent/vendor/github.com/containerd/cgroups/utils.go +++ b/agent/vendor/github.com/containerd/cgroups/utils.go @@ -1,7 +1,24 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( "bufio" + "errors" "fmt" "io" "io/ioutil" @@ -9,41 +26,93 @@ import ( "path/filepath" "strconv" "strings" + "sync" + "syscall" "time" units "github.com/docker/go-units" specs "github.com/opencontainers/runtime-spec/specs-go" + "golang.org/x/sys/unix" +) + +var ( + nsOnce sync.Once + inUserNS bool + checkMode sync.Once + cgMode CGMode ) -var isUserNS = runningInUserNS() +const unifiedMountpoint = "/sys/fs/cgroup" -// runningInUserNS detects whether we are currently running in a user namespace. +// CGMode is the cgroups mode of the host system +type CGMode int + +const ( + // Unavailable cgroup mountpoint + Unavailable CGMode = iota + // Legacy cgroups v1 + Legacy + // Hybrid with cgroups v1 and v2 controllers mounted + Hybrid + // Unified with only cgroups v2 mounted + Unified +) + +// Mode returns the cgroups mode running on the host +func Mode() CGMode { + checkMode.Do(func() { + var st unix.Statfs_t + if err := unix.Statfs(unifiedMountpoint, &st); err != nil { + cgMode = Unavailable + return + } + switch st.Type { + case unix.CGROUP2_SUPER_MAGIC: + cgMode = Unified + default: + cgMode = Legacy + if err := unix.Statfs(filepath.Join(unifiedMountpoint, "unified"), &st); err != nil { + return + } + if st.Type == unix.CGROUP2_SUPER_MAGIC { + cgMode = Hybrid + } + } + }) + return cgMode +} + +// RunningInUserNS detects whether we are currently running in a user namespace. // Copied from github.com/lxc/lxd/shared/util.go -func runningInUserNS() bool { - file, err := os.Open("/proc/self/uid_map") - if err != nil { - // This kernel-provided file only exists if user namespaces are supported - return false - } - defer file.Close() +func RunningInUserNS() bool { + nsOnce.Do(func() { + file, err := os.Open("/proc/self/uid_map") + if err != nil { + // This kernel-provided file only exists if user namespaces are supported + return + } + defer file.Close() - buf := bufio.NewReader(file) - l, _, err := buf.ReadLine() - if err != nil { - return false - } + buf := bufio.NewReader(file) + l, _, err := buf.ReadLine() + if err != nil { + return + } - line := string(l) - var a, b, c int64 - fmt.Sscanf(line, "%d %d %d", &a, &b, &c) - /* - * We assume we are in the initial user namespace if we have a full - * range - 4294967295 uids starting at uid 0. - */ - if a == 0 && b == 0 && c == 4294967295 { - return false - } - return true + line := string(l) + var a, b, c int64 + fmt.Sscanf(line, "%d %d %d", &a, &b, &c) + + /* + * We assume we are in the initial user namespace if we have a full + * range - 4294967295 uids starting at uid 0. + */ + if a == 0 && b == 0 && c == 4294967295 { + return + } + inUserNS = true + }) + return inUserNS } // defaults returns all known groups @@ -59,15 +128,16 @@ func defaults(root string) ([]Subsystem, error) { NewNetCls(root), NewNetPrio(root), NewPerfEvent(root), - NewCputset(root), + NewCpuset(root), NewCpu(root), NewCpuacct(root), NewMemory(root), NewBlkio(root), + NewRdma(root), } // only add the devices cgroup if we are not in a user namespace // because modifications are not allowed - if !isUserNS { + if !RunningInUserNS() { s = append(s, NewDevices(root)) } // add the hugetlb cgroup if error wasn't due to missing hugetlb @@ -81,8 +151,8 @@ func defaults(root string) ([]Subsystem, error) { // remove will remove a cgroup path handling EAGAIN and EBUSY errors and // retrying the remove after a exp timeout func remove(path string) error { + delay := 10 * time.Millisecond for i := 0; i < 5; i++ { - delay := 10 * time.Millisecond if i != 0 { time.Sleep(delay) delay *= 2 @@ -94,9 +164,9 @@ func remove(path string) error { return fmt.Errorf("cgroups: unable to remove path %q", path) } -// readPids will read all the pids in a cgroup by the provided path -func readPids(path string, subsystem Name) ([]Process, error) { - f, err := os.Open(filepath.Join(path, cgroupProcs)) +// readPids will read all the pids of processes or tasks in a cgroup by the provided path +func readPids(path string, subsystem Name, pType procType) ([]Process, error) { + f, err := os.Open(filepath.Join(path, pType)) if err != nil { return nil, err } @@ -118,13 +188,17 @@ func readPids(path string, subsystem Name) ([]Process, error) { }) } } + if err := s.Err(); err != nil { + // failed to read all pids? + return nil, err + } return out, nil } func hugePageSizes() ([]string, error) { var ( pageSizes []string - sizeList = []string{"B", "kB", "MB", "GB", "TB", "PB"} + sizeList = []string{"B", "KB", "MB", "GB", "TB", "PB"} ) files, err := ioutil.ReadDir("/sys/kernel/mm/hugepages") if err != nil { @@ -181,7 +255,16 @@ func parseKV(raw string) (string, uint64, error) { } } -func parseCgroupFile(path string) (map[string]string, error) { +// ParseCgroupFile parses the given cgroup file, typically /proc/self/cgroup +// or /proc//cgroup, into a map of subsystems to cgroup paths, e.g. +// "cpu": "/user.slice/user-1000.slice" +// "pids": "/user.slice/user-1000.slice" +// etc. +// +// Note that for cgroup v2 unified hierarchy, there are no per-controller +// cgroup paths, so the resulting map will have a single element where the key +// is empty string ("") and the value is the cgroup path the is in. +func ParseCgroupFile(path string) (map[string]string, error) { f, err := os.Open(path) if err != nil { return nil, err @@ -196,20 +279,22 @@ func parseCgroupFromReader(r io.Reader) (map[string]string, error) { s = bufio.NewScanner(r) ) for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } var ( text = s.Text() parts = strings.SplitN(text, ":", 3) ) if len(parts) < 3 { - return nil, fmt.Errorf("invalid cgroup entry: must contain at least two colons: %v", text) + return nil, fmt.Errorf("invalid cgroup entry: %q", text) } for _, subs := range strings.Split(parts[1], ",") { - cgroups[subs] = parts[2] + if subs != "" { + cgroups[subs] = parts[2] + } } } + if err := s.Err(); err != nil { + return nil, err + } return cgroups, nil } @@ -221,16 +306,23 @@ func getCgroupDestination(subsystem string) (string, error) { defer f.Close() s := bufio.NewScanner(f) for s.Scan() { - if err := s.Err(); err != nil { - return "", err + fields := strings.Split(s.Text(), " ") + if len(fields) < 10 { + // broken mountinfo? + continue + } + if fields[len(fields)-3] != "cgroup" { + continue } - fields := strings.Fields(s.Text()) for _, opt := range strings.Split(fields[len(fields)-1], ",") { if opt == subsystem { return fields[3], nil } } } + if err := s.Err(); err != nil { + return "", err + } return "", ErrNoCgroupMountDestination } @@ -274,5 +366,18 @@ func cleanPath(path string) string { if !filepath.IsAbs(path) { path, _ = filepath.Rel(string(os.PathSeparator), filepath.Clean(string(os.PathSeparator)+path)) } - return filepath.Clean(path) + return path +} + +func retryingWriteFile(path string, data []byte, mode os.FileMode) error { + // Retry writes on EINTR; see: + // https://github.com/golang/go/issues/38033 + for { + err := ioutil.WriteFile(path, data, mode) + if err == nil { + return nil + } else if !errors.Is(err, syscall.EINTR) { + return err + } + } } diff --git a/agent/vendor/github.com/containerd/cgroups/v1.go b/agent/vendor/github.com/containerd/cgroups/v1.go index f6608f7c72f..2ec215c06f4 100644 --- a/agent/vendor/github.com/containerd/cgroups/v1.go +++ b/agent/vendor/github.com/containerd/cgroups/v1.go @@ -1,3 +1,19 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + package cgroups import ( @@ -38,28 +54,20 @@ func v1MountPoint() (string, error) { defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { - if err := scanner.Err(); err != nil { - return "", err - } var ( - text = scanner.Text() - fields = strings.Split(text, " ") - // safe as mountinfo encodes mountpoints with spaces as \040. - index = strings.Index(text, " - ") - postSeparatorFields = strings.Fields(text[index+3:]) - numPostFields = len(postSeparatorFields) + text = scanner.Text() + fields = strings.Split(text, " ") + numFields = len(fields) ) - // this is an error as we can't detect if the mount is for "cgroup" - if numPostFields == 0 { - return "", fmt.Errorf("Found no fields post '-' in %q", text) + if numFields < 10 { + return "", fmt.Errorf("mountinfo: bad entry %q", text) } - if postSeparatorFields[0] == "cgroup" { - // check that the mount is properly formated. - if numPostFields < 3 { - return "", fmt.Errorf("Error found less than 3 fields post '-' in %q", text) - } + if fields[numFields-3] == "cgroup" { return filepath.Dir(fields[4]), nil } } + if err := scanner.Err(); err != nil { + return "", err + } return "", ErrMountPointNotExist } diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/LICENSE b/agent/vendor/github.com/coreos/go-systemd/v22/LICENSE new file mode 100644 index 00000000000..37ec93a14fd --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/NOTICE b/agent/vendor/github.com/coreos/go-systemd/v22/NOTICE new file mode 100644 index 00000000000..23a0ada2fbb --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/NOTICE @@ -0,0 +1,5 @@ +CoreOS Project +Copyright 2018 CoreOS, Inc + +This product includes software developed at CoreOS, Inc. +(http://www.coreos.com/). diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go new file mode 100644 index 00000000000..cff5af1a64c --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go @@ -0,0 +1,261 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/ +package dbus + +import ( + "context" + "encoding/hex" + "fmt" + "os" + "strconv" + "strings" + "sync" + + "github.com/godbus/dbus/v5" +) + +const ( + alpha = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` + num = `0123456789` + alphanum = alpha + num + signalBuffer = 100 +) + +// needsEscape checks whether a byte in a potential dbus ObjectPath needs to be escaped +func needsEscape(i int, b byte) bool { + // Escape everything that is not a-z-A-Z-0-9 + // Also escape 0-9 if it's the first character + return strings.IndexByte(alphanum, b) == -1 || + (i == 0 && strings.IndexByte(num, b) != -1) +} + +// PathBusEscape sanitizes a constituent string of a dbus ObjectPath using the +// rules that systemd uses for serializing special characters. +func PathBusEscape(path string) string { + // Special case the empty string + if len(path) == 0 { + return "_" + } + n := []byte{} + for i := 0; i < len(path); i++ { + c := path[i] + if needsEscape(i, c) { + e := fmt.Sprintf("_%x", c) + n = append(n, []byte(e)...) + } else { + n = append(n, c) + } + } + return string(n) +} + +// pathBusUnescape is the inverse of PathBusEscape. +func pathBusUnescape(path string) string { + if path == "_" { + return "" + } + n := []byte{} + for i := 0; i < len(path); i++ { + c := path[i] + if c == '_' && i+2 < len(path) { + res, err := hex.DecodeString(path[i+1 : i+3]) + if err == nil { + n = append(n, res...) + } + i += 2 + } else { + n = append(n, c) + } + } + return string(n) +} + +// Conn is a connection to systemd's dbus endpoint. +type Conn struct { + // sysconn/sysobj are only used to call dbus methods + sysconn *dbus.Conn + sysobj dbus.BusObject + + // sigconn/sigobj are only used to receive dbus signals + sigconn *dbus.Conn + sigobj dbus.BusObject + + jobListener struct { + jobs map[dbus.ObjectPath]chan<- string + sync.Mutex + } + subStateSubscriber struct { + updateCh chan<- *SubStateUpdate + errCh chan<- error + sync.Mutex + ignore map[dbus.ObjectPath]int64 + cleanIgnore int64 + } + propertiesSubscriber struct { + updateCh chan<- *PropertiesUpdate + errCh chan<- error + sync.Mutex + } +} + +// Deprecated: use NewWithContext instead. +func New() (*Conn, error) { + return NewWithContext(context.Background()) +} + +// NewWithContext establishes a connection to any available bus and authenticates. +// Callers should call Close() when done with the connection. +func NewWithContext(ctx context.Context) (*Conn, error) { + conn, err := NewSystemConnectionContext(ctx) + if err != nil && os.Geteuid() == 0 { + return NewSystemdConnectionContext(ctx) + } + return conn, err +} + +// Deprecated: use NewSystemConnectionContext instead. +func NewSystemConnection() (*Conn, error) { + return NewSystemConnectionContext(context.Background()) +} + +// NewSystemConnectionContext establishes a connection to the system bus and authenticates. +// Callers should call Close() when done with the connection. +func NewSystemConnectionContext(ctx context.Context) (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + return dbusAuthHelloConnection(ctx, dbus.SystemBusPrivate) + }) +} + +// Deprecated: use NewUserConnectionContext instead. +func NewUserConnection() (*Conn, error) { + return NewUserConnectionContext(context.Background()) +} + +// NewUserConnectionContext establishes a connection to the session bus and +// authenticates. This can be used to connect to systemd user instances. +// Callers should call Close() when done with the connection. +func NewUserConnectionContext(ctx context.Context) (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + return dbusAuthHelloConnection(ctx, dbus.SessionBusPrivate) + }) +} + +// Deprecated: use NewSystemdConnectionContext instead. +func NewSystemdConnection() (*Conn, error) { + return NewSystemdConnectionContext(context.Background()) +} + +// NewSystemdConnectionContext establishes a private, direct connection to systemd. +// This can be used for communicating with systemd without a dbus daemon. +// Callers should call Close() when done with the connection. +func NewSystemdConnectionContext(ctx context.Context) (*Conn, error) { + return NewConnection(func() (*dbus.Conn, error) { + // We skip Hello when talking directly to systemd. + return dbusAuthConnection(ctx, func(opts ...dbus.ConnOption) (*dbus.Conn, error) { + return dbus.Dial("unix:path=/run/systemd/private", opts...) + }) + }) +} + +// Close closes an established connection. +func (c *Conn) Close() { + c.sysconn.Close() + c.sigconn.Close() +} + +// NewConnection establishes a connection to a bus using a caller-supplied function. +// This allows connecting to remote buses through a user-supplied mechanism. +// The supplied function may be called multiple times, and should return independent connections. +// The returned connection must be fully initialised: the org.freedesktop.DBus.Hello call must have succeeded, +// and any authentication should be handled by the function. +func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) { + sysconn, err := dialBus() + if err != nil { + return nil, err + } + + sigconn, err := dialBus() + if err != nil { + sysconn.Close() + return nil, err + } + + c := &Conn{ + sysconn: sysconn, + sysobj: systemdObject(sysconn), + sigconn: sigconn, + sigobj: systemdObject(sigconn), + } + + c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64) + c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string) + + // Setup the listeners on jobs so that we can get completions + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'") + + c.dispatch() + return c, nil +} + +// GetManagerProperty returns the value of a property on the org.freedesktop.systemd1.Manager +// interface. The value is returned in its string representation, as defined at +// https://developer.gnome.org/glib/unstable/gvariant-text.html. +func (c *Conn) GetManagerProperty(prop string) (string, error) { + variant, err := c.sysobj.GetProperty("org.freedesktop.systemd1.Manager." + prop) + if err != nil { + return "", err + } + return variant.String(), nil +} + +func dbusAuthConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { + conn, err := createBus(dbus.WithContext(ctx)) + if err != nil { + return nil, err + } + + // Only use EXTERNAL method, and hardcode the uid (not username) + // to avoid a username lookup (which requires a dynamically linked + // libc) + methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} + + err = conn.Auth(methods) + if err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +func dbusAuthHelloConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { + conn, err := dbusAuthConnection(ctx, createBus) + if err != nil { + return nil, err + } + + if err = conn.Hello(); err != nil { + conn.Close() + return nil, err + } + + return conn, nil +} + +func systemdObject(conn *dbus.Conn) dbus.BusObject { + return conn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1")) +} diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go new file mode 100644 index 00000000000..fa04afc708e --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go @@ -0,0 +1,830 @@ +// Copyright 2015, 2018 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbus + +import ( + "context" + "errors" + "fmt" + "path" + "strconv" + + "github.com/godbus/dbus/v5" +) + +// Who can be used to specify which process to kill in the unit via the KillUnitWithTarget API +type Who string + +const ( + // All sends the signal to all processes in the unit + All Who = "all" + // Main sends the signal to the main process of the unit + Main Who = "main" + // Control sends the signal to the control process of the unit + Control Who = "control" +) + +func (c *Conn) jobComplete(signal *dbus.Signal) { + var id uint32 + var job dbus.ObjectPath + var unit string + var result string + dbus.Store(signal.Body, &id, &job, &unit, &result) + c.jobListener.Lock() + out, ok := c.jobListener.jobs[job] + if ok { + out <- result + delete(c.jobListener.jobs, job) + } + c.jobListener.Unlock() +} + +func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) { + if ch != nil { + c.jobListener.Lock() + defer c.jobListener.Unlock() + } + + var p dbus.ObjectPath + err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p) + if err != nil { + return 0, err + } + + if ch != nil { + c.jobListener.jobs[p] = ch + } + + // ignore error since 0 is fine if conversion fails + jobID, _ := strconv.Atoi(path.Base(string(p))) + + return jobID, nil +} + +// Deprecated: use StartUnitContext instead. +func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.StartUnitContext(context.Background(), name, mode, ch) +} + +// StartUnitContext enqueues a start job and depending jobs, if any (unless otherwise +// specified by the mode string). +// +// Takes the unit to activate, plus a mode string. The mode needs to be one of +// replace, fail, isolate, ignore-dependencies, ignore-requirements. If +// "replace" the call will start the unit and its dependencies, possibly +// replacing already queued jobs that conflict with this. If "fail" the call +// will start the unit and its dependencies, but will fail if this would change +// an already queued job. If "isolate" the call will start the unit in question +// and terminate all units that aren't dependencies of it. If +// "ignore-dependencies" it will start a unit but ignore all its dependencies. +// If "ignore-requirements" it will start a unit but only ignore the +// requirement dependencies. It is not recommended to make use of the latter +// two options. +// +// If the provided channel is non-nil, a result string will be sent to it upon +// job completion: one of done, canceled, timeout, failed, dependency, skipped. +// done indicates successful execution of a job. canceled indicates that a job +// has been canceled before it finished execution. timeout indicates that the +// job timeout was reached. failed indicates that the job failed. dependency +// indicates that a job this job has been depending on failed and the job hence +// has been removed too. skipped indicates that a job was skipped because it +// didn't apply to the units current state. +// +// If no error occurs, the ID of the underlying systemd job will be returned. There +// does exist the possibility for no error to be returned, but for the returned job +// ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint +// should not be considered authoritative. +// +// If an error does occur, it will be returned to the user alongside a job ID of 0. +func (c *Conn) StartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode) +} + +// Deprecated: use StopUnitContext instead. +func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) { + return c.StopUnitContext(context.Background(), name, mode, ch) +} + +// StopUnitContext is similar to StartUnitContext, but stops the specified unit +// rather than starting it. +func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode) +} + +// Deprecated: use ReloadUnitContext instead. +func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) { + return c.ReloadUnitContext(context.Background(), name, mode, ch) +} + +// ReloadUnitContext reloads a unit. Reloading is done only if the unit +// is already running, and fails otherwise. +func (c *Conn) ReloadUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode) +} + +// Deprecated: use RestartUnitContext instead. +func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.RestartUnitContext(context.Background(), name, mode, ch) +} + +// RestartUnitContext restarts a service. If a service is restarted that isn't +// running it will be started. +func (c *Conn) RestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode) +} + +// Deprecated: use TryRestartUnitContext instead. +func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.TryRestartUnitContext(context.Background(), name, mode, ch) +} + +// TryRestartUnitContext is like RestartUnitContext, except that a service that +// isn't running is not affected by the restart. +func (c *Conn) TryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode) +} + +// Deprecated: use ReloadOrRestartUnitContext instead. +func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.ReloadOrRestartUnitContext(context.Background(), name, mode, ch) +} + +// ReloadOrRestartUnitContext attempts a reload if the unit supports it and use +// a restart otherwise. +func (c *Conn) ReloadOrRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode) +} + +// Deprecated: use ReloadOrTryRestartUnitContext instead. +func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) { + return c.ReloadOrTryRestartUnitContext(context.Background(), name, mode, ch) +} + +// ReloadOrTryRestartUnitContext attempts a reload if the unit supports it, +// and use a "Try" flavored restart otherwise. +func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode) +} + +// Deprecated: use StartTransientUnitContext instead. +func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) { + return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch) +} + +// StartTransientUnitContext may be used to create and start a transient unit, which +// will be released as soon as it is not running or referenced anymore or the +// system is rebooted. name is the unit name including suffix, and must be +// unique. mode is the same as in StartUnitContext, properties contains properties +// of the unit. +func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) { + return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) +} + +// Deprecated: use KillUnitContext instead. +func (c *Conn) KillUnit(name string, signal int32) { + c.KillUnitContext(context.Background(), name, signal) +} + +// KillUnitContext takes the unit name and a UNIX signal number to send. +// All of the unit's processes are killed. +func (c *Conn) KillUnitContext(ctx context.Context, name string, signal int32) { + c.KillUnitWithTarget(ctx, name, All, signal) +} + +// KillUnitWithTarget is like KillUnitContext, but allows you to specify which +// process in the unit to send the signal to. +func (c *Conn) KillUnitWithTarget(ctx context.Context, name string, target Who, signal int32) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.KillUnit", 0, name, string(target), signal).Store() +} + +// Deprecated: use ResetFailedUnitContext instead. +func (c *Conn) ResetFailedUnit(name string) error { + return c.ResetFailedUnitContext(context.Background(), name) +} + +// ResetFailedUnitContext resets the "failed" state of a specific unit. +func (c *Conn) ResetFailedUnitContext(ctx context.Context, name string) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store() +} + +// Deprecated: use SystemStateContext instead. +func (c *Conn) SystemState() (*Property, error) { + return c.SystemStateContext(context.Background()) +} + +// SystemStateContext returns the systemd state. Equivalent to +// systemctl is-system-running. +func (c *Conn) SystemStateContext(ctx context.Context) (*Property, error) { + var err error + var prop dbus.Variant + + obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") + err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop) + if err != nil { + return nil, err + } + + return &Property{Name: "SystemState", Value: prop}, nil +} + +// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface. +func (c *Conn) getProperties(ctx context.Context, path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) { + var err error + var props map[string]dbus.Variant + + if !path.IsValid() { + return nil, fmt.Errorf("invalid unit name: %v", path) + } + + obj := c.sysconn.Object("org.freedesktop.systemd1", path) + err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props) + if err != nil { + return nil, err + } + + out := make(map[string]interface{}, len(props)) + for k, v := range props { + out[k] = v.Value() + } + + return out, nil +} + +// Deprecated: use GetUnitPropertiesContext instead. +func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { + return c.GetUnitPropertiesContext(context.Background(), unit) +} + +// GetUnitPropertiesContext takes the (unescaped) unit name and returns all of +// its dbus object properties. +func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { + path := unitPath(unit) + return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") +} + +// Deprecated: use GetUnitPathPropertiesContext instead. +func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) { + return c.GetUnitPathPropertiesContext(context.Background(), path) +} + +// GetUnitPathPropertiesContext takes the (escaped) unit path and returns all +// of its dbus object properties. +func (c *Conn) GetUnitPathPropertiesContext(ctx context.Context, path dbus.ObjectPath) (map[string]interface{}, error) { + return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") +} + +// Deprecated: use GetAllPropertiesContext instead. +func (c *Conn) GetAllProperties(unit string) (map[string]interface{}, error) { + return c.GetAllPropertiesContext(context.Background(), unit) +} + +// GetAllPropertiesContext takes the (unescaped) unit name and returns all of +// its dbus object properties. +func (c *Conn) GetAllPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { + path := unitPath(unit) + return c.getProperties(ctx, path, "") +} + +func (c *Conn) getProperty(ctx context.Context, unit string, dbusInterface string, propertyName string) (*Property, error) { + var err error + var prop dbus.Variant + + path := unitPath(unit) + if !path.IsValid() { + return nil, errors.New("invalid unit name: " + unit) + } + + obj := c.sysconn.Object("org.freedesktop.systemd1", path) + err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop) + if err != nil { + return nil, err + } + + return &Property{Name: propertyName, Value: prop}, nil +} + +// Deprecated: use GetUnitPropertyContext instead. +func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) { + return c.GetUnitPropertyContext(context.Background(), unit, propertyName) +} + +// GetUnitPropertyContext takes an (unescaped) unit name, and a property name, +// and returns the property value. +func (c *Conn) GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*Property, error) { + return c.getProperty(ctx, unit, "org.freedesktop.systemd1.Unit", propertyName) +} + +// Deprecated: use GetServicePropertyContext instead. +func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) { + return c.GetServicePropertyContext(context.Background(), service, propertyName) +} + +// GetServiceProperty returns property for given service name and property name. +func (c *Conn) GetServicePropertyContext(ctx context.Context, service string, propertyName string) (*Property, error) { + return c.getProperty(ctx, service, "org.freedesktop.systemd1.Service", propertyName) +} + +// Deprecated: use GetUnitTypePropertiesContext instead. +func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { + return c.GetUnitTypePropertiesContext(context.Background(), unit, unitType) +} + +// GetUnitTypePropertiesContext returns the extra properties for a unit, specific to the unit type. +// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope. +// Returns "dbus.Error: Unknown interface" error if the unitType is not the correct type of the unit. +func (c *Conn) GetUnitTypePropertiesContext(ctx context.Context, unit string, unitType string) (map[string]interface{}, error) { + path := unitPath(unit) + return c.getProperties(ctx, path, "org.freedesktop.systemd1."+unitType) +} + +// Deprecated: use SetUnitPropertiesContext instead. +func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error { + return c.SetUnitPropertiesContext(context.Background(), name, runtime, properties...) +} + +// SetUnitPropertiesContext may be used to modify certain unit properties at runtime. +// Not all properties may be changed at runtime, but many resource management +// settings (primarily those in systemd.cgroup(5)) may. The changes are applied +// instantly, and stored on disk for future boots, unless runtime is true, in which +// case the settings only apply until the next reboot. name is the name of the unit +// to modify. properties are the settings to set, encoded as an array of property +// name and value pairs. +func (c *Conn) SetUnitPropertiesContext(ctx context.Context, name string, runtime bool, properties ...Property) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store() +} + +// Deprecated: use GetUnitTypePropertyContext instead. +func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) { + return c.GetUnitTypePropertyContext(context.Background(), unit, unitType, propertyName) +} + +// GetUnitTypePropertyContext takes a property name, a unit name, and a unit type, +// and returns a property value. For valid values of unitType, see GetUnitTypePropertiesContext. +func (c *Conn) GetUnitTypePropertyContext(ctx context.Context, unit string, unitType string, propertyName string) (*Property, error) { + return c.getProperty(ctx, unit, "org.freedesktop.systemd1."+unitType, propertyName) +} + +type UnitStatus struct { + Name string // The primary unit name as string + Description string // The human readable description string + LoadState string // The load state (i.e. whether the unit file has been loaded successfully) + ActiveState string // The active state (i.e. whether the unit is currently started or not) + SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not) + Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string. + Path dbus.ObjectPath // The unit object path + JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise + JobType string // The job type as string + JobPath dbus.ObjectPath // The job object path +} + +type storeFunc func(retvalues ...interface{}) error + +func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { + result := make([][]interface{}, 0) + err := f(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + status := make([]UnitStatus, len(result)) + statusInterface := make([]interface{}, len(status)) + for i := range status { + statusInterface[i] = &status[i] + } + + err = dbus.Store(resultInterface, statusInterface...) + if err != nil { + return nil, err + } + + return status, nil +} + +// Deprecated: use ListUnitsContext instead. +func (c *Conn) ListUnits() ([]UnitStatus, error) { + return c.ListUnitsContext(context.Background()) +} + +// ListUnitsContext returns an array with all currently loaded units. Note that +// units may be known by multiple names at the same time, and hence there might +// be more unit names loaded than actual units behind them. +// Also note that a unit is only loaded if it is active and/or enabled. +// Units that are both disabled and inactive will thus not be returned. +func (c *Conn) ListUnitsContext(ctx context.Context) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnits", 0).Store) +} + +// Deprecated: use ListUnitsFilteredContext instead. +func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) { + return c.ListUnitsFilteredContext(context.Background(), states) +} + +// ListUnitsFilteredContext returns an array with units filtered by state. +// It takes a list of units' statuses to filter. +func (c *Conn) ListUnitsFilteredContext(ctx context.Context, states []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store) +} + +// Deprecated: use ListUnitsByPatternsContext instead. +func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) { + return c.ListUnitsByPatternsContext(context.Background(), states, patterns) +} + +// ListUnitsByPatternsContext returns an array with units. +// It takes a list of units' statuses and names to filter. +// Note that units may be known by multiple names at the same time, +// and hence there might be more unit names loaded than actual units behind them. +func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store) +} + +// Deprecated: use ListUnitsByNamesContext instead. +func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) { + return c.ListUnitsByNamesContext(context.Background(), units) +} + +// ListUnitsByNamesContext returns an array with units. It takes a list of units' +// names and returns an UnitStatus array. Comparing to ListUnitsByPatternsContext +// method, this method returns statuses even for inactive or non-existing +// units. Input array should contain exact unit names, but not patterns. +// +// Requires systemd v230 or higher. +func (c *Conn) ListUnitsByNamesContext(ctx context.Context, units []string) ([]UnitStatus, error) { + return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store) +} + +type UnitFile struct { + Path string + Type string +} + +func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) { + result := make([][]interface{}, 0) + err := f(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + files := make([]UnitFile, len(result)) + fileInterface := make([]interface{}, len(files)) + for i := range files { + fileInterface[i] = &files[i] + } + + err = dbus.Store(resultInterface, fileInterface...) + if err != nil { + return nil, err + } + + return files, nil +} + +// Deprecated: use ListUnitFilesContext instead. +func (c *Conn) ListUnitFiles() ([]UnitFile, error) { + return c.ListUnitFilesContext(context.Background()) +} + +// ListUnitFiles returns an array of all available units on disk. +func (c *Conn) ListUnitFilesContext(ctx context.Context) ([]UnitFile, error) { + return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store) +} + +// Deprecated: use ListUnitFilesByPatternsContext instead. +func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) { + return c.ListUnitFilesByPatternsContext(context.Background(), states, patterns) +} + +// ListUnitFilesByPatternsContext returns an array of all available units on disk matched the patterns. +func (c *Conn) ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitFile, error) { + return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store) +} + +type LinkUnitFileChange EnableUnitFileChange + +// Deprecated: use LinkUnitFilesContext instead. +func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { + return c.LinkUnitFilesContext(context.Background(), files, runtime, force) +} + +// LinkUnitFilesContext links unit files (that are located outside of the +// usual unit search paths) into the unit search path. +// +// It takes a list of absolute paths to unit files to link and two +// booleans. +// +// The first boolean controls whether the unit shall be +// enabled for runtime only (true, /run), or persistently (false, +// /etc). +// +// The second controls whether symlinks pointing to other units shall +// be replaced if necessary. +// +// This call returns a list of the changes made. The list consists of +// structures with three strings: the type of the change (one of symlink +// or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) LinkUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]LinkUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +// Deprecated: use EnableUnitFilesContext instead. +func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { + return c.EnableUnitFilesContext(context.Background(), files, runtime, force) +} + +// EnableUnitFilesContext may be used to enable one or more units in the system +// (by creating symlinks to them in /etc or /run). +// +// It takes a list of unit files to enable (either just file names or full +// absolute paths if the unit files are residing outside the usual unit +// search paths), and two booleans: the first controls whether the unit shall +// be enabled for runtime only (true, /run), or persistently (false, /etc). +// The second one controls whether symlinks pointing to other units shall +// be replaced if necessary. +// +// This call returns one boolean and an array with the changes made. The +// boolean signals whether the unit files contained any enablement +// information (i.e. an [Install]) section. The changes list consists of +// structures with three strings: the type of the change (one of symlink +// or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) EnableUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { + var carries_install_info bool + + result := make([][]interface{}, 0) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result) + if err != nil { + return false, nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]EnableUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return false, nil, err + } + + return carries_install_info, changes, nil +} + +type EnableUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// Deprecated: use DisableUnitFilesContext instead. +func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) { + return c.DisableUnitFilesContext(context.Background(), files, runtime) +} + +// DisableUnitFilesContext may be used to disable one or more units in the +// system (by removing symlinks to them from /etc or /run). +// +// It takes a list of unit files to disable (either just file names or full +// absolute paths if the unit files are residing outside the usual unit +// search paths), and one boolean: whether the unit was enabled for runtime +// only (true, /run), or persistently (false, /etc). +// +// This call returns an array with the changes made. The changes list +// consists of structures with three strings: the type of the change (one of +// symlink or unlink), the file name of the symlink and the destination of the +// symlink. +func (c *Conn) DisableUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]DisableUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]DisableUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type DisableUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// Deprecated: use MaskUnitFilesContext instead. +func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { + return c.MaskUnitFilesContext(context.Background(), files, runtime, force) +} + +// MaskUnitFilesContext masks one or more units in the system. +// +// The files argument contains a list of units to mask (either just file names +// or full absolute paths if the unit files are residing outside the usual unit +// search paths). +// +// The runtime argument is used to specify whether the unit was enabled for +// runtime only (true, /run/systemd/..), or persistently (false, +// /etc/systemd/..). +func (c *Conn) MaskUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]MaskUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type MaskUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// Deprecated: use UnmaskUnitFilesContext instead. +func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) { + return c.UnmaskUnitFilesContext(context.Background(), files, runtime) +} + +// UnmaskUnitFilesContext unmasks one or more units in the system. +// +// It takes the list of unit files to mask (either just file names or full +// absolute paths if the unit files are residing outside the usual unit search +// paths), and a boolean runtime flag to specify whether the unit was enabled +// for runtime only (true, /run/systemd/..), or persistently (false, +// /etc/systemd/..). +func (c *Conn) UnmaskUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]UnmaskUnitFileChange, error) { + result := make([][]interface{}, 0) + err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result) + if err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + changes := make([]UnmaskUnitFileChange, len(result)) + changesInterface := make([]interface{}, len(changes)) + for i := range changes { + changesInterface[i] = &changes[i] + } + + err = dbus.Store(resultInterface, changesInterface...) + if err != nil { + return nil, err + } + + return changes, nil +} + +type UnmaskUnitFileChange struct { + Type string // Type of the change (one of symlink or unlink) + Filename string // File name of the symlink + Destination string // Destination of the symlink +} + +// Deprecated: use ReloadContext instead. +func (c *Conn) Reload() error { + return c.ReloadContext(context.Background()) +} + +// ReloadContext instructs systemd to scan for and reload unit files. This is +// an equivalent to systemctl daemon-reload. +func (c *Conn) ReloadContext(ctx context.Context) error { + return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.Reload", 0).Store() +} + +func unitPath(name string) dbus.ObjectPath { + return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name)) +} + +// unitName returns the unescaped base element of the supplied escaped path. +func unitName(dpath dbus.ObjectPath) string { + return pathBusUnescape(path.Base(string(dpath))) +} + +// JobStatus holds a currently queued job definition. +type JobStatus struct { + Id uint32 // The numeric job id + Unit string // The primary unit name for this job + JobType string // The job type as string + Status string // The job state as string + JobPath dbus.ObjectPath // The job object path + UnitPath dbus.ObjectPath // The unit object path +} + +// Deprecated: use ListJobsContext instead. +func (c *Conn) ListJobs() ([]JobStatus, error) { + return c.ListJobsContext(context.Background()) +} + +// ListJobsContext returns an array with all currently queued jobs. +func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) { + return c.listJobsInternal(ctx) +} + +func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) { + result := make([][]interface{}, 0) + if err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store(&result); err != nil { + return nil, err + } + + resultInterface := make([]interface{}, len(result)) + for i := range result { + resultInterface[i] = result[i] + } + + status := make([]JobStatus, len(result)) + statusInterface := make([]interface{}, len(status)) + for i := range status { + statusInterface[i] = &status[i] + } + + if err := dbus.Store(resultInterface, statusInterface...); err != nil { + return nil, err + } + + return status, nil +} diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go new file mode 100644 index 00000000000..fb42b627338 --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go @@ -0,0 +1,237 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbus + +import ( + "github.com/godbus/dbus/v5" +) + +// From the systemd docs: +// +// The properties array of StartTransientUnit() may take many of the settings +// that may also be configured in unit files. Not all parameters are currently +// accepted though, but we plan to cover more properties with future release. +// Currently you may set the Description, Slice and all dependency types of +// units, as well as RemainAfterExit, ExecStart for service units, +// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares, +// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth, +// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit, +// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map +// directly to their counterparts in unit files and as normal D-Bus object +// properties. The exception here is the PIDs field of scope units which is +// used for construction of the scope only and specifies the initial PIDs to +// add to the scope object. + +type Property struct { + Name string + Value dbus.Variant +} + +type PropertyCollection struct { + Name string + Properties []Property +} + +type execStart struct { + Path string // the binary path to execute + Args []string // an array with all arguments to pass to the executed command, starting with argument 0 + UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly +} + +// PropExecStart sets the ExecStart service property. The first argument is a +// slice with the binary path to execute followed by the arguments to pass to +// the executed command. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= +func PropExecStart(command []string, uncleanIsFailure bool) Property { + execStarts := []execStart{ + { + Path: command[0], + Args: command, + UncleanIsFailure: uncleanIsFailure, + }, + } + + return Property{ + Name: "ExecStart", + Value: dbus.MakeVariant(execStarts), + } +} + +// PropRemainAfterExit sets the RemainAfterExit service property. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit= +func PropRemainAfterExit(b bool) Property { + return Property{ + Name: "RemainAfterExit", + Value: dbus.MakeVariant(b), + } +} + +// PropType sets the Type service property. See +// http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= +func PropType(t string) Property { + return Property{ + Name: "Type", + Value: dbus.MakeVariant(t), + } +} + +// PropDescription sets the Description unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description= +func PropDescription(desc string) Property { + return Property{ + Name: "Description", + Value: dbus.MakeVariant(desc), + } +} + +func propDependency(name string, units []string) Property { + return Property{ + Name: name, + Value: dbus.MakeVariant(units), + } +} + +// PropRequires sets the Requires unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires= +func PropRequires(units ...string) Property { + return propDependency("Requires", units) +} + +// PropRequiresOverridable sets the RequiresOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable= +func PropRequiresOverridable(units ...string) Property { + return propDependency("RequiresOverridable", units) +} + +// PropRequisite sets the Requisite unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite= +func PropRequisite(units ...string) Property { + return propDependency("Requisite", units) +} + +// PropRequisiteOverridable sets the RequisiteOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable= +func PropRequisiteOverridable(units ...string) Property { + return propDependency("RequisiteOverridable", units) +} + +// PropWants sets the Wants unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants= +func PropWants(units ...string) Property { + return propDependency("Wants", units) +} + +// PropBindsTo sets the BindsTo unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo= +func PropBindsTo(units ...string) Property { + return propDependency("BindsTo", units) +} + +// PropRequiredBy sets the RequiredBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy= +func PropRequiredBy(units ...string) Property { + return propDependency("RequiredBy", units) +} + +// PropRequiredByOverridable sets the RequiredByOverridable unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable= +func PropRequiredByOverridable(units ...string) Property { + return propDependency("RequiredByOverridable", units) +} + +// PropWantedBy sets the WantedBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy= +func PropWantedBy(units ...string) Property { + return propDependency("WantedBy", units) +} + +// PropBoundBy sets the BoundBy unit property. See +// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy= +func PropBoundBy(units ...string) Property { + return propDependency("BoundBy", units) +} + +// PropConflicts sets the Conflicts unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts= +func PropConflicts(units ...string) Property { + return propDependency("Conflicts", units) +} + +// PropConflictedBy sets the ConflictedBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy= +func PropConflictedBy(units ...string) Property { + return propDependency("ConflictedBy", units) +} + +// PropBefore sets the Before unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before= +func PropBefore(units ...string) Property { + return propDependency("Before", units) +} + +// PropAfter sets the After unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After= +func PropAfter(units ...string) Property { + return propDependency("After", units) +} + +// PropOnFailure sets the OnFailure unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure= +func PropOnFailure(units ...string) Property { + return propDependency("OnFailure", units) +} + +// PropTriggers sets the Triggers unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers= +func PropTriggers(units ...string) Property { + return propDependency("Triggers", units) +} + +// PropTriggeredBy sets the TriggeredBy unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy= +func PropTriggeredBy(units ...string) Property { + return propDependency("TriggeredBy", units) +} + +// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo= +func PropPropagatesReloadTo(units ...string) Property { + return propDependency("PropagatesReloadTo", units) +} + +// PropRequiresMountsFor sets the RequiresMountsFor unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor= +func PropRequiresMountsFor(units ...string) Property { + return propDependency("RequiresMountsFor", units) +} + +// PropSlice sets the Slice unit property. See +// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice= +func PropSlice(slice string) Property { + return Property{ + Name: "Slice", + Value: dbus.MakeVariant(slice), + } +} + +// PropPids sets the PIDs field of scope units used in the initial construction +// of the scope only and specifies the initial PIDs to add to the scope object. +// See https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/#properties +func PropPids(pids ...uint32) Property { + return Property{ + Name: "PIDs", + Value: dbus.MakeVariant(pids), + } +} diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/set.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/set.go new file mode 100644 index 00000000000..17c5d485657 --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/set.go @@ -0,0 +1,47 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbus + +type set struct { + data map[string]bool +} + +func (s *set) Add(value string) { + s.data[value] = true +} + +func (s *set) Remove(value string) { + delete(s.data, value) +} + +func (s *set) Contains(value string) (exists bool) { + _, exists = s.data[value] + return +} + +func (s *set) Length() int { + return len(s.data) +} + +func (s *set) Values() (values []string) { + for val := range s.data { + values = append(values, val) + } + return +} + +func newSet() *set { + return &set{make(map[string]bool)} +} diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go new file mode 100644 index 00000000000..7e370fea212 --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go @@ -0,0 +1,333 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbus + +import ( + "errors" + "log" + "time" + + "github.com/godbus/dbus/v5" +) + +const ( + cleanIgnoreInterval = int64(10 * time.Second) + ignoreInterval = int64(30 * time.Millisecond) +) + +// Subscribe sets up this connection to subscribe to all systemd dbus events. +// This is required before calling SubscribeUnits. When the connection closes +// systemd will automatically stop sending signals so there is no need to +// explicitly call Unsubscribe(). +func (c *Conn) Subscribe() error { + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'") + c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, + "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") + + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() +} + +// Unsubscribe this connection from systemd dbus events. +func (c *Conn) Unsubscribe() error { + return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() +} + +func (c *Conn) dispatch() { + ch := make(chan *dbus.Signal, signalBuffer) + + c.sigconn.Signal(ch) + + go func() { + for { + signal, ok := <-ch + if !ok { + return + } + + if signal.Name == "org.freedesktop.systemd1.Manager.JobRemoved" { + c.jobComplete(signal) + } + + if c.subStateSubscriber.updateCh == nil && + c.propertiesSubscriber.updateCh == nil { + continue + } + + var unitPath dbus.ObjectPath + switch signal.Name { + case "org.freedesktop.systemd1.Manager.JobRemoved": + unitName := signal.Body[2].(string) + c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath) + case "org.freedesktop.systemd1.Manager.UnitNew": + unitPath = signal.Body[1].(dbus.ObjectPath) + case "org.freedesktop.DBus.Properties.PropertiesChanged": + if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { + unitPath = signal.Path + + if len(signal.Body) >= 2 { + if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok { + c.sendPropertiesUpdate(unitPath, changed) + } + } + } + } + + if unitPath == dbus.ObjectPath("") { + continue + } + + c.sendSubStateUpdate(unitPath) + } + }() +} + +// SubscribeUnits returns two unbuffered channels which will receive all changed units every +// interval. Deleted units are sent as nil. +func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) { + return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil) +} + +// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer +// size of the channels, the comparison function for detecting changes and a filter +// function for cutting down on the noise that your channel receives. +func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) { + old := make(map[string]*UnitStatus) + statusChan := make(chan map[string]*UnitStatus, buffer) + errChan := make(chan error, buffer) + + go func() { + for { + timerChan := time.After(interval) + + units, err := c.ListUnits() + if err == nil { + cur := make(map[string]*UnitStatus) + for i := range units { + if filterUnit != nil && filterUnit(units[i].Name) { + continue + } + cur[units[i].Name] = &units[i] + } + + // add all new or changed units + changed := make(map[string]*UnitStatus) + for n, u := range cur { + if oldU, ok := old[n]; !ok || isChanged(oldU, u) { + changed[n] = u + } + delete(old, n) + } + + // add all deleted units + for oldN := range old { + changed[oldN] = nil + } + + old = cur + + if len(changed) != 0 { + statusChan <- changed + } + } else { + errChan <- err + } + + <-timerChan + } + }() + + return statusChan, errChan +} + +type SubStateUpdate struct { + UnitName string + SubState string +} + +// SetSubStateSubscriber writes to updateCh when any unit's substate changes. +// Although this writes to updateCh on every state change, the reported state +// may be more recent than the change that generated it (due to an unavoidable +// race in the systemd dbus interface). That is, this method provides a good +// way to keep a current view of all units' states, but is not guaranteed to +// show every state transition they go through. Furthermore, state changes +// will only be written to the channel with non-blocking writes. If updateCh +// is full, it attempts to write an error to errCh; if errCh is full, the error +// passes silently. +func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { + if c == nil { + msg := "nil receiver" + select { + case errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } + + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + c.subStateSubscriber.updateCh = updateCh + c.subStateSubscriber.errCh = errCh +} + +func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) { + c.subStateSubscriber.Lock() + defer c.subStateSubscriber.Unlock() + + if c.subStateSubscriber.updateCh == nil { + return + } + + isIgnored := c.shouldIgnore(unitPath) + defer c.cleanIgnore() + if isIgnored { + return + } + + info, err := c.GetUnitPathProperties(unitPath) + if err != nil { + select { + case c.subStateSubscriber.errCh <- err: + default: + log.Printf("full error channel while reporting: %s\n", err) + } + return + } + defer c.updateIgnore(unitPath, info) + + name, ok := info["Id"].(string) + if !ok { + msg := "failed to cast info.Id" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", err) + } + return + } + substate, ok := info["SubState"].(string) + if !ok { + msg := "failed to cast info.SubState" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } + + update := &SubStateUpdate{name, substate} + select { + case c.subStateSubscriber.updateCh <- update: + default: + msg := "update channel is full" + select { + case c.subStateSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } +} + +// The ignore functions work around a wart in the systemd dbus interface. +// Requesting the properties of an unloaded unit will cause systemd to send a +// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's +// properties on UnitNew (as that's the only indication of a new unit coming up +// for the first time), we would enter an infinite loop if we did not attempt +// to detect and ignore these spurious signals. The signal themselves are +// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an +// unloaded unit's signals for a short time after requesting its properties. +// This means that we will miss e.g. a transient unit being restarted +// *immediately* upon failure and also a transient unit being started +// immediately after requesting its status (with systemctl status, for example, +// because this causes a UnitNew signal to be sent which then causes us to fetch +// the properties). + +func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { + t, ok := c.subStateSubscriber.ignore[path] + return ok && t >= time.Now().UnixNano() +} + +func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { + loadState, ok := info["LoadState"].(string) + if !ok { + return + } + + // unit is unloaded - it will trigger bad systemd dbus behavior + if loadState == "not-found" { + c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval + } +} + +// without this, ignore would grow unboundedly over time +func (c *Conn) cleanIgnore() { + now := time.Now().UnixNano() + if c.subStateSubscriber.cleanIgnore < now { + c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval + + for p, t := range c.subStateSubscriber.ignore { + if t < now { + delete(c.subStateSubscriber.ignore, p) + } + } + } +} + +// PropertiesUpdate holds a map of a unit's changed properties +type PropertiesUpdate struct { + UnitName string + Changed map[string]dbus.Variant +} + +// SetPropertiesSubscriber writes to updateCh when any unit's properties +// change. Every property change reported by systemd will be sent; that is, no +// transitions will be "missed" (as they might be with SetSubStateSubscriber). +// However, state changes will only be written to the channel with non-blocking +// writes. If updateCh is full, it attempts to write an error to errCh; if +// errCh is full, the error passes silently. +func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + c.propertiesSubscriber.updateCh = updateCh + c.propertiesSubscriber.errCh = errCh +} + +// we don't need to worry about shouldIgnore() here because +// sendPropertiesUpdate doesn't call GetProperties() +func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) { + c.propertiesSubscriber.Lock() + defer c.propertiesSubscriber.Unlock() + + if c.propertiesSubscriber.updateCh == nil { + return + } + + update := &PropertiesUpdate{unitName(unitPath), changedProps} + + select { + case c.propertiesSubscriber.updateCh <- update: + default: + msg := "update channel is full" + select { + case c.propertiesSubscriber.errCh <- errors.New(msg): + default: + log.Printf("full error channel while reporting: %s\n", msg) + } + return + } +} diff --git a/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go new file mode 100644 index 00000000000..5b408d5847a --- /dev/null +++ b/agent/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go @@ -0,0 +1,57 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package dbus + +import ( + "time" +) + +// SubscriptionSet returns a subscription set which is like conn.Subscribe but +// can filter to only return events for a set of units. +type SubscriptionSet struct { + *set + conn *Conn +} + +func (s *SubscriptionSet) filter(unit string) bool { + return !s.Contains(unit) +} + +// Subscribe starts listening for dbus events for all of the units in the set. +// Returns channels identical to conn.SubscribeUnits. +func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) { + // TODO: Make fully evented by using systemd 209 with properties changed values + return s.conn.SubscribeUnitsCustom(time.Second, 0, + mismatchUnitStatus, + func(unit string) bool { return s.filter(unit) }, + ) +} + +// NewSubscriptionSet returns a new subscription set. +func (conn *Conn) NewSubscriptionSet() *SubscriptionSet { + return &SubscriptionSet{newSet(), conn} +} + +// mismatchUnitStatus returns true if the provided UnitStatus objects +// are not equivalent. false is returned if the objects are equivalent. +// Only the Name, Description and state-related fields are used in +// the comparison. +func mismatchUnitStatus(u1, u2 *UnitStatus) bool { + return u1.Name != u2.Name || + u1.Description != u2.Description || + u1.LoadState != u2.LoadState || + u1.ActiveState != u2.ActiveState || + u1.SubState != u2.SubState +} diff --git a/agent/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md b/agent/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md new file mode 100644 index 00000000000..c88f9b2bdd0 --- /dev/null +++ b/agent/vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md @@ -0,0 +1,50 @@ +# How to Contribute + +## Getting Started + +- Fork the repository on GitHub +- Read the [README](README.markdown) for build and test instructions +- Play with the project, submit bugs, submit patches! + +## Contribution Flow + +This is a rough outline of what a contributor's workflow looks like: + +- Create a topic branch from where you want to base your work (usually master). +- Make commits of logical units. +- Make sure your commit messages are in the proper format (see below). +- Push your changes to a topic branch in your fork of the repository. +- Make sure the tests pass, and add any new tests as appropriate. +- Submit a pull request to the original repository. + +Thanks for your contributions! + +### Format of the Commit Message + +We follow a rough convention for commit messages that is designed to answer two +questions: what changed and why. The subject line should feature the what and +the body of the commit should describe the why. + +``` +scripts: add the test-cluster command + +this uses tmux to setup a test cluster that you can easily kill and +start for debugging. + +Fixes #38 +``` + +The format can be described more formally as follows: + +``` +: + + + +