Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <psteinhardt@gitlab.com>2020-12-09 16:56:47 +0300
committerPatrick Steinhardt <psteinhardt@gitlab.com>2020-12-09 16:56:47 +0300
commitea6022becb7e04a14cefeca1117730c7b5827eb3 (patch)
treec5be8bb74edcc9ea9471d53d5bce41c5fab38c29
parent4a654f393f40a9c92c81e6b315139f06c8689008 (diff)
parentc000a7a19cb7e6c47da811d8d0c96ffca77ba8a7 (diff)
Merge branch 'cgroups-impl' into 'master'
Add initial implementation of spawning git inside cgroups See merge request gitlab-org/gitaly!2819
-rw-r--r--NOTICE860
-rw-r--r--changelogs/unreleased/cgroups-impl.yml5
-rw-r--r--cmd/gitaly/main.go11
-rw-r--r--config.toml.example13
-rw-r--r--go.mod3
-rw-r--r--go.sum26
-rw-r--r--internal/cgroups/cgroups.go29
-rw-r--r--internal/cgroups/cgroups_test.go30
-rw-r--r--internal/cgroups/mock_test.go56
-rw-r--r--internal/cgroups/noop.go20
-rw-r--r--internal/cgroups/v1.go12
-rw-r--r--internal/cgroups/v1_linux.go113
-rw-r--r--internal/cgroups/v1_test.go133
-rw-r--r--internal/command/command.go5
-rw-r--r--internal/git/command.go39
-rw-r--r--internal/gitaly/config/cgroups/cgroups.go32
-rw-r--r--internal/gitaly/config/config.go29
-rw-r--r--internal/gitaly/config/config_test.go127
18 files changed, 1531 insertions, 12 deletions
diff --git a/NOTICE b/NOTICE
index 69589dcf6..b9e72d367 100644
--- a/NOTICE
+++ b/NOTICE
@@ -346,6 +346,412 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/containerd/cgroups
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ &#34;License&#34; shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ &#34;Licensor&#34; shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ &#34;Legal Entity&#34; 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,
+ &#34;control&#34; 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.
+
+ &#34;You&#34; (or &#34;Your&#34;) shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ &#34;Source&#34; form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ &#34;Object&#34; 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.
+
+ &#34;Work&#34; 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).
+
+ &#34;Derivative Works&#34; 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.
+
+ &#34;Contribution&#34; 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, &#34;submitted&#34;
+ 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 &#34;Not a Contribution.&#34;
+
+ &#34;Contributor&#34; 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:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) 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
+
+ (d) If the Work includes a &#34;NOTICE&#34; 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 &#34;AS IS&#34; 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 &#34;[]&#34;
+ replaced with your own identifying information. (Don&#39;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 &#34;printed page&#34; 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 &#34;License&#34;);
+ 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 &#34;AS IS&#34; 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.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/coreos/go-systemd/v22/dbus
+Apache License
+Version 2.0, January 2004
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+&#34;License&#34; shall mean the terms and conditions for use, reproduction, and
+distribution as defined by Sections 1 through 9 of this document.
+
+&#34;Licensor&#34; shall mean the copyright owner or entity authorized by the copyright
+owner that is granting the License.
+
+&#34;Legal Entity&#34; 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, &#34;control&#34; 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.
+
+&#34;You&#34; (or &#34;Your&#34;) shall mean an individual or Legal Entity exercising
+permissions granted by this License.
+
+&#34;Source&#34; form shall mean the preferred form for making modifications, including
+but not limited to software source code, documentation source, and configuration
+files.
+
+&#34;Object&#34; 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.
+
+&#34;Work&#34; 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).
+
+&#34;Derivative Works&#34; 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.
+
+&#34;Contribution&#34; 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,
+&#34;submitted&#34; 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 &#34;Not a Contribution.&#34;
+
+&#34;Contributor&#34; 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 &#34;NOTICE&#34; 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 &#34;AS IS&#34; 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 &#34;[]&#34; replaced with your own
+identifying information. (Don&#39;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 &#34;printed page&#34; 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 &#34;License&#34;);
+ 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 &#34;AS IS&#34; 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.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+NOTICE - github.com/coreos/go-systemd/v22/dbus
+CoreOS Project
+Copyright 2018 CoreOS, Inc
+
+This product includes software developed at CoreOS, Inc.
+(http://www.coreos.com/).
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - github.com/davecgh/go-spew/spew
ISC License
@@ -364,6 +770,200 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/docker/go-units
+
+ Apache License
+ Version 2.0, January 2004
+ https://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ &#34;License&#34; shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ &#34;Licensor&#34; shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ &#34;Legal Entity&#34; 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,
+ &#34;control&#34; 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.
+
+ &#34;You&#34; (or &#34;Your&#34;) shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ &#34;Source&#34; form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ &#34;Object&#34; 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.
+
+ &#34;Work&#34; 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).
+
+ &#34;Derivative Works&#34; 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.
+
+ &#34;Contribution&#34; 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, &#34;submitted&#34;
+ 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 &#34;Not a Contribution.&#34;
+
+ &#34;Contributor&#34; 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:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) 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
+
+ (d) If the Work includes a &#34;NOTICE&#34; 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 &#34;AS IS&#34; 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
+
+ Copyright 2015 Docker, Inc.
+
+ Licensed under the Apache License, Version 2.0 (the &#34;License&#34;);
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ https://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 &#34;AS IS&#34; 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.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - github.com/dpotapov/go-spnego
MIT License
@@ -556,6 +1156,72 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/godbus/dbus/v5
+Copyright (c) 2013, Georg Reinke (&lt;guelfey at gmail dot com&gt;), Google
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+&#34;AS IS&#34; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/gogo/protobuf
+Copyright (c) 2013, The GoGo Authors. All rights reserved.
+
+Protocol Buffers for Go with Gadgets
+
+Go support for Protocol Buffers - Google&#39;s data interchange format
+
+Copyright 2010 The Go Authors. All rights reserved.
+https://github.com/golang/protobuf
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+ * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+&#34;AS IS&#34; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - github.com/golang/groupcache/lru
Apache License
Version 2.0, January 2004
@@ -5113,6 +5779,200 @@ 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.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+LICENSE - github.com/opencontainers/runtime-spec/specs-go
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ &#34;License&#34; shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ &#34;Licensor&#34; shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ &#34;Legal Entity&#34; 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,
+ &#34;control&#34; 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.
+
+ &#34;You&#34; (or &#34;Your&#34;) shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ &#34;Source&#34; form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ &#34;Object&#34; 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.
+
+ &#34;Work&#34; 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).
+
+ &#34;Derivative Works&#34; 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.
+
+ &#34;Contribution&#34; 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, &#34;submitted&#34;
+ 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 &#34;Not a Contribution.&#34;
+
+ &#34;Contributor&#34; 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:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) 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
+
+ (d) If the Work includes a &#34;NOTICE&#34; 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 &#34;AS IS&#34; 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
+
+ Copyright 2015 The Linux Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the &#34;License&#34;);
+ 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 &#34;AS IS&#34; 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.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LICENSE - github.com/opentracing/opentracing-go
Apache License
Version 2.0, January 2004
diff --git a/changelogs/unreleased/cgroups-impl.yml b/changelogs/unreleased/cgroups-impl.yml
new file mode 100644
index 000000000..1d3869f3b
--- /dev/null
+++ b/changelogs/unreleased/cgroups-impl.yml
@@ -0,0 +1,5 @@
+---
+title: Add initial implementation of spawning git inside cgroups
+merge_request: 2819
+author:
+type: added
diff --git a/cmd/gitaly/main.go b/cmd/gitaly/main.go
index 9d4cc45c0..73f1a38fa 100644
--- a/cmd/gitaly/main.go
+++ b/cmd/gitaly/main.go
@@ -12,6 +12,7 @@ import (
"gitlab.com/gitlab-org/gitaly/client"
"gitlab.com/gitlab-org/gitaly/internal/bootstrap"
"gitlab.com/gitlab-org/gitaly/internal/bootstrap/starter"
+ "gitlab.com/gitlab-org/gitaly/internal/cgroups"
"gitlab.com/gitlab-org/gitaly/internal/git"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config/sentry"
@@ -80,6 +81,16 @@ func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
+ cgroupsManager := cgroups.NewManager(config.Config.Cgroups)
+ if err := cgroupsManager.Setup(); err != nil {
+ log.WithError(err).Fatal("failed setting up cgroups")
+ }
+ defer func() {
+ if err := cgroupsManager.Cleanup(); err != nil {
+ log.WithError(err).Warn("error cleaning up cgroups")
+ }
+ }()
+
gitVersion, err := git.Version(ctx)
if err != nil {
log.WithError(err).Fatal("Git version detection")
diff --git a/config.toml.example b/config.toml.example
index befe90a37..f3312072c 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -117,3 +117,16 @@ self_signed_cert = false
# start_minute = 30
# duration = "45m"
# storages = ["default"]
+
+# [cgroups]
+# count = 10
+# mountpoint = "/sys/fs/cgroup"
+# hierarchy_root = "gitaly"
+
+# [cgroups.memory]
+# enabled = true
+# limit = 1048576
+
+# [cgroups.cpu]
+# enabled = true
+# shares = 512
diff --git a/go.mod b/go.mod
index 622e9b6bb..fcfb688f1 100644
--- a/go.mod
+++ b/go.mod
@@ -3,9 +3,9 @@ module gitlab.com/gitlab-org/gitaly
require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cloudflare/tableflip v1.2.1-0.20200514155827-4baec9811f2b
+ github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99
github.com/getsentry/sentry-go v0.7.0
github.com/git-lfs/git-lfs v1.5.1-0.20200916154635-9ea4eed5b112
- github.com/gogo/protobuf v1.2.1 // indirect
github.com/golang/protobuf v1.3.2
github.com/google/uuid v1.1.1
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0
@@ -17,6 +17,7 @@ require (
github.com/libgit2/git2go/v30 v30.0.18
github.com/mattn/go-isatty v0.0.12 // indirect
github.com/olekukonko/tablewriter v0.0.2
+ github.com/opencontainers/runtime-spec v1.0.2
github.com/opentracing/opentracing-go v1.2.0
github.com/otiai10/curr v1.0.0 // indirect
github.com/pelletier/go-toml v1.8.1
diff --git a/go.sum b/go.sum
index 66012ac13..bb845cf78 100644
--- a/go.sum
+++ b/go.sum
@@ -50,6 +50,7 @@ github.com/certifi/gocertifi v0.0.0-20180905225744-ee1a9a0726d2/go.mod h1:GJKEex
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
+github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/client9/reopen v1.0.0 h1:8tpLVR74DLpLObrn2KvsyxJY++2iORGR17WLUdSzUws=
github.com/client9/reopen v1.0.0/go.mod h1:caXVCEr+lUtoN1FlsRiOWdfQtdRHIYfcb0ai8qKWtkQ=
@@ -59,10 +60,16 @@ github.com/cloudflare/tableflip v1.2.1-0.20200514155827-4baec9811f2b/go.mod h1:v
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
+github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99 h1:8aDph9eB64Upszigf7VXsoA8NVHNQMpbo8luXmT6DkM=
+github.com/containerd/cgroups v0.0.0-20201118023556-2819c83ced99/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd/v22 v22.0.0 h1:XJIw/+VlJ+87J+doOxznsAWIdmWuViOVhkQamW5YV28=
+github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+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/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=
@@ -70,6 +77,8 @@ github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xb
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
+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/dpotapov/go-spnego v0.0.0-20190506202455-c2c609116ad0 h1:Hhh7nu7CfFVlnBJqmDDUh+j1H5fqjLMzM4czZzNNJGM=
github.com/dpotapov/go-spnego v0.0.0-20190506202455-c2c609116ad0/go.mod h1:P4f4MSk7h52F2PK0lCapn5+fu47Uf8aRdxDSqgezxZE=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
@@ -123,10 +132,12 @@ github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kE
github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo=
github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
+github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME=
+github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.1.1 h1:72R+M5VuhED/KujmZVcIquuo8mBgX4oVda//DQb3PXo=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
-github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
@@ -213,7 +224,7 @@ github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6i
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM=
github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
-github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
@@ -287,6 +298,8 @@ github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
+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/opentracing/opentracing-go v1.0.2 h1:3jA2P6O1F9UOrWVpwrIo17pu01KWvNWg4X946/Y5Zwg=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
@@ -318,6 +331,8 @@ github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
@@ -348,6 +363,7 @@ github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlp
github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086 h1:mncRSDOqYCng7jOD+Y6+IivdRI6Kzv2BLWYkWkdQfu0=
github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35 h1:eajwn6K3weW5cd1ZXLu2sJ4pvwlBiCWY4uDejOr73gM=
github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0=
@@ -404,6 +420,7 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
+github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
@@ -543,6 +560,7 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1 h1:gZpLHxUX5BdYLA08Lj4YCJNN/jk7KtquiArPoeX0WvA=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f h1:6Sc1XOXTulBN6imkqo6XoAXDEzoQ4/ro6xy7Vn8+rOM=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -556,9 +574,9 @@ golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
-golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
diff --git a/internal/cgroups/cgroups.go b/internal/cgroups/cgroups.go
new file mode 100644
index 000000000..9251a0fba
--- /dev/null
+++ b/internal/cgroups/cgroups.go
@@ -0,0 +1,29 @@
+package cgroups
+
+import (
+ "gitlab.com/gitlab-org/gitaly/internal/command"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
+)
+
+// Manager supplies an interface for interacting with cgroups
+type Manager interface {
+ // Setup creates cgroups and assigns configured limitations.
+ // It is expected to be called once at Gitaly startup from any
+ // instance of the Manager.
+ Setup() error
+ // AddCommand adds a Command to a cgroup
+ AddCommand(*command.Command) error
+ // Cleanup cleans up cgroups created in Setup.
+ // It is expected to be called once at Gitaly shutdown from any
+ // instance of the Manager.
+ Cleanup() error
+}
+
+// NewManager returns the appropriate Cgroups manager
+func NewManager(cfg cgroups.Config) Manager {
+ if cfg.Count > 0 {
+ return newV1Manager(cfg)
+ }
+
+ return &NoopManager{}
+}
diff --git a/internal/cgroups/cgroups_test.go b/internal/cgroups/cgroups_test.go
new file mode 100644
index 000000000..f4494573e
--- /dev/null
+++ b/internal/cgroups/cgroups_test.go
@@ -0,0 +1,30 @@
+package cgroups
+
+import (
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+)
+
+func TestMain(m *testing.M) {
+ os.Exit(testMain(m))
+}
+
+func testMain(m *testing.M) int {
+ defer testhelper.MustHaveNoChildProcess()
+
+ cleanup := testhelper.Configure()
+ defer cleanup()
+
+ return m.Run()
+}
+
+func TestNewManager(t *testing.T) {
+ cfg := cgroups.Config{Count: 10}
+
+ require.IsType(t, &CGroupV1Manager{}, &CGroupV1Manager{cfg: cfg})
+ require.IsType(t, &NoopManager{}, NewManager(cgroups.Config{}))
+}
diff --git a/internal/cgroups/mock_test.go b/internal/cgroups/mock_test.go
new file mode 100644
index 000000000..6376cbf4b
--- /dev/null
+++ b/internal/cgroups/mock_test.go
@@ -0,0 +1,56 @@
+/*
+ Adapted from https://github.com/containerd/cgroups/blob/f1d9380fd3c028194db9582825512fdf3f39ab2a/mock_test.go
+
+ 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"
+ "path/filepath"
+ "testing"
+
+ "github.com/containerd/cgroups"
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/testhelper"
+)
+
+type mockCgroup struct {
+ root string
+ subsystems []cgroups.Subsystem
+}
+
+func newMock(t *testing.T) (*mockCgroup, func()) {
+ t.Helper()
+
+ root, clean := testhelper.TempDir(t)
+
+ subsystems, err := defaultSubsystems(root)
+ require.NoError(t, err)
+
+ for _, s := range subsystems {
+ require.NoError(t, os.MkdirAll(filepath.Join(root, string(s.Name())), os.FileMode(0755)))
+ }
+
+ return &mockCgroup{
+ root: root,
+ subsystems: subsystems,
+ }, clean
+}
+
+func (m *mockCgroup) hierarchy() ([]cgroups.Subsystem, error) {
+ return m.subsystems, nil
+}
diff --git a/internal/cgroups/noop.go b/internal/cgroups/noop.go
new file mode 100644
index 000000000..49c0f68f1
--- /dev/null
+++ b/internal/cgroups/noop.go
@@ -0,0 +1,20 @@
+package cgroups
+
+import (
+ "gitlab.com/gitlab-org/gitaly/internal/command"
+)
+
+// NoopManager is a cgroups manager that does nothing
+type NoopManager struct{}
+
+func (cg *NoopManager) Setup() error {
+ return nil
+}
+
+func (cg *NoopManager) AddCommand(cmd *command.Command) error {
+ return nil
+}
+
+func (cg *NoopManager) Cleanup() error {
+ return nil
+}
diff --git a/internal/cgroups/v1.go b/internal/cgroups/v1.go
new file mode 100644
index 000000000..68ad87a8e
--- /dev/null
+++ b/internal/cgroups/v1.go
@@ -0,0 +1,12 @@
+// +build !linux
+
+package cgroups
+
+import (
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
+)
+
+// For systems other than Linux, we return a noop manager if cgroups was enabled.
+func newV1Manager(cfg cgroups.Config) *NoopManager {
+ return &NoopManager{}
+}
diff --git a/internal/cgroups/v1_linux.go b/internal/cgroups/v1_linux.go
new file mode 100644
index 000000000..436b4d97a
--- /dev/null
+++ b/internal/cgroups/v1_linux.go
@@ -0,0 +1,113 @@
+package cgroups
+
+import (
+ "fmt"
+ "hash/crc32"
+ "strings"
+
+ "github.com/containerd/cgroups"
+ specs "github.com/opencontainers/runtime-spec/specs-go"
+ "gitlab.com/gitlab-org/gitaly/internal/command"
+ cgroupscfg "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
+)
+
+// CGroupV1Manager is the manager for cgroups v1
+type CGroupV1Manager struct {
+ cfg cgroupscfg.Config
+ hierarchy func() ([]cgroups.Subsystem, error)
+}
+
+func newV1Manager(cfg cgroupscfg.Config) *CGroupV1Manager {
+ return &CGroupV1Manager{
+ cfg: cfg,
+ hierarchy: func() ([]cgroups.Subsystem, error) {
+ return defaultSubsystems(cfg.Mountpoint)
+ },
+ }
+}
+
+func (cg *CGroupV1Manager) Setup() error {
+ resources := &specs.LinuxResources{}
+
+ if cg.cfg.CPU.Enabled {
+ resources.CPU = &specs.LinuxCPU{
+ Shares: &cg.cfg.CPU.Shares,
+ }
+ }
+
+ if cg.cfg.Memory.Enabled {
+ resources.Memory = &specs.LinuxMemory{
+ Limit: &cg.cfg.Memory.Limit,
+ }
+ }
+
+ for i := 0; i < int(cg.cfg.Count); i++ {
+ _, err := cgroups.New(cg.hierarchy, cgroups.StaticPath(cg.cgroupPath(i)), resources)
+ if err != nil {
+ return fmt.Errorf("failed creating cgroup: %w", err)
+ }
+ }
+
+ return nil
+}
+
+func (cg *CGroupV1Manager) AddCommand(cmd *command.Command) error {
+ checksum := crc32.ChecksumIEEE([]byte(strings.Join(cmd.Args(), "")))
+ groupID := uint(checksum) % cg.cfg.Count
+ cgroupPath := cg.cgroupPath(int(groupID))
+
+ control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(cgroupPath))
+ if err != nil {
+ return fmt.Errorf("failed loading %s cgroup: %w", cgroupPath, err)
+ }
+
+ if err := control.Add(cgroups.Process{Pid: cmd.Pid()}); err != nil {
+ // Command could finish so quickly before we can add it to a cgroup, so
+ // we don't consider it an error.
+ if strings.Contains(err.Error(), "no such process") {
+ return nil
+ }
+ return fmt.Errorf("failed adding process to cgroup: %w", err)
+ }
+
+ return nil
+}
+
+func (cg *CGroupV1Manager) Cleanup() error {
+ var failures []string
+
+ for i := 0; i < int(cg.cfg.Count); i++ {
+ cgroupPath := cg.cgroupPath(i)
+ control, err := cgroups.Load(cg.hierarchy, cgroups.StaticPath(cgroupPath))
+ if err != nil {
+ failure := fmt.Sprintf("%s: %v", cgroupPath, err)
+ failures = append(failures, failure)
+ continue
+ }
+
+ if err := control.Delete(); err != nil {
+ failure := fmt.Sprintf("%s: %v", cgroupPath, err)
+ failures = append(failures, failure)
+ continue
+ }
+ }
+
+ if len(failures) > 0 {
+ return fmt.Errorf("failed cleaning up cgroups: %s", strings.Join(failures, ","))
+ }
+
+ return nil
+}
+
+func (cg *CGroupV1Manager) cgroupPath(groupID int) string {
+ return fmt.Sprintf("/%s/gitaly-%d", cg.cfg.HierarchyRoot, groupID)
+}
+
+func defaultSubsystems(root string) ([]cgroups.Subsystem, error) {
+ subsystems := []cgroups.Subsystem{
+ cgroups.NewMemory(root),
+ cgroups.NewCpu(root),
+ }
+
+ return subsystems, nil
+}
diff --git a/internal/cgroups/v1_test.go b/internal/cgroups/v1_test.go
new file mode 100644
index 000000000..da0039a2b
--- /dev/null
+++ b/internal/cgroups/v1_test.go
@@ -0,0 +1,133 @@
+package cgroups
+
+import (
+ "context"
+ "fmt"
+ "hash/crc32"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/command"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
+)
+
+func defaultCgroupsConfig() cgroups.Config {
+ return cgroups.Config{
+ Count: 3,
+ HierarchyRoot: "gitaly",
+ CPU: cgroups.CPU{
+ Enabled: true,
+ Shares: 256,
+ },
+ Memory: cgroups.Memory{
+ Enabled: true,
+ Limit: 1024000,
+ },
+ }
+}
+
+func TestSetup(t *testing.T) {
+ mock, clean := newMock(t)
+ defer clean()
+
+ v1Manager := &CGroupV1Manager{
+ cfg: defaultCgroupsConfig(),
+ hierarchy: mock.hierarchy,
+ }
+ require.NoError(t, v1Manager.Setup())
+
+ for i := 0; i < 3; i++ {
+ memoryPath := filepath.Join(
+ mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", i), "memory.limit_in_bytes",
+ )
+ memoryContent := readCgroupFile(t, memoryPath)
+
+ require.Equal(t, string(memoryContent), "1024000")
+
+ cpuPath := filepath.Join(
+ mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", i), "cpu.shares",
+ )
+ cpuContent := readCgroupFile(t, cpuPath)
+
+ require.Equal(t, string(cpuContent), "256")
+ }
+}
+
+func TestAddCommand(t *testing.T) {
+ mock, clean := newMock(t)
+ defer clean()
+
+ config := defaultCgroupsConfig()
+ v1Manager1 := &CGroupV1Manager{
+ cfg: config,
+ hierarchy: mock.hierarchy,
+ }
+ require.NoError(t, v1Manager1.Setup())
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ cmd1 := exec.Command("ls", "-hal", ".")
+ cmd2, err := command.New(ctx, cmd1, nil, nil, nil)
+ require.NoError(t, err)
+ require.NoError(t, cmd2.Wait())
+
+ v1Manager2 := &CGroupV1Manager{
+ cfg: config,
+ hierarchy: mock.hierarchy,
+ }
+ require.NoError(t, v1Manager2.AddCommand(cmd2))
+
+ checksum := crc32.ChecksumIEEE([]byte(strings.Join(cmd2.Args(), "")))
+ groupID := uint(checksum) % config.Count
+
+ for _, s := range mock.subsystems {
+ path := filepath.Join(mock.root, string(s.Name()), "gitaly", fmt.Sprintf("gitaly-%d", groupID), "cgroup.procs")
+ content := readCgroupFile(t, path)
+
+ pid, err := strconv.Atoi(string(content))
+ require.NoError(t, err)
+
+ require.Equal(t, cmd2.Pid(), pid)
+ }
+}
+
+func TestCleanup(t *testing.T) {
+ mock, clean := newMock(t)
+ defer clean()
+
+ v1Manager := &CGroupV1Manager{
+ cfg: defaultCgroupsConfig(),
+ hierarchy: mock.hierarchy,
+ }
+ require.NoError(t, v1Manager.Setup())
+ require.NoError(t, v1Manager.Cleanup())
+
+ for i := 0; i < 3; i++ {
+ memoryPath := filepath.Join(mock.root, "memory", "gitaly", fmt.Sprintf("gitaly-%d", i))
+ cpuPath := filepath.Join(mock.root, "cpu", "gitaly", fmt.Sprintf("gitaly-%d", i))
+
+ require.NoDirExists(t, memoryPath)
+ require.NoDirExists(t, cpuPath)
+ }
+}
+
+func readCgroupFile(t *testing.T, path string) []byte {
+ t.Helper()
+
+ // The cgroups package defaults to permission 0 as it expects the file to be existing (the kernel creates the file)
+ // and its testing override the permission private variable to something sensible, hence we have to chmod ourselves
+ // so we can read the file.
+ require.NoError(t, os.Chmod(path, 0666))
+
+ content, err := ioutil.ReadFile(path)
+ require.NoError(t, err)
+
+ return content
+}
diff --git a/internal/command/command.go b/internal/command/command.go
index 7ba78459c..028b8eb38 100644
--- a/internal/command/command.go
+++ b/internal/command/command.go
@@ -475,6 +475,11 @@ func (c *Command) Env() []string {
return c.cmd.Env
}
+// Pid is an accessor for the pid
+func (c *Command) Pid() int {
+ return c.cmd.Process.Pid
+}
+
// suppressedContext suppresses cancellation or expiration of the context.
type suppressedContext struct{ context.Context }
diff --git a/internal/git/command.go b/internal/git/command.go
index 6bfda7546..d4c7e883a 100644
--- a/internal/git/command.go
+++ b/internal/git/command.go
@@ -4,6 +4,7 @@ import (
"context"
"os/exec"
+ "gitlab.com/gitlab-org/gitaly/internal/cgroups"
"gitlab.com/gitlab-org/gitaly/internal/command"
"gitlab.com/gitlab-org/gitaly/internal/git/alternates"
"gitlab.com/gitlab-org/gitaly/internal/git/repository"
@@ -13,15 +14,20 @@ import (
// CommandFactory knows how to properly construct different types of commands.
type CommandFactory struct {
- locator storage.Locator
- cfg config.Cfg
+ locator storage.Locator
+ cfg config.Cfg
+ cgroupsManager cgroups.Manager
}
// NewCommandFactory returns a new instance of initialized CommandFactory.
// Current implementation relies on the global var 'config.Config' and a single type of 'Locator' we currently have.
// This dependency will be removed on the next iterations in scope of: https://gitlab.com/gitlab-org/gitaly/-/issues/2699
func NewCommandFactory() *CommandFactory {
- return &CommandFactory{cfg: config.Config, locator: config.NewLocator(config.Config)}
+ return &CommandFactory{
+ cfg: config.Config,
+ locator: config.NewLocator(config.Config),
+ cgroupsManager: cgroups.NewManager(config.Config.Cgroups),
+ }
}
func (cf *CommandFactory) gitPath() string {
@@ -69,14 +75,33 @@ func (cf *CommandFactory) argsAndEnv(repo repository.GitRepo, args ...string) ([
func (cf *CommandFactory) unsafeBareCmd(ctx context.Context, stream CmdStream, env []string, args ...string) (*command.Command, error) {
env = append(env, command.GitEnv...)
- return command.New(ctx, exec.Command(cf.gitPath(), args...), stream.In, stream.Out, stream.Err, env...)
+ cmd, err := command.New(ctx, exec.Command(cf.gitPath(), args...), stream.In, stream.Out, stream.Err, env...)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := cf.cgroupsManager.AddCommand(cmd); err != nil {
+ return nil, err
+ }
+
+ return cmd, err
}
// unsafeBareCmdInDir calls unsafeBareCmd in dir.
func (cf *CommandFactory) unsafeBareCmdInDir(ctx context.Context, dir string, stream CmdStream, env []string, args ...string) (*command.Command, error) {
env = append(env, command.GitEnv...)
- cmd := exec.Command(cf.gitPath(), args...)
- cmd.Dir = dir
- return command.New(ctx, cmd, stream.In, stream.Out, stream.Err, env...)
+ cmd1 := exec.Command(cf.gitPath(), args...)
+ cmd1.Dir = dir
+
+ cmd2, err := command.New(ctx, cmd1, stream.In, stream.Out, stream.Err, env...)
+ if err != nil {
+ return nil, err
+ }
+
+ if err := cf.cgroupsManager.AddCommand(cmd2); err != nil {
+ return nil, err
+ }
+
+ return cmd2, nil
}
diff --git a/internal/gitaly/config/cgroups/cgroups.go b/internal/gitaly/config/cgroups/cgroups.go
new file mode 100644
index 000000000..dcfcdd571
--- /dev/null
+++ b/internal/gitaly/config/cgroups/cgroups.go
@@ -0,0 +1,32 @@
+package cgroups
+
+// Config is a struct for cgroups config
+type Config struct {
+ // Count is the number of cgroups to be created at startup
+ Count uint `toml:"count"`
+ // Mountpoint is where the cgroup filesystem is mounted, usually under /sys/fs/cgroup/
+ Mountpoint string `toml:"mountpoint"`
+ // HierarchyRoot is the parent cgroup under which Gitaly creates <Count> of cgroups.
+ // A system administrator is expected to create such cgroup/directory under <Mountpoint>/memory
+ // and/or <Mountpoint>/cpu depending on which resource is enabled. HierarchyRoot is expected to
+ // be owned by the user and group Gitaly runs as.
+ HierarchyRoot string `toml:"hierarchy_root"`
+ // CPU holds CPU resource configurations
+ CPU CPU `toml:"cpu"`
+ // Memory holds memory resource configurations
+ Memory Memory `toml:"memory"`
+}
+
+// Memory is a struct storing cgroups memory config
+type Memory struct {
+ Enabled bool `toml:"enabled"`
+ // Limit is the memory limit in bytes. Could be -1 to indicate unlimited memory.
+ Limit int64 `toml:"limit"`
+}
+
+// CPU is a struct storing cgroups CPU config
+type CPU struct {
+ Enabled bool `toml:"enabled"`
+ // Shares is the number of CPU shares (relative weight (ratio) vs. other cgroups with CPU shares).
+ Shares uint64 `toml:"shares"`
+}
diff --git a/internal/gitaly/config/config.go b/internal/gitaly/config/config.go
index 3d718904e..7ca472daf 100644
--- a/internal/gitaly/config/config.go
+++ b/internal/gitaly/config/config.go
@@ -16,6 +16,7 @@ import (
"github.com/pelletier/go-toml"
log "github.com/sirupsen/logrus"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config/auth"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
internallog "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/log"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config/prometheus"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config/sentry"
@@ -59,6 +60,7 @@ type Cfg struct {
GracefulRestartTimeout Duration `toml:"graceful_restart_timeout"`
InternalSocketDir string `toml:"internal_socket_dir"`
DailyMaintenance DailyJob `toml:"daily_maintenance"`
+ Cgroups cgroups.Config `toml:"cgroups"`
}
// TLS configuration
@@ -170,6 +172,7 @@ func (cfg *Cfg) Validate() error {
cfg.validateInternalSocketDir,
cfg.validateHooks,
cfg.validateMaintenance,
+ cfg.validateCgroups,
} {
if err := run(); err != nil {
return err
@@ -475,3 +478,29 @@ func (cfg *Cfg) validateMaintenance() error {
return nil
}
+
+func (cfg *Cfg) validateCgroups() error {
+ cg := cfg.Cgroups
+
+ if cg.Count == 0 {
+ return nil
+ }
+
+ if cg.Mountpoint == "" {
+ return fmt.Errorf("cgroups mountpoint cannot be empty")
+ }
+
+ if cg.HierarchyRoot == "" {
+ return fmt.Errorf("cgroups hierarchy root cannot be empty")
+ }
+
+ if cg.CPU.Enabled && cg.CPU.Shares == 0 {
+ return fmt.Errorf("cgroups CPU shares has to be greater than zero")
+ }
+
+ if cg.Memory.Enabled && (cg.Memory.Limit == 0 || cg.Memory.Limit < -1) {
+ return fmt.Errorf("cgroups memory limit has to be greater than zero or equal to -1")
+ }
+
+ return nil
+}
diff --git a/internal/gitaly/config/config_test.go b/internal/gitaly/config/config_test.go
index ff46ff564..3133560a8 100644
--- a/internal/gitaly/config/config_test.go
+++ b/internal/gitaly/config/config_test.go
@@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+ "gitlab.com/gitlab-org/gitaly/internal/gitaly/config/cgroups"
"gitlab.com/gitlab-org/gitaly/internal/gitaly/config/sentry"
)
@@ -818,3 +819,129 @@ storages = ["default"]
})
}
}
+
+func TestValidateCgroups(t *testing.T) {
+ for _, tt := range []struct {
+ name string
+ rawCfg string
+ expect cgroups.Config
+ validateErr error
+ }{
+ {
+ name: "enabled success",
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = "/sys/fs/cgroup"
+ hierarchy_root = "gitaly"
+ [cgroups.memory]
+ enabled = true
+ limit = 1024
+ [cgroups.cpu]
+ enabled = true
+ shares = 512`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "/sys/fs/cgroup",
+ HierarchyRoot: "gitaly",
+ Memory: cgroups.Memory{
+ Enabled: true,
+ Limit: 1024,
+ },
+ CPU: cgroups.CPU{
+ Enabled: true,
+ Shares: 512,
+ },
+ },
+ }, {
+ name: "disabled success",
+ rawCfg: `[cgroups]
+ count = 0`,
+ expect: cgroups.Config{
+ Count: 0,
+ },
+ },
+ {
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = ""`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "",
+ },
+ validateErr: errors.New("cgroups mountpoint cannot be empty"),
+ }, {
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = "/sys/fs/cgroup"
+ hierarchy_root = ""`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "/sys/fs/cgroup",
+ HierarchyRoot: "",
+ },
+ validateErr: errors.New("cgroups hierarchy root cannot be empty"),
+ }, {
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = "/sys/fs/cgroup"
+ hierarchy_root = "gitaly"
+ [cgroups.cpu]
+ enabled = true
+ shares = 0`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "/sys/fs/cgroup",
+ HierarchyRoot: "gitaly",
+ CPU: cgroups.CPU{
+ Enabled: true,
+ Shares: 0,
+ },
+ },
+ validateErr: errors.New("cgroups CPU shares has to be greater than zero"),
+ }, {
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = "/sys/fs/cgroup"
+ hierarchy_root = "gitaly"
+ [cgroups.memory]
+ enabled = true
+ limit = 0`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "/sys/fs/cgroup",
+ HierarchyRoot: "gitaly",
+ Memory: cgroups.Memory{
+ Enabled: true,
+ Limit: 0,
+ },
+ },
+ validateErr: errors.New("cgroups memory limit has to be greater than zero or equal to -1"),
+ }, {
+ rawCfg: `[cgroups]
+ count = 10
+ mountpoint = "/sys/fs/cgroup"
+ hierarchy_root = "gitaly"
+ [cgroups.memory]
+ enabled = true
+ limit = -5`,
+ expect: cgroups.Config{
+ Count: 10,
+ Mountpoint: "/sys/fs/cgroup",
+ HierarchyRoot: "gitaly",
+ Memory: cgroups.Memory{
+ Enabled: true,
+ Limit: -5,
+ },
+ },
+ validateErr: errors.New("cgroups memory limit has to be greater than zero or equal to -1"),
+ },
+ } {
+ t.Run(tt.name, func(t *testing.T) {
+ tmpFile := strings.NewReader(tt.rawCfg)
+ cfg, err := Load(tmpFile)
+ require.NoError(t, err)
+ require.Equal(t, tt.expect, cfg.Cgroups)
+ require.Equal(t, tt.validateErr, cfg.validateCgroups())
+ })
+ }
+}