TUN-4356: Set AUTOMAXPROCS to the CPU limit when running in a Linux container
This commit is contained in:
		
							parent
							
								
									209091da39
								
							
						
					
					
						commit
						07af2a33b7
					
				| 
						 | 
					@ -10,6 +10,7 @@ import (
 | 
				
			||||||
	homedir "github.com/mitchellh/go-homedir"
 | 
						homedir "github.com/mitchellh/go-homedir"
 | 
				
			||||||
	"github.com/pkg/errors"
 | 
						"github.com/pkg/errors"
 | 
				
			||||||
	"github.com/urfave/cli/v2"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
 | 
						_ "go.uber.org/automaxprocs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/cloudflare/cloudflared/cmd/cloudflared/access"
 | 
						"github.com/cloudflare/cloudflared/cmd/cloudflared/access"
 | 
				
			||||||
	"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
 | 
						"github.com/cloudflare/cloudflared/cmd/cloudflared/cliutil"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										1
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -43,6 +43,7 @@ require (
 | 
				
			||||||
	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 | 
						github.com/russross/blackfriday/v2 v2.1.0 // indirect
 | 
				
			||||||
	github.com/stretchr/testify v1.6.0
 | 
						github.com/stretchr/testify v1.6.0
 | 
				
			||||||
	github.com/urfave/cli/v2 v2.2.0
 | 
						github.com/urfave/cli/v2 v2.2.0
 | 
				
			||||||
 | 
						go.uber.org/automaxprocs v1.4.0
 | 
				
			||||||
	golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
						golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
				
			||||||
	golang.org/x/net v0.0.0-20200904194848-62affa334b73
 | 
						golang.org/x/net v0.0.0-20200904194848-62affa334b73
 | 
				
			||||||
	golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
 | 
						golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 // indirect
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -609,6 +609,8 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 | 
				
			||||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 | 
					go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 | 
				
			||||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
					go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
				
			||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
					go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0=
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs v1.4.0/go.mod h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
 | 
				
			||||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 | 
					go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 | 
				
			||||||
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
 | 
					go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
 | 
				
			||||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
 | 
					go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					coverage:
 | 
				
			||||||
 | 
					  range: 80..100
 | 
				
			||||||
 | 
					  round: down
 | 
				
			||||||
 | 
					  precision: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  status:
 | 
				
			||||||
 | 
					    project:                   # measuring the overall project coverage
 | 
				
			||||||
 | 
					      default:                 # context, you can create multiple ones with custom titles
 | 
				
			||||||
 | 
					        enabled: yes           # must be yes|true to enable this status
 | 
				
			||||||
 | 
					        target: 90%            # specify the target coverage for each commit status
 | 
				
			||||||
 | 
					                               #   option: "auto" (must increase from parent commit or pull request base)
 | 
				
			||||||
 | 
					                               #   option: "X%" a static target percentage to hit
 | 
				
			||||||
 | 
					        if_not_found: success  # if parent is not found report status as success, error, or failure
 | 
				
			||||||
 | 
					        if_ci_failed: error    # if ci fails report status as success, error, or failure
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					# Compiled Object files, Static and Dynamic libs (Shared Objects)
 | 
				
			||||||
 | 
					*.o
 | 
				
			||||||
 | 
					*.a
 | 
				
			||||||
 | 
					*.so
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Folders
 | 
				
			||||||
 | 
					_obj
 | 
				
			||||||
 | 
					_test
 | 
				
			||||||
 | 
					vendor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Architecture specific extensions/prefixes
 | 
				
			||||||
 | 
					*.[568vq]
 | 
				
			||||||
 | 
					[568vq].out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*.cgo1.go
 | 
				
			||||||
 | 
					*.cgo2.c
 | 
				
			||||||
 | 
					_cgo_defun.c
 | 
				
			||||||
 | 
					_cgo_gotypes.go
 | 
				
			||||||
 | 
					_cgo_export.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_testmain.go
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*.exe
 | 
				
			||||||
 | 
					*.test
 | 
				
			||||||
 | 
					*.prof
 | 
				
			||||||
 | 
					*.pprof
 | 
				
			||||||
 | 
					*.out
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
 | 
					coverage.txt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/bin
 | 
				
			||||||
 | 
					cover.out
 | 
				
			||||||
 | 
					cover.html
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					language: go
 | 
				
			||||||
 | 
					sudo: false
 | 
				
			||||||
 | 
					go_import_path: go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					env:
 | 
				
			||||||
 | 
					  global:
 | 
				
			||||||
 | 
					    - GO111MODULE=on
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					matrix:
 | 
				
			||||||
 | 
					  include:
 | 
				
			||||||
 | 
					    - go: oldstable
 | 
				
			||||||
 | 
					    - go: stable
 | 
				
			||||||
 | 
					      env: LINT=1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					install:
 | 
				
			||||||
 | 
					  - make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					script:
 | 
				
			||||||
 | 
					  - test -z "$LINT" || make lint
 | 
				
			||||||
 | 
					  - make test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					after_success:
 | 
				
			||||||
 | 
					  - make cover
 | 
				
			||||||
 | 
					  - bash <(curl -s https://codecov.io/bash)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,26 @@
 | 
				
			||||||
 | 
					# Changelog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.4.0 (2021-02-01)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Support colons in cgroup names.
 | 
				
			||||||
 | 
					- Remove linters from runtime dependencies.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.3.0 (2020-01-23)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Migrate to Go modules.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.2.0 (2018-02-22)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Fixed quota clamping to always round down rather than up; Rather than
 | 
				
			||||||
 | 
					  guaranteeing constant throttling at saturation, instead assume that the
 | 
				
			||||||
 | 
					  fractional CPU was added as a hedge for factors outside of Go's scheduler.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.1.0 (2017-11-10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Log the new value of `GOMAXPROCS` rather than the current value.
 | 
				
			||||||
 | 
					- Make logs more explicit about whether `GOMAXPROCS` was modified or not.
 | 
				
			||||||
 | 
					- Allow customization of the minimum `GOMAXPROCS`, and modify default from 2 to 1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## v1.0.0 (2017-08-09)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Initial release.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,75 @@
 | 
				
			||||||
 | 
					# Contributor Covenant Code of Conduct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Our Pledge
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In the interest of fostering an open and welcoming environment, we as
 | 
				
			||||||
 | 
					contributors and maintainers pledge to making participation in our project and
 | 
				
			||||||
 | 
					our community a harassment-free experience for everyone, regardless of age,
 | 
				
			||||||
 | 
					body size, disability, ethnicity, gender identity and expression, level of
 | 
				
			||||||
 | 
					experience, nationality, personal appearance, race, religion, or sexual
 | 
				
			||||||
 | 
					identity and orientation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Our Standards
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples of behavior that contributes to creating a positive environment
 | 
				
			||||||
 | 
					include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Using welcoming and inclusive language
 | 
				
			||||||
 | 
					* Being respectful of differing viewpoints and experiences
 | 
				
			||||||
 | 
					* Gracefully accepting constructive criticism
 | 
				
			||||||
 | 
					* Focusing on what is best for the community
 | 
				
			||||||
 | 
					* Showing empathy towards other community members
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Examples of unacceptable behavior by participants include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* The use of sexualized language or imagery and unwelcome sexual attention or
 | 
				
			||||||
 | 
					  advances
 | 
				
			||||||
 | 
					* Trolling, insulting/derogatory comments, and personal or political attacks
 | 
				
			||||||
 | 
					* Public or private harassment
 | 
				
			||||||
 | 
					* Publishing others' private information, such as a physical or electronic
 | 
				
			||||||
 | 
					  address, without explicit permission
 | 
				
			||||||
 | 
					* Other conduct which could reasonably be considered inappropriate in a
 | 
				
			||||||
 | 
					  professional setting
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Our Responsibilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project maintainers are responsible for clarifying the standards of acceptable
 | 
				
			||||||
 | 
					behavior and are expected to take appropriate and fair corrective action in
 | 
				
			||||||
 | 
					response to any instances of unacceptable behavior.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project maintainers have the right and responsibility to remove, edit, or
 | 
				
			||||||
 | 
					reject comments, commits, code, wiki edits, issues, and other contributions
 | 
				
			||||||
 | 
					that are not aligned to this Code of Conduct, or to ban temporarily or
 | 
				
			||||||
 | 
					permanently any contributor for other behaviors that they deem inappropriate,
 | 
				
			||||||
 | 
					threatening, offensive, or harmful.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Scope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Code of Conduct applies both within project spaces and in public spaces
 | 
				
			||||||
 | 
					when an individual is representing the project or its community. Examples of
 | 
				
			||||||
 | 
					representing a project or community include using an official project e-mail
 | 
				
			||||||
 | 
					address, posting via an official social media account, or acting as an
 | 
				
			||||||
 | 
					appointed representative at an online or offline event. Representation of a
 | 
				
			||||||
 | 
					project may be further defined and clarified by project maintainers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Enforcement
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Instances of abusive, harassing, or otherwise unacceptable behavior may be
 | 
				
			||||||
 | 
					reported by contacting the project team at oss-conduct@uber.com. The project
 | 
				
			||||||
 | 
					team will review and investigate all complaints, and will respond in a way
 | 
				
			||||||
 | 
					that it deems appropriate to the circumstances. The project team is obligated
 | 
				
			||||||
 | 
					to maintain confidentiality with regard to the reporter of an incident.
 | 
				
			||||||
 | 
					Further details of specific enforcement policies may be posted separately.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Project maintainers who do not follow or enforce the Code of Conduct in good
 | 
				
			||||||
 | 
					faith may face temporary or permanent repercussions as determined by other
 | 
				
			||||||
 | 
					members of the project's leadership.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Attribution
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Code of Conduct is adapted from the [Contributor Covenant][homepage],
 | 
				
			||||||
 | 
					version 1.4, available at
 | 
				
			||||||
 | 
					[http://contributor-covenant.org/version/1/4][version].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[homepage]: http://contributor-covenant.org
 | 
				
			||||||
 | 
					[version]: http://contributor-covenant.org/version/1/4/
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,81 @@
 | 
				
			||||||
 | 
					# Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We'd love your help improving this package!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you'd like to add new exported APIs, please [open an issue][open-issue]
 | 
				
			||||||
 | 
					describing your proposal — discussing API changes ahead of time makes
 | 
				
			||||||
 | 
					pull request review much smoother. In your issue, pull request, and any other
 | 
				
			||||||
 | 
					communications, please remember to treat your fellow contributors with
 | 
				
			||||||
 | 
					respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that you'll need to sign [Uber's Contributor License Agreement][cla]
 | 
				
			||||||
 | 
					before we can accept any of your contributions. If necessary, a bot will remind
 | 
				
			||||||
 | 
					you to accept the CLA when you open your pull request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Fork][fork], then clone the repository:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					mkdir -p $GOPATH/src/go.uber.org
 | 
				
			||||||
 | 
					cd $GOPATH/src/go.uber.org
 | 
				
			||||||
 | 
					git clone git@github.com:your_github_username/automaxprocs.git
 | 
				
			||||||
 | 
					cd automaxprocs
 | 
				
			||||||
 | 
					git remote add upstream https://github.com/uber-go/automaxprocs.git
 | 
				
			||||||
 | 
					git fetch upstream
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Install the test dependencies:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					make dependencies
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make sure that the tests and the linters pass:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					make test
 | 
				
			||||||
 | 
					make lint
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you're not using the minor version of Go specified in the Makefile's
 | 
				
			||||||
 | 
					`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is
 | 
				
			||||||
 | 
					fine, but it means that you'll only discover lint failures after you open your
 | 
				
			||||||
 | 
					pull request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Making Changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Start by creating a new branch for your changes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					cd $GOPATH/src/go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					git checkout master
 | 
				
			||||||
 | 
					git fetch upstream
 | 
				
			||||||
 | 
					git rebase upstream/master
 | 
				
			||||||
 | 
					git checkout -b cool_new_feature
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Make your changes, then ensure that `make lint` and `make test` still pass. If
 | 
				
			||||||
 | 
					you're satisfied with your changes, push them to your fork.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					git push origin cool_new_feature
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Then use the GitHub UI to open a pull request.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					At this point, you're waiting on us to review your changes. We *try* to respond
 | 
				
			||||||
 | 
					to issues and pull requests within a few business days, and we may suggest some
 | 
				
			||||||
 | 
					improvements or alternatives. Once your changes are approved, one of the
 | 
				
			||||||
 | 
					project maintainers will merge them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We're much more likely to approve your changes if you:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* Add tests for new functionality.
 | 
				
			||||||
 | 
					* Write a [good commit message][commit-message].
 | 
				
			||||||
 | 
					* Maintain backward compatibility.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[fork]: https://github.com/uber-go/automaxprocs/fork
 | 
				
			||||||
 | 
					[open-issue]: https://github.com/uber-go/automaxprocs/issues/new
 | 
				
			||||||
 | 
					[cla]: https://cla-assistant.io/uber-go/automaxprocs
 | 
				
			||||||
 | 
					[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					THE SOFTWARE.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					export GOBIN ?= $(shell pwd)/bin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GO_FILES := $(shell \
 | 
				
			||||||
 | 
						find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
 | 
				
			||||||
 | 
						-o -name '*.go' -print | cut -b3-)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GOLINT = $(GOBIN)/golint
 | 
				
			||||||
 | 
					STATICCHECK = $(GOBIN)/staticcheck
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: build
 | 
				
			||||||
 | 
					build:
 | 
				
			||||||
 | 
						go build ./...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: install
 | 
				
			||||||
 | 
					install:
 | 
				
			||||||
 | 
						go mod download
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: test
 | 
				
			||||||
 | 
					test:
 | 
				
			||||||
 | 
						go test -race ./...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: cover
 | 
				
			||||||
 | 
					cover:
 | 
				
			||||||
 | 
						go test -coverprofile=cover.out -covermode=atomic -coverpkg=./... ./...
 | 
				
			||||||
 | 
						go tool cover -html=cover.out -o cover.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(GOLINT): tools/go.mod
 | 
				
			||||||
 | 
						cd tools && go install golang.org/x/lint/golint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					$(STATICCHECK): tools/go.mod
 | 
				
			||||||
 | 
						cd tools && go install honnef.co/go/tools/cmd/staticcheck
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: lint
 | 
				
			||||||
 | 
					lint: $(GOLINT) $(STATICCHECK)
 | 
				
			||||||
 | 
						@rm -rf lint.log
 | 
				
			||||||
 | 
						@echo "Checking gofmt"
 | 
				
			||||||
 | 
						@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
 | 
				
			||||||
 | 
						@echo "Checking go vet"
 | 
				
			||||||
 | 
						@go vet ./... 2>&1 | tee -a lint.log
 | 
				
			||||||
 | 
						@echo "Checking golint"
 | 
				
			||||||
 | 
						@$(GOLINT) ./... | tee -a lint.log
 | 
				
			||||||
 | 
						@echo "Checking staticcheck"
 | 
				
			||||||
 | 
						@$(STATICCHECK) ./... 2>&1 |  tee -a lint.log
 | 
				
			||||||
 | 
						@echo "Checking for license headers..."
 | 
				
			||||||
 | 
						@./.build/check_license.sh | tee -a lint.log
 | 
				
			||||||
 | 
						@[ ! -s lint.log ]
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,46 @@
 | 
				
			||||||
 | 
					# automaxprocs [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Automatically set `GOMAXPROCS` to match Linux container CPU quota.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`go get -u go.uber.org/automaxprocs`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Quick Start
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					import _ "go.uber.org/automaxprocs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func main() {
 | 
				
			||||||
 | 
					  // Your application logic here.
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Development Status: Stable
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					All APIs are finalized, and no breaking changes will be made in the 1.x series
 | 
				
			||||||
 | 
					of releases. Users of semver-aware dependency management systems should pin
 | 
				
			||||||
 | 
					automaxprocs to `^1`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contributing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					We encourage and support an active, healthy community of contributors —
 | 
				
			||||||
 | 
					including you! Details are in the [contribution guide](CONTRIBUTING.md) and
 | 
				
			||||||
 | 
					the [code of conduct](CODE_OF_CONDUCT.md). The automaxprocs maintainers keep
 | 
				
			||||||
 | 
					an eye on issues and pull requests, but you can also report any negative
 | 
				
			||||||
 | 
					conduct to oss-conduct@uber.com. That email list is a private, safe space;
 | 
				
			||||||
 | 
					even the automaxprocs maintainers don't have access, so don't hesitate to hold
 | 
				
			||||||
 | 
					us to a high standard.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<hr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Released under the [MIT License](LICENSE).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[doc-img]: https://godoc.org/go.uber.org/automaxprocs?status.svg
 | 
				
			||||||
 | 
					[doc]: https://godoc.org/go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					[ci-img]: https://travis-ci.com/uber-go/automaxprocs.svg?branch=master
 | 
				
			||||||
 | 
					[ci]: https://travis-ci.com/uber-go/automaxprocs
 | 
				
			||||||
 | 
					[cov-img]: https://codecov.io/gh/uber-go/automaxprocs/branch/master/graph/badge.svg
 | 
				
			||||||
 | 
					[cov]: https://codecov.io/gh/uber-go/automaxprocs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Package automaxprocs automatically sets GOMAXPROCS to match the Linux
 | 
				
			||||||
 | 
					// container CPU quota, if any.
 | 
				
			||||||
 | 
					package automaxprocs // import "go.uber.org/automaxprocs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"go.uber.org/automaxprocs/maxprocs"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						maxprocs.Set(maxprocs.Logger(log.Printf))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					package: go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					import: []
 | 
				
			||||||
 | 
					testImport:
 | 
				
			||||||
 | 
					- package: github.com/stretchr/testify
 | 
				
			||||||
 | 
					  version: ^1.1.4
 | 
				
			||||||
 | 
					  subpackages:
 | 
				
			||||||
 | 
					  - assert
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					module go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					go 1.13
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require (
 | 
				
			||||||
 | 
						github.com/kr/pretty v0.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/stretchr/testify v1.4.0
 | 
				
			||||||
 | 
						gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 | 
				
			||||||
 | 
					github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
				
			||||||
 | 
					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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 | 
				
			||||||
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
 | 
					github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
 | 
					gopkg.in/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 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,78 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CGroup represents the data structure for a Linux control group.
 | 
				
			||||||
 | 
					type CGroup struct {
 | 
				
			||||||
 | 
						path string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewCGroup returns a new *CGroup from a given path.
 | 
				
			||||||
 | 
					func NewCGroup(path string) *CGroup {
 | 
				
			||||||
 | 
						return &CGroup{path: path}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Path returns the path of the CGroup*.
 | 
				
			||||||
 | 
					func (cg *CGroup) Path() string {
 | 
				
			||||||
 | 
						return cg.path
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ParamPath returns the path of the given cgroup param under itself.
 | 
				
			||||||
 | 
					func (cg *CGroup) ParamPath(param string) string {
 | 
				
			||||||
 | 
						return filepath.Join(cg.path, param)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// readFirstLine reads the first line from a cgroup param file.
 | 
				
			||||||
 | 
					func (cg *CGroup) readFirstLine(param string) (string, error) {
 | 
				
			||||||
 | 
						paramFile, err := os.Open(cg.ParamPath(param))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer paramFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(paramFile)
 | 
				
			||||||
 | 
						if scanner.Scan() {
 | 
				
			||||||
 | 
							return scanner.Text(), nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := scanner.Err(); err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return "", io.ErrUnexpectedEOF
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// readInt parses the first line from a cgroup param file as int.
 | 
				
			||||||
 | 
					func (cg *CGroup) readInt(param string) (int, error) {
 | 
				
			||||||
 | 
						text, err := cg.readFirstLine(param)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return strconv.Atoi(text)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,117 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// _cgroupFSType is the Linux CGroup file system type used in
 | 
				
			||||||
 | 
						// `/proc/$PID/mountinfo`.
 | 
				
			||||||
 | 
						_cgroupFSType = "cgroup"
 | 
				
			||||||
 | 
						// _cgroupSubsysCPU is the CPU CGroup subsystem.
 | 
				
			||||||
 | 
						_cgroupSubsysCPU = "cpu"
 | 
				
			||||||
 | 
						// _cgroupSubsysCPUAcct is the CPU accounting CGroup subsystem.
 | 
				
			||||||
 | 
						_cgroupSubsysCPUAcct = "cpuacct"
 | 
				
			||||||
 | 
						// _cgroupSubsysCPUSet is the CPUSet CGroup subsystem.
 | 
				
			||||||
 | 
						_cgroupSubsysCPUSet = "cpuset"
 | 
				
			||||||
 | 
						// _cgroupSubsysMemory is the Memory CGroup subsystem.
 | 
				
			||||||
 | 
						_cgroupSubsysMemory = "memory"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// _cgroupCPUCFSQuotaUsParam is the file name for the CGroup CFS quota
 | 
				
			||||||
 | 
						// parameter.
 | 
				
			||||||
 | 
						_cgroupCPUCFSQuotaUsParam = "cpu.cfs_quota_us"
 | 
				
			||||||
 | 
						// _cgroupCPUCFSPeriodUsParam is the file name for the CGroup CFS period
 | 
				
			||||||
 | 
						// parameter.
 | 
				
			||||||
 | 
						_cgroupCPUCFSPeriodUsParam = "cpu.cfs_period_us"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_procPathCGroup    = "/proc/self/cgroup"
 | 
				
			||||||
 | 
						_procPathMountInfo = "/proc/self/mountinfo"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CGroups is a map that associates each CGroup with its subsystem name.
 | 
				
			||||||
 | 
					type CGroups map[string]*CGroup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewCGroups returns a new *CGroups from given `mountinfo` and `cgroup` files
 | 
				
			||||||
 | 
					// under for some process under `/proc` file system (see also proc(5) for more
 | 
				
			||||||
 | 
					// information).
 | 
				
			||||||
 | 
					func NewCGroups(procPathMountInfo, procPathCGroup string) (CGroups, error) {
 | 
				
			||||||
 | 
						cgroupSubsystems, err := parseCGroupSubsystems(procPathCGroup)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgroups := make(CGroups)
 | 
				
			||||||
 | 
						newMountPoint := func(mp *MountPoint) error {
 | 
				
			||||||
 | 
							if mp.FSType != _cgroupFSType {
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for _, opt := range mp.SuperOptions {
 | 
				
			||||||
 | 
								subsys, exists := cgroupSubsystems[opt]
 | 
				
			||||||
 | 
								if !exists {
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								cgroupPath, err := mp.Translate(subsys.Name)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								cgroups[opt] = NewCGroup(cgroupPath)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := parseMountInfo(procPathMountInfo, newMountPoint); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return cgroups, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewCGroupsForCurrentProcess returns a new *CGroups instance for the current
 | 
				
			||||||
 | 
					// process.
 | 
				
			||||||
 | 
					func NewCGroupsForCurrentProcess() (CGroups, error) {
 | 
				
			||||||
 | 
						return NewCGroups(_procPathMountInfo, _procPathCGroup)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CPUQuota returns the CPU quota applied with the CPU cgroup controller.
 | 
				
			||||||
 | 
					// It is a result of `cpu.cfs_quota_us / cpu.cfs_period_us`. If the value of
 | 
				
			||||||
 | 
					// `cpu.cfs_quota_us` was not set (-1), the method returns `(-1, nil)`.
 | 
				
			||||||
 | 
					func (cg CGroups) CPUQuota() (float64, bool, error) {
 | 
				
			||||||
 | 
						cpuCGroup, exists := cg[_cgroupSubsysCPU]
 | 
				
			||||||
 | 
						if !exists {
 | 
				
			||||||
 | 
							return -1, false, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfsQuotaUs, err := cpuCGroup.readInt(_cgroupCPUCFSQuotaUsParam)
 | 
				
			||||||
 | 
						if defined := cfsQuotaUs > 0; err != nil || !defined {
 | 
				
			||||||
 | 
							return -1, defined, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cfsPeriodUs, err := cpuCGroup.readInt(_cgroupCPUCFSPeriodUsParam)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return -1, false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return float64(cfsQuotaUs) / float64(cfsPeriodUs), true, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Package cgroups provides utilities to access Linux control group (CGroups)
 | 
				
			||||||
 | 
					// parameters (CPU quota, for example) for a given process.
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type cgroupSubsysFormatInvalidError struct {
 | 
				
			||||||
 | 
						line string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type mountPointFormatInvalidError struct {
 | 
				
			||||||
 | 
						line string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type pathNotExposedFromMountPointError struct {
 | 
				
			||||||
 | 
						mountPoint string
 | 
				
			||||||
 | 
						root       string
 | 
				
			||||||
 | 
						path       string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err cgroupSubsysFormatInvalidError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("invalid format for CGroupSubsys: %q", err.line)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err mountPointFormatInvalidError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("invalid format for MountPoint: %q", err.line)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (err pathNotExposedFromMountPointError) Error() string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("path %q is not a descendant of mount point root %q and cannot be exposed from %q", err.path, err.root, err.mountPoint)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,166 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_mountInfoSep               = " "
 | 
				
			||||||
 | 
						_mountInfoOptsSep           = ","
 | 
				
			||||||
 | 
						_mountInfoOptionalFieldsSep = "-"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_miFieldIDMountID = iota
 | 
				
			||||||
 | 
						_miFieldIDParentID
 | 
				
			||||||
 | 
						_miFieldIDDeviceID
 | 
				
			||||||
 | 
						_miFieldIDRoot
 | 
				
			||||||
 | 
						_miFieldIDMountPoint
 | 
				
			||||||
 | 
						_miFieldIDOptions
 | 
				
			||||||
 | 
						_miFieldIDOptionalFields
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_miFieldCountFirstHalf
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_miFieldOffsetFSType = iota
 | 
				
			||||||
 | 
						_miFieldOffsetMountSource
 | 
				
			||||||
 | 
						_miFieldOffsetSuperOptions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_miFieldCountSecondHalf
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const _miFieldCountMin = _miFieldCountFirstHalf + _miFieldCountSecondHalf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// MountPoint is the data structure for the mount points in
 | 
				
			||||||
 | 
					// `/proc/$PID/mountinfo`. See also proc(5) for more information.
 | 
				
			||||||
 | 
					type MountPoint struct {
 | 
				
			||||||
 | 
						MountID        int
 | 
				
			||||||
 | 
						ParentID       int
 | 
				
			||||||
 | 
						DeviceID       string
 | 
				
			||||||
 | 
						Root           string
 | 
				
			||||||
 | 
						MountPoint     string
 | 
				
			||||||
 | 
						Options        []string
 | 
				
			||||||
 | 
						OptionalFields []string
 | 
				
			||||||
 | 
						FSType         string
 | 
				
			||||||
 | 
						MountSource    string
 | 
				
			||||||
 | 
						SuperOptions   []string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewMountPointFromLine parses a line read from `/proc/$PID/mountinfo` and
 | 
				
			||||||
 | 
					// returns a new *MountPoint.
 | 
				
			||||||
 | 
					func NewMountPointFromLine(line string) (*MountPoint, error) {
 | 
				
			||||||
 | 
						fields := strings.Split(line, _mountInfoSep)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(fields) < _miFieldCountMin {
 | 
				
			||||||
 | 
							return nil, mountPointFormatInvalidError{line}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mountID, err := strconv.Atoi(fields[_miFieldIDMountID])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						parentID, err := strconv.Atoi(fields[_miFieldIDParentID])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i, field := range fields[_miFieldIDOptionalFields:] {
 | 
				
			||||||
 | 
							if field == _mountInfoOptionalFieldsSep {
 | 
				
			||||||
 | 
								fsTypeStart := _miFieldIDOptionalFields + i + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if len(fields) != fsTypeStart+_miFieldCountSecondHalf {
 | 
				
			||||||
 | 
									return nil, mountPointFormatInvalidError{line}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								miFieldIDFSType := _miFieldOffsetFSType + fsTypeStart
 | 
				
			||||||
 | 
								miFieldIDMountSource := _miFieldOffsetMountSource + fsTypeStart
 | 
				
			||||||
 | 
								miFieldIDSuperOptions := _miFieldOffsetSuperOptions + fsTypeStart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return &MountPoint{
 | 
				
			||||||
 | 
									MountID:        mountID,
 | 
				
			||||||
 | 
									ParentID:       parentID,
 | 
				
			||||||
 | 
									DeviceID:       fields[_miFieldIDDeviceID],
 | 
				
			||||||
 | 
									Root:           fields[_miFieldIDRoot],
 | 
				
			||||||
 | 
									MountPoint:     fields[_miFieldIDMountPoint],
 | 
				
			||||||
 | 
									Options:        strings.Split(fields[_miFieldIDOptions], _mountInfoOptsSep),
 | 
				
			||||||
 | 
									OptionalFields: fields[_miFieldIDOptionalFields:(fsTypeStart - 1)],
 | 
				
			||||||
 | 
									FSType:         fields[miFieldIDFSType],
 | 
				
			||||||
 | 
									MountSource:    fields[miFieldIDMountSource],
 | 
				
			||||||
 | 
									SuperOptions:   strings.Split(fields[miFieldIDSuperOptions], _mountInfoOptsSep),
 | 
				
			||||||
 | 
								}, nil
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return nil, mountPointFormatInvalidError{line}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Translate converts an absolute path inside the *MountPoint's file system to
 | 
				
			||||||
 | 
					// the host file system path in the mount namespace the *MountPoint belongs to.
 | 
				
			||||||
 | 
					func (mp *MountPoint) Translate(absPath string) (string, error) {
 | 
				
			||||||
 | 
						relPath, err := filepath.Rel(mp.Root, absPath)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return "", err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if relPath == ".." || strings.HasPrefix(relPath, "../") {
 | 
				
			||||||
 | 
							return "", pathNotExposedFromMountPointError{
 | 
				
			||||||
 | 
								mountPoint: mp.MountPoint,
 | 
				
			||||||
 | 
								root:       mp.Root,
 | 
				
			||||||
 | 
								path:       absPath,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return filepath.Join(mp.MountPoint, relPath), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseMountInfo parses procPathMountInfo (usually at `/proc/$PID/mountinfo`)
 | 
				
			||||||
 | 
					// and yields parsed *MountPoint into newMountPoint.
 | 
				
			||||||
 | 
					func parseMountInfo(procPathMountInfo string, newMountPoint func(*MountPoint) error) error {
 | 
				
			||||||
 | 
						mountInfoFile, err := os.Open(procPathMountInfo)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer mountInfoFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(mountInfoFile)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for scanner.Scan() {
 | 
				
			||||||
 | 
							mountPoint, err := NewMountPointFromLine(scanner.Text())
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if err := newMountPoint(mountPoint); err != nil {
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return scanner.Err()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,102 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cgroups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_cgroupSep       = ":"
 | 
				
			||||||
 | 
						_cgroupSubsysSep = ","
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						_csFieldIDID = iota
 | 
				
			||||||
 | 
						_csFieldIDSubsystems
 | 
				
			||||||
 | 
						_csFieldIDName
 | 
				
			||||||
 | 
						_csFieldCount
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CGroupSubsys represents the data structure for entities in
 | 
				
			||||||
 | 
					// `/proc/$PID/cgroup`. See also proc(5) for more information.
 | 
				
			||||||
 | 
					type CGroupSubsys struct {
 | 
				
			||||||
 | 
						ID         int
 | 
				
			||||||
 | 
						Subsystems []string
 | 
				
			||||||
 | 
						Name       string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewCGroupSubsysFromLine returns a new *CGroupSubsys by parsing a string in
 | 
				
			||||||
 | 
					// the format of `/proc/$PID/cgroup`
 | 
				
			||||||
 | 
					func NewCGroupSubsysFromLine(line string) (*CGroupSubsys, error) {
 | 
				
			||||||
 | 
						fields := strings.SplitN(line, _cgroupSep, _csFieldCount)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(fields) != _csFieldCount {
 | 
				
			||||||
 | 
							return nil, cgroupSubsysFormatInvalidError{line}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						id, err := strconv.Atoi(fields[_csFieldIDID])
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cgroup := &CGroupSubsys{
 | 
				
			||||||
 | 
							ID:         id,
 | 
				
			||||||
 | 
							Subsystems: strings.Split(fields[_csFieldIDSubsystems], _cgroupSubsysSep),
 | 
				
			||||||
 | 
							Name:       fields[_csFieldIDName],
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return cgroup, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// parseCGroupSubsystems parses procPathCGroup (usually at `/proc/$PID/cgroup`)
 | 
				
			||||||
 | 
					// and returns a new map[string]*CGroupSubsys.
 | 
				
			||||||
 | 
					func parseCGroupSubsystems(procPathCGroup string) (map[string]*CGroupSubsys, error) {
 | 
				
			||||||
 | 
						cgroupFile, err := os.Open(procPathCGroup)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer cgroupFile.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(cgroupFile)
 | 
				
			||||||
 | 
						subsystems := make(map[string]*CGroupSubsys)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for scanner.Scan() {
 | 
				
			||||||
 | 
							cgroup, err := NewCGroupSubsysFromLine(scanner.Text())
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							for _, subsys := range cgroup.Subsystems {
 | 
				
			||||||
 | 
								subsystems[subsys] = cgroup
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := scanner.Err(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return subsystems, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										49
									
								
								vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										49
									
								
								vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
					@ -0,0 +1,49 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"math"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cg "go.uber.org/automaxprocs/internal/cgroups"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
 | 
				
			||||||
 | 
					// to a valid GOMAXPROCS value.
 | 
				
			||||||
 | 
					func CPUQuotaToGOMAXPROCS(minValue int) (int, CPUQuotaStatus, error) {
 | 
				
			||||||
 | 
						cgroups, err := cg.NewCGroupsForCurrentProcess()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return -1, CPUQuotaUndefined, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						quota, defined, err := cgroups.CPUQuota()
 | 
				
			||||||
 | 
						if !defined || err != nil {
 | 
				
			||||||
 | 
							return -1, CPUQuotaUndefined, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						maxProcs := int(math.Floor(quota))
 | 
				
			||||||
 | 
						if minValue > 0 && maxProcs < minValue {
 | 
				
			||||||
 | 
							return minValue, CPUQuotaMinUsed, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return maxProcs, CPUQuotaUsed, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							
							
						
						
									
										30
									
								
								vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
								
								
									generated
								
								
									vendored
								
								
									Normal file
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// +build !linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
 | 
				
			||||||
 | 
					// to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
 | 
				
			||||||
 | 
					// current OS.
 | 
				
			||||||
 | 
					func CPUQuotaToGOMAXPROCS(_ int) (int, CPUQuotaStatus, error) {
 | 
				
			||||||
 | 
						return -1, CPUQuotaUndefined, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CPUQuotaStatus presents the status of how CPU quota is used
 | 
				
			||||||
 | 
					type CPUQuotaStatus int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						// CPUQuotaUndefined is returned when CPU quota is undefined
 | 
				
			||||||
 | 
						CPUQuotaUndefined CPUQuotaStatus = iota
 | 
				
			||||||
 | 
						// CPUQuotaUsed is returned when a valid CPU quota can be used
 | 
				
			||||||
 | 
						CPUQuotaUsed
 | 
				
			||||||
 | 
						// CPUQuotaMinUsed is return when CPU quota is smaller than the min value
 | 
				
			||||||
 | 
						CPUQuotaMinUsed
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,130 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
 | 
				
			||||||
 | 
					// match the configured Linux CPU quota. Unlike the top-level automaxprocs
 | 
				
			||||||
 | 
					// package, it lets the caller configure logging and handle errors.
 | 
				
			||||||
 | 
					package maxprocs // import "go.uber.org/automaxprocs/maxprocs"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						iruntime "go.uber.org/automaxprocs/internal/runtime"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const _maxProcsKey = "GOMAXPROCS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func currentMaxProcs() int {
 | 
				
			||||||
 | 
						return runtime.GOMAXPROCS(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type config struct {
 | 
				
			||||||
 | 
						printf        func(string, ...interface{})
 | 
				
			||||||
 | 
						procs         func(int) (int, iruntime.CPUQuotaStatus, error)
 | 
				
			||||||
 | 
						minGOMAXPROCS int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *config) log(fmt string, args ...interface{}) {
 | 
				
			||||||
 | 
						if c.printf != nil {
 | 
				
			||||||
 | 
							c.printf(fmt, args...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An Option alters the behavior of Set.
 | 
				
			||||||
 | 
					type Option interface {
 | 
				
			||||||
 | 
						apply(*config)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Logger uses the supplied printf implementation for log output. By default,
 | 
				
			||||||
 | 
					// Set doesn't log anything.
 | 
				
			||||||
 | 
					func Logger(printf func(string, ...interface{})) Option {
 | 
				
			||||||
 | 
						return optionFunc(func(cfg *config) {
 | 
				
			||||||
 | 
							cfg.printf = printf
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Min sets the minimum GOMAXPROCS value that will be used.
 | 
				
			||||||
 | 
					// Any value below 1 is ignored.
 | 
				
			||||||
 | 
					func Min(n int) Option {
 | 
				
			||||||
 | 
						return optionFunc(func(cfg *config) {
 | 
				
			||||||
 | 
							if n >= 1 {
 | 
				
			||||||
 | 
								cfg.minGOMAXPROCS = n
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type optionFunc func(*config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (of optionFunc) apply(cfg *config) { of(cfg) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
 | 
				
			||||||
 | 
					// any error encountered and an undo function.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Set is a no-op on non-Linux systems and in Linux environments without a
 | 
				
			||||||
 | 
					// configured CPU quota.
 | 
				
			||||||
 | 
					func Set(opts ...Option) (func(), error) {
 | 
				
			||||||
 | 
						cfg := &config{
 | 
				
			||||||
 | 
							procs:         iruntime.CPUQuotaToGOMAXPROCS,
 | 
				
			||||||
 | 
							minGOMAXPROCS: 1,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for _, o := range opts {
 | 
				
			||||||
 | 
							o.apply(cfg)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						undoNoop := func() {
 | 
				
			||||||
 | 
							cfg.log("maxprocs: No GOMAXPROCS change to reset")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Honor the GOMAXPROCS environment variable if present. Otherwise, amend
 | 
				
			||||||
 | 
						// `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
 | 
				
			||||||
 | 
						// Linux, and guarantee a minimum value of 1. The minimum guaranteed value
 | 
				
			||||||
 | 
						// can be overriden using `maxprocs.Min()`.
 | 
				
			||||||
 | 
						if max, exists := os.LookupEnv(_maxProcsKey); exists {
 | 
				
			||||||
 | 
							cfg.log("maxprocs: Honoring GOMAXPROCS=%q as set in environment", max)
 | 
				
			||||||
 | 
							return undoNoop, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return undoNoop, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if status == iruntime.CPUQuotaUndefined {
 | 
				
			||||||
 | 
							cfg.log("maxprocs: Leaving GOMAXPROCS=%v: CPU quota undefined", currentMaxProcs())
 | 
				
			||||||
 | 
							return undoNoop, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						prev := currentMaxProcs()
 | 
				
			||||||
 | 
						undo := func() {
 | 
				
			||||||
 | 
							cfg.log("maxprocs: Resetting GOMAXPROCS to %v", prev)
 | 
				
			||||||
 | 
							runtime.GOMAXPROCS(prev)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch status {
 | 
				
			||||||
 | 
						case iruntime.CPUQuotaMinUsed:
 | 
				
			||||||
 | 
							cfg.log("maxprocs: Updating GOMAXPROCS=%v: using minimum allowed GOMAXPROCS", maxProcs)
 | 
				
			||||||
 | 
						case iruntime.CPUQuotaUsed:
 | 
				
			||||||
 | 
							cfg.log("maxprocs: Updating GOMAXPROCS=%v: determined from CPU quota", maxProcs)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						runtime.GOMAXPROCS(maxProcs)
 | 
				
			||||||
 | 
						return undo, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					// Copyright (c) 2017 Uber Technologies, Inc.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					// of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					// in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					// copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					// furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// The above copyright notice and this permission notice shall be included in
 | 
				
			||||||
 | 
					// all copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 | 
					// THE SOFTWARE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package maxprocs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Version is the current package version.
 | 
				
			||||||
 | 
					const Version = "1.4.0"
 | 
				
			||||||
| 
						 | 
					@ -250,6 +250,12 @@ github.com/stretchr/testify/require
 | 
				
			||||||
## explicit
 | 
					## explicit
 | 
				
			||||||
github.com/urfave/cli/v2
 | 
					github.com/urfave/cli/v2
 | 
				
			||||||
github.com/urfave/cli/v2/altsrc
 | 
					github.com/urfave/cli/v2/altsrc
 | 
				
			||||||
 | 
					# go.uber.org/automaxprocs v1.4.0
 | 
				
			||||||
 | 
					## explicit
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs/internal/cgroups
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs/internal/runtime
 | 
				
			||||||
 | 
					go.uber.org/automaxprocs/maxprocs
 | 
				
			||||||
# golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
					# golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
 | 
				
			||||||
## explicit
 | 
					## explicit
 | 
				
			||||||
golang.org/x/crypto/blake2b
 | 
					golang.org/x/crypto/blake2b
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue