├── .editorconfig ├── .fixtures.yml ├── .github ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md ├── labeler.yml ├── release.yml └── workflows │ ├── ci.yml │ ├── labeler.yml │ ├── prepare_release.yml │ └── release.yml ├── .gitignore ├── .msync.yml ├── .overcommit.yml ├── .pmtignore ├── .puppet-lint.rc ├── .rubocop.yml ├── .rubocop_todo.yml ├── .sync.yml ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── README.md ├── REFERENCE.md ├── Rakefile ├── data ├── defaults.yaml └── family │ ├── RedHat.yaml │ └── Suse.yaml ├── hiera.yaml ├── lib ├── puppet │ └── functions │ │ └── gitlab_ci_runner │ │ ├── register.rb │ │ ├── register_to_file.rb │ │ ├── to_toml.rb │ │ ├── unregister.rb │ │ └── unregister_from_file.rb └── puppet_x │ └── gitlab │ ├── dumper.rb │ └── runner.rb ├── manifests ├── config.pp ├── init.pp ├── install.pp ├── repo.pp ├── runner.pp └── service.pp ├── metadata.json ├── scripts ├── start-gitlab.sh └── start-squid.sh ├── spec ├── acceptance │ ├── bolt_tasks_spec.rb │ ├── class_spec.rb │ ├── gitlab_ci_runner_spec.rb │ └── runner_spec.rb ├── classes │ └── gitlab_ci_runner_spec.rb ├── defines │ └── runner_spec.rb ├── functions │ ├── register_spec.rb │ ├── register_to_file_spec.rb │ ├── to_toml_spec.rb │ ├── unregister_from_file_spec.rb │ └── unregister_spec.rb ├── setup_acceptance_node.pp ├── spec_helper.rb ├── spec_helper_acceptance.rb ├── spec_helper_local.rb ├── tasks │ ├── register_runner_spec.rb │ └── unregister_runner_spec.rb ├── type_aliases │ ├── log_format_spec.rb │ ├── log_level_spec.rb │ └── session_server_spec.rb └── unit │ └── puppet_x │ └── gitlab │ └── runner_spec.rb ├── tasks ├── register_runner.json ├── register_runner.rb ├── unregister_runner.json └── unregister_runner.rb └── types ├── keyserver.pp ├── log_format.pp ├── log_level.pp ├── register.pp ├── register_parameters.pp └── session_server.pp /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | # Managed by modulesync - DO NOT EDIT 4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 5 | 6 | root = true 7 | 8 | [*] 9 | charset = utf-8 10 | end_of_line = lf 11 | indent_size = 2 12 | tab_width = 2 13 | indent_style = space 14 | insert_final_newline = true 15 | trim_trailing_whitespace = true 16 | -------------------------------------------------------------------------------- /.fixtures.yml: -------------------------------------------------------------------------------- 1 | --- 2 | fixtures: 3 | repositories: 4 | stdlib: "https://github.com/puppetlabs/puppetlabs-stdlib.git" 5 | apt: "https://github.com/puppetlabs/puppetlabs-apt.git" 6 | concat: "https://github.com/puppetlabs/puppetlabs-concat.git" 7 | docker: "https://github.com/puppetlabs/puppetlabs-docker.git" 8 | ruby_task_helper: "https://github.com/puppetlabs/puppetlabs-ruby_task_helper.git" 9 | translate: "https://github.com/puppetlabs/puppetlabs-translate.git" 10 | yumrepo_core: "https://github.com/puppetlabs/puppetlabs-yumrepo_core.git" 11 | archive: "https://github.com/voxpupuli/puppet-archive.git" 12 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution guidelines 2 | 3 | ## Table of contents 4 | 5 | * [Contributing](#contributing) 6 | * [Writing proper commits - short version](#writing-proper-commits-short-version) 7 | * [Writing proper commits - long version](#writing-proper-commits-long-version) 8 | * [Dependencies](#dependencies) 9 | * [Note for OS X users](#note-for-os-x-users) 10 | * [The test matrix](#the-test-matrix) 11 | * [Syntax and style](#syntax-and-style) 12 | * [Running the unit tests](#running-the-unit-tests) 13 | * [Unit tests in docker](#unit-tests-in-docker) 14 | * [Integration tests](#integration-tests) 15 | 16 | This module has grown over time based on a range of contributions from 17 | people using it. If you follow these contributing guidelines your patch 18 | will likely make it into a release a little more quickly. 19 | 20 | ## Contributing 21 | 22 | Please note that this project is released with a Contributor Code of Conduct. 23 | By participating in this project you agree to abide by its terms. 24 | [Contributor Code of Conduct](https://voxpupuli.org/coc/). 25 | 26 | * Fork the repo. 27 | * Create a separate branch for your change. 28 | * We only take pull requests with passing tests, and documentation. [GitHub Actions](https://docs.github.com/en/actions) run the tests for us. You can also execute them locally. This is explained [in a later section](#the-test-matrix). 29 | * Checkout [our docs](https://voxpupuli.org/docs/reviewing_pr/) we use to review a module and the [official styleguide](https://puppet.com/docs/puppet/6.0/style_guide.html). They provide some guidance for new code that might help you before you submit a pull request. 30 | * Add a test for your change. Only refactoring and documentation changes require no new tests. If you are adding functionality or fixing a bug, please add a test. 31 | * Squash your commits down into logical components. Make sure to rebase against our current master. 32 | * Push the branch to your fork and submit a pull request. 33 | 34 | Please be prepared to repeat some of these steps as our contributors review your code. 35 | 36 | Also consider sending in your profile code that calls this component module as an acceptance test or provide it via an issue. This helps reviewers a lot to test your use case and prevents future regressions! 37 | 38 | ## Writing proper commits - short version 39 | 40 | * Make commits of logical units. 41 | * Check for unnecessary whitespace with "git diff --check" before committing. 42 | * Commit using Unix line endings (check the settings around "crlf" in git-config(1)). 43 | * Do not check in commented out code or unneeded files. 44 | * The first line of the commit message should be a short description (50 characters is the soft limit, excluding ticket number(s)), and should skip the full stop. 45 | * Associate the issue in the message. The first line should include the issue number in the form "(#XXXX) Rest of message". 46 | * The body should provide a meaningful commit message, which: 47 | *uses the imperative, present tense: `change`, not `changed` or `changes`. 48 | * includes motivation for the change, and contrasts its implementation with the previous behavior. 49 | * Make sure that you have tests for the bug you are fixing, or feature you are adding. 50 | * Make sure the test suites passes after your commit: 51 | * When introducing a new feature, make sure it is properly documented in the README.md 52 | 53 | ## Writing proper commits - long version 54 | 55 | 1. Make separate commits for logically separate changes. 56 | 57 | Please break your commits down into logically consistent units 58 | which include new or changed tests relevant to the rest of the 59 | change. The goal of doing this is to make the diff easier to 60 | read for whoever is reviewing your code. In general, the easier 61 | your diff is to read, the more likely someone will be happy to 62 | review it and get it into the code base. 63 | 64 | If you are going to refactor a piece of code, please do so as a 65 | separate commit from your feature or bug fix changes. 66 | 67 | We also really appreciate changes that include tests to make 68 | sure the bug is not re-introduced, and that the feature is not 69 | accidentally broken. 70 | 71 | Describe the technical detail of the change(s). If your 72 | description starts to get too long, that is a good sign that you 73 | probably need to split up your commit into more finely grained 74 | pieces. 75 | 76 | Commits which plainly describe the things which help 77 | reviewers check the patch and future developers understand the 78 | code are much more likely to be merged in with a minimum of 79 | bike-shedding or requested changes. Ideally, the commit message 80 | would include information, and be in a form suitable for 81 | inclusion in the release notes for the version of Puppet that 82 | includes them. 83 | 84 | Please also check that you are not introducing any trailing 85 | whitespace or other "whitespace errors". You can do this by 86 | running "git diff --check" on your changes before you commit. 87 | 88 | 2. Sending your patches 89 | 90 | To submit your changes via a GitHub pull request, we _highly_ 91 | recommend that you have them on a topic branch, instead of 92 | directly on `master`. 93 | It makes things much easier to keep track of, especially if 94 | you decide to work on another thing before your first change 95 | is merged in. 96 | 97 | GitHub has some pretty good 98 | [general documentation](http://help.github.com/) on using 99 | their site. They also have documentation on 100 | [creating pull requests](http://help.github.com/send-pull-requests/). 101 | 102 | In general, after pushing your topic branch up to your 103 | repository on GitHub, you can switch to the branch in the 104 | GitHub UI and click "Pull Request" towards the top of the page 105 | in order to open a pull request. 106 | 107 | 108 | 3. Update the related GitHub issue. 109 | 110 | If there is a GitHub issue associated with the change you 111 | submitted, then you should update the ticket to include the 112 | location of your branch, along with any other commentary you 113 | may wish to make. 114 | 115 | ## Dependencies 116 | 117 | The testing and development tools have a bunch of dependencies, 118 | all managed by [bundler](http://bundler.io/) according to the 119 | [Puppet support matrix](http://docs.puppetlabs.com/guides/platforms.html#ruby-versions). 120 | 121 | By default the tests use a baseline version of Puppet. 122 | 123 | If you have Ruby 2.x or want a specific version of Puppet, 124 | you must set an environment variable such as: 125 | 126 | ```sh 127 | export PUPPET_GEM_VERSION="~> 6.1.0" 128 | ``` 129 | 130 | You can install all needed gems for spec tests into the modules directory by 131 | running: 132 | 133 | ```sh 134 | bundle config set --local path '.vendor/' 135 | bundle config set --local without 'development system_tests release' 136 | bundle install --jobs "$(nproc)" 137 | ``` 138 | 139 | If you also want to run acceptance tests: 140 | 141 | ```sh 142 | bundle config set --local path '.vendor/' 143 | bundle config set --local without 'development release' 144 | bundle config set --local with 'system_tests' 145 | bundle install --jobs "$(nproc)" 146 | ``` 147 | 148 | Our all in one solution if you don't know if you need to install or update gems: 149 | 150 | ```sh 151 | bundle config set --local path '.vendor/' 152 | bundle config set --local without 'development release' 153 | bundle config set --local with 'system_tests' 154 | bundle install --jobs "$(nproc)" 155 | bundle update 156 | bundle clean 157 | ``` 158 | 159 | As an alternative to the `--jobs "$(nproc)` parameter, you can set an 160 | environment variable: 161 | 162 | ```sh 163 | BUNDLE_JOBS="$(nproc)" 164 | ``` 165 | 166 | ### Note for OS X users 167 | 168 | `nproc` isn't a valid command under OS x. As an alternative, you can do: 169 | 170 | ```sh 171 | --jobs "$(sysctl -n hw.ncpu)" 172 | ``` 173 | 174 | ## The test matrix 175 | 176 | ### Syntax and style 177 | 178 | The test suite will run [Puppet Lint](http://puppet-lint.com/) and 179 | [Puppet Syntax](https://github.com/gds-operations/puppet-syntax) to 180 | check various syntax and style things. You can run these locally with: 181 | 182 | ```sh 183 | bundle exec rake lint 184 | bundle exec rake validate 185 | ``` 186 | 187 | It will also run some [Rubocop](http://batsov.com/rubocop/) tests 188 | against it. You can run those locally ahead of time with: 189 | 190 | ```sh 191 | bundle exec rake rubocop 192 | ``` 193 | 194 | ### Running the unit tests 195 | 196 | The unit test suite covers most of the code, as mentioned above please 197 | add tests if you're adding new functionality. If you've not used 198 | [rspec-puppet](http://rspec-puppet.com/) before then feel free to ask 199 | about how best to test your new feature. 200 | 201 | To run the linter, the syntax checker and the unit tests: 202 | 203 | ```sh 204 | bundle exec rake test 205 | ``` 206 | 207 | To run your all the unit tests 208 | 209 | ```sh 210 | bundle exec rake spec 211 | ``` 212 | 213 | To run a specific spec test set the `SPEC` variable: 214 | 215 | ```sh 216 | bundle exec rake spec SPEC=spec/foo_spec.rb 217 | ``` 218 | 219 | #### Unit tests in docker 220 | 221 | Some people don't want to run the dependencies locally or don't want to install 222 | ruby. We ship a Dockerfile that enables you to run all unit tests and linting. 223 | You only need to run: 224 | 225 | ```sh 226 | docker build . 227 | ``` 228 | 229 | Please ensure that a docker daemon is running and that your user has the 230 | permission to talk to it. You can specify a remote docker host by setting the 231 | `DOCKER_HOST` environment variable. it will copy the content of the module into 232 | the docker image. So it will not work if a Gemfile.lock exists. 233 | 234 | ### Integration tests 235 | 236 | The unit tests just check the code runs, not that it does exactly what 237 | we want on a real machine. For that we're using 238 | [beaker](https://github.com/puppetlabs/beaker). 239 | 240 | This fires up a new virtual machine (using vagrant) and runs a series of 241 | simple tests against it after applying the module. You can run this 242 | with: 243 | 244 | ```sh 245 | BEAKER_PUPPET_COLLECTION=puppet7 BEAKER_setfile=debian11-64 bundle exec rake beaker 246 | ``` 247 | 248 | or 249 | 250 | ```sh 251 | BEAKER_PUPPET_COLLECTION=none BEAKER_setfile=archlinux-64 bundle exec rake beaker 252 | ``` 253 | 254 | This latter example will use the distribution's own version of Puppet. 255 | 256 | You can replace the string `debian11` with any common operating system. 257 | The following strings are known to work: 258 | 259 | * ubuntu2004 260 | * ubuntu2204 261 | * debian11 262 | * debian12 263 | * centos9 264 | * archlinux 265 | * almalinux8 266 | * almalinux9 267 | * fedora36 268 | 269 | For more information and tips & tricks, see [voxpupuli-acceptance's documentation](https://github.com/voxpupuli/voxpupuli-acceptance#running-tests). 270 | 271 | The source of this file is in our [modulesync_config](https://github.com/voxpupuli/modulesync_config/blob/master/moduleroot/.github/CONTRIBUTING.md.erb) 272 | repository. 273 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ## Affected Puppet, Ruby, OS and module versions/distributions 12 | 13 | - Puppet: 14 | - Ruby: 15 | - Distribution: 16 | - Module version: 17 | 18 | ## How to reproduce (e.g Puppet code you use) 19 | 20 | ## What are you seeing 21 | 22 | ## What behaviour did you expect instead 23 | 24 | ## Output log 25 | 26 | ## Any additional information you'd like to impart 27 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 9 | #### Pull Request (PR) description 10 | 13 | 14 | #### This Pull Request (PR) fixes the following issues 15 | 21 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | skip-changelog: 6 | - head-branch: ['^release-*', 'release'] 7 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | # https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes 6 | 7 | changelog: 8 | exclude: 9 | labels: 10 | - duplicate 11 | - invalid 12 | - modulesync 13 | - question 14 | - skip-changelog 15 | - wont-fix 16 | - wontfix 17 | 18 | categories: 19 | - title: Breaking Changes 🛠 20 | labels: 21 | - backwards-incompatible 22 | 23 | - title: New Features 🎉 24 | labels: 25 | - enhancement 26 | 27 | - title: Bug Fixes 🐛 28 | labels: 29 | - bug 30 | 31 | - title: Documentation Updates 📚 32 | labels: 33 | - documentation 34 | - docs 35 | 36 | - title: Dependency Updates ⬆️ 37 | labels: 38 | - dependencies 39 | 40 | - title: Other Changes 41 | labels: 42 | - "*" 43 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # (NOT) Managed by modulesync??? 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: CI 6 | 7 | on: pull_request 8 | 9 | concurrency: 10 | group: ${{ github.ref_name }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | setup_matrix: 15 | name: 'Setup Test Matrix' 16 | runs-on: ubuntu-latest 17 | timeout-minutes: 40 18 | outputs: 19 | puppet_unit_test_matrix: ${{ steps.get-outputs.outputs.puppet_unit_test_matrix }} 20 | puppet_beaker_test_matrix: ${{ steps.get-outputs.outputs.puppet_beaker_test_matrix }} 21 | env: 22 | BUNDLE_WITHOUT: development:system_tests:release 23 | PUPPET_GEM_VERSION: ">= 7.0" 24 | steps: 25 | - uses: actions/checkout@v4 26 | - name: Setup ruby 27 | uses: ruby/setup-ruby@v1 28 | with: 29 | ruby-version: '3.3' 30 | bundler-cache: true 31 | - name: Run static validations 32 | run: bundle exec rake validate lint check 33 | - name: Run rake rubocop 34 | run: bundle exec rake rubocop 35 | - name: Setup Test Matrix 36 | id: get-outputs 37 | run: bundle exec metadata2gha --pidfile-workaround false 38 | 39 | unit: 40 | needs: setup_matrix 41 | runs-on: ubuntu-latest 42 | timeout-minutes: 40 43 | strategy: 44 | fail-fast: false 45 | matrix: 46 | include: ${{fromJson(needs.setup_matrix.outputs.puppet_unit_test_matrix)}} 47 | env: 48 | BUNDLE_WITHOUT: development:system_tests:release 49 | PUPPET_VERSION: "~> ${{ matrix.puppet }}.0" 50 | name: Puppet ${{ matrix.puppet }} (Ruby ${{ matrix.ruby }}) 51 | steps: 52 | - uses: actions/checkout@v4 53 | - name: Setup ruby 54 | uses: ruby/setup-ruby@v1 55 | with: 56 | ruby-version: ${{ matrix.ruby }} 57 | bundler-cache: true 58 | - name: Create task helper symlink 59 | run: ln -s puppet-gitlab_ci_runner/spec/fixtures/modules/ruby_task_helper ../ 60 | - name: Run tests 61 | run: bundle exec rake parallel_spec 62 | 63 | acceptance: 64 | needs: setup_matrix 65 | runs-on: ubuntu-24.04 66 | env: 67 | BUNDLE_WITHOUT: development:test:release 68 | strategy: 69 | fail-fast: false 70 | matrix: 71 | include: ${{fromJson(needs.setup_matrix.outputs.puppet_beaker_test_matrix)}} 72 | name: "${{ matrix.name }}" 73 | steps: 74 | - uses: actions/checkout@v4 75 | - name: Setup ruby 76 | uses: ruby/setup-ruby@v1 77 | with: 78 | ruby-version: '3.3' 79 | bundler-cache: true 80 | - name: Start gitlab 81 | run: ./scripts/start-gitlab.sh 82 | - name: Start squid 83 | run: ./scripts/start-squid.sh 84 | - name: Run tests 85 | run: bundle exec rake beaker 86 | env: ${{ matrix.env }} 87 | - name: squid logs 88 | run: docker logs squid --tail 50 89 | if: always() 90 | 91 | 92 | tests: 93 | needs: 94 | - unit 95 | - acceptance 96 | runs-on: ubuntu-latest 97 | name: Test suite 98 | steps: 99 | - run: echo Test suite completed 100 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: "Pull Request Labeler" 6 | 7 | # yamllint disable-line rule:truthy 8 | on: 9 | pull_request_target: {} 10 | 11 | jobs: 12 | labeler: 13 | permissions: 14 | contents: read 15 | pull-requests: write 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/labeler@v5 19 | -------------------------------------------------------------------------------- /.github/workflows/prepare_release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: 'Prepare Release' 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | version: 11 | description: 'Module version to be released. Must be a valid semver string without leading v. (1.2.3)' 12 | required: false 13 | 14 | jobs: 15 | release_prep: 16 | uses: 'voxpupuli/gha-puppet/.github/workflows/prepare_release.yml@v3' 17 | with: 18 | version: ${{ github.event.inputs.version }} 19 | allowed_owner: 'voxpupuli' 20 | secrets: 21 | # Configure secrets here: 22 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets 23 | github_pat: '${{ secrets.PCCI_PAT_RELEASE_PREP }}' 24 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | name: Release 6 | 7 | # yamllint disable-line rule:truthy 8 | on: 9 | push: 10 | tags: 11 | - '*' 12 | 13 | jobs: 14 | release: 15 | name: Release 16 | uses: voxpupuli/gha-puppet/.github/workflows/release.yml@v3 17 | with: 18 | allowed_owner: 'voxpupuli' 19 | secrets: 20 | # Configure secrets here: 21 | # https://docs.github.com/en/actions/security-guides/encrypted-secrets 22 | username: ${{ secrets.PUPPET_FORGE_USERNAME }} 23 | api_key: ${{ secrets.PUPPET_FORGE_API_KEY }} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | /pkg/ 5 | /Gemfile.lock 6 | /Gemfile.local 7 | /vendor/ 8 | /.vendor/ 9 | /spec/fixtures/manifests/ 10 | /spec/fixtures/modules/ 11 | /.vagrant/ 12 | /.bundle/ 13 | /.ruby-version 14 | /coverage/ 15 | /log/ 16 | /.idea/ 17 | /.dependencies/ 18 | /.librarian/ 19 | /Puppetfile.lock 20 | *.iml 21 | .*.sw? 22 | /.yardoc/ 23 | /Guardfile 24 | bolt-debug.log 25 | .rerun.json 26 | -------------------------------------------------------------------------------- /.msync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | modulesync_config_version: '9.5.0' 6 | -------------------------------------------------------------------------------- /.overcommit.yml: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | # 4 | # Hooks are only enabled if you take action. 5 | # 6 | # To enable the hooks run: 7 | # 8 | # ``` 9 | # bundle exec overcommit --install 10 | # # ensure .overcommit.yml does not harm to you and then 11 | # bundle exec overcommit --sign 12 | # ``` 13 | # 14 | # (it will manage the .git/hooks directory): 15 | # 16 | # Examples howto skip a test for a commit or push: 17 | # 18 | # ``` 19 | # SKIP=RuboCop git commit 20 | # SKIP=PuppetLint git commit 21 | # SKIP=RakeTask git push 22 | # ``` 23 | # 24 | # Don't invoke overcommit at all: 25 | # 26 | # ``` 27 | # OVERCOMMIT_DISABLE=1 git commit 28 | # ``` 29 | # 30 | # Read more about overcommit: https://github.com/brigade/overcommit 31 | # 32 | # To manage this config yourself in your module add 33 | # 34 | # ``` 35 | # .overcommit.yml: 36 | # unmanaged: true 37 | # ``` 38 | # 39 | # to your modules .sync.yml config 40 | --- 41 | PreCommit: 42 | RuboCop: 43 | enabled: true 44 | description: 'Runs rubocop on modified files only' 45 | command: ['bundle', 'exec', 'rubocop'] 46 | RakeTarget: 47 | enabled: true 48 | description: 'Runs lint on modified files only' 49 | targets: 50 | - 'lint' 51 | command: ['bundle', 'exec', 'rake'] 52 | YamlSyntax: 53 | enabled: true 54 | JsonSyntax: 55 | enabled: true 56 | TrailingWhitespace: 57 | enabled: true 58 | 59 | PrePush: 60 | RakeTarget: 61 | enabled: true 62 | description: 'Run rake targets' 63 | targets: 64 | - 'validate' 65 | - 'test' 66 | - 'rubocop' 67 | command: ['bundle', 'exec', 'rake'] 68 | -------------------------------------------------------------------------------- /.pmtignore: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | /docs/ 5 | /pkg/ 6 | /Gemfile 7 | /Gemfile.lock 8 | /Gemfile.local 9 | /vendor/ 10 | /.vendor/ 11 | /spec/ 12 | /Rakefile 13 | /.vagrant/ 14 | /.bundle/ 15 | /.ruby-version 16 | /coverage/ 17 | /log/ 18 | /.idea/ 19 | /.dependencies/ 20 | /.github/ 21 | /.librarian/ 22 | /Puppetfile.lock 23 | /Puppetfile 24 | *.iml 25 | /.editorconfig 26 | /.fixtures.yml 27 | /.gitignore 28 | /.msync.yml 29 | /.overcommit.yml 30 | /.pmtignore 31 | /.rspec 32 | /.rspec_parallel 33 | /.rubocop.yml 34 | /.sync.yml 35 | .*.sw? 36 | /.yardoc/ 37 | /.yardopts 38 | /Dockerfile 39 | /HISTORY.md 40 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | --fail-on-warnings 5 | --no-parameter_documentation-check 6 | --no-parameter_types-check 7 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Managed by modulesync - DO NOT EDIT 3 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 4 | 5 | inherit_from: .rubocop_todo.yml 6 | inherit_gem: 7 | voxpupuli-test: rubocop.yml 8 | -------------------------------------------------------------------------------- /.rubocop_todo.yml: -------------------------------------------------------------------------------- 1 | # This configuration was generated by 2 | # `rubocop --auto-gen-config` 3 | # on 2023-08-17 21:32:43 UTC using RuboCop version 1.50.2. 4 | # The point is for the user to remove these configuration records 5 | # one by one as the offenses are removed from the code base. 6 | # Note that changes in the inspected code, or installation of new 7 | # versions of RuboCop, may require this file to be generated again. 8 | 9 | # Offense count: 5 10 | # This cop supports unsafe autocorrection (--autocorrect-all). 11 | RSpec/BeEq: 12 | Exclude: 13 | - 'spec/functions/register_spec.rb' 14 | - 'spec/functions/register_to_file_spec.rb' 15 | - 'spec/functions/to_toml_spec.rb' 16 | - 'spec/functions/unregister_from_file_spec.rb' 17 | - 'spec/functions/unregister_spec.rb' 18 | 19 | # Offense count: 1 20 | # This cop supports unsafe autocorrection (--autocorrect-all). 21 | # Configuration parameters: MinBranchesCount. 22 | Style/CaseLikeIf: 23 | Exclude: 24 | - 'lib/puppet_x/gitlab/dumper.rb' 25 | 26 | # Offense count: 3 27 | # This cop supports unsafe autocorrection (--autocorrect-all). 28 | # Configuration parameters: Mode. 29 | Style/StringConcatenation: 30 | Exclude: 31 | - 'lib/puppet_x/gitlab/dumper.rb' 32 | -------------------------------------------------------------------------------- /.sync.yml: -------------------------------------------------------------------------------- 1 | --- 2 | Gemfile: 3 | optional: 4 | ':test': 5 | - gem: 'webmock' 6 | - gem: puppet-lint-param-docs 7 | spec/spec_helper.rb: 8 | spec_overrides: 9 | - require 'spec_helper_local' 10 | .github/workflows/ci.yml: 11 | unmanaged: true 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | Each new release typically also includes the latest modulesync defaults. 5 | These should not affect the functionality of the module. 6 | 7 | ## [v6.1.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v6.1.0) (2025-02-11) 8 | 9 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v6.0.0...v6.1.0) 10 | 11 | **Merged pull requests:** 12 | 13 | - puppetlabs/apt: Allow 10.x [\#214](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/214) ([bastelfreak](https://github.com/bastelfreak)) 14 | 15 | ## [v6.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v6.0.0) (2024-11-22) 16 | 17 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v5.1.0...v6.0.0) 18 | 19 | **Breaking changes:** 20 | 21 | - Drop EoL CentOS 8 support [\#204](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/204) ([bastelfreak](https://github.com/bastelfreak)) 22 | - Upgrade Github CI and drop RHEL 7-based operating systems [\#193](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/193) ([yakatz](https://github.com/yakatz)) 23 | - Drop Debian 10 and Ubuntu 18.04 support [\#191](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/191) ([traylenator](https://github.com/traylenator)) 24 | - Use apt keyring on Debian [\#189](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/189) ([jonhattan](https://github.com/jonhattan)) 25 | 26 | **Implemented enhancements:** 27 | 28 | - Enable gpgcheck for YUM RPM based Distributions [\#205](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/205) ([traylenator](https://github.com/traylenator)) 29 | - Add Ubuntu 24.04 support [\#203](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/203) ([bastelfreak](https://github.com/bastelfreak)) 30 | - Avoid use of lsb facts [\#200](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/200) ([traylenator](https://github.com/traylenator)) 31 | - Add basic SuSE support [\#194](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/194) ([tuxmea](https://github.com/tuxmea)) 32 | - register\_to\_file: Support Sensitive `regtoken` [\#164](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/164) ([arusso](https://github.com/arusso)) 33 | 34 | **Merged pull requests:** 35 | 36 | - Respect bolt\_supported from beaker\_helper [\#211](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/211) ([traylenator](https://github.com/traylenator)) 37 | - Rename spec files so they run [\#210](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/210) ([traylenator](https://github.com/traylenator)) 38 | - doc: clarify requirements for Docker [\#209](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/209) ([kjetilho](https://github.com/kjetilho)) 39 | 40 | ## [v5.1.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v5.1.0) (2023-12-04) 41 | 42 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v5.0.0...v5.1.0) 43 | 44 | **Implemented enhancements:** 45 | 46 | - Add shutdown\_timeout parameter [\#182](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/182) ([wardhus](https://github.com/wardhus)) 47 | - Add Puppet 8 support [\#173](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/173) ([bastelfreak](https://github.com/bastelfreak)) 48 | 49 | ## [v5.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v5.0.0) (2023-10-17) 50 | 51 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.4.0...v5.0.0) 52 | 53 | **Breaking changes:** 54 | 55 | - Replace deprecated ensure\_packages\(\) with stdlib::ensure\_packages\(\) [\#180](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/180) ([bastelfreak](https://github.com/bastelfreak)) 56 | - Drop Debian 9 \(EOL\) [\#170](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/170) ([smortex](https://github.com/smortex)) 57 | - Drop Puppet 6 support [\#168](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/168) ([bastelfreak](https://github.com/bastelfreak)) 58 | 59 | **Implemented enhancements:** 60 | 61 | - Replace legacy merge\(\) with native puppet code [\#179](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/179) ([bastelfreak](https://github.com/bastelfreak)) 62 | - Add EL9 support [\#175](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/175) ([bastelfreak](https://github.com/bastelfreak)) 63 | - Add AlmaLinux/Rocky support [\#174](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/174) ([bastelfreak](https://github.com/bastelfreak)) 64 | - Relax dependencies version requirements [\#171](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/171) ([smortex](https://github.com/smortex)) 65 | 66 | **Fixed bugs:** 67 | 68 | - Fix broken apt::source declaration for Debian-based systems [\#142](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/142) ([logicminds](https://github.com/logicminds)) 69 | 70 | **Merged pull requests:** 71 | 72 | - .fixtures.yml: Drop puppet 6 leftovers [\#178](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/178) ([bastelfreak](https://github.com/bastelfreak)) 73 | - Fix acceptance tests [\#165](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/165) ([smortex](https://github.com/smortex)) 74 | - Fix broken Apache-2 license [\#163](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/163) ([bastelfreak](https://github.com/bastelfreak)) 75 | 76 | ## [v4.4.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.4.0) (2022-12-14) 77 | 78 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.3.1...v4.4.0) 79 | 80 | **Implemented enhancements:** 81 | 82 | - Add Ubuntu 22.04 support [\#160](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/160) ([bastelfreak](https://github.com/bastelfreak)) 83 | - check for presence of specifed ca\_file [\#159](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/159) ([bastelfreak](https://github.com/bastelfreak)) 84 | - Add extra logging when registering/unregistering [\#157](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/157) ([bastelfreak](https://github.com/bastelfreak)) 85 | - Allow up-to-date dependencies [\#154](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/154) ([smortex](https://github.com/smortex)) 86 | - Add Debian 11 support [\#122](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/122) ([bastelfreak](https://github.com/bastelfreak)) 87 | 88 | ## [v4.3.1](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.3.1) (2022-06-20) 89 | 90 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.3.0...v4.3.1) 91 | 92 | **Fixed bugs:** 93 | 94 | - Ubuntu 18 Puppet 6: Install lsb-release during CI [\#151](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/151) ([bastelfreak](https://github.com/bastelfreak)) 95 | - Set ca\_file per runner [\#150](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/150) ([tuxmea](https://github.com/tuxmea)) 96 | 97 | **Merged pull requests:** 98 | 99 | - Remove temp directories in docs [\#143](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/143) ([logicminds](https://github.com/logicminds)) 100 | - Fix puppet markup [\#140](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/140) ([smortex](https://github.com/smortex)) 101 | 102 | ## [v4.3.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.3.0) (2022-01-20) 103 | 104 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.2.0...v4.3.0) 105 | 106 | **Implemented enhancements:** 107 | 108 | - Implement support for config file/dir permission management. [\#95](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/95) ([UiP9AV6Y](https://github.com/UiP9AV6Y)) 109 | 110 | **Merged pull requests:** 111 | 112 | - toml gem: apply upstream changes [\#139](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/139) ([bastelfreak](https://github.com/bastelfreak)) 113 | 114 | ## [v4.2.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.2.0) (2021-12-06) 115 | 116 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.1.0...v4.2.0) 117 | 118 | **Closed issues:** 119 | 120 | - Certificate verify failed on update to v4.0.0 [\#124](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/124) 121 | 122 | **Merged pull requests:** 123 | 124 | - Add `ca_file` parameter for use during registration [\#135](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/135) ([alexjfisher](https://github.com/alexjfisher)) 125 | 126 | ## [v4.1.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.1.0) (2021-11-04) 127 | 128 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v4.0.0...v4.1.0) 129 | 130 | **Implemented enhancements:** 131 | 132 | - Make session\_server section configurable [\#132](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/132) ([baurmatt](https://github.com/baurmatt)) 133 | 134 | **Merged pull requests:** 135 | 136 | - Add puppet-lint-param-docs [\#121](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/121) ([bastelfreak](https://github.com/bastelfreak)) 137 | 138 | ## [v4.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v4.0.0) (2021-08-26) 139 | 140 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v3.0.0...v4.0.0) 141 | 142 | Version 4.0.0 is a new major release of this module. It has many improvements but also significant breaking changes that you should read about and test before deploying into a production environment. Specifically Puppet 6 is required, your code will probably need updating and existing runners will reregister. 143 | 144 | The [README ](https://github.com/voxpupuli/puppet-gitlab_ci_runner/blob/383db3524e7cd3eac13755da251ef1871290f941/README.md#upgrading-from-version-3)has further details. 145 | 146 | Huge thanks to all our contributors and especially to [Matthias Baur](https://github.com/baurmatt) for his excellent contributions to this release. 147 | 148 | **Breaking changes:** 149 | 150 | - Drop RHEL/CentOS 6 and Amazon Linux Support [\#118](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/118) 151 | - Deprecate support for Debian 8 and Ubuntu 16.04 \(and add support for Ubuntu 20.04\) [\#114](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/114) ([alexjfisher](https://github.com/alexjfisher)) 152 | - Add support for registration by leveraging a "Deferred" function [\#107](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/107) ([baurmatt](https://github.com/baurmatt)) 153 | - Move to concat for config.toml [\#75](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/75) ([baurmatt](https://github.com/baurmatt)) 154 | 155 | **Implemented enhancements:** 156 | 157 | - Support Puppet 7 [\#116](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/116) ([alexjfisher](https://github.com/alexjfisher)) 158 | - Add runner registration proxy support [\#109](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/109) ([alexjfisher](https://github.com/alexjfisher)) 159 | - Allow `hkp://` style URLs for `repo_keyserver` URL [\#102](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/102) ([hp197](https://github.com/hp197)) 160 | 161 | **Fixed bugs:** 162 | 163 | - Fix runner unregistering [\#111](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/111) ([alexjfisher](https://github.com/alexjfisher)) 164 | - Fix unregistering runner with `ensure => absent` [\#110](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/110) ([alexjfisher](https://github.com/alexjfisher)) 165 | 166 | **Closed issues:** 167 | 168 | - Get acceptance tests setup and running [\#20](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/20) 169 | 170 | **Merged pull requests:** 171 | 172 | - Allow up-to-date dependencies [\#117](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/117) ([smortex](https://github.com/smortex)) 173 | - Update README with upgrade information [\#115](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/115) ([alexjfisher](https://github.com/alexjfisher)) 174 | - Update module dependencies [\#112](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/112) ([alexjfisher](https://github.com/alexjfisher)) 175 | - Fix typos in README.md [\#94](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/94) ([nikitasg](https://github.com/nikitasg)) 176 | 177 | ## [v3.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v3.0.0) (2020-09-15) 178 | 179 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v2.1.0...v3.0.0) 180 | 181 | **Breaking changes:** 182 | 183 | - Make manage\_docker optional and include the docker module if used [\#80](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/80) ([baurmatt](https://github.com/baurmatt)) 184 | 185 | **Implemented enhancements:** 186 | 187 | - Allow management of check\_interval config setting [\#91](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/91) ([tuxmea](https://github.com/tuxmea)) 188 | - Add support for CentOS 8, Debian 10 [\#87](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/87) ([dhoppe](https://github.com/dhoppe)) 189 | 190 | **Merged pull requests:** 191 | 192 | - Fix CI problems [\#89](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/89) ([carljohnstone](https://github.com/carljohnstone)) 193 | - Switch from Ubuntu Trusty to Ubuntu Focal [\#88](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/88) ([carljohnstone](https://github.com/carljohnstone)) 194 | - Use voxpupuli-acceptance [\#83](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/83) ([ekohl](https://github.com/ekohl)) 195 | 196 | ## [v2.1.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v2.1.0) (2020-04-07) 197 | 198 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v2.0.0...v2.1.0) 199 | 200 | **Implemented enhancements:** 201 | 202 | - Use new gitlab gpg keys for package management [\#84](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/84) ([dhoppe](https://github.com/dhoppe)) 203 | 204 | **Closed issues:** 205 | 206 | - Release new version [\#58](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/58) 207 | 208 | ## [v2.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v2.0.0) (2020-02-06) 209 | 210 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/v1.0.0...v2.0.0) 211 | 212 | **Breaking changes:** 213 | 214 | - Completely refactor gitlab\_ci\_runner::runner [\#74](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/74) ([baurmatt](https://github.com/baurmatt)) 215 | - drop Ubuntu support [\#60](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/60) ([bastelfreak](https://github.com/bastelfreak)) 216 | - modulesync 2.7.0 and drop puppet 4 [\#39](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/39) ([bastelfreak](https://github.com/bastelfreak)) 217 | 218 | **Implemented enhancements:** 219 | 220 | - Module should manage build\_dir and cache\_dir [\#33](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/33) 221 | - Add bolt task to register/unregister a runner [\#73](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/73) ([baurmatt](https://github.com/baurmatt)) 222 | - Add Amazon Linux support \(RedHat OS Family\) [\#70](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/70) ([bFekete](https://github.com/bFekete)) 223 | - Add listen\_address parameter [\#65](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/65) ([baurmatt](https://github.com/baurmatt)) 224 | - Add custom repo [\#48](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/48) ([lupintrd](https://github.com/lupintrd)) 225 | - Add support for current releases [\#41](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/41) ([dhoppe](https://github.com/dhoppe)) 226 | - Fix xz dependency on RedHat systems [\#40](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/40) ([smortex](https://github.com/smortex)) 227 | 228 | **Fixed bugs:** 229 | 230 | - Multiple tags in tag-list are ignored only last is respected [\#37](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/37) 231 | - The package `xz-utils` is `xz` on CentOS [\#25](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/25) 232 | - Fix bugs which got introduced by to runner.pp refactoring [\#76](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/76) ([baurmatt](https://github.com/baurmatt)) 233 | - Fix runner name in unregister command [\#57](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/57) ([dcasella](https://github.com/dcasella)) 234 | - Use '=' to avoid errors while joining cmd options+values [\#31](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/31) ([ajcollett](https://github.com/ajcollett)) 235 | 236 | **Closed issues:** 237 | 238 | - registration\_token containing undescore gets modified [\#61](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/61) 239 | - /etc/gitlab-runner/config.toml must exist [\#35](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/35) 240 | - Metrics server and Session listen address' [\#26](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/26) 241 | 242 | **Merged pull requests:** 243 | 244 | - Extract resources out of init.pp [\#72](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/72) ([baurmatt](https://github.com/baurmatt)) 245 | - Allow puppetlabs/stdlib 6.x [\#71](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/71) ([dhoppe](https://github.com/dhoppe)) 246 | - Switch to puppet-strings for documentation [\#64](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/64) ([baurmatt](https://github.com/baurmatt)) 247 | - Use grep with --fixed-strings to avoid issues with some characters in the runner's names [\#63](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/63) ([Farfaday](https://github.com/Farfaday)) 248 | - Extend documentation in README with example tags [\#59](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/59) ([jacksgt](https://github.com/jacksgt)) 249 | - add limitations about the runner configurations [\#56](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/56) ([thde](https://github.com/thde)) 250 | - ensure config exists [\#53](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/53) ([thde](https://github.com/thde)) 251 | - Added suport for configuring sentry\_dsn [\#44](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/44) ([schewara](https://github.com/schewara)) 252 | - Allow ensure =\> "present" for runners [\#36](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/36) ([evhan](https://github.com/evhan)) 253 | - allow build\_dir and cache\_dir to be managed [\#34](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/34) ([slmagus](https://github.com/slmagus)) 254 | 255 | ## [v1.0.0](https://github.com/voxpupuli/puppet-gitlab_ci_runner/tree/v1.0.0) (2018-11-21) 256 | 257 | [Full Changelog](https://github.com/voxpupuli/puppet-gitlab_ci_runner/compare/a499e3dab7578847be6bba12baba63168b077bfa...v1.0.0) 258 | 259 | This is the first release of `puppet/gitlab_ci_runner`. The functionality in this module was previously part of [puppet/gitlab](https://github.com/voxpupuli/puppet-gitlab) 260 | 261 | **Fixed bugs:** 262 | 263 | - Fix \(un-\)registering runner with similar names [\#22](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/22) ([elkangaroo](https://github.com/elkangaroo)) 264 | 265 | **Closed issues:** 266 | 267 | - Import cirunner code from voxpupuli/puppet-gitlab module [\#12](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/12) 268 | - remove `apt` from dependencies [\#4](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/4) 269 | - Update license in metadata.json and add LiCENSE file [\#3](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/3) 270 | - Update ruby version in Dockerfile [\#2](https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/2) 271 | 272 | **Merged pull requests:** 273 | 274 | - modulesync 2.1.0 and allow puppet 6.x [\#23](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/23) ([bastelfreak](https://github.com/bastelfreak)) 275 | - allow puppetlabs/stdlib 5.x [\#19](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/19) ([bastelfreak](https://github.com/bastelfreak)) 276 | - initial import of puppet code [\#13](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/13) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 277 | - remove apt from metadata.json dependencies [\#10](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/10) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 278 | - Update ruby version in dockerfile [\#8](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/8) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 279 | - fix module name in metadata.json [\#6](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/6) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 280 | - update licensing information [\#5](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/5) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 281 | - modulesync setup [\#1](https://github.com/voxpupuli/puppet-gitlab_ci_runner/pull/1) ([LongLiveCHIEF](https://github.com/LongLiveCHIEF)) 282 | 283 | 284 | 285 | \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* 286 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 5 | 6 | group :test do 7 | gem 'voxpupuli-test', '~> 9.0', :require => false 8 | gem 'coveralls', :require => false 9 | gem 'simplecov-console', :require => false 10 | gem 'puppet_metadata', '~> 5.0', :require => false 11 | gem 'webmock', :require => false 12 | gem 'puppet-lint-param-docs', :require => false 13 | end 14 | 15 | group :development do 16 | gem 'guard-rake', :require => false 17 | gem 'overcommit', '>= 0.39.1', :require => false 18 | end 19 | 20 | group :system_tests do 21 | gem 'voxpupuli-acceptance', '~> 3.5', :require => false 22 | end 23 | 24 | group :release do 25 | gem 'voxpupuli-release', '~> 3.0', :require => false 26 | end 27 | 28 | gem 'rake', :require => false 29 | gem 'facter', ENV['FACTER_GEM_VERSION'], :require => false, :groups => [:test] 30 | 31 | puppetversion = ENV['PUPPET_GEM_VERSION'] || [">= 7.24", "< 9"] 32 | gem 'puppet', puppetversion, :require => false, :groups => [:test] 33 | 34 | # vim: syntax=ruby 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gitlab-CI runner module for Puppet 2 | 3 | [![Build Status](https://github.com/voxpupuli/puppet-gitlab_ci_runner/workflows/CI/badge.svg)](https://github.com/voxpupuli/puppet-gitlab_ci_runner/actions?query=workflow%3ACI) 4 | [![Release](https://github.com/voxpupuli/puppet-gitlab_ci_runner/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/puppet-gitlab_ci_runner/actions/workflows/release.yml) 5 | [![Puppet Forge](https://img.shields.io/puppetforge/v/puppet/gitlab_ci_runner.svg)](https://forge.puppetlabs.com/puppet/gitlab_ci_runner) 6 | [![Puppet Forge - downloads](https://img.shields.io/puppetforge/dt/puppet/gitlab_ci_runner.svg)](https://forge.puppetlabs.com/puppet/gitlab_ci_runner) 7 | [![Puppet Forge - endorsement](https://img.shields.io/puppetforge/e/puppet/gitlab_ci_runner.svg)](https://forge.puppetlabs.com/puppet/gitlab_ci_runner) 8 | [![Puppet Forge - scores](https://img.shields.io/puppetforge/f/puppet/gitlab_ci_runner.svg)](https://forge.puppetlabs.com/puppet/gitlab_ci_runner) 9 | [![puppetmodule.info docs](http://www.puppetmodule.info/images/badge.png)](http://www.puppetmodule.info/m/puppet-gitlab_ci_runner) 10 | [![Apache-2 License](https://img.shields.io/github/license/voxpupuli/puppet-gitlab_ci_runner.svg)](LICENSE) 11 | 12 | #### Table of Contents 13 | 14 | - [Gitlab-CI runner module for Puppet](#gitlab-ci-runner-module-for-puppet) 15 | - [Table of Contents](#table-of-contents) 16 | - [Overview](#overview) 17 | - [Usage](#usage) 18 | - [SLES](#sles) 19 | - [Upgrading from version 3](#upgrading-from-version-3) 20 | - [Limitations](#limitations) 21 | - [License](#license) 22 | 23 | ## Overview 24 | 25 | This module installs and configures the Gitlab CI Runner Package or nodes. 26 | 27 | ## Usage 28 | 29 | Here is an example how to configure Gitlab CI runners using Hiera: 30 | 31 | Set `$manage_docker` to false (the default) if Docker is not required (e.g., with `executor: "shell"`) or is managed by other means. 32 | 33 | Setting `$manage_docker` to true requires the [puppetlabs/docker](https://forge.puppetlabs.com/puppetlabs/docker) module. 34 | 35 | ```yaml 36 | gitlab_ci_runner::concurrent: 4 37 | 38 | gitlab_ci_runner::check_interval: 4 39 | 40 | gitlab_ci_runner::metrics_server: "localhost:8888" 41 | 42 | gitlab_ci_runner::manage_docker: true 43 | 44 | gitlab_ci_runner::config_path: "/etc/gitlab-runner/config.toml" 45 | 46 | gitlab_ci_runner::runners: 47 | test_runner1:{} 48 | test_runner2:{} 49 | test_runner3: 50 | url: "https://git.alternative.org/ci" 51 | registration-token: "abcdef1234567890" 52 | tag-list: "aws,docker,example-tag" 53 | ca_file: "/etc/pki/cert/foo.pem" 54 | 55 | gitlab_ci_runner::runner_defaults: 56 | url: "https://git.example.com/ci" 57 | registration-token: "1234567890abcdef" 58 | executor: "docker" 59 | docker: 60 | image: "ubuntu:focal" 61 | ``` 62 | 63 | To unregister a specific runner you may use `ensure` param: 64 | 65 | ```yaml 66 | gitlab_ci_runner::runners: 67 | test_runner1:{} 68 | test_runner2:{} 69 | test_runner3: 70 | url: "https://git.alternative.org/ci" 71 | registration-token: "abcdef1234567890" 72 | ensure: absent 73 | ``` 74 | 75 | ## SLES 76 | 77 | There are no gitlab_ci_runner repositories for SLES/zypper available! 78 | Instead one can use the go binary. 79 | This setup requires the [puppet-archive](https://github.com/voxpupuli/puppet-archive) module. 80 | 81 | Please set the following data to be able to use this module on SLES: 82 | 83 | ```yaml 84 | gitlab_ci_runner::install_method: 'binary' # required for SLES 85 | gitlab_ci_runner::binary_source: 'https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-linux-amd64' # default value 86 | gitlab_ci_runner::binary_path: '/usr/local/bin/gitlab-runner' # default value 87 | ``` 88 | 89 | ## Upgrading from version 3 90 | 91 | Version 4 of this module introduces some big changes. 92 | Puppet 6 or above is now **required** as the module now makes use of [Deferred Functions](https://puppet.com/docs/puppet/6/deferring_functions.html) when registering a runner. 93 | 94 | Previously the `gitlab_ci_runner::runner:config` was only used when a runner was registered. 95 | The configuration was used as the arguments to the runner `register` command, which would write the configuration file after registering with the gitlab server. 96 | Puppet did not manage this file directly. 97 | 98 | The module now manages the configuration file properly. 99 | That means, it's now possible to update most configuration settings *after* the initial registration, and more advanced configurations are supported. 100 | 101 | :warning: When upgrading, your runners will be **re-registered**. 102 | 103 | When upgrading to version 4 you may need to update some of your manifests accordingly. 104 | For example: 105 | 106 | ```puppet 107 | class { 'gitlab_ci_runner': 108 | # [...] 109 | runners => { 110 | 'my_runner' => { 111 | 'url' => 'https://gitlab.com/ci', 112 | 'registration-token' => 'abcdef1234567890', 113 | 'docker-image' => 'ubuntu:focal', 114 | }, 115 | }, 116 | } 117 | ``` 118 | 119 | would need to be converted to: 120 | 121 | ```puppet 122 | class { 'gitlab_ci_runner': 123 | # [...] 124 | runners => { 125 | 'my_runner' => { 126 | 'url' => 'https://gitlab.com', 127 | 'registration-token' => 'abcdef1234567890', 128 | 'docker' => { 129 | 'image' => 'ubuntu:focal', 130 | }, 131 | }, 132 | }, 133 | } 134 | ``` 135 | 136 | Configuration keys that are specific to registration, (such as `registration-token`, `run_untagged` etc.) are **not** written to the runner's configuration file, but are automatically extracted and used during registration only. 137 | Changing these after registration has no affect. 138 | 139 | ## Limitations 140 | 141 | For the current list of tested and support operating systems, please checkout the metadata.json file. 142 | 143 | It is currently not possible to alter registration specific configuration settings after a runner is registered. 144 | 145 | ## License 146 | 147 | [lib/puppet_x/gitlab/dumper.rb](lib/puppet_x/gitlab/dumper.rb) is licensed under MIT. All other code is licensed under Apache 2.0. 148 | -------------------------------------------------------------------------------- /REFERENCE.md: -------------------------------------------------------------------------------- 1 | # Reference 2 | 3 | 4 | 5 | ## Table of Contents 6 | 7 | ### Classes 8 | 9 | #### Public Classes 10 | 11 | * [`gitlab_ci_runner`](#gitlab_ci_runner): This module installs and configures Gitlab CI Runners. 12 | 13 | #### Private Classes 14 | 15 | * `gitlab_ci_runner::config`: Manages the configuration of Gitlab runner 16 | * `gitlab_ci_runner::install`: Manages the package of Gitlab runner 17 | * `gitlab_ci_runner::repo`: Manages the repository for Gitlab runner 18 | * `gitlab_ci_runner::service`: Manages the service of Gitlab runner 19 | 20 | ### Defined types 21 | 22 | * [`gitlab_ci_runner::runner`](#gitlab_ci_runner--runner): This configures a Gitlab CI runner. 23 | 24 | ### Functions 25 | 26 | * [`gitlab_ci_runner::register`](#gitlab_ci_runner--register): A function that registers a Gitlab runner on a Gitlab instance. Be careful, this will be triggered on noop runs as well! 27 | * [`gitlab_ci_runner::register_to_file`](#gitlab_ci_runner--register_to_file): A function that registers a Gitlab runner on a Gitlab instance, if it doesn't already exist, _and_ saves the retrieved authentication token t 28 | * [`gitlab_ci_runner::to_toml`](#gitlab_ci_runner--to_toml): Convert a data structure and output to TOML. 29 | * [`gitlab_ci_runner::unregister`](#gitlab_ci_runner--unregister): A function that unregisters a Gitlab runner from a Gitlab instance. Be careful, this will be triggered on noop runs as well! 30 | * [`gitlab_ci_runner::unregister_from_file`](#gitlab_ci_runner--unregister_from_file): A function that unregisters a Gitlab runner from a Gitlab instance, if the local token is there. This is meant to be used in conjunction with 31 | 32 | ### Data types 33 | 34 | * [`Gitlab_ci_runner::Keyserver`](#Gitlab_ci_runner--Keyserver): Type to match repo_keyserver Regex from: https://github.com/puppetlabs/puppetlabs-apt/blob/main/manifests/key.pp 35 | * [`Gitlab_ci_runner::Log_format`](#Gitlab_ci_runner--Log_format): Gitlab Runner log format configuration 36 | * [`Gitlab_ci_runner::Log_level`](#Gitlab_ci_runner--Log_level): Gitlab Runner log level configuration 37 | * [`Gitlab_ci_runner::Register`](#Gitlab_ci_runner--Register): A struct of all possible additionl options for gitlab_ci_runner::register 38 | * [`Gitlab_ci_runner::Register_parameters`](#Gitlab_ci_runner--Register_parameters): A enum containing a possible keys used for Gitlab runner registrations 39 | * [`Gitlab_ci_runner::Session_server`](#Gitlab_ci_runner--Session_server): Gitlab Runner session_server configuration 40 | 41 | ### Tasks 42 | 43 | * [`register_runner`](#register_runner): Registers a runner on a Gitlab instance. 44 | * [`unregister_runner`](#unregister_runner): Unregisters a runner from a Gitlab instance. 45 | 46 | ## Classes 47 | 48 | ### `gitlab_ci_runner` 49 | 50 | This module installs and configures Gitlab CI Runners. 51 | 52 | #### Examples 53 | 54 | ##### Simple runner registration 55 | 56 | ```puppet 57 | class { 'gitlab_ci_runner': 58 | runners => { 59 | example_runner => { 60 | 'registration-token' => 'gitlab-token', 61 | 'url' => 'https://gitlab.com', 62 | 'tag-list' => 'docker,aws', 63 | }, 64 | }, 65 | } 66 | ``` 67 | 68 | #### Parameters 69 | 70 | The following parameters are available in the `gitlab_ci_runner` class: 71 | 72 | * [`runners`](#-gitlab_ci_runner--runners) 73 | * [`runner_defaults`](#-gitlab_ci_runner--runner_defaults) 74 | * [`xz_package_name`](#-gitlab_ci_runner--xz_package_name) 75 | * [`concurrent`](#-gitlab_ci_runner--concurrent) 76 | * [`log_level`](#-gitlab_ci_runner--log_level) 77 | * [`log_format`](#-gitlab_ci_runner--log_format) 78 | * [`check_interval`](#-gitlab_ci_runner--check_interval) 79 | * [`shutdown_timeout`](#-gitlab_ci_runner--shutdown_timeout) 80 | * [`sentry_dsn`](#-gitlab_ci_runner--sentry_dsn) 81 | * [`listen_address`](#-gitlab_ci_runner--listen_address) 82 | * [`session_server`](#-gitlab_ci_runner--session_server) 83 | * [`manage_docker`](#-gitlab_ci_runner--manage_docker) 84 | * [`install_method`](#-gitlab_ci_runner--install_method) 85 | * [`binary_source`](#-gitlab_ci_runner--binary_source) 86 | * [`binary_path`](#-gitlab_ci_runner--binary_path) 87 | * [`manage_user`](#-gitlab_ci_runner--manage_user) 88 | * [`user`](#-gitlab_ci_runner--user) 89 | * [`group`](#-gitlab_ci_runner--group) 90 | * [`manage_repo`](#-gitlab_ci_runner--manage_repo) 91 | * [`package_ensure`](#-gitlab_ci_runner--package_ensure) 92 | * [`package_name`](#-gitlab_ci_runner--package_name) 93 | * [`repo_base_url`](#-gitlab_ci_runner--repo_base_url) 94 | * [`repo_keyserver`](#-gitlab_ci_runner--repo_keyserver) 95 | * [`config_path`](#-gitlab_ci_runner--config_path) 96 | * [`config_owner`](#-gitlab_ci_runner--config_owner) 97 | * [`config_group`](#-gitlab_ci_runner--config_group) 98 | * [`config_mode`](#-gitlab_ci_runner--config_mode) 99 | * [`manage_config_dir`](#-gitlab_ci_runner--manage_config_dir) 100 | * [`config_dir_mode`](#-gitlab_ci_runner--config_dir_mode) 101 | * [`http_proxy`](#-gitlab_ci_runner--http_proxy) 102 | * [`ca_file`](#-gitlab_ci_runner--ca_file) 103 | * [`repo_keysource`](#-gitlab_ci_runner--repo_keysource) 104 | * [`package_keysource`](#-gitlab_ci_runner--package_keysource) 105 | * [`package_gpgcheck`](#-gitlab_ci_runner--package_gpgcheck) 106 | 107 | ##### `runners` 108 | 109 | Data type: `Hash` 110 | 111 | Hashkeys are used as $title in runners.pp. The subkeys have to be named as the parameter names from ´gitlab-runner register´ command cause they're later joined to one entire string using 2 hyphen to look like shell command parameters. See ´https://docs.gitlab.com/runner/register/#one-line-registration-command´ for details. 112 | 113 | Default value: `{}` 114 | 115 | ##### `runner_defaults` 116 | 117 | Data type: `Hash` 118 | 119 | A hash with defaults which will be later merged with $runners. 120 | 121 | Default value: `{}` 122 | 123 | ##### `xz_package_name` 124 | 125 | Data type: `String` 126 | 127 | The name of the 'xz' package. Needed for local docker installations. 128 | 129 | ##### `concurrent` 130 | 131 | Data type: `Optional[Integer]` 132 | 133 | Limits how many jobs globally can be run concurrently. The most upper limit of jobs using all defined runners. 0 does not mean unlimited! 134 | 135 | Default value: `undef` 136 | 137 | ##### `log_level` 138 | 139 | Data type: `Optional[Gitlab_ci_runner::Log_level]` 140 | 141 | Log level (options: debug, info, warn, error, fatal, panic). Note that this setting has lower priority than level set by command line argument --debug, -l or --log-level 142 | 143 | Default value: `undef` 144 | 145 | ##### `log_format` 146 | 147 | Data type: `Optional[Gitlab_ci_runner::Log_format]` 148 | 149 | Log format (options: runner, text, json). Note that this setting has lower priority than format set by command line argument --log-format 150 | 151 | Default value: `undef` 152 | 153 | ##### `check_interval` 154 | 155 | Data type: `Optional[Integer]` 156 | 157 | Defines the interval length, in seconds, between new jobs check. The default value is 3; if set to 0 or lower, the default value will be used. 158 | 159 | Default value: `undef` 160 | 161 | ##### `shutdown_timeout` 162 | 163 | Data type: `Optional[Integer]` 164 | 165 | Number of seconds until the forceful shutdown operation times out and exits the process. 166 | 167 | Default value: `undef` 168 | 169 | ##### `sentry_dsn` 170 | 171 | Data type: `Optional[String]` 172 | 173 | Enable tracking of all system level errors to sentry. 174 | 175 | Default value: `undef` 176 | 177 | ##### `listen_address` 178 | 179 | Data type: `Optional[Pattern[/.*:.+/]]` 180 | 181 | Address (:) on which the Prometheus metrics HTTP server should be listening. 182 | 183 | Default value: `undef` 184 | 185 | ##### `session_server` 186 | 187 | Data type: `Optional[Gitlab_ci_runner::Session_server]` 188 | 189 | Session server lets users interact with jobs, for example, in the interactive web terminal. 190 | 191 | Default value: `undef` 192 | 193 | ##### `manage_docker` 194 | 195 | Data type: `Boolean` 196 | 197 | If docker should be installs (uses the puppetlabs-docker). 198 | 199 | Default value: `false` 200 | 201 | ##### `install_method` 202 | 203 | Data type: `Enum['repo', 'binary']` 204 | 205 | If repo or binary should be installed 206 | 207 | Default value: `'repo'` 208 | 209 | ##### `binary_source` 210 | 211 | Data type: `Stdlib::HTTPUrl` 212 | 213 | URL to the binary file 214 | 215 | Default value: `'https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-linux-amd64'` 216 | 217 | ##### `binary_path` 218 | 219 | Data type: `Stdlib::Absolutepath` 220 | 221 | Absolute path where to install gitlab_runner binary 222 | 223 | Default value: `'/usr/local/bin/gitlab-runner'` 224 | 225 | ##### `manage_user` 226 | 227 | Data type: `Boolean` 228 | 229 | If the user should be managed. 230 | 231 | Default value: `false` 232 | 233 | ##### `user` 234 | 235 | Data type: `String[1]` 236 | 237 | The user to manage. 238 | 239 | Default value: `'gitlab-runner'` 240 | 241 | ##### `group` 242 | 243 | Data type: `String[1]` 244 | 245 | The group to manage. 246 | 247 | Default value: `$user` 248 | 249 | ##### `manage_repo` 250 | 251 | Data type: `Boolean` 252 | 253 | If the repository should be managed. 254 | 255 | Default value: `true` 256 | 257 | ##### `package_ensure` 258 | 259 | Data type: `String` 260 | 261 | The package 'ensure' state. 262 | 263 | Default value: `installed` 264 | 265 | ##### `package_name` 266 | 267 | Data type: `String` 268 | 269 | The name of the package. 270 | 271 | Default value: `'gitlab-runner'` 272 | 273 | ##### `repo_base_url` 274 | 275 | Data type: `Stdlib::HTTPUrl` 276 | 277 | The base repository url. 278 | 279 | Default value: `'https://packages.gitlab.com'` 280 | 281 | ##### `repo_keyserver` 282 | 283 | Data type: `Optional[Gitlab_ci_runner::Keyserver]` 284 | 285 | The keyserver which should be used to get the repository key. 286 | 287 | Default value: `undef` 288 | 289 | ##### `config_path` 290 | 291 | Data type: `String` 292 | 293 | The path to the config file of Gitlab runner. 294 | 295 | Default value: `'/etc/gitlab-runner/config.toml'` 296 | 297 | ##### `config_owner` 298 | 299 | Data type: `String[1]` 300 | 301 | The user owning the config file. 302 | (and config directory if managed). 303 | 304 | Default value: `'root'` 305 | 306 | ##### `config_group` 307 | 308 | Data type: `String[1]` 309 | 310 | The group ownership assigned to the config file 311 | (and config directory if managed). 312 | 313 | Default value: `'root'` 314 | 315 | ##### `config_mode` 316 | 317 | Data type: `Stdlib::Filemode` 318 | 319 | The file permissions applied to the config file. 320 | 321 | Default value: `'0444'` 322 | 323 | ##### `manage_config_dir` 324 | 325 | Data type: `Boolean` 326 | 327 | Manage the parent directory of the config file. 328 | 329 | Default value: `false` 330 | 331 | ##### `config_dir_mode` 332 | 333 | Data type: `Optional[Stdlib::Filemode]` 334 | 335 | The file permissions applied to the config directory. 336 | 337 | Default value: `undef` 338 | 339 | ##### `http_proxy` 340 | 341 | Data type: `Optional[Stdlib::HTTPUrl]` 342 | 343 | An HTTP proxy to use whilst registering runners. 344 | This setting is only used when registering or unregistering runners and will be used for all runners in the `runners` parameter. 345 | If you have some runners that need to use a proxy and others that don't, leave `runners` and `http_proxy` unset and declare `gitlab_ci_runnner::runner` resources separately. 346 | If you do need to use an http proxy, you'll probably also want to configure other aspects of your runners to use it, (eg. setting `http_proxy` environment variables, `pre-clone-script`, `pre-build-script` etc.) 347 | Exactly how you might need to configure your runners varies between runner executors and specific use-cases. 348 | This module makes no attempt to automatically alter your runner configurations based on the value of this parameter. 349 | More information on what you might need to configure can be found [here](https://docs.gitlab.com/runner/configuration/proxy.html) 350 | 351 | Default value: `undef` 352 | 353 | ##### `ca_file` 354 | 355 | Data type: `Optional[Stdlib::Unixpath]` 356 | 357 | A file containing public keys of trusted certificate authorities in PEM format. 358 | This setting is only used when registering or unregistering runners and will be used for all runners in the `runners` parameter. 359 | It can be used when the certificate of the gitlab server is signed using a CA 360 | and when upon registering a runner the following error is shown: 361 | `certificate verify failed (self signed certificate in certificate chain)` 362 | Using the CA file solves https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/124. 363 | The ca_file must exist. If it doesn't, Gitlab runner token generation will be skipped. Gitlab runner will not register until either the file exists or the ca_file parameter is not specified. 364 | 365 | Default value: `undef` 366 | 367 | ##### `repo_keysource` 368 | 369 | Data type: `Stdlib::HTTPSUrl` 370 | 371 | URL to the gpg file used to sign the apt packages 372 | 373 | Default value: `"${repo_base_url}/gpg.key"` 374 | 375 | ##### `package_keysource` 376 | 377 | Data type: `Optional[Stdlib::HTTPSUrl]` 378 | 379 | 380 | 381 | Default value: `undef` 382 | 383 | ##### `package_gpgcheck` 384 | 385 | Data type: `Boolean` 386 | 387 | 388 | 389 | Default value: `true` 390 | 391 | ## Defined types 392 | 393 | ### `gitlab_ci_runner::runner` 394 | 395 | This configures a Gitlab CI runner. 396 | 397 | #### Examples 398 | 399 | ##### Add a simple runner 400 | 401 | ```puppet 402 | gitlab_ci_runner::runner { 'testrunner': 403 | config => { 404 | 'url' => 'https://gitlab.com', 405 | 'token' => '123456789abcdefgh', # Note this is different from the registration token used by `gitlab-runner register` 406 | 'executor' => 'shell', 407 | }, 408 | } 409 | ``` 410 | 411 | ##### Add a autoscaling runner with DigitalOcean as IaaS 412 | 413 | ```puppet 414 | gitlab_ci_runner::runner { 'autoscale-runner': 415 | config => { 416 | url => 'https://gitlab.com', 417 | token => 'RUNNER_TOKEN', # Note this is different from the registration token used by `gitlab-runner register` 418 | name => 'autoscale-runner', 419 | executor => 'docker+machine', 420 | limit => 10, 421 | docker => { 422 | image => 'ruby:2.6', 423 | }, 424 | machine => { 425 | OffPeakPeriods => [ 426 | '* * 0-9,18-23 * * mon-fri *', 427 | '* * * * * sat,sun *', 428 | ], 429 | OffPeakIdleCount => 1, 430 | OffPeakIdleTime => 1200, 431 | IdleCount => 5, 432 | IdleTime => 600, 433 | MaxBuilds => 100, 434 | MachineName => 'auto-scale-%s', 435 | MachineDriver => 'digitalocean', 436 | MachineOptions => [ 437 | 'digitalocean-image=coreos-stable', 438 | 'digitalocean-ssh-user=core', 439 | 'digitalocean-access-token=DO_ACCESS_TOKEN', 440 | 'digitalocean-region=nyc2', 441 | 'digitalocean-size=4gb', 442 | 'digitalocean-private-networking', 443 | 'engine-registry-mirror=http://10.11.12.13:12345', 444 | ], 445 | }, 446 | cache => { 447 | 'Type' => 's3', 448 | s3 => { 449 | ServerAddress => 's3-eu-west-1.amazonaws.com', 450 | AccessKey => 'AMAZON_S3_ACCESS_KEY', 451 | SecretKey => 'AMAZON_S3_SECRET_KEY', 452 | BucketName => 'runner', 453 | Insecure => false, 454 | }, 455 | }, 456 | }, 457 | } 458 | ``` 459 | 460 | #### Parameters 461 | 462 | The following parameters are available in the `gitlab_ci_runner::runner` defined type: 463 | 464 | * [`config`](#-gitlab_ci_runner--runner--config) 465 | * [`ensure`](#-gitlab_ci_runner--runner--ensure) 466 | * [`ca_file`](#-gitlab_ci_runner--runner--ca_file) 467 | * [`http_proxy`](#-gitlab_ci_runner--runner--http_proxy) 468 | 469 | ##### `config` 470 | 471 | Data type: `Hash` 472 | 473 | Hash with configuration options. 474 | See https://docs.gitlab.com/runner/configuration/advanced-configuration.html for all possible options. 475 | If you omit the 'name' configuration, we will automatically use the $title of this define class. 476 | 477 | ##### `ensure` 478 | 479 | Data type: `Enum['present', 'absent']` 480 | 481 | If the runner should be 'present' or 'absent'. 482 | Will add/remove the configuration from config.toml 483 | Will also register/unregister the runner. 484 | 485 | Default value: `'present'` 486 | 487 | ##### `ca_file` 488 | 489 | Data type: `Optional[Stdlib::Unixpath]` 490 | 491 | A path to a file containing public keys of trusted certificate authorities in PEM format. 492 | Used during runner registration/unregistration only. 493 | 494 | Default value: `undef` 495 | 496 | ##### `http_proxy` 497 | 498 | Data type: `Optional[Stdlib::HTTPUrl]` 499 | 500 | 501 | 502 | Default value: `undef` 503 | 504 | ## Functions 505 | 506 | ### `gitlab_ci_runner::register` 507 | 508 | Type: Ruby 4.x API 509 | 510 | A function that registers a Gitlab runner on a Gitlab instance. Be careful, this will be triggered on noop runs as well! 511 | 512 | #### Examples 513 | 514 | ##### Using it as a replacement for the Bolt 'register_runner' task 515 | 516 | ```puppet 517 | puppet apply -e "notice(gitlab_ci_runner::register('https://gitlab.com', 'registration-token'))" 518 | ``` 519 | 520 | #### `gitlab_ci_runner::register(Stdlib::HTTPUrl $url, String[1] $token, Optional[Gitlab_ci_runner::Register] $additional_options, Optional[Optional[Stdlib::Unixpath]] $ca_file)` 521 | 522 | A function that registers a Gitlab runner on a Gitlab instance. Be careful, this will be triggered on noop runs as well! 523 | 524 | Returns: `Struct[{ id => Integer[1], token => String[1], }]` Returns a hash with the runner id and authentcation token 525 | 526 | ##### Examples 527 | 528 | ###### Using it as a replacement for the Bolt 'register_runner' task 529 | 530 | ```puppet 531 | puppet apply -e "notice(gitlab_ci_runner::register('https://gitlab.com', 'registration-token'))" 532 | ``` 533 | 534 | ##### `url` 535 | 536 | Data type: `Stdlib::HTTPUrl` 537 | 538 | The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 539 | 540 | ##### `token` 541 | 542 | Data type: `String[1]` 543 | 544 | Registration token. 545 | 546 | ##### `additional_options` 547 | 548 | Data type: `Optional[Gitlab_ci_runner::Register]` 549 | 550 | A hash with all additional configuration options for that runner 551 | 552 | ##### `ca_file` 553 | 554 | Data type: `Optional[Optional[Stdlib::Unixpath]]` 555 | 556 | An absolute path to a trusted certificate authority file. 557 | 558 | ### `gitlab_ci_runner::register_to_file` 559 | 560 | Type: Ruby 4.x API 561 | 562 | A function that registers a Gitlab runner on a Gitlab instance, if it doesn't already exist, 563 | _and_ saves the retrieved authentication token to a file. This is helpful for Deferred functions. 564 | 565 | #### Examples 566 | 567 | ##### Using it as a Deferred function 568 | 569 | ```puppet 570 | gitlab_ci_runner::runner { 'testrunner': 571 | config => { 572 | 'url' => 'https://gitlab.com', 573 | 'token' => Deferred('gitlab_ci_runner::register_runner_to_file', [$config['url'], $config['registration-token'], 'testrunner']) 574 | 'executor' => 'shell', 575 | }, 576 | } 577 | ``` 578 | 579 | #### `gitlab_ci_runner::register_to_file(String[1] $url, Variant[String[1], Sensitive[String[1]]] $regtoken, String[1] $runner_name, Optional[Hash] $additional_options, Optional[Optional[String[1]]] $proxy, Optional[Optional[String[1]]] $ca_file)` 580 | 581 | A function that registers a Gitlab runner on a Gitlab instance, if it doesn't already exist, 582 | _and_ saves the retrieved authentication token to a file. This is helpful for Deferred functions. 583 | 584 | Returns: `String[1]` Returns the authentication token 585 | 586 | ##### Examples 587 | 588 | ###### Using it as a Deferred function 589 | 590 | ```puppet 591 | gitlab_ci_runner::runner { 'testrunner': 592 | config => { 593 | 'url' => 'https://gitlab.com', 594 | 'token' => Deferred('gitlab_ci_runner::register_runner_to_file', [$config['url'], $config['registration-token'], 'testrunner']) 595 | 'executor' => 'shell', 596 | }, 597 | } 598 | ``` 599 | 600 | ##### `url` 601 | 602 | Data type: `String[1]` 603 | 604 | The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 605 | 606 | ##### `regtoken` 607 | 608 | Data type: `Variant[String[1], Sensitive[String[1]]]` 609 | 610 | Registration token. 611 | 612 | ##### `runner_name` 613 | 614 | Data type: `String[1]` 615 | 616 | The name of the runner. Use as identifier for the retrieved auth token. 617 | 618 | ##### `additional_options` 619 | 620 | Data type: `Optional[Hash]` 621 | 622 | A hash with all additional configuration options for that runner 623 | 624 | ##### `proxy` 625 | 626 | Data type: `Optional[Optional[String[1]]]` 627 | 628 | The HTTP proxy to use when registering 629 | 630 | ##### `ca_file` 631 | 632 | Data type: `Optional[Optional[String[1]]]` 633 | 634 | An absolute path to a trusted certificate authority file. 635 | 636 | ### `gitlab_ci_runner::to_toml` 637 | 638 | Type: Ruby 4.x API 639 | 640 | Convert a data structure and output to TOML. 641 | 642 | #### Examples 643 | 644 | ##### How to output TOML to a file 645 | 646 | ```puppet 647 | file { '/tmp/config.toml': 648 | ensure => file, 649 | content => to_toml($myhash), 650 | } 651 | ``` 652 | 653 | #### `gitlab_ci_runner::to_toml(Hash $data)` 654 | 655 | The gitlab_ci_runner::to_toml function. 656 | 657 | Returns: `String` Converted data as TOML string 658 | 659 | ##### Examples 660 | 661 | ###### How to output TOML to a file 662 | 663 | ```puppet 664 | file { '/tmp/config.toml': 665 | ensure => file, 666 | content => to_toml($myhash), 667 | } 668 | ``` 669 | 670 | ##### `data` 671 | 672 | Data type: `Hash` 673 | 674 | Data structure which needs to be converted into TOML 675 | 676 | ### `gitlab_ci_runner::unregister` 677 | 678 | Type: Ruby 4.x API 679 | 680 | A function that unregisters a Gitlab runner from a Gitlab instance. Be careful, this will be triggered on noop runs as well! 681 | 682 | #### Examples 683 | 684 | ##### Using it as a replacement for the Bolt 'unregister_runner' task 685 | 686 | ```puppet 687 | puppet apply -e "notice(gitlab_ci_runner::unregister('https://gitlab.com', 'runner-auth-token'))" 688 | ``` 689 | 690 | #### `gitlab_ci_runner::unregister(Stdlib::HTTPUrl $url, String[1] $token, Optional[Optional[Stdlib::Unixpath]] $ca_file)` 691 | 692 | A function that unregisters a Gitlab runner from a Gitlab instance. Be careful, this will be triggered on noop runs as well! 693 | 694 | Returns: `Struct[{ status => Enum['success'], }]` Returns a hash with the runner id and authentcation token 695 | 696 | ##### Examples 697 | 698 | ###### Using it as a replacement for the Bolt 'unregister_runner' task 699 | 700 | ```puppet 701 | puppet apply -e "notice(gitlab_ci_runner::unregister('https://gitlab.com', 'runner-auth-token'))" 702 | ``` 703 | 704 | ##### `url` 705 | 706 | Data type: `Stdlib::HTTPUrl` 707 | 708 | The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 709 | 710 | ##### `token` 711 | 712 | Data type: `String[1]` 713 | 714 | Runners authentication token. 715 | 716 | ##### `ca_file` 717 | 718 | Data type: `Optional[Optional[Stdlib::Unixpath]]` 719 | 720 | An absolute path to a trusted certificate authority file. 721 | 722 | ### `gitlab_ci_runner::unregister_from_file` 723 | 724 | Type: Ruby 4.x API 725 | 726 | A function that unregisters a Gitlab runner from a Gitlab instance, if the local token is there. 727 | This is meant to be used in conjunction with the gitlab_ci_runner::register_to_file function. 728 | 729 | #### Examples 730 | 731 | ##### Using it as a Deferred function with a file resource 732 | 733 | ```puppet 734 | file { '/etc/gitlab-runner/auth-token-testrunner': 735 | file => absent, 736 | content => Deferred('gitlab_ci_runner::unregister_from_file', ['http://gitlab.example.org']) 737 | } 738 | ``` 739 | 740 | #### `gitlab_ci_runner::unregister_from_file(String[1] $url, String[1] $runner_name, Optional[Optional[String[1]]] $proxy, Optional[Optional[String[1]]] $ca_file)` 741 | 742 | A function that unregisters a Gitlab runner from a Gitlab instance, if the local token is there. 743 | This is meant to be used in conjunction with the gitlab_ci_runner::register_to_file function. 744 | 745 | Returns: `Any` 746 | 747 | ##### Examples 748 | 749 | ###### Using it as a Deferred function with a file resource 750 | 751 | ```puppet 752 | file { '/etc/gitlab-runner/auth-token-testrunner': 753 | file => absent, 754 | content => Deferred('gitlab_ci_runner::unregister_from_file', ['http://gitlab.example.org']) 755 | } 756 | ``` 757 | 758 | ##### `url` 759 | 760 | Data type: `String[1]` 761 | 762 | The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 763 | 764 | ##### `runner_name` 765 | 766 | Data type: `String[1]` 767 | 768 | The name of the runner. Use as identifier for the retrived auth token. 769 | 770 | ##### `proxy` 771 | 772 | Data type: `Optional[Optional[String[1]]]` 773 | 774 | HTTP proxy to use when unregistering 775 | 776 | ##### `ca_file` 777 | 778 | Data type: `Optional[Optional[String[1]]]` 779 | 780 | An absolute path to a trusted certificate authority file. 781 | 782 | ## Data types 783 | 784 | ### `Gitlab_ci_runner::Keyserver` 785 | 786 | Type to match repo_keyserver 787 | Regex from: https://github.com/puppetlabs/puppetlabs-apt/blob/main/manifests/key.pp 788 | 789 | Alias of `Pattern[/\A((hkp|hkps|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?(\/[a-zA-Z\d\-_.]+)*\/?$/]` 790 | 791 | ### `Gitlab_ci_runner::Log_format` 792 | 793 | Gitlab Runner log format configuration 794 | 795 | Alias of `Enum['runner', 'text', 'json']` 796 | 797 | ### `Gitlab_ci_runner::Log_level` 798 | 799 | Gitlab Runner log level configuration 800 | 801 | Alias of `Enum['debug', 'info', 'warn', 'error', 'fatal', 'panic']` 802 | 803 | ### `Gitlab_ci_runner::Register` 804 | 805 | A struct of all possible additionl options for gitlab_ci_runner::register 806 | 807 | Alias of 808 | 809 | ```puppet 810 | Struct[{ 811 | Optional[description] => String[1], 812 | Optional[info] => Hash[String[1],String[1]], 813 | Optional[active] => Boolean, 814 | Optional[locked] => Boolean, 815 | Optional[run_untagged] => Boolean, 816 | Optional[tag_list] => Array[String[1]], 817 | Optional[access_level] => Enum['not_protected', 'ref_protected'], 818 | Optional[maximum_timeout] => Integer, 819 | }] 820 | ``` 821 | 822 | ### `Gitlab_ci_runner::Register_parameters` 823 | 824 | A enum containing a possible keys used for Gitlab runner registrations 825 | 826 | Alias of `Enum['description', 'info', 'active', 'locked', 'run_untagged', 'run-untagged', 'tag_list', 'tag-list', 'access_level', 'access-level', 'maximum_timeout', 'maximum-timeout']` 827 | 828 | ### `Gitlab_ci_runner::Session_server` 829 | 830 | Gitlab Runner session_server configuration 831 | 832 | Alias of 833 | 834 | ```puppet 835 | Struct[{ 836 | listen_address => String[1], 837 | advertise_address => String[1], 838 | session_timeout => Optional[Integer], 839 | }] 840 | ``` 841 | 842 | ## Tasks 843 | 844 | ### `register_runner` 845 | 846 | Registers a runner on a Gitlab instance. 847 | 848 | **Supports noop?** false 849 | 850 | #### Parameters 851 | 852 | ##### `url` 853 | 854 | Data type: `String[1]` 855 | 856 | The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 857 | 858 | ##### `token` 859 | 860 | Data type: `String[1]` 861 | 862 | Registration token. 863 | 864 | ##### `description` 865 | 866 | Data type: `Optional[String[1]]` 867 | 868 | Runners description. 869 | 870 | ##### `info` 871 | 872 | Data type: `Optional[Hash]` 873 | 874 | Runners metadata. 875 | 876 | ##### `active` 877 | 878 | Data type: `Optional[Boolean]` 879 | 880 | Whether the Runner is active. 881 | 882 | ##### `locked` 883 | 884 | Data type: `Optional[Boolean]` 885 | 886 | Whether the Runner should be locked for current project. 887 | 888 | ##### `run_untagged` 889 | 890 | Data type: `Optional[Boolean]` 891 | 892 | Whether the Runner should handle untagged jobs. 893 | 894 | ##### `tag_list` 895 | 896 | Data type: `Optional[Array[String[1]]]` 897 | 898 | List of Runners tags. 899 | 900 | ##### `access_level` 901 | 902 | Data type: `Optional[Enum['not_protected', 'ref_protected']]` 903 | 904 | The access_level of the runner. 905 | 906 | ##### `maximum_timeout` 907 | 908 | Data type: `Optional[Integer[1]]` 909 | 910 | Maximum timeout set when this Runner will handle the job. 911 | 912 | ### `unregister_runner` 913 | 914 | Unregisters a runner from a Gitlab instance. 915 | 916 | **Supports noop?** false 917 | 918 | #### Parameters 919 | 920 | ##### `url` 921 | 922 | Data type: `String[1]` 923 | 924 | The url to your Gitlab instance. Please provide the host part only! (e.g https://gitlab.com) 925 | 926 | ##### `token` 927 | 928 | Data type: `String[1]` 929 | 930 | Runners authentication token. 931 | 932 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Managed by modulesync - DO NOT EDIT 2 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 3 | 4 | # Attempt to load voxpupuli-test (which pulls in puppetlabs_spec_helper), 5 | # otherwise attempt to load it directly. 6 | begin 7 | require 'voxpupuli/test/rake' 8 | rescue LoadError 9 | begin 10 | require 'puppetlabs_spec_helper/rake_tasks' 11 | rescue LoadError 12 | end 13 | end 14 | 15 | # load optional tasks for acceptance 16 | # only available if gem group releases is installed 17 | begin 18 | require 'voxpupuli/acceptance/rake' 19 | rescue LoadError 20 | end 21 | 22 | # load optional tasks for releases 23 | # only available if gem group releases is installed 24 | begin 25 | require 'voxpupuli/release/rake_tasks' 26 | rescue LoadError 27 | # voxpupuli-release not present 28 | else 29 | GCGConfig.user = 'voxpupuli' 30 | GCGConfig.project = 'puppet-gitlab_ci_runner' 31 | end 32 | 33 | desc "Run main 'test' task and report merged results to coveralls" 34 | task test_with_coveralls: [:test] do 35 | if Dir.exist?(File.expand_path('../lib', __FILE__)) 36 | require 'coveralls/rake/task' 37 | Coveralls::RakeTask.new 38 | Rake::Task['coveralls:push'].invoke 39 | else 40 | puts 'Skipping reporting to coveralls. Module has no lib dir' 41 | end 42 | end 43 | 44 | # vim: syntax=ruby 45 | -------------------------------------------------------------------------------- /data/defaults.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | gitlab_ci_runner::xz_package_name: 'xz-utils' 3 | -------------------------------------------------------------------------------- /data/family/RedHat.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | gitlab_ci_runner::xz_package_name: 'xz' 3 | gitlab_ci_runner::package_keysource: 'https://packages.gitlab.com/runner/gitlab-runner/gpgkey/runner-gitlab-runner-49F16C5CC3A0F81F.pub.gpg' 4 | -------------------------------------------------------------------------------- /data/family/Suse.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | gitlab_ci_runner::install_method: 'binary' 3 | gitlab_ci_runner::manage_repo: false 4 | gitlab_ci_runner::manage_config_dir: true 5 | gitlab_ci_runner::manage_user: true 6 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: 5 | datadir: 'data' 6 | data_hash: yaml_data 7 | 8 | hierarchy: 9 | - name: 'OS Major Release Overrides' 10 | path: "family/%{facts.os.family}/%{facts.os.release.major}.yaml" 11 | - name: 'Operating System' 12 | path: "os/%{facts.os.name}.yaml" 13 | - name: 'Operating System Family' 14 | path: "family/%{facts.os.family}.yaml" 15 | - name: 'Defaults' 16 | path: 'defaults.yaml' 17 | -------------------------------------------------------------------------------- /lib/puppet/functions/gitlab_ci_runner/register.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../../../puppet_x/gitlab/runner' 4 | 5 | # A function that registers a Gitlab runner on a Gitlab instance. Be careful, this will be triggered on noop runs as well! 6 | Puppet::Functions.create_function(:'gitlab_ci_runner::register') do 7 | # @param url The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 8 | # @param token Registration token. 9 | # @param additional_options A hash with all additional configuration options for that runner 10 | # @param ca_file An absolute path to a trusted certificate authority file. 11 | # @return [Struct[{ id => Integer[1], token => String[1], }]] Returns a hash with the runner id and authentcation token 12 | # @example Using it as a replacement for the Bolt 'register_runner' task 13 | # puppet apply -e "notice(gitlab_ci_runner::register('https://gitlab.com', 'registration-token'))" 14 | # 15 | dispatch :register do 16 | param 'Stdlib::HTTPUrl', :url 17 | param 'String[1]', :token 18 | optional_param 'Gitlab_ci_runner::Register', :additional_options 19 | optional_param 'Optional[Stdlib::Unixpath]', :ca_file 20 | return_type 'Struct[{ id => Integer[1], token => String[1], }]' 21 | end 22 | 23 | def register(url, token, additional_options = {}, ca_file = nil) 24 | PuppetX::Gitlab::Runner.register(url, additional_options.merge('token' => token), ca_file: ca_file) 25 | rescue Net::HTTPError => e 26 | raise "Gitlab runner failed to register: #{e.message}" 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/puppet/functions/gitlab_ci_runner/register_to_file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../../../puppet_x/gitlab/runner' 4 | require 'fileutils' 5 | 6 | # A function that registers a Gitlab runner on a Gitlab instance, if it doesn't already exist, 7 | # _and_ saves the retrieved authentication token to a file. This is helpful for Deferred functions. 8 | Puppet::Functions.create_function(:'gitlab_ci_runner::register_to_file') do 9 | # @param url The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 10 | # @param regtoken Registration token. 11 | # @param runner_name The name of the runner. Use as identifier for the retrieved auth token. 12 | # @param additional_options A hash with all additional configuration options for that runner 13 | # @param proxy The HTTP proxy to use when registering 14 | # @param ca_file An absolute path to a trusted certificate authority file. 15 | # @return [String] Returns the authentication token 16 | # @example Using it as a Deferred function 17 | # gitlab_ci_runner::runner { 'testrunner': 18 | # config => { 19 | # 'url' => 'https://gitlab.com', 20 | # 'token' => Deferred('gitlab_ci_runner::register_runner_to_file', [$config['url'], $config['registration-token'], 'testrunner']) 21 | # 'executor' => 'shell', 22 | # }, 23 | # } 24 | # 25 | dispatch :register_to_file do 26 | # We use only core data types because others aren't synced to the agent. 27 | param 'String[1]', :url 28 | param 'Variant[String[1], Sensitive[String[1]]]', :regtoken 29 | param 'String[1]', :runner_name 30 | optional_param 'Hash', :additional_options 31 | optional_param 'Optional[String[1]]', :proxy 32 | optional_param 'Optional[String[1]]', :ca_file # This function will be deferred so can't use types from Stdlib etc. 33 | return_type 'String[1]' 34 | end 35 | 36 | def register_to_file(url, regtoken, runner_name, additional_options = {}, proxy = nil, ca_file = nil) 37 | filename = "/etc/gitlab-runner/auth-token-#{runner_name}" 38 | if File.exist?(filename) 39 | authtoken = File.read(filename).strip 40 | else 41 | return 'DUMMY-NOOP-TOKEN' if Puppet.settings[:noop] 42 | 43 | begin 44 | # Confirm the specified ca file exists 45 | if !ca_file.nil? && !File.exist?(ca_file) 46 | Puppet.warning('Unable to register gitlab runner at this time as the specified `ca_file` does not exist (yet). If puppet is managing this file, the next run should complete the registration process.') 47 | return 'Specified CA file doesn\'t exist, not attempting to create authtoken' 48 | end 49 | 50 | # If this is a Sensitive value it will be unwrapped, otherwise the String 51 | # will be returned unmodified. 52 | regtoken = call_function('unwrap', regtoken) 53 | 54 | authtoken = PuppetX::Gitlab::Runner.register(url, additional_options.merge('token' => regtoken), proxy, ca_file)['token'] 55 | 56 | # If this function is used as a Deferred function the Gitlab Runner config dir 57 | # will not exist on the first run, because the package isn't installed yet. 58 | dirname = File.dirname(filename) 59 | unless File.exist?(dirname) 60 | FileUtils.mkdir_p(File.dirname(filename)) 61 | File.chmod(0o700, dirname) 62 | end 63 | 64 | File.write(filename, authtoken) 65 | File.chmod(0o400, filename) 66 | rescue Net::HTTPError => e 67 | raise "Gitlab runner failed to register: #{e.message}" 68 | end 69 | end 70 | 71 | authtoken 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /lib/puppet/functions/gitlab_ci_runner/to_toml.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../../../puppet_x/gitlab/dumper' 4 | # @summary Convert a data structure and output to TOML. 5 | Puppet::Functions.create_function(:'gitlab_ci_runner::to_toml') do 6 | # @param data Data structure which needs to be converted into TOML 7 | # @return [String] Converted data as TOML string 8 | # @example How to output TOML to a file 9 | # file { '/tmp/config.toml': 10 | # ensure => file, 11 | # content => to_toml($myhash), 12 | # } 13 | dispatch :to_toml do 14 | required_param 'Hash', :data 15 | return_type 'String' 16 | end 17 | 18 | def to_toml(data) 19 | PuppetX::Gitlab::Dumper.new(data).toml_str 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/puppet/functions/gitlab_ci_runner/unregister.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../../../puppet_x/gitlab/runner' 4 | 5 | # A function that unregisters a Gitlab runner from a Gitlab instance. Be careful, this will be triggered on noop runs as well! 6 | Puppet::Functions.create_function(:'gitlab_ci_runner::unregister') do 7 | # @summary A function that unregisters a Gitlab runner from a Gitlab instance. Be careful, this will be triggered on noop runs as well! 8 | # @param url The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 9 | # @param token Runners authentication token. 10 | # @param ca_file An absolute path to a trusted certificate authority file. 11 | # @return [Struct[{ id => Integer[1], token => String[1], }]] Returns a hash with the runner id and authentcation token 12 | # @example Using it as a replacement for the Bolt 'unregister_runner' task 13 | # puppet apply -e "notice(gitlab_ci_runner::unregister('https://gitlab.com', 'runner-auth-token'))" 14 | # 15 | dispatch :unregister do 16 | param 'Stdlib::HTTPUrl', :url 17 | param 'String[1]', :token 18 | optional_param 'Optional[Stdlib::Unixpath]', :ca_file 19 | return_type "Struct[{ status => Enum['success'], }]" 20 | end 21 | 22 | def unregister(url, token, ca_file = nil) 23 | PuppetX::Gitlab::Runner.unregister(url, { 'token' => token }, ca_file: ca_file) 24 | { 'status' => 'success' } 25 | rescue Net::HTTPError => e 26 | raise "Gitlab runner failed to unregister: #{e.message}" 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /lib/puppet/functions/gitlab_ci_runner/unregister_from_file.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require_relative '../../../puppet_x/gitlab/runner' 4 | 5 | # A function that unregisters a Gitlab runner from a Gitlab instance, if the local token is there. 6 | # This is meant to be used in conjunction with the gitlab_ci_runner::register_to_file function. 7 | Puppet::Functions.create_function(:'gitlab_ci_runner::unregister_from_file') do 8 | # @param url The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com) 9 | # @param runner_name The name of the runner. Use as identifier for the retrived auth token. 10 | # @param proxy HTTP proxy to use when unregistering 11 | # @param ca_file An absolute path to a trusted certificate authority file. 12 | # @example Using it as a Deferred function with a file resource 13 | # file { '/etc/gitlab-runner/auth-token-testrunner': 14 | # file => absent, 15 | # content => Deferred('gitlab_ci_runner::unregister_from_file', ['http://gitlab.example.org']) 16 | # } 17 | # 18 | dispatch :unregister_from_file do 19 | # We use only core data types because others aren't synced to the agent. 20 | param 'String[1]', :url 21 | param 'String[1]', :runner_name 22 | optional_param 'Optional[String[1]]', :proxy 23 | optional_param 'Optional[String[1]]', :ca_file # This function will be deferred so can't use types from stdlib etc. 24 | end 25 | 26 | def unregister_from_file(url, runner_name, proxy = nil, ca_file = nil) 27 | filename = "/etc/gitlab-runner/auth-token-#{runner_name}" 28 | return "#{filename} file doesn't exist" unless File.exist?(filename) 29 | 30 | authtoken = File.read(filename).strip 31 | if Puppet.settings[:noop] 32 | message = "Not unregistering gitlab runner #{runner_name} when in noop mode" 33 | Puppet.debug message 34 | message 35 | else 36 | begin 37 | if !ca_file.nil? && !File.exist?(ca_file) 38 | Puppet.warning('Unable to unregister gitlab runner at this time as the specified `ca_file` does not exist. The runner config will be removed from this hosts config only; please remove from gitlab manually.') 39 | return 'Specified CA file doesn\'t exist, not attempting to create authtoken' 40 | end 41 | PuppetX::Gitlab::Runner.unregister(url, { 'token' => authtoken }, proxy, ca_file) 42 | message = "Successfully unregistered gitlab runner #{runner_name}" 43 | Puppet.debug message 44 | message 45 | rescue Net::HTTPError => e 46 | # Chances are the runner is already unregistered. Best to just log a warning message but otherwise exit the function cleanly 47 | message = "Error whilst unregistering gitlab runner #{runner_name}: #{e.message}" 48 | Puppet.warning message 49 | message 50 | end 51 | end 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /lib/puppet_x/gitlab/dumper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # The MIT License (MIT) 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | # THE SOFTWARE. 22 | # 23 | # The Dumper class was blindly copied from https://github.com/emancu/toml-rb/blob/v2.0.1/lib/toml-rb/dumper.rb 24 | # This allows us to use the `to_toml` function as a `Deferred` function because the `toml-rb` gem is usually 25 | # installed on the agent and the `Deferred` function gets evaluated before the catalog gets applied. This 26 | # makes it in most scenarios impossible to install the gem before it is used. 27 | 28 | require 'date' 29 | 30 | module PuppetX 31 | module Gitlab 32 | class Dumper 33 | attr_reader :toml_str 34 | 35 | def initialize(hash) 36 | @toml_str = '' 37 | 38 | visit(hash, []) 39 | end 40 | 41 | private 42 | 43 | def visit(hash, prefix, extra_brackets = false) 44 | simple_pairs, nested_pairs, table_array_pairs = sort_pairs hash 45 | 46 | print_prefix prefix, extra_brackets if prefix.any? && (simple_pairs.any? || hash.empty?) 47 | 48 | dump_pairs simple_pairs, nested_pairs, table_array_pairs, prefix 49 | end 50 | 51 | def sort_pairs(hash) 52 | nested_pairs = [] 53 | simple_pairs = [] 54 | table_array_pairs = [] 55 | 56 | hash.keys.sort.each do |key| 57 | val = hash[key] 58 | element = [key, val] 59 | 60 | if val.is_a? Hash 61 | nested_pairs << element 62 | elsif val.is_a?(Array) && val.first.is_a?(Hash) 63 | table_array_pairs << element 64 | else 65 | simple_pairs << element 66 | end 67 | end 68 | 69 | [simple_pairs, nested_pairs, table_array_pairs] 70 | end 71 | 72 | def dump_pairs(simple, nested, table_array, prefix = []) 73 | # First add simple pairs, under the prefix 74 | dump_simple_pairs simple 75 | dump_nested_pairs nested, prefix 76 | dump_table_array_pairs table_array, prefix 77 | end 78 | 79 | def dump_simple_pairs(simple_pairs) 80 | simple_pairs.each do |key, val| 81 | key = quote_key(key) unless bare_key? key 82 | @toml_str += "#{key} = #{to_toml(val)}\n" 83 | end 84 | end 85 | 86 | def dump_nested_pairs(nested_pairs, prefix) 87 | nested_pairs.each do |key, val| 88 | key = quote_key(key) unless bare_key? key 89 | 90 | visit val, prefix + [key], false 91 | end 92 | end 93 | 94 | def dump_table_array_pairs(table_array_pairs, prefix) 95 | table_array_pairs.each do |key, val| 96 | key = quote_key(key) unless bare_key? key 97 | aux_prefix = prefix + [key] 98 | 99 | val.each do |child| 100 | print_prefix aux_prefix, true 101 | args = sort_pairs(child) << aux_prefix 102 | 103 | dump_pairs(*args) 104 | end 105 | end 106 | end 107 | 108 | def print_prefix(prefix, extra_brackets = false) 109 | new_prefix = prefix.join('.') 110 | new_prefix = '[' + new_prefix + ']' if extra_brackets 111 | 112 | @toml_str += "[" + new_prefix + "]\n" # rubocop:disable Style/StringLiterals 113 | end 114 | 115 | def to_toml(obj) 116 | if obj.is_a?(Time) || obj.is_a?(DateTime) 117 | obj.strftime('%Y-%m-%dT%H:%M:%SZ') 118 | elsif obj.is_a?(Date) 119 | obj.strftime('%Y-%m-%d') 120 | elsif obj.is_a? Regexp 121 | obj.inspect.inspect 122 | elsif obj.is_a? String 123 | obj.inspect.gsub(/\\(#[$@{])/, '\1') # rubocop:disable Style/RegexpLiteral 124 | else 125 | obj.inspect 126 | end 127 | end 128 | 129 | def bare_key?(key) 130 | # rubocop:disable Style/RegexpLiteral 131 | !!key.to_s.match(/^[a-zA-Z0-9_-]*$/) 132 | # rubocop:enable Style/RegexpLiteral 133 | end 134 | 135 | def quote_key(key) 136 | '"' + key.gsub('"', '\\"') + '"' 137 | end 138 | end 139 | end 140 | end 141 | -------------------------------------------------------------------------------- /lib/puppet_x/gitlab/runner.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'json' 4 | require 'net/http' 5 | require 'uri' 6 | require 'puppet' 7 | 8 | module PuppetX 9 | module Gitlab 10 | module APIClient 11 | def self.delete(url, options, proxy, ca_file) 12 | response = request(url, Net::HTTP::Delete, options, proxy, ca_file) 13 | validate(response) 14 | 15 | {} 16 | end 17 | 18 | def self.post(url, options, proxy, ca_file) 19 | response = request(url, Net::HTTP::Post, options, proxy, ca_file) 20 | validate(response) 21 | 22 | JSON.parse(response.body) 23 | end 24 | 25 | def self.request(url, http_method, options, proxy, ca_file) 26 | uri = URI.parse(url) 27 | headers = { 28 | 'Accept' => 'application/json', 29 | 'Content-Type' => 'application/json' 30 | } 31 | if proxy 32 | proxy_uri = URI.parse(proxy) 33 | proxy_host = proxy_uri.host 34 | proxy_port = proxy_uri.port 35 | else 36 | proxy_host = nil 37 | proxy_port = nil 38 | end 39 | 40 | http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port) 41 | if uri.scheme == 'https' 42 | http.use_ssl = true 43 | http.verify_mode = OpenSSL::SSL::VERIFY_PEER 44 | http.ca_file = ca_file if ca_file 45 | end 46 | request = http_method.new(uri.request_uri, headers) 47 | request.body = options.to_json 48 | 49 | begin 50 | http.request(request) 51 | rescue Net::OpenTimeout 52 | msg = if http.proxy? 53 | "Timeout connecting to proxy #{http.proxy_address} when trying to register/unregister gitlab runner" 54 | else 55 | "Timeout connecting to #{http.address} when trying to register/unregister gitlab runner" 56 | end 57 | raise Puppet::Error, msg 58 | end 59 | end 60 | 61 | def self.validate(response) 62 | raise Net::HTTPError.new(response.message, response) unless response.code.start_with?('2') 63 | end 64 | end 65 | 66 | module Runner 67 | def self.register(host, options, proxy = nil, ca_file = nil) 68 | url = "#{host}/api/v4/runners" 69 | Puppet.info "Registering gitlab runner with #{host}" 70 | PuppetX::Gitlab::APIClient.post(url, options, proxy, ca_file) 71 | end 72 | 73 | def self.unregister(host, options, proxy = nil, ca_file = nil) 74 | url = "#{host}/api/v4/runners" 75 | Puppet.info "Unregistering gitlab runner with #{host}" 76 | PuppetX::Gitlab::APIClient.delete(url, options, proxy, ca_file) 77 | end 78 | end 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /manifests/config.pp: -------------------------------------------------------------------------------- 1 | # @summary Manages the configuration of Gitlab runner 2 | # 3 | # @api private 4 | # 5 | class gitlab_ci_runner::config ( 6 | $config_path = $gitlab_ci_runner::config_path, 7 | $config_owner = $gitlab_ci_runner::config_owner, 8 | $config_group = $gitlab_ci_runner::config_group, 9 | $config_mode = $gitlab_ci_runner::config_mode, 10 | $manage_config_dir = $gitlab_ci_runner::manage_config_dir, 11 | $config_dir_mode = $gitlab_ci_runner::config_dir_mode, 12 | $concurrent = $gitlab_ci_runner::concurrent, 13 | $log_level = $gitlab_ci_runner::log_level, 14 | $log_format = $gitlab_ci_runner::log_format, 15 | $check_interval = $gitlab_ci_runner::check_interval, 16 | $shutdown_timeout = $gitlab_ci_runner::shutdown_timeout, 17 | $sentry_dsn = $gitlab_ci_runner::sentry_dsn, 18 | $session_server = $gitlab_ci_runner::session_server, 19 | $listen_address = $gitlab_ci_runner::listen_address, 20 | $package_name = $gitlab_ci_runner::package_name, 21 | ) { 22 | assert_private() 23 | 24 | concat { $config_path: 25 | ensure => present, 26 | owner => $config_owner, 27 | group => $config_group, 28 | mode => $config_mode, 29 | ensure_newline => true, 30 | } 31 | 32 | $global_options = { 33 | concurrent => $concurrent, 34 | log_level => $log_level, 35 | log_format => $log_format, 36 | check_interval => $check_interval, 37 | shutdown_timeout => $shutdown_timeout, 38 | sentry_dsn => $sentry_dsn, 39 | session_server => $session_server, 40 | listen_address => $listen_address, 41 | }.filter |$key, $val| { $val =~ NotUndef } 42 | 43 | concat::fragment { "${config_path} - header": 44 | target => $config_path, 45 | order => 0, 46 | content => '# MANAGED BY PUPPET', 47 | } 48 | 49 | concat::fragment { "${config_path} - global options": 50 | target => $config_path, 51 | order => 1, 52 | content => gitlab_ci_runner::to_toml($global_options), 53 | } 54 | 55 | if $manage_config_dir { 56 | $_config_dir = dirname($config_path) 57 | 58 | file { $_config_dir: 59 | ensure => 'directory', 60 | owner => $config_owner, 61 | group => $config_group, 62 | mode => $config_dir_mode, 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /manifests/init.pp: -------------------------------------------------------------------------------- 1 | # @summary This module installs and configures Gitlab CI Runners. 2 | # 3 | # @example Simple runner registration 4 | # class { 'gitlab_ci_runner': 5 | # runners => { 6 | # example_runner => { 7 | # 'registration-token' => 'gitlab-token', 8 | # 'url' => 'https://gitlab.com', 9 | # 'tag-list' => 'docker,aws', 10 | # }, 11 | # }, 12 | # } 13 | # 14 | # @param runners 15 | # Hashkeys are used as $title in runners.pp. The subkeys have to be named as the parameter names from ´gitlab-runner register´ command cause they're later joined to one entire string using 2 hyphen to look like shell command parameters. See ´https://docs.gitlab.com/runner/register/#one-line-registration-command´ for details. 16 | # @param runner_defaults 17 | # A hash with defaults which will be later merged with $runners. 18 | # @param xz_package_name 19 | # The name of the 'xz' package. Needed for local docker installations. 20 | # @param concurrent 21 | # Limits how many jobs globally can be run concurrently. The most upper limit of jobs using all defined runners. 0 does not mean unlimited! 22 | # @param log_level 23 | # Log level (options: debug, info, warn, error, fatal, panic). Note that this setting has lower priority than level set by command line argument --debug, -l or --log-level 24 | # @param log_format 25 | # Log format (options: runner, text, json). Note that this setting has lower priority than format set by command line argument --log-format 26 | # @param check_interval 27 | # Defines the interval length, in seconds, between new jobs check. The default value is 3; if set to 0 or lower, the default value will be used. 28 | # @param shutdown_timeout 29 | # Number of seconds until the forceful shutdown operation times out and exits the process. 30 | # @param sentry_dsn 31 | # Enable tracking of all system level errors to sentry. 32 | # @param listen_address 33 | # Address (:) on which the Prometheus metrics HTTP server should be listening. 34 | # @param session_server 35 | # Session server lets users interact with jobs, for example, in the interactive web terminal. 36 | # @param manage_docker 37 | # If docker should be installs (uses the puppetlabs-docker). 38 | # @param install_method 39 | # If repo or binary should be installed 40 | # @param binary_source 41 | # URL to the binary file 42 | # @param binary_path 43 | # Absolute path where to install gitlab_runner binary 44 | # @param manage_user 45 | # If the user should be managed. 46 | # @param user 47 | # The user to manage. 48 | # @param group 49 | # The group to manage. 50 | # @param manage_repo 51 | # If the repository should be managed. 52 | # @param package_ensure 53 | # The package 'ensure' state. 54 | # @param package_name 55 | # The name of the package. 56 | # @param repo_base_url 57 | # The base repository url. 58 | # @param repo_keyserver 59 | # The keyserver which should be used to get the repository key. 60 | # @param config_path 61 | # The path to the config file of Gitlab runner. 62 | # @param config_owner 63 | # The user owning the config file. 64 | # (and config directory if managed). 65 | # @param config_group 66 | # The group ownership assigned to the config file 67 | # (and config directory if managed). 68 | # @param config_mode 69 | # The file permissions applied to the config file. 70 | # @param manage_config_dir 71 | # Manage the parent directory of the config file. 72 | # @param config_dir_mode 73 | # The file permissions applied to the config directory. 74 | # @param http_proxy 75 | # An HTTP proxy to use whilst registering runners. 76 | # This setting is only used when registering or unregistering runners and will be used for all runners in the `runners` parameter. 77 | # If you have some runners that need to use a proxy and others that don't, leave `runners` and `http_proxy` unset and declare `gitlab_ci_runnner::runner` resources separately. 78 | # If you do need to use an http proxy, you'll probably also want to configure other aspects of your runners to use it, (eg. setting `http_proxy` environment variables, `pre-clone-script`, `pre-build-script` etc.) 79 | # Exactly how you might need to configure your runners varies between runner executors and specific use-cases. 80 | # This module makes no attempt to automatically alter your runner configurations based on the value of this parameter. 81 | # More information on what you might need to configure can be found [here](https://docs.gitlab.com/runner/configuration/proxy.html) 82 | # @param ca_file 83 | # A file containing public keys of trusted certificate authorities in PEM format. 84 | # This setting is only used when registering or unregistering runners and will be used for all runners in the `runners` parameter. 85 | # It can be used when the certificate of the gitlab server is signed using a CA 86 | # and when upon registering a runner the following error is shown: 87 | # `certificate verify failed (self signed certificate in certificate chain)` 88 | # Using the CA file solves https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues/124. 89 | # The ca_file must exist. If it doesn't, Gitlab runner token generation will be skipped. Gitlab runner will not register until either the file exists or the ca_file parameter is not specified. 90 | # @param repo_keysource URL to the gpg file used to sign the apt packages 91 | # 92 | class gitlab_ci_runner ( 93 | String $xz_package_name, # Defaults in module hieradata 94 | Hash $runners = {}, 95 | Hash $runner_defaults = {}, 96 | Optional[Integer] $concurrent = undef, 97 | Optional[Gitlab_ci_runner::Log_level] $log_level = undef, 98 | Optional[Gitlab_ci_runner::Log_format] $log_format = undef, 99 | Optional[Integer] $check_interval = undef, 100 | Optional[Integer] $shutdown_timeout = undef, 101 | Optional[String] $sentry_dsn = undef, 102 | Optional[Pattern[/.*:.+/]] $listen_address = undef, 103 | Optional[Gitlab_ci_runner::Session_server] $session_server = undef, 104 | Enum['repo', 'binary'] $install_method = 'repo', 105 | Stdlib::HTTPUrl $binary_source = 'https://s3.dualstack.us-east-1.amazonaws.com/gitlab-runner-downloads/latest/binaries/gitlab-runner-linux-amd64', 106 | Stdlib::Absolutepath $binary_path = '/usr/local/bin/gitlab-runner', 107 | Boolean $manage_user = false, 108 | String[1] $user = 'gitlab-runner', 109 | String[1] $group = $user, 110 | Boolean $manage_docker = false, 111 | Boolean $manage_repo = true, 112 | String $package_ensure = installed, 113 | String $package_name = 'gitlab-runner', 114 | Stdlib::HTTPUrl $repo_base_url = 'https://packages.gitlab.com', 115 | Optional[Gitlab_ci_runner::Keyserver] $repo_keyserver = undef, 116 | String $config_path = '/etc/gitlab-runner/config.toml', 117 | String[1] $config_owner = 'root', 118 | String[1] $config_group = 'root', 119 | Stdlib::Filemode $config_mode = '0444', 120 | Boolean $manage_config_dir = false, 121 | Optional[Stdlib::Filemode] $config_dir_mode = undef, 122 | Optional[Stdlib::HTTPUrl] $http_proxy = undef, 123 | Optional[Stdlib::Unixpath] $ca_file = undef, 124 | Stdlib::HTTPSUrl $repo_keysource = "${repo_base_url}/gpg.key", 125 | Optional[Stdlib::HTTPSUrl] $package_keysource = undef, 126 | Boolean $package_gpgcheck = true, 127 | ) { 128 | if $manage_docker { 129 | # workaround for cirunner issue #1617 130 | # https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/issues/1617 131 | stdlib::ensure_packages($xz_package_name) 132 | 133 | $docker_images = { 134 | ubuntu_focal => { 135 | image => 'ubuntu', 136 | image_tag => 'focal', 137 | }, 138 | } 139 | 140 | include docker 141 | class { 'docker::images': 142 | images => $docker_images, 143 | } 144 | } 145 | 146 | if $manage_repo { 147 | contain gitlab_ci_runner::repo 148 | } 149 | 150 | contain gitlab_ci_runner::install 151 | contain gitlab_ci_runner::config 152 | contain gitlab_ci_runner::service 153 | 154 | Class['gitlab_ci_runner::install'] 155 | -> Class['gitlab_ci_runner::config'] 156 | ~> Class['gitlab_ci_runner::service'] 157 | 158 | $runners.each |$runner_name,$config| { 159 | $_config = $runner_defaults + $config 160 | $title = $_config['name'] ? { 161 | undef => $runner_name, 162 | default => $_config['name'], 163 | } 164 | $_ca_file = $_config['ca_file'] ? { 165 | undef => $ca_file, 166 | default => $_config['ca_file'], 167 | } 168 | 169 | gitlab_ci_runner::runner { $title: 170 | ensure => $_config['ensure'], 171 | config => $_config - ['ensure', 'name', 'ca_file'], 172 | http_proxy => $http_proxy, 173 | ca_file => $_ca_file, 174 | require => Class['gitlab_ci_runner::config'], 175 | notify => Class['gitlab_ci_runner::service'], 176 | } 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /manifests/install.pp: -------------------------------------------------------------------------------- 1 | # @summary Manages the package of Gitlab runner 2 | # 3 | # @api private 4 | # 5 | class gitlab_ci_runner::install ( 6 | $package_name = $gitlab_ci_runner::package_name, 7 | $package_ensure = $gitlab_ci_runner::package_ensure, 8 | ) { 9 | assert_private() 10 | 11 | case $gitlab_ci_runner::install_method { 12 | 'repo': { 13 | package { $package_name: 14 | ensure => $package_ensure, 15 | } 16 | } 17 | 'binary': { 18 | $_package_ensure = $package_ensure ? { 19 | 'installed' => 'present', 20 | default => $package_ensure, 21 | } 22 | archive { $gitlab_ci_runner::binary_path: 23 | ensure => $_package_ensure, 24 | source => $gitlab_ci_runner::binary_source, 25 | extract => false, 26 | creates => $gitlab_ci_runner::binary_path, 27 | } 28 | file { $gitlab_ci_runner::binary_path: 29 | ensure => file, 30 | mode => '0755', 31 | } 32 | if $gitlab_ci_runner::manage_user { 33 | group { $gitlab_ci_runner::group: 34 | ensure => present, 35 | } 36 | user { $gitlab_ci_runner::user: 37 | ensure => present, 38 | gid => $gitlab_ci_runner::group, 39 | } 40 | } 41 | } 42 | default: { 43 | fail("Unsupported install method: ${gitlab_ci_runner::install_method}") 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /manifests/repo.pp: -------------------------------------------------------------------------------- 1 | # @summary Manages the repository for Gitlab runner 2 | # 3 | # @api private 4 | # 5 | class gitlab_ci_runner::repo ( 6 | $repo_base_url = $gitlab_ci_runner::repo_base_url, 7 | $repo_keyserver = $gitlab_ci_runner::repo_keyserver, 8 | $repo_keysource = $gitlab_ci_runner::repo_keysource, 9 | $package_keysource = $gitlab_ci_runner::package_keysource, 10 | $package_gpgcheck = $gitlab_ci_runner::package_gpgcheck, 11 | $package_name = $gitlab_ci_runner::package_name, 12 | ) { 13 | assert_private() 14 | case $facts['os']['family'] { 15 | 'Debian': { 16 | apt::source { 'apt_gitlabci': 17 | comment => 'GitlabCI Runner Repo', 18 | location => "${repo_base_url}/runner/${package_name}/${facts['os']['distro']['id'].downcase}/", 19 | repos => 'main', 20 | key => { 21 | 'name' => 'gitlab_ci_runner.asc', 22 | 'source' => $repo_keysource, 23 | 'server' => $repo_keyserver, 24 | }, 25 | include => { 26 | 'src' => false, 27 | 'deb' => true, 28 | }, 29 | } 30 | Apt::Source['apt_gitlabci'] -> Package[$package_name] 31 | Exec['apt_update'] -> Package[$package_name] 32 | } 33 | 'RedHat': { 34 | if $facts['os']['name'] == 'Amazon' { 35 | if $facts['os']['release']['major'] == '2' { # Amazon Linux 2 is based off of CentOS 7 36 | $base_url = "${repo_base_url}/runner/${package_name}/el/7/\$basearch" 37 | $source_base_url = "${repo_base_url}/runner/${package_name}/el/7/SRPMS" 38 | } else { # Amazon Linux 1 is based off of CentOS 6 but os.release.major will differ 39 | $base_url = "${repo_base_url}/runner/${package_name}/el/6/\$basearch" 40 | $source_base_url = "${repo_base_url}/runner/${package_name}/el/6/SRPMS" 41 | } 42 | } else { 43 | $base_url = "${repo_base_url}/runner/${package_name}/el/\$releasever/\$basearch" 44 | $source_base_url = "${repo_base_url}/runner/${package_name}/el/\$releasever/SRPMS" 45 | } 46 | 47 | $_gpgkeys = [$repo_keysource,$package_keysource].delete_undef_values.join(' ') 48 | yumrepo { "runner_${package_name}": 49 | ensure => 'present', 50 | baseurl => $base_url, 51 | descr => "runner_${package_name}", 52 | enabled => '1', 53 | gpgcheck => String(Integer($package_gpgcheck)), 54 | gpgkey => $_gpgkeys, 55 | repo_gpgcheck => '1', 56 | sslcacert => '/etc/pki/tls/certs/ca-bundle.crt', 57 | sslverify => '1', 58 | } 59 | 60 | yumrepo { "runner_${package_name}-source": 61 | ensure => 'present', 62 | baseurl => $source_base_url, 63 | descr => "runner_${package_name}-source", 64 | enabled => '1', 65 | gpgcheck => String(Integer($package_gpgcheck)), 66 | gpgkey => $_gpgkeys, 67 | repo_gpgcheck => '1', 68 | sslcacert => '/etc/pki/tls/certs/ca-bundle.crt', 69 | sslverify => '1', 70 | } 71 | } 72 | default: { 73 | fail ("gitlab_ci_runner::repo isn't suppored for ${facts['os']['family']}!") 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /manifests/runner.pp: -------------------------------------------------------------------------------- 1 | # @summary This configures a Gitlab CI runner. 2 | # 3 | # @example Add a simple runner 4 | # gitlab_ci_runner::runner { 'testrunner': 5 | # config => { 6 | # 'url' => 'https://gitlab.com', 7 | # 'token' => '123456789abcdefgh', # Note this is different from the registration token used by `gitlab-runner register` 8 | # 'executor' => 'shell', 9 | # }, 10 | # } 11 | # 12 | # @example Add a autoscaling runner with DigitalOcean as IaaS 13 | # gitlab_ci_runner::runner { 'autoscale-runner': 14 | # config => { 15 | # url => 'https://gitlab.com', 16 | # token => 'RUNNER_TOKEN', # Note this is different from the registration token used by `gitlab-runner register` 17 | # name => 'autoscale-runner', 18 | # executor => 'docker+machine', 19 | # limit => 10, 20 | # docker => { 21 | # image => 'ruby:2.6', 22 | # }, 23 | # machine => { 24 | # OffPeakPeriods => [ 25 | # '* * 0-9,18-23 * * mon-fri *', 26 | # '* * * * * sat,sun *', 27 | # ], 28 | # OffPeakIdleCount => 1, 29 | # OffPeakIdleTime => 1200, 30 | # IdleCount => 5, 31 | # IdleTime => 600, 32 | # MaxBuilds => 100, 33 | # MachineName => 'auto-scale-%s', 34 | # MachineDriver => 'digitalocean', 35 | # MachineOptions => [ 36 | # 'digitalocean-image=coreos-stable', 37 | # 'digitalocean-ssh-user=core', 38 | # 'digitalocean-access-token=DO_ACCESS_TOKEN', 39 | # 'digitalocean-region=nyc2', 40 | # 'digitalocean-size=4gb', 41 | # 'digitalocean-private-networking', 42 | # 'engine-registry-mirror=http://10.11.12.13:12345', 43 | # ], 44 | # }, 45 | # cache => { 46 | # 'Type' => 's3', 47 | # s3 => { 48 | # ServerAddress => 's3-eu-west-1.amazonaws.com', 49 | # AccessKey => 'AMAZON_S3_ACCESS_KEY', 50 | # SecretKey => 'AMAZON_S3_SECRET_KEY', 51 | # BucketName => 'runner', 52 | # Insecure => false, 53 | # }, 54 | # }, 55 | # }, 56 | # } 57 | # 58 | # @param config 59 | # Hash with configuration options. 60 | # See https://docs.gitlab.com/runner/configuration/advanced-configuration.html for all possible options. 61 | # If you omit the 'name' configuration, we will automatically use the $title of this define class. 62 | # 63 | # @param ensure 64 | # If the runner should be 'present' or 'absent'. 65 | # Will add/remove the configuration from config.toml 66 | # Will also register/unregister the runner. 67 | # 68 | # @param ca_file 69 | # A path to a file containing public keys of trusted certificate authorities in PEM format. 70 | # Used during runner registration/unregistration only. 71 | # 72 | define gitlab_ci_runner::runner ( 73 | Hash $config, 74 | Enum['present', 'absent'] $ensure = 'present', 75 | Optional[Stdlib::HTTPUrl] $http_proxy = undef, 76 | Optional[Stdlib::Unixpath] $ca_file = undef, 77 | ) { 78 | include gitlab_ci_runner 79 | 80 | $config_path = $gitlab_ci_runner::config_path 81 | # Use title parameter if config hash doesn't contain one. 82 | $_config = $config['name'] ? { 83 | undef => $config + { name => $title }, 84 | default => $config, 85 | } 86 | 87 | if $_config['registration-token'] { 88 | $register_additional_options = $config 89 | .filter |$item| { $item[0] =~ Gitlab_ci_runner::Register_parameters } # Get all items use for the registration process 90 | .reduce({}) |$memo, $item| { $memo + { regsubst($item[0], '-', '_', 'G') => $item[1] } } # Ensure all keys use '_' instead of '-' 91 | 92 | $deferred_call = Deferred('gitlab_ci_runner::register_to_file', [$_config['url'], $_config['registration-token'], $_config['name'], $register_additional_options, $http_proxy, $ca_file]) 93 | 94 | # Remove registration-token and add a 'token' key to the config with a Deferred function to get it. 95 | $__config = ($_config - (Array(Gitlab_ci_runner::Register_parameters) + 'registration-token')) + { 'token' => $deferred_call } 96 | } else { 97 | # Fail if the user supplied configuration options which are meant for the registration, but not for the config file 98 | $_config.keys.each |$key| { 99 | if $key in Array(Gitlab_ci_runner::Register_parameters) { 100 | fail("\$config contains a configuration key (${key}) which is meant for the registration, but not for the config file. Please remove it or add a 'registration-token'!") 101 | } 102 | } 103 | 104 | $__config = $_config 105 | } 106 | 107 | $content = $__config['token'] =~ Deferred ? { 108 | true => Deferred('gitlab_ci_runner::to_toml', [{ runners => [$__config], }]), 109 | false => gitlab_ci_runner::to_toml({ runners => [$__config], }), 110 | } 111 | 112 | if $ensure == 'present' { 113 | concat::fragment { "${config_path} - ${title}": 114 | target => $config_path, 115 | order => 2, 116 | content => $content, 117 | } 118 | } else { 119 | $absent_content = Deferred('gitlab_ci_runner::unregister_from_file', [$_config['url'], $_config['name'], $http_proxy, $ca_file]) 120 | 121 | file { "/etc/gitlab-runner/auth-token-${_config['name']}": 122 | ensure => absent, 123 | content => $absent_content, # This line might look pointless, but isn't. The Deferred must appear in the catalog if we actually want it to run. 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /manifests/service.pp: -------------------------------------------------------------------------------- 1 | # @summary Manages the service of Gitlab runner 2 | # 3 | # @api private 4 | # 5 | class gitlab_ci_runner::service ( 6 | $package_name = $gitlab_ci_runner::package_name, 7 | ) { 8 | assert_private() 9 | 10 | if $facts['os']['family'] == 'Suse' { 11 | exec { "${gitlab_ci_runner::binary_path} install -u ${gitlab_ci_runner::user}": 12 | creates => '/etc/systemd/system/gitlab-runner.service', 13 | } 14 | } 15 | service { $package_name: 16 | ensure => running, 17 | enable => true, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "puppet-gitlab_ci_runner", 3 | "version": "6.1.1-rc0", 4 | "author": "Vox Pupuli", 5 | "summary": "Installation and configuration of Gitlab CI Runner", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/voxpupuli/puppet-gitlab_ci_runner", 8 | "project_page": "https://github.com/voxpupuli/puppet-gitlab_ci_runner", 9 | "issues_url": "https://github.com/voxpupuli/puppet-gitlab_ci_runner/issues", 10 | "tags": [ 11 | "git", 12 | "gitlab" 13 | ], 14 | "dependencies": [ 15 | { 16 | "name": "puppetlabs/concat", 17 | "version_requirement": ">= 6.3.0 < 10.0.0" 18 | }, 19 | { 20 | "name": "puppetlabs/stdlib", 21 | "version_requirement": ">= 4.25.0 < 10.0.0" 22 | }, 23 | { 24 | "name": "puppetlabs/apt", 25 | "version_requirement": ">= 6.3.0 < 11.0.0" 26 | } 27 | ], 28 | "operatingsystem_support": [ 29 | { 30 | "operatingsystem": "RedHat", 31 | "operatingsystemrelease": [ 32 | "8", 33 | "9" 34 | ] 35 | }, 36 | { 37 | "operatingsystem": "CentOS", 38 | "operatingsystemrelease": [ 39 | "9" 40 | ] 41 | }, 42 | { 43 | "operatingsystem": "Rocky", 44 | "operatingsystemrelease": [ 45 | "8", 46 | "9" 47 | ] 48 | }, 49 | { 50 | "operatingsystem": "AlmaLinux", 51 | "operatingsystemrelease": [ 52 | "8", 53 | "9" 54 | ] 55 | }, 56 | { 57 | "operatingsystem": "OracleLinux", 58 | "operatingsystemrelease": [ 59 | "8", 60 | "9" 61 | ] 62 | }, 63 | { 64 | "operatingsystem": "Debian", 65 | "operatingsystemrelease": [ 66 | "11", 67 | "12" 68 | ] 69 | }, 70 | { 71 | "operatingsystem": "Ubuntu", 72 | "operatingsystemrelease": [ 73 | "20.04", 74 | "22.04", 75 | "24.04" 76 | ] 77 | }, 78 | { 79 | "operatingsystem": "SLES", 80 | "operatingsystemrelease": [ 81 | "12", 82 | "15" 83 | ] 84 | } 85 | ], 86 | "requirements": [ 87 | { 88 | "name": "puppet", 89 | "version_requirement": ">= 7.0.0 < 9.0.0" 90 | }, 91 | { 92 | "name": "openvox", 93 | "version_requirement": ">= 7.0.0 < 9.0.0" 94 | } 95 | ] 96 | } 97 | -------------------------------------------------------------------------------- /scripts/start-gitlab.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | docker run --detach --rm \ 4 | --name gitlab \ 5 | --hostname gitlab \ 6 | -e GITLAB_ROOT_PASSWORD=voxpupulirocks \ 7 | --publish 80:80 \ 8 | gitlab/gitlab-ce 9 | 10 | docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' gitlab > ~/GITLAB_IP 11 | 12 | until wget -t 1 'http://localhost:80' -O /dev/null -q; do 13 | docker logs gitlab --tail 10 14 | sleep 3 15 | done 16 | 17 | OUTPUT="$(echo 'puts "INSTANCE TOKEN: #{Gitlab::CurrentSettings.current_application_settings.runners_registration_token}"' | docker exec -i gitlab gitlab-rails console)" 18 | INSTANCE_TOKEN="$(echo "$OUTPUT" | awk '/^INSTANCE TOKEN:/ {print $NF}')" 19 | echo "${INSTANCE_TOKEN}" > ~/INSTANCE_TOKEN 20 | -------------------------------------------------------------------------------- /scripts/start-squid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cat << EOF > /tmp/squid.conf 4 | http_port 3128 5 | http_access allow all 6 | logfile_rotate 0 7 | cache_log stdio:/dev/stdout 8 | access_log stdio:/dev/stdout 9 | cache_store_log stdio:/dev/stdout 10 | EOF 11 | 12 | GITLAB_IP=`cat ~/GITLAB_IP` 13 | 14 | docker run --detach --rm \ 15 | --name squid \ 16 | --hostname squid \ 17 | --publish 3128:3128 \ 18 | --env='SQUID_CONFIG_FILE=/etc/squid/my-squid.conf' \ 19 | --volume=/tmp/squid.conf:/etc/squid/my-squid.conf:ro \ 20 | --add-host="gitlab:${GITLAB_IP}" \ 21 | b4tman/squid 22 | 23 | sleep 3 24 | docker logs squid --tail 100 25 | 26 | docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' squid > ~/SQUID_IP 27 | -------------------------------------------------------------------------------- /spec/acceptance/bolt_tasks_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | require 'json' 5 | 6 | if bolt_supported? 7 | describe 'Gitlab Runner bolt tasks' do 8 | let(:registrationtoken) do 9 | File.read(File.expand_path('~/INSTANCE_TOKEN')).chomp 10 | end 11 | 12 | describe 'register_runner' do 13 | context 'registers a runner' do 14 | let(:result) do 15 | result = shell("bolt task run gitlab_ci_runner::register_runner --format json --targets localhost url=http://gitlab token=#{registrationtoken}").stdout.chomp 16 | JSON.parse(result)['items'][0]['value'] 17 | end 18 | 19 | it 'returns a valid token' do 20 | expect(result['token']).to be_instance_of(String) 21 | end 22 | 23 | it 'returns a runner id' do 24 | expect(result['id']).to be_instance_of(Integer) 25 | end 26 | end 27 | 28 | context 'returns error on failure' do 29 | let(:result) do 30 | result = shell('bolt task run gitlab_ci_runner::register_runner --format json --targets localhost url=http://gitlab token=wrong-token', acceptable_exit_codes: [0, 1, 2]).stdout.chomp 31 | JSON.parse(result)['items'][0]['value'] 32 | end 33 | 34 | it 'returns the correct exception' do 35 | expect(result['_error']['kind']).to eq('bolt-plugin/gitlab-ci-runner-register-error') 36 | end 37 | end 38 | end 39 | 40 | describe 'unregister_runner' do 41 | context 'unregisters a runner' do 42 | let(:authtoken) do 43 | result = shell("bolt task run gitlab_ci_runner::register_runner --format json --targets localhost url=http://gitlab token=#{registrationtoken}").stdout.chomp 44 | JSON.parse(result)['items'][0]['value']['token'] 45 | end 46 | let(:result) do 47 | result = shell("bolt task run gitlab_ci_runner::unregister_runner --format json --targets localhost url=http://gitlab token=#{authtoken}").stdout.chomp 48 | JSON.parse(result)['items'][0]['value'] 49 | end 50 | 51 | it 'succeeds' do 52 | expect(result['status']).to eq('success') 53 | end 54 | end 55 | 56 | context 'returns error on failure' do 57 | let(:result) do 58 | result = shell('bolt task run gitlab_ci_runner::unregister_runner --format json --targets localhost url=http://gitlab token=wrong-token', acceptable_exit_codes: [0, 1, 2]).stdout.chomp 59 | JSON.parse(result)['items'][0]['value'] 60 | end 61 | 62 | it 'returns the correct exception' do 63 | expect(result['_error']['kind']).to eq('bolt-plugin/gitlab-ci-runner-unregister-error') 64 | end 65 | end 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /spec/acceptance/class_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'gitlab_ci_runner class' do 6 | context 'default parameters' do 7 | it 'idempotently with no errors' do 8 | pp = <<-EOS 9 | include gitlab_ci_runner 10 | EOS 11 | 12 | apply_manifest(pp, catch_failures: true) 13 | apply_manifest(pp, catch_changes: true) 14 | end 15 | 16 | describe package('gitlab-runner') do 17 | it { is_expected.to be_installed } 18 | end 19 | 20 | describe service('gitlab-runner') do 21 | it { is_expected.to be_running } 22 | it { is_expected.to be_enabled } 23 | end 24 | 25 | describe file('/etc/gitlab-runner/config.toml') do 26 | it { is_expected.to contain '# MANAGED BY PUPPET' } 27 | end 28 | end 29 | 30 | context 'concurrent => 20' do 31 | it_behaves_like 'an idempotent resource' do 32 | let(:manifest) do 33 | <<-EOS 34 | class { 'gitlab_ci_runner': 35 | concurrent => 20, 36 | } 37 | EOS 38 | end 39 | end 40 | 41 | describe file('/etc/gitlab-runner/config.toml') do 42 | it { is_expected.to contain 'concurrent = 20' } 43 | end 44 | end 45 | 46 | context 'log_level => error' do 47 | it_behaves_like 'an idempotent resource' do 48 | let(:manifest) do 49 | <<-EOS 50 | class { 'gitlab_ci_runner': 51 | log_level => 'error', 52 | } 53 | EOS 54 | end 55 | end 56 | 57 | describe file('/etc/gitlab-runner/config.toml') do 58 | it { is_expected.to contain 'log_level = "error"' } 59 | end 60 | end 61 | 62 | context 'log_format => text' do 63 | it_behaves_like 'an idempotent resource' do 64 | let(:manifest) do 65 | <<-EOS 66 | class { 'gitlab_ci_runner': 67 | log_format => 'text', 68 | } 69 | EOS 70 | end 71 | end 72 | 73 | describe file('/etc/gitlab-runner/config.toml') do 74 | it { is_expected.to contain 'log_format = "text"' } 75 | end 76 | end 77 | 78 | context 'check_interval => 42' do 79 | it_behaves_like 'an idempotent resource' do 80 | let(:manifest) do 81 | <<-EOS 82 | class { 'gitlab_ci_runner': 83 | check_interval => 42, 84 | } 85 | EOS 86 | end 87 | end 88 | 89 | describe file('/etc/gitlab-runner/config.toml') do 90 | it { is_expected.to contain 'check_interval = 42' } 91 | end 92 | end 93 | 94 | context 'shutdown_timeout => 22' do 95 | it_behaves_like 'an idempotent resource' do 96 | let(:manifest) do 97 | <<-EOS 98 | class { 'gitlab_ci_runner': 99 | shutdown_timeout => 22, 100 | } 101 | EOS 102 | end 103 | end 104 | 105 | describe file('/etc/gitlab-runner/config.toml') do 106 | it { is_expected.to contain 'shutdown_timeout = 22' } 107 | end 108 | end 109 | 110 | context 'sentry_dsn => https://123abc@localhost/1' do 111 | it_behaves_like 'an idempotent resource' do 112 | let(:manifest) do 113 | <<-EOS 114 | class { 'gitlab_ci_runner': 115 | sentry_dsn => 'https://123abc@localhost/1', 116 | } 117 | EOS 118 | end 119 | end 120 | 121 | describe file('/etc/gitlab-runner/config.toml') do 122 | it { is_expected.to contain 'sentry_dsn = "https://123abc@localhost/1"' } 123 | end 124 | end 125 | 126 | context 'listen_address => localhost:9252' do 127 | it_behaves_like 'an idempotent resource' do 128 | let(:manifest) do 129 | <<-EOS 130 | class { 'gitlab_ci_runner': 131 | listen_address => 'localhost:9252', 132 | } 133 | EOS 134 | end 135 | end 136 | 137 | describe file('/etc/gitlab-runner/config.toml') do 138 | it { is_expected.to contain 'listen_address = "localhost:9252"' } 139 | end 140 | 141 | describe port('9252') do 142 | it { is_expected.to be_listening } 143 | end 144 | end 145 | 146 | context 'with session_server => { listen_address => "[::]:8093", advertise_address => "runner-host-name.tld:8093", session_timeout => 1234 }' do 147 | it_behaves_like 'an idempotent resource' do 148 | let(:manifest) do 149 | <<-EOS 150 | class { 'gitlab_ci_runner': 151 | session_server => { 152 | listen_address => "[::]:8093", 153 | advertise_address => "runner-host-name.tld:8093", 154 | session_timeout => 1234, 155 | } 156 | } 157 | EOS 158 | end 159 | end 160 | 161 | describe file('/etc/gitlab-runner/config.toml') do 162 | it { is_expected.to contain '[session_server]' } 163 | it { is_expected.to contain 'listen_address = "[::]:8093"' } 164 | it { is_expected.to contain 'advertise_address = "runner-host-name.tld:8093"' } 165 | it { is_expected.to contain 'session_timeout = 1234' } 166 | end 167 | 168 | describe port('8093') do 169 | it { is_expected.to be_listening } 170 | end 171 | end 172 | end 173 | -------------------------------------------------------------------------------- /spec/acceptance/gitlab_ci_runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'gitlab_ci_runner class' do 6 | # We run a sidecar Gitlab container next to acceptance tests. 7 | # See puppet-gitlab_ci_runner/scripts/start-gitlab.sh 8 | let(:registrationtoken) do 9 | File.read(File.expand_path('~/INSTANCE_TOKEN')).chomp 10 | end 11 | 12 | authtoken = nil 13 | context 'default parameters' do 14 | it_behaves_like 'an idempotent resource' do 15 | let(:manifest) do 16 | <<-EOS 17 | class { 'gitlab_ci_runner': 18 | manage_docker => false, 19 | runners => { 20 | test_runner => {} 21 | }, 22 | runner_defaults => { 23 | url => 'http://gitlab', 24 | registration-token => '#{registrationtoken}', 25 | executor => 'shell', 26 | } 27 | } 28 | EOS 29 | end 30 | end 31 | 32 | describe package('gitlab-runner') do 33 | it { is_expected.to be_installed } 34 | end 35 | 36 | describe service('gitlab-runner') do 37 | it { is_expected.to be_running } 38 | it { is_expected.to be_enabled } 39 | end 40 | 41 | describe 'registration' do 42 | it 'registered the runner' do 43 | authtoken = shell("grep 'token = ' /etc/gitlab-runner/config.toml | cut -d '\"' -f2").stdout.chomp 44 | shell("/usr/bin/env curl -X POST --form 'token=#{authtoken}' http://gitlab/api/v4/runners/verify") do |r| 45 | expect(JSON.parse(r.stdout)).to include('token' => authtoken.chomp) 46 | end 47 | end 48 | end 49 | end 50 | 51 | context 'unregistering' do 52 | it_behaves_like 'an idempotent resource' do 53 | let(:manifest) do 54 | <<-EOS 55 | class { 'gitlab_ci_runner': 56 | manage_docker => false, 57 | runners => { 58 | test_runner => { 59 | ensure => absent, 60 | } 61 | }, 62 | runner_defaults => { 63 | url => 'http://gitlab', 64 | registration-token => '#{registrationtoken}', 65 | executor => 'shell', 66 | } 67 | } 68 | EOS 69 | end 70 | end 71 | 72 | describe package('gitlab-runner') do 73 | it { is_expected.to be_installed } 74 | end 75 | 76 | describe service('gitlab-runner') do 77 | it { is_expected.to be_running } 78 | it { is_expected.to be_enabled } 79 | end 80 | 81 | describe 'registration' do 82 | it 'unregistered the runner' do 83 | shell("/usr/bin/env curl -X POST --form 'token=#{authtoken}' http://gitlab/api/v4/runners/verify") do |r| 84 | expect(JSON.parse(r.stdout)).to include('message' => '403 Forbidden') 85 | end 86 | end 87 | end 88 | end 89 | 90 | context 'using proxy parameters' do 91 | it_behaves_like 'an idempotent resource' do 92 | let(:manifest) do 93 | <<-EOS 94 | class { 'gitlab_ci_runner': 95 | http_proxy => 'http://squid:3128', 96 | manage_docker => false, 97 | runners => { 98 | test_runner => {} 99 | }, 100 | runner_defaults => { 101 | url => 'http://gitlab', 102 | registration-token => '#{registrationtoken}', 103 | executor => 'shell', 104 | } 105 | } 106 | EOS 107 | end 108 | end 109 | 110 | describe package('gitlab-runner') do 111 | it { is_expected.to be_installed } 112 | end 113 | 114 | describe service('gitlab-runner') do 115 | it { is_expected.to be_running } 116 | it { is_expected.to be_enabled } 117 | end 118 | 119 | describe 'registration' do 120 | it 'registered the runner' do 121 | authtoken = shell("grep 'token = ' /etc/gitlab-runner/config.toml | cut -d '\"' -f2").stdout.chomp 122 | shell("/usr/bin/env curl -X POST --form 'token=#{authtoken}' http://gitlab/api/v4/runners/verify") do |r| 123 | expect(JSON.parse(r.stdout)).to include('token' => authtoken.chomp) 124 | end 125 | end 126 | end 127 | end 128 | end 129 | -------------------------------------------------------------------------------- /spec/acceptance/runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper_acceptance' 4 | 5 | describe 'gitlab_ci_runner::runner define' do 6 | context 'simple runner' do 7 | it_behaves_like 'an idempotent resource' do 8 | let(:manifest) do 9 | <<-EOS 10 | gitlab_ci_runner::runner { 'testrunner': 11 | config => { 12 | 'url' => 'https://gitlab.com', 13 | 'token' => '123456789abcdefgh', 14 | 'executor' => 'shell', 15 | }, 16 | } 17 | EOS 18 | end 19 | end 20 | 21 | describe package('gitlab-runner') do 22 | it { is_expected.to be_installed } 23 | end 24 | 25 | describe service('gitlab-runner') do 26 | it { is_expected.to be_running } 27 | it { is_expected.to be_enabled } 28 | end 29 | 30 | describe file('/etc/gitlab-runner/config.toml') do 31 | it { is_expected.to contain '[[runners]]' } 32 | it { is_expected.to contain 'name = "testrunner"' } 33 | it { is_expected.to contain 'url = "https://gitlab.com"' } 34 | it { is_expected.to contain 'token = "123456789abcdefgh"' } 35 | it { is_expected.to contain 'executor = "shell"' } 36 | end 37 | end 38 | 39 | context 'autoscaling runner with DigitalOcean as IaaS' do 40 | it_behaves_like 'an idempotent resource' do 41 | let(:manifest) do 42 | <<-EOS 43 | gitlab_ci_runner::runner { 'autoscale-runner': 44 | config => { 45 | url => 'https://gitlab.com', 46 | token => '123456789abcdefgh', 47 | name => 'autoscale-runner', 48 | executor => 'docker+machine', 49 | limit => 10, 50 | docker => { 51 | image => 'ruby:2.6', 52 | }, 53 | machine => { 54 | 'OffPeakPeriods' => [ 55 | '* * 0-9,18-23 * * mon-fri *', 56 | '* * * * * sat,sun *', 57 | ], 58 | 'OffPeakIdleCount' => 1, 59 | 'OffPeakIdleTime' => 1200, 60 | 'IdleCount' => 5, 61 | 'IdleTime' => 600, 62 | 'MaxBuilds' => 100, 63 | 'MachineName' => 'auto-scale-%s', 64 | 'MachineDriver' => 'digitalocean', 65 | 'MachineOptions' => [ 66 | 'digitalocean-image=coreos-stable', 67 | 'digitalocean-ssh-user=core', 68 | 'digitalocean-access-token=DO_ACCESS_TOKEN', 69 | 'digitalocean-region=nyc2', 70 | 'digitalocean-size=4gb', 71 | 'digitalocean-private-networking', 72 | 'engine-registry-mirror=http://10.11.12.13:12345', 73 | ], 74 | }, 75 | cache => { 76 | 'Type' => 's3', 77 | s3 => { 78 | 'ServerAddress' => 's3-eu-west-1.amazonaws.com', 79 | 'AccessKey' => 'AMAZON_S3_ACCESS_KEY', 80 | 'SecretKey' => 'AMAZON_S3_SECRET_KEY', 81 | 'BucketName' => 'runner', 82 | 'Insecure' => false, 83 | }, 84 | }, 85 | }, 86 | } 87 | EOS 88 | end 89 | end 90 | 91 | describe package('gitlab-runner') do 92 | it { is_expected.to be_installed } 93 | end 94 | 95 | describe service('gitlab-runner') do 96 | it { is_expected.to be_running } 97 | it { is_expected.to be_enabled } 98 | end 99 | 100 | describe file('/etc/gitlab-runner/config.toml') do 101 | it { is_expected.to contain '[[runners]]' } 102 | it { is_expected.to contain 'url = "https://gitlab.com"' } 103 | it { is_expected.to contain 'token = "123456789abcdefgh"' } 104 | it { is_expected.to contain 'name = "autoscale-runner"' } 105 | it { is_expected.to contain 'executor = "docker+machine"' } 106 | it { is_expected.to contain 'limit = 10' } 107 | it { is_expected.to contain '[runners.docker]' } 108 | it { is_expected.to contain 'image = "ruby:2.6"' } 109 | it { is_expected.to contain '[runners.machine]' } 110 | it { is_expected.to contain 'OffPeakPeriods = ["* * 0-9,18-23 * * mon-fri *", "* * * * * sat,sun *"]' } 111 | it { is_expected.to contain 'OffPeakIdleCount = 1' } 112 | it { is_expected.to contain 'OffPeakIdleTime = 1200' } 113 | it { is_expected.to contain 'IdleCount = 5' } 114 | it { is_expected.to contain 'IdleTime = 600' } 115 | it { is_expected.to contain 'MaxBuilds = 100' } 116 | it { is_expected.to contain 'MachineName = "auto-scale-%s"' } 117 | it { is_expected.to contain 'MachineDriver = "digitalocean"' } 118 | it { is_expected.to contain 'MachineOptions = ["digitalocean-image=coreos-stable", "digitalocean-ssh-user=core", "digitalocean-access-token=DO_ACCESS_TOKEN", "digitalocean-region=nyc2", "digitalocean-size=4gb", "digitalocean-private-networking", "engine-registry-mirror=http://10.11.12.13:12345"]' } 119 | it { is_expected.to contain '[runners.cache]' } 120 | it { is_expected.to contain 'Type = "s3"' } 121 | it { is_expected.to contain '[runners.cache.s3]' } 122 | it { is_expected.to contain 'ServerAddress = "s3-eu-west-1.amazonaws.com"' } 123 | it { is_expected.to contain 'AccessKey = "AMAZON_S3_ACCESS_KEY"' } 124 | it { is_expected.to contain 'SecretKey = "AMAZON_S3_SECRET_KEY"' } 125 | it { is_expected.to contain 'BucketName = "runner"' } 126 | it { is_expected.to contain 'Insecure = false' } 127 | end 128 | end 129 | end 130 | -------------------------------------------------------------------------------- /spec/classes/gitlab_ci_runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe 'gitlab_ci_runner', type: :class do 6 | let(:undef_value) do 7 | Puppet::Util::Package.versioncmp(Puppet.version, '6.0.0') < 0 ? :undef : nil 8 | end 9 | 10 | on_supported_os.each do |os, facts| 11 | context "on #{os}" do 12 | before do 13 | # Make 'gitlab_ci_runner::register_to_file' think that we already have a token on disk 14 | # This ensure the function won't call a Gitlab server to try getting the auth token. 15 | allow(File).to receive(:exist?).and_call_original 16 | allow(File).to receive(:exist?).with('/etc/gitlab-runner/auth-token-test_runner').and_return(true) 17 | allow(File).to receive(:read).and_call_original 18 | allow(File).to receive(:read).with('/etc/gitlab-runner/auth-token-test_runner').and_return('authtoken') 19 | end 20 | 21 | let(:facts) do 22 | facts 23 | end 24 | let(:params) do 25 | { 26 | 'runner_defaults' => { 27 | 'url' => 'https://git.example.com/ci', 28 | 'registration-token' => '1234567890abcdef', 29 | 'executor' => 'shell' 30 | }, 31 | 'runners' => { 32 | 'test_runner' => {} 33 | } 34 | } 35 | end 36 | 37 | it { is_expected.to compile.with_all_deps } 38 | 39 | it { is_expected.not_to contain_class('docker') } 40 | it { is_expected.not_to contain_class('docker::images') } 41 | 42 | it { is_expected.to contain_package('gitlab-runner') } unless facts[:os]['family'] == 'Suse' 43 | 44 | it { is_expected.to contain_service('gitlab-runner') } 45 | it { is_expected.to contain_class('gitlab_ci_runner::install') } 46 | 47 | it do 48 | is_expected.to contain_class('gitlab_ci_runner::config'). 49 | that_requires('Class[gitlab_ci_runner::install]'). 50 | that_notifies('Class[gitlab_ci_runner::service]') 51 | end 52 | 53 | it { is_expected.to contain_class('gitlab_ci_runner::service') } 54 | 55 | it do 56 | is_expected.to contain_concat('/etc/gitlab-runner/config.toml'). 57 | with( 58 | ensure: 'present', 59 | owner: 'root', 60 | group: 'root', 61 | mode: '0444', 62 | ensure_newline: true 63 | ) 64 | end 65 | 66 | it do 67 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - header'). 68 | with( 69 | target: '/etc/gitlab-runner/config.toml', 70 | order: 0, 71 | content: '# MANAGED BY PUPPET' 72 | ) 73 | end 74 | 75 | describe 'ca_file' do 76 | context 'without ca_file' do 77 | it { is_expected.to contain_gitlab_ci_runner__runner('test_runner').without(['ca_file']) } 78 | end 79 | 80 | context 'with ca_file' do 81 | let(:params) { super().merge(ca_file: '/path/to/ca_file') } 82 | 83 | it { is_expected.to contain_gitlab_ci_runner__runner('test_runner').with_ca_file('/path/to/ca_file') } 84 | end 85 | end 86 | 87 | describe 'runner ensure' do 88 | before do 89 | allow(File).to receive(:exist?).and_call_original 90 | allow(File).to receive(:read).and_call_original 91 | allow(File).to receive(:exist?).with('/etc/gitlab-runner/auth-token-runner_with_ensure_present').and_return(true) 92 | allow(File).to receive(:read).with('/etc/gitlab-runner/auth-token-runner_with_ensure_present').and_return('authtoken') 93 | allow(File).to receive(:exist?).with('/etc/gitlab-runner/auth-token-runner_with_ensure_absent').and_return(false) 94 | end 95 | 96 | let(:params) do 97 | { 98 | runner_defaults: { 99 | 'url' => 'https://git.example.com/ci', 100 | 'registration-token' => '1234567890abcdef', 101 | 'executor' => 'shell' 102 | }, 103 | runners: { 104 | 'runner_with_ensure_absent' => { 'ensure' => 'absent' }, 105 | 'runner_with_ensure_present' => { 'ensure' => 'present' }, 106 | } 107 | } 108 | end 109 | 110 | it { is_expected.to contain_gitlab_ci_runner__runner('runner_with_ensure_present').with_ensure('present') } 111 | it { is_expected.to contain_gitlab_ci_runner__runner('runner_with_ensure_absent').with_ensure('absent') } 112 | end 113 | 114 | context 'with config permissions' do 115 | let(:params) do 116 | { 117 | 'runner_defaults' => {}, 118 | 'runners' => {}, 119 | 'config_owner' => 'gitlab-runner', 120 | 'config_group' => 'gitlab-runner', 121 | 'config_mode' => '0640' 122 | } 123 | end 124 | 125 | it do 126 | is_expected.to contain_concat('/etc/gitlab-runner/config.toml').with('owner' => 'gitlab-runner', 127 | 'group' => 'gitlab-runner', 128 | 'mode' => '0640') 129 | end 130 | end 131 | 132 | context 'with manage_config_dir => true' do 133 | let(:params) do 134 | { 135 | 'runner_defaults' => {}, 136 | 'runners' => {}, 137 | 'manage_config_dir' => true 138 | } 139 | end 140 | 141 | it do 142 | is_expected.to contain_file('/etc/gitlab-runner').with('ensure' => 'directory') 143 | end 144 | end 145 | 146 | context 'with config dir permissions' do 147 | let(:params) do 148 | { 149 | 'runner_defaults' => {}, 150 | 'runners' => {}, 151 | 'manage_config_dir' => true, 152 | 'config_owner' => 'gitlab-runner', 153 | 'config_group' => 'gitlab-runner', 154 | 'config_dir_mode' => '0750' 155 | } 156 | end 157 | 158 | it do 159 | is_expected.to contain_file('/etc/gitlab-runner').with('ensure' => 'directory', 160 | 'owner' => 'gitlab-runner', 161 | 'group' => 'gitlab-runner', 162 | 'mode' => '0750') 163 | end 164 | end 165 | 166 | context 'with concurrent => 10' do 167 | let(:params) do 168 | { 169 | 'concurrent' => 10 170 | } 171 | end 172 | 173 | it do 174 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 175 | with( 176 | target: '/etc/gitlab-runner/config.toml', 177 | order: 1, 178 | content: %r{concurrent = 10} 179 | ) 180 | end 181 | end 182 | 183 | context 'with log_level => error' do 184 | let(:params) do 185 | { 186 | 'log_level' => 'error' 187 | } 188 | end 189 | 190 | it do 191 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 192 | with( 193 | target: '/etc/gitlab-runner/config.toml', 194 | order: 1, 195 | content: %r{log_level = "error"} 196 | ) 197 | end 198 | end 199 | 200 | context 'with log_format => json' do 201 | let(:params) do 202 | { 203 | 'log_format' => 'json' 204 | } 205 | end 206 | 207 | it do 208 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 209 | with( 210 | target: '/etc/gitlab-runner/config.toml', 211 | order: 1, 212 | content: %r{log_format = "json"} 213 | ) 214 | end 215 | end 216 | 217 | context 'with check_interval => 6' do 218 | let(:params) do 219 | { 220 | 'check_interval' => 6 221 | } 222 | end 223 | 224 | it do 225 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 226 | with( 227 | target: '/etc/gitlab-runner/config.toml', 228 | order: 1, 229 | content: %r{check_interval = 6} 230 | ) 231 | end 232 | end 233 | 234 | context 'with shutdown_timeout => 4' do 235 | let(:params) do 236 | { 237 | 'shutdown_timeout' => 4 238 | } 239 | end 240 | 241 | it do 242 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 243 | with( 244 | target: '/etc/gitlab-runner/config.toml', 245 | order: 1, 246 | content: %r{shutdown_timeout = 4} 247 | ) 248 | end 249 | end 250 | 251 | context 'with sentry_dsn => https://123abc@localhost/1' do 252 | let(:params) do 253 | { 254 | 'sentry_dsn' => 'https://123abc@localhost/1' 255 | } 256 | end 257 | 258 | it do 259 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 260 | with( 261 | target: '/etc/gitlab-runner/config.toml', 262 | order: 1, 263 | content: %r{sentry_dsn = "https://123abc@localhost/1"} 264 | ) 265 | end 266 | end 267 | 268 | context 'with listen_address => localhost:9252' do 269 | let(:params) do 270 | { 271 | 'listen_address' => 'localhost:9252' 272 | } 273 | end 274 | 275 | it do 276 | is_expected.to contain_concat__fragment('/etc/gitlab-runner/config.toml - global options'). 277 | with( 278 | target: '/etc/gitlab-runner/config.toml', 279 | order: 1, 280 | content: %r{listen_address = "localhost:9252"} 281 | ) 282 | end 283 | end 284 | 285 | context 'with session_server' do 286 | context 'with session_server => { listen_address => "[::]:8093", advertise_address => "runner-host-name.tld:8093"}' do 287 | let(:params) do 288 | { 289 | 'session_server' => { 290 | listen_address: '[::]:8093', 291 | advertise_address: 'runner-host-name.tld:8093', 292 | } 293 | } 294 | end 295 | 296 | it do 297 | verify_concat_fragment_exact_contents( 298 | catalogue, 299 | '/etc/gitlab-runner/config.toml - global options', 300 | [ 301 | '[session_server]', 302 | 'listen_address = "[::]:8093"', 303 | 'advertise_address = "runner-host-name.tld:8093"', 304 | ] 305 | ) 306 | end 307 | end 308 | 309 | context 'with session_server => { listen_address => "[::]:8093", advertise_address => "runner-host-name.tld:8093", session_timeout => 1234 }' do 310 | let(:params) do 311 | { 312 | 'session_server' => { 313 | listen_address: '[::]:8093', 314 | advertise_address: 'runner-host-name.tld:8093', 315 | session_timeout: 1234, 316 | } 317 | } 318 | end 319 | 320 | it do 321 | verify_concat_fragment_exact_contents( 322 | catalogue, 323 | '/etc/gitlab-runner/config.toml - global options', 324 | [ 325 | '[session_server]', 326 | 'listen_address = "[::]:8093"', 327 | 'advertise_address = "runner-host-name.tld:8093"', 328 | 'session_timeout = 1234' 329 | ] 330 | ) 331 | end 332 | end 333 | end 334 | 335 | context 'with manage_docker => true' do 336 | let(:params) do 337 | { 338 | manage_docker: true 339 | } 340 | end 341 | 342 | unless facts[:os]['family'] == 'Suse' 343 | it { is_expected.to compile } 344 | 345 | it { is_expected.to contain_class('docker') } 346 | 347 | it do 348 | is_expected.to contain_class('docker::images'). 349 | with( 350 | images: { 351 | 'ubuntu_focal' => { 352 | 'image' => 'ubuntu', 353 | 'image_tag' => 'focal' 354 | } 355 | } 356 | ) 357 | end 358 | end 359 | end 360 | 361 | context 'with manage_repo => true' do 362 | let(:params) do 363 | super().merge( 364 | manage_repo: true 365 | ) 366 | end 367 | 368 | unless facts[:os]['family'] == 'Suse' 369 | it { is_expected.to compile } 370 | it { is_expected.to contain_class('gitlab_ci_runner::repo') } 371 | end 372 | case facts[:os]['family'] 373 | when 'Debian' 374 | it do 375 | is_expected.to contain_apt__source('apt_gitlabci'). 376 | with( 377 | comment: 'GitlabCI Runner Repo', 378 | location: "https://packages.gitlab.com/runner/gitlab-runner/#{facts[:os]['name'].downcase}/", 379 | repos: 'main', 380 | key: { 381 | 'name' => 'gitlab_ci_runner.asc', 382 | 'server' => undef_value, 383 | 'source' => 'https://packages.gitlab.com/gpg.key', 384 | }, 385 | include: { 386 | 'src' => false, 387 | 'deb' => true 388 | } 389 | ) 390 | end 391 | when 'RedHat' 392 | os_release_version = if facts[:os]['name'] == 'Amazon' 393 | if facts[:os]['release']['major'] == '2' 394 | '7' 395 | else 396 | '6' 397 | end 398 | else 399 | '$releasever' 400 | end 401 | 402 | it do 403 | is_expected.to contain_yumrepo('runner_gitlab-runner'). 404 | with( 405 | ensure: 'present', 406 | baseurl: "https://packages.gitlab.com/runner/gitlab-runner/el/#{os_release_version}/$basearch", 407 | descr: 'runner_gitlab-runner', 408 | enabled: '1', 409 | gpgcheck: '1', 410 | gpgkey: 'https://packages.gitlab.com/gpg.key https://packages.gitlab.com/runner/gitlab-runner/gpgkey/runner-gitlab-runner-49F16C5CC3A0F81F.pub.gpg', 411 | repo_gpgcheck: '1', 412 | sslcacert: '/etc/pki/tls/certs/ca-bundle.crt', 413 | sslverify: '1' 414 | ) 415 | end 416 | 417 | it do 418 | is_expected.to contain_yumrepo('runner_gitlab-runner-source'). 419 | with( 420 | ensure: 'present', 421 | baseurl: "https://packages.gitlab.com/runner/gitlab-runner/el/#{os_release_version}/SRPMS", 422 | descr: 'runner_gitlab-runner-source', 423 | enabled: '1', 424 | gpgcheck: '1', 425 | gpgkey: 'https://packages.gitlab.com/gpg.key https://packages.gitlab.com/runner/gitlab-runner/gpgkey/runner-gitlab-runner-49F16C5CC3A0F81F.pub.gpg', 426 | repo_gpgcheck: '1', 427 | sslcacert: '/etc/pki/tls/certs/ca-bundle.crt', 428 | sslverify: '1' 429 | ) 430 | end 431 | 432 | context 'when package_gpgcheck is false' do 433 | let(:params) do 434 | super().merge(package_gpgcheck: false) 435 | end 436 | 437 | it do 438 | is_expected.to contain_yumrepo('runner_gitlab-runner').with_gpgcheck('0') 439 | end 440 | 441 | it do 442 | is_expected.to contain_yumrepo('runner_gitlab-runner-source').with_gpgcheck('0') 443 | end 444 | end 445 | end 446 | end 447 | 448 | if facts[:os]['family'] == 'Debian' 449 | # <= v3.0.0 450 | context 'with manage_repo => true and repo_keyserver => keys.gnupg.net' do 451 | let(:params) do 452 | super().merge( 453 | manage_repo: true, 454 | repo_keyserver: 'keys.gnupg.net' 455 | ) 456 | end 457 | 458 | it { is_expected.to compile } 459 | it { is_expected.to contain_class('gitlab_ci_runner::repo') } 460 | 461 | it do 462 | is_expected.to contain_apt__source('apt_gitlabci').with_key('name' => 'gitlab_ci_runner.asc', 'source' => 'https://packages.gitlab.com/gpg.key', 'server' => 'keys.gnupg.net') 463 | end 464 | end 465 | 466 | # allowed > 3.0.0 (see issue #101) 467 | context 'with manage_repo => true and repo_keyserver => hkp://keys.gnupg.net:80' do 468 | let(:params) do 469 | super().merge( 470 | manage_repo: true, 471 | repo_keyserver: 'hkp://keys.gnupg.net:80' 472 | ) 473 | end 474 | 475 | it { is_expected.to compile } 476 | it { is_expected.to contain_class('gitlab_ci_runner::repo') } 477 | 478 | it do 479 | is_expected.to contain_apt__source('apt_gitlabci').with_key('name' => 'gitlab_ci_runner.asc', 'source' => 'https://packages.gitlab.com/gpg.key', 'server' => 'hkp://keys.gnupg.net:80') 480 | end 481 | end 482 | 483 | context 'with manage_repo => true and repo_keyserver => https://keys.gnupg.net:88' do 484 | let(:params) do 485 | super().merge( 486 | manage_repo: true, 487 | repo_keyserver: 'https://keys.gnupg.net:88' 488 | ) 489 | end 490 | 491 | it { is_expected.to compile } 492 | it { is_expected.to contain_class('gitlab_ci_runner::repo') } 493 | 494 | it do 495 | is_expected.to contain_apt__source('apt_gitlabci').with_key('name' => 'gitlab_ci_runner.asc', 'source' => 'https://packages.gitlab.com/gpg.key', 'server' => 'https://keys.gnupg.net:88') 496 | end 497 | end 498 | end 499 | end 500 | end 501 | end 502 | -------------------------------------------------------------------------------- /spec/defines/runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe 'gitlab_ci_runner::runner' do 6 | on_supported_os.each do |os, facts| 7 | context "on #{os}" do 8 | let(:facts) { facts } 9 | let(:title) { 'testrunner' } 10 | 11 | context 'with simple shell runner' do 12 | let(:params) do 13 | { 14 | config: { 15 | url: 'https://gitlab.com', 16 | token: '123456789abcdefgh', 17 | executor: 'shell' 18 | } 19 | } 20 | end 21 | 22 | it { is_expected.to compile.with_all_deps } 23 | 24 | it do 25 | verify_concat_fragment_exact_contents( 26 | catalogue, 27 | '/etc/gitlab-runner/config.toml - testrunner', 28 | [ 29 | '[[runners]]', 30 | 'name = "testrunner"', 31 | 'url = "https://gitlab.com"', 32 | 'token = "123456789abcdefgh"', 33 | 'executor = "shell"' 34 | ] 35 | ) 36 | end 37 | end 38 | 39 | context 'with autoscaling runner with DigitalOcean as IaaS' do 40 | let(:params) do 41 | { 42 | config: { 43 | url: 'https://gitlab.com', 44 | token: '123456789abcdefgh', 45 | name: 'autoscale-runner', 46 | executor: 'docker+machine', 47 | limit: 10, 48 | docker: { 49 | image: 'ruby:2.6' 50 | }, 51 | machine: { 52 | OffPeakPeriods: [ 53 | '* * 0-9,18-23 * * mon-fri *', 54 | '* * * * * sat,sun *' 55 | ], 56 | OffPeakIdleCount: 1, 57 | OffPeakIdleTime: 1200, 58 | IdleCount: 5, 59 | IdleTime: 600, 60 | MaxBuilds: 100, 61 | MachineName: 'auto-scale-%s', 62 | MachineDriver: 'digitalocean', 63 | MachineOptions: [ 64 | 'digitalocean-image=coreos-stable', 65 | 'digitalocean-ssh-user=core', 66 | 'digitalocean-access-token=DO_ACCESS_TOKEN', 67 | 'digitalocean-region=nyc2', 68 | 'digitalocean-size=4gb', 69 | 'digitalocean-private-networking', 70 | 'engine-registry-mirror=http://10.11.12.13:12345' 71 | ] 72 | }, 73 | cache: { 74 | Type: 's3', 75 | s3: { 76 | ServerAddress: 's3-eu-west-1.amazonaws.com', 77 | AccessKey: 'AMAZON_S3_ACCESS_KEY', 78 | SecretKey: 'AMAZON_S3_SECRET_KEY', 79 | BucketName: 'runner', 80 | Insecure: false 81 | } 82 | } 83 | } 84 | } 85 | end 86 | 87 | it { is_expected.to compile.with_all_deps } 88 | 89 | it do 90 | verify_concat_fragment_exact_contents( 91 | catalogue, 92 | '/etc/gitlab-runner/config.toml - testrunner', 93 | [ 94 | '[[runners]]', 95 | 'url = "https://gitlab.com"', 96 | 'token = "123456789abcdefgh"', 97 | 'name = "autoscale-runner"', 98 | 'executor = "docker+machine"', 99 | 'limit = 10', 100 | '[runners.docker]', 101 | 'image = "ruby:2.6"', 102 | '[runners.machine]', 103 | 'OffPeakPeriods = ["* * 0-9,18-23 * * mon-fri *", "* * * * * sat,sun *"]', 104 | 'OffPeakIdleCount = 1', 105 | 'OffPeakIdleTime = 1200', 106 | 'IdleCount = 5', 107 | 'IdleTime = 600', 108 | 'MaxBuilds = 100', 109 | 'MachineName = "auto-scale-%s"', 110 | 'MachineDriver = "digitalocean"', 111 | 'MachineOptions = ["digitalocean-image=coreos-stable", "digitalocean-ssh-user=core", "digitalocean-access-token=DO_ACCESS_TOKEN", "digitalocean-region=nyc2", "digitalocean-size=4gb", "digitalocean-private-networking", "engine-registry-mirror=http://10.11.12.13:12345"]', 112 | '[runners.cache]', 113 | 'Type = "s3"', 114 | '[runners.cache.s3]', 115 | 'ServerAddress = "s3-eu-west-1.amazonaws.com"', 116 | 'AccessKey = "AMAZON_S3_ACCESS_KEY"', 117 | 'SecretKey = "AMAZON_S3_SECRET_KEY"', 118 | 'BucketName = "runner"', 119 | 'Insecure = false' 120 | ] 121 | ) 122 | end 123 | end 124 | 125 | context 'with name not included in config' do 126 | let(:params) do 127 | { 128 | config: {} 129 | } 130 | end 131 | 132 | it { is_expected.to compile.with_all_deps } 133 | 134 | it do 135 | verify_concat_fragment_exact_contents( 136 | catalogue, 137 | '/etc/gitlab-runner/config.toml - testrunner', 138 | [ 139 | '[[runners]]', 140 | 'name = "testrunner"' 141 | ] 142 | ) 143 | end 144 | end 145 | 146 | context 'with name included in config' do 147 | let(:params) do 148 | { 149 | config: { 150 | name: 'foo-runner' 151 | } 152 | } 153 | end 154 | 155 | it { is_expected.to compile.with_all_deps } 156 | 157 | it do 158 | verify_concat_fragment_exact_contents( 159 | catalogue, 160 | '/etc/gitlab-runner/config.toml - testrunner', 161 | [ 162 | '[[runners]]', 163 | 'name = "foo-runner"' 164 | ] 165 | ) 166 | end 167 | end 168 | end 169 | end 170 | end 171 | -------------------------------------------------------------------------------- /spec/functions/register_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'webmock/rspec' 5 | 6 | describe 'gitlab_ci_runner::register' do 7 | let(:url) { 'https://gitlab.example.org' } 8 | let(:regtoken) { 'registration-token' } 9 | let(:return_hash) do 10 | { 11 | 'id' => 1234, 12 | 'token' => 'auth-token' 13 | } 14 | end 15 | 16 | it { is_expected.not_to eq(nil) } 17 | it { is_expected.to run.with_params.and_raise_error(ArgumentError) } 18 | it { is_expected.to run.with_params('').and_raise_error(ArgumentError) } 19 | it { is_expected.to run.with_params('ftp://foooo.bar').and_raise_error(ArgumentError) } 20 | it { is_expected.to run.with_params('https://gitlab.com', 1234).and_raise_error(ArgumentError) } 21 | it { is_expected.to run.with_params('https://gitlab.com', 'registration-token', project: 1234).and_raise_error(ArgumentError) } 22 | 23 | it "calls 'PuppetX::Gitlab::Runner.register'" do 24 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken }, ca_file: nil).and_return(return_hash) 25 | 26 | is_expected.to run.with_params(url, regtoken).and_return(return_hash) 27 | expect(PuppetX::Gitlab::Runner).to have_received(:register) 28 | end 29 | 30 | it "passes additional args to 'PuppetX::Gitlab::Runner.register'" do 31 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken, 'active' => false }, ca_file: nil).and_return(return_hash) 32 | 33 | is_expected.to run.with_params(url, regtoken, 'active' => false).and_return(return_hash) 34 | expect(PuppetX::Gitlab::Runner).to have_received(:register) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/functions/register_to_file_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'webmock/rspec' 5 | 6 | describe 'gitlab_ci_runner::register_to_file' do 7 | let(:url) { 'https://gitlab.example.org' } 8 | let(:regtoken) { 'registration-token' } 9 | let(:runner_name) { 'testrunner' } 10 | let(:filename) { "/etc/gitlab-runner/auth-token-#{runner_name}" } 11 | let(:return_hash) do 12 | { 13 | 'id' => 1234, 14 | 'token' => 'auth-token' 15 | } 16 | end 17 | 18 | it { is_expected.not_to eq(nil) } 19 | it { is_expected.to run.with_params.and_raise_error(ArgumentError) } 20 | it { is_expected.to run.with_params('').and_raise_error(ArgumentError) } 21 | it { is_expected.to run.with_params('ftp://foooo.bar').and_raise_error(ArgumentError) } 22 | it { is_expected.to run.with_params('https://gitlab.com', 1234).and_raise_error(ArgumentError) } 23 | it { is_expected.to run.with_params('https://gitlab.com', 'registration-token', project: 1234).and_raise_error(ArgumentError) } 24 | 25 | context 'uses an existing auth token from file' do 26 | before do 27 | allow(File).to receive(:exist?).and_call_original 28 | allow(File).to receive(:exist?).with(filename).and_return(true) 29 | allow(File).to receive(:read).and_call_original 30 | allow(File).to receive(:read).with(filename).and_return(return_hash['token']) 31 | end 32 | 33 | it { is_expected.to run.with_params(url, regtoken, runner_name).and_return(return_hash['token']) } 34 | end 35 | 36 | context "retrieves from Gitlab and writes auth token to file if it doesn't exist" do 37 | before do 38 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken }, nil, nil).and_return(return_hash) 39 | allow(File).to receive(:exist?).and_call_original 40 | allow(File).to receive(:exist?).with(File.dirname(filename)).and_return(true) 41 | allow(File).to receive(:write).with(filename, return_hash['token']) 42 | allow(File).to receive(:chmod).with(0o400, filename) 43 | end 44 | 45 | it { is_expected.to run.with_params(url, regtoken, runner_name).and_return(return_hash['token']) } 46 | 47 | context 'with existing file ca_file option' do 48 | before do 49 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken }, nil, '/tmp').and_return(return_hash) 50 | end 51 | 52 | it { is_expected.to run.with_params(url, regtoken, runner_name, {}, nil, '/tmp').and_return(return_hash['token']) } 53 | end 54 | 55 | context 'with non existent ca_file option' do 56 | before do 57 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken }, nil, '/path/to/ca_file').and_return(return_hash) 58 | end 59 | 60 | it { is_expected.to run.with_params(url, regtoken, runner_name, {}, nil, '/path/to/ca_file').and_return('Specified CA file doesn\'t exist, not attempting to create authtoken') } 61 | end 62 | 63 | context 'with sensitive token value' do 64 | before do 65 | allow(PuppetX::Gitlab::Runner).to receive(:register).with(url, { 'token' => regtoken }, nil, '/tmp').and_return(return_hash) 66 | end 67 | 68 | it { is_expected.to run.with_params(url, sensitive(regtoken), runner_name, {}, nil, '/tmp').and_return(return_hash['token']) } 69 | end 70 | end 71 | 72 | context 'noop does not register runner and returns dummy token' do 73 | before do 74 | allow(Puppet.settings).to receive(:[]).and_call_original 75 | allow(Puppet.settings).to receive(:[]).with(:noop).and_return(true) 76 | end 77 | 78 | it { is_expected.to run.with_params(url, regtoken, runner_name).and_return('DUMMY-NOOP-TOKEN') } 79 | end 80 | end 81 | -------------------------------------------------------------------------------- /spec/functions/to_toml_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe 'gitlab_ci_runner::to_toml' do 6 | context 'fails on invalid params' do 7 | it { is_expected.not_to eq(nil) } 8 | 9 | [ 10 | nil, 11 | '', 12 | 'foobar', 13 | 1, 14 | true, 15 | false, 16 | [] 17 | ].each do |value| 18 | it { is_expected.to run.with_params(value).and_raise_error(ArgumentError) } 19 | end 20 | end 21 | 22 | context 'returns TOML string on valid params' do 23 | it { is_expected.to run.with_params({}).and_return('') } 24 | it { is_expected.to run.with_params(foo: 'bar').and_return("foo = \"bar\"\n") } 25 | it { is_expected.to run.with_params(foo: { bar: 'baz' }).and_return("[foo]\nbar = \"baz\"\n") } 26 | it { is_expected.to run.with_params(foo: %w[bar baz]).and_return("foo = [\"bar\", \"baz\"]\n") } 27 | it { is_expected.to run.with_params(foo: [{ bar: {}, baz: {} }]).and_return("[[foo]]\n[foo.bar]\n[foo.baz]\n") } 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/functions/unregister_from_file_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'webmock/rspec' 5 | 6 | describe 'gitlab_ci_runner::unregister_from_file' do 7 | let(:url) { 'https://gitlab.example.org' } 8 | let(:runner_name) { 'testrunner' } 9 | let(:filename) { "/etc/gitlab-runner/auth-token-#{runner_name}" } 10 | 11 | it { is_expected.not_to eq(nil) } 12 | it { is_expected.to run.with_params.and_raise_error(ArgumentError) } 13 | it { is_expected.to run.with_params('').and_raise_error(ArgumentError) } 14 | it { is_expected.to run.with_params('https://gitlab.com', 1234).and_raise_error(ArgumentError) } 15 | 16 | context 'uses an existing auth token from file to unregister the runner' do 17 | before do 18 | allow(File).to receive(:exist?).and_call_original 19 | allow(File).to receive(:exist?).with(filename).and_return(true) 20 | allow(File).to receive(:read).and_call_original 21 | allow(File).to receive(:read).with(filename).and_return('authtoken') 22 | allow(PuppetX::Gitlab::Runner).to receive(:unregister).with(url, { 'token' => 'authtoken' }, nil, nil).and_return(nil) 23 | end 24 | 25 | it { is_expected.to run.with_params(url, runner_name).and_return('Successfully unregistered gitlab runner testrunner') } 26 | 27 | context 'with existing file ca_file option' do 28 | before do 29 | allow(PuppetX::Gitlab::Runner).to receive(:unregister).with(url, { 'token' => 'authtoken' }, nil, '/tmp').and_return(nil) 30 | end 31 | 32 | it { is_expected.to run.with_params(url, runner_name, nil, '/tmp').and_return('Successfully unregistered gitlab runner testrunner') } 33 | end 34 | 35 | context 'with non existent ca_file option' do 36 | before do 37 | allow(PuppetX::Gitlab::Runner).to receive(:unregister).with(url, { 'token' => 'authtoken' }, nil, '/path/to/ca_file').and_return(nil) 38 | end 39 | 40 | it { is_expected.to run.with_params(url, runner_name, nil, '/path/to/ca_file').and_return('Specified CA file doesn\'t exist, not attempting to create authtoken') } 41 | end 42 | end 43 | 44 | context "does nothing if file doesn't exist" do 45 | before do 46 | allow(File).to receive(:exist?).and_call_original 47 | allow(File).to receive(:exist?).with(filename).and_return(false) 48 | end 49 | 50 | it { is_expected.to run.with_params(url, runner_name).and_return('/etc/gitlab-runner/auth-token-testrunner file doesn\'t exist') } 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /spec/functions/unregister_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'webmock/rspec' 5 | 6 | describe 'gitlab_ci_runner::unregister' do 7 | let(:url) { 'https://gitlab.example.org' } 8 | let(:authtoken) { 'registration-token' } 9 | let(:return_hash) { { 'status' => 'success' } } 10 | 11 | it { is_expected.not_to eq(nil) } 12 | it { is_expected.to run.with_params.and_raise_error(ArgumentError) } 13 | it { is_expected.to run.with_params('').and_raise_error(ArgumentError) } 14 | it { is_expected.to run.with_params('ftp://foooo.bar').and_raise_error(ArgumentError) } 15 | it { is_expected.to run.with_params('https://gitlab.com', 1234).and_raise_error(ArgumentError) } 16 | it { is_expected.to run.with_params('https://gitlab.com', 'registration-token', project: 1234).and_raise_error(ArgumentError) } 17 | 18 | it "calls 'PuppetX::Gitlab::Runner.unregister'" do 19 | allow(PuppetX::Gitlab::Runner).to receive(:unregister).with(url, { 'token' => authtoken }, ca_file: nil).and_return(return_hash) 20 | 21 | is_expected.to run.with_params(url, authtoken).and_return(return_hash) 22 | expect(PuppetX::Gitlab::Runner).to have_received(:unregister) 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/setup_acceptance_node.pp: -------------------------------------------------------------------------------- 1 | # The omnibus installer use the following algorithm to know what to do. 2 | # https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/runit/recipes/default.rb 3 | # If this peace of code trigger docker case, the installer hang indefinitly. 4 | file {'/.dockerenv': 5 | ensure => absent, 6 | } 7 | 8 | package { 'curl': 9 | ensure => present, 10 | } 11 | 12 | # Setup Puppet Bolt 13 | $bolt_config = @("BOLTPROJECT"/L) 14 | modulepath: "/etc/puppetlabs/code/modules:/etc/puppetlabs/code/environments/production/modules" 15 | analytics: false 16 | | BOLTPROJECT 17 | 18 | 19 | file { [ '/root/.puppetlabs', '/root/.puppetlabs/bolt', '/root/.puppetlabs/etc', '/root/.puppetlabs/etc/bolt']: 20 | ensure => directory, 21 | } 22 | 23 | # Needs to existing to not trigger a warning sign... 24 | file { '/root/.puppetlabs/etc/bolt/analytics.yaml': 25 | ensure => file, 26 | } 27 | 28 | file { '/root/.puppetlabs/bolt/bolt-project.yaml': 29 | ensure => file, 30 | content => $bolt_config, 31 | } 32 | 33 | file_line { '/etc/hosts-gitlab': 34 | path => '/etc/hosts', 35 | line => "${facts['gitlab_ip']} gitlab", 36 | } 37 | file_line { '/etc/hosts-squid': 38 | path => '/etc/hosts', 39 | line => "${facts['squid_ip']} squid", 40 | } 41 | 42 | # Needed for os.distro.codebase fact on ubuntu 16/18 on puppet 6 43 | if $facts['os']['name'] == 'Ubuntu' and versioncmp($facts['puppetversion'], '7.0.0') < 0 { 44 | package{'lsb-release': 45 | ensure => present, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Managed by modulesync - DO NOT EDIT 4 | # https://voxpupuli.org/docs/updating-files-managed-with-modulesync/ 5 | 6 | # puppetlabs_spec_helper will set up coverage if the env variable is set. 7 | # We want to do this if lib exists and it hasn't been explicitly set. 8 | ENV['COVERAGE'] ||= 'yes' if Dir.exist?(File.expand_path('../lib', __dir__)) 9 | 10 | require 'voxpupuli/test/spec_helper' 11 | 12 | RSpec.configure do |c| 13 | c.facterdb_string_keys = false 14 | end 15 | 16 | add_mocked_facts! 17 | 18 | if File.exist?(File.join(__dir__, 'default_module_facts.yml')) 19 | facts = YAML.safe_load(File.read(File.join(__dir__, 'default_module_facts.yml'))) 20 | facts&.each do |name, value| 21 | add_custom_fact name.to_sym, value 22 | end 23 | end 24 | 25 | require 'spec_helper_local' 26 | Dir['./spec/support/spec/**/*.rb'].sort.each { |f| require f } 27 | -------------------------------------------------------------------------------- /spec/spec_helper_acceptance.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'voxpupuli/acceptance/spec_helper_acceptance' 4 | 5 | ENV['BEAKER_FACTER_GITLAB_IP'] = File.read(File.expand_path('~/GITLAB_IP')).chomp 6 | ENV['BEAKER_FACTER_SQUID_IP'] = File.read(File.expand_path('~/SQUID_IP')).chomp 7 | 8 | configure_beaker do |host| 9 | host.install_package('puppet-bolt') if bolt_supported?(host) 10 | install_puppet_module_via_pmt_on(host, 'puppetlabs/docker') 11 | end 12 | -------------------------------------------------------------------------------- /spec/spec_helper_local.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Taken from https://github.com/theforeman/puppet-puppet/blob/143199e1f529581f138fcd9c8edea2990ea4a69c/spec/spec_helper.rb 4 | def verify_concat_fragment_exact_contents(subject, title, expected_lines) 5 | is_expected.to contain_concat__fragment(title) 6 | content = subject.resource('concat::fragment', title).send(:parameters)[:content] 7 | expect(content.split(%r{\n}).grep_v(%r{(^#|^$|^\s+#)})).to match_array(expected_lines) 8 | end 9 | -------------------------------------------------------------------------------- /spec/tasks/register_runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'webmock/rspec' 4 | require_relative '../../tasks/register_runner' 5 | 6 | describe RegisterRunnerTask do 7 | let(:params) do 8 | { 9 | token: 'registrationtoken', 10 | url: 'https://gitlab.example.org' 11 | } 12 | end 13 | let(:described_object) { described_class.new } 14 | 15 | describe '.task' do 16 | it 'can register a runner' do 17 | allow(PuppetX::Gitlab::Runner).to receive(:register). 18 | with('https://gitlab.example.org', { token: 'registrationtoken' }). 19 | and_return('id' => 777, 'token' => '3bz5wqfDiYBhxoUNuGVu') 20 | 21 | expect(described_object.task(**params)).to eq('id' => 777, 'token' => '3bz5wqfDiYBhxoUNuGVu') 22 | end 23 | 24 | it 'can raise an error' do 25 | params.merge(token: 'invalid-token') 26 | stub_request(:post, 'https://gitlab.example.org/api/v4/runners'). 27 | to_return(status: [403, 'Forbidden']) 28 | expect { described_object.task(**params) }.to raise_error(TaskHelper::Error, %r{Gitlab runner failed to register: Forbidden}) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/tasks/unregister_runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'webmock/rspec' 4 | require_relative '../../tasks/unregister_runner' 5 | 6 | describe UnregisterRunnerTask do 7 | let(:params) do 8 | { 9 | url: 'https://gitlab.example.org', 10 | token: 'abcdef1234' 11 | } 12 | end 13 | let(:described_object) { described_class.new } 14 | 15 | describe '.task' do 16 | it 'can unregister a runner' do 17 | allow(PuppetX::Gitlab::Runner).to receive(:unregister). 18 | with('https://gitlab.example.org', { token: 'abcdef1234' }). 19 | and_return({}) 20 | 21 | expect(described_object.task(**params)).to eq(status: 'success') 22 | end 23 | 24 | it 'can raise an error' do 25 | params.merge(token: 'invalid-token') 26 | stub_request(:delete, 'https://gitlab.example.org/api/v4/runners'). 27 | to_return(status: [403, 'Forbidden']) 28 | expect { described_object.task(**params) }.to raise_error(TaskHelper::Error, %r{Gitlab runner failed to unregister: Forbidden}) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/type_aliases/log_format_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe 'Gitlab_ci_runner::Log_format' do 6 | %w[runner text json].each do |value| 7 | it { is_expected.to allow_value(value) } 8 | end 9 | 10 | [:undef, 1, '', 'WARN', 'DEBUG1', true, false, 42].each do |value| 11 | it { is_expected.not_to allow_value(value) } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/type_aliases/log_level_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | describe 'Gitlab_ci_runner::Log_level' do 6 | %w[debug info warn error fatal panic].each do |value| 7 | it { is_expected.to allow_value(value) } 8 | end 9 | 10 | [:undef, 1, '', 'WARN', 'DEBUG1', true, false, 42].each do |value| 11 | it { is_expected.not_to allow_value(value) } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/type_aliases/session_server_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | 5 | valid_values = [ 6 | { 7 | listen_address: '127.0.0.1:8093', 8 | advertise_address: '127.0.0.1:8093', 9 | }, 10 | { 11 | listen_address: 'localhost:8093', 12 | advertise_address: 'runner-host-name.tld:8093', 13 | }, 14 | { 15 | listen_address: '[::]:8093', 16 | advertise_address: 'runner-host-name.tld:8093', 17 | } 18 | ] 19 | 20 | describe 'Gitlab_ci_runner::Session_server' do 21 | valid_values.each do |value| 22 | it { is_expected.to allow_value(value) } 23 | it { is_expected.to allow_value(value.merge(session_timeout: 1234)) } 24 | end 25 | 26 | [:undef, { listen_address: '127.0.0.1:8093' }, { advertise_address: 'runner-host-name.tld:8093' }, { session_timeout: 1234 }].each do |value| 27 | it { is_expected.not_to allow_value(value) } 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/unit/puppet_x/gitlab/runner_spec.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | require 'spec_helper' 4 | require 'webmock/rspec' 5 | require_relative '../../../../lib/puppet_x/gitlab/runner' 6 | 7 | module PuppetX::Gitlab 8 | describe APIClient do 9 | describe 'self.delete' do 10 | it 'returns an empty hash' do 11 | stub_request(:delete, 'https://example.org'). 12 | with( 13 | body: '{}', 14 | headers: { 15 | 'Accept' => 'application/json', 16 | 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 17 | 'Content-Type' => 'application/json', 18 | 'User-Agent' => 'Ruby' 19 | } 20 | ). 21 | to_return(status: 204, body: '', headers: {}) 22 | 23 | expect(described_class.delete('https://example.org', {}, nil, nil)).to eq({}) 24 | end 25 | 26 | it 'raises an exception on non 200 http code' do 27 | stub_request(:delete, 'https://example.org'). 28 | to_return(status: 403) 29 | 30 | expect { described_class.delete('https://example.org', {}, nil, nil) }.to raise_error(Net::HTTPError) 31 | end 32 | end 33 | 34 | describe 'self.post' do 35 | it 'returns a hash' do 36 | stub_request(:post, 'https://example.org'). 37 | with( 38 | body: '{}', 39 | headers: { 40 | 'Accept' => 'application/json', 41 | 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 42 | 'Content-Type' => 'application/json', 43 | 'User-Agent' => 'Ruby' 44 | } 45 | ). 46 | to_return(status: 201, body: '{ "id": "12345", "token": "6337ff461c94fd3fa32ba3b1ff4125" }', headers: {}) 47 | 48 | expect(described_class.post('https://example.org', {}, nil, nil)).to eq('id' => '12345', 'token' => '6337ff461c94fd3fa32ba3b1ff4125') 49 | end 50 | 51 | it 'raises an exception on non 200 http code' do 52 | stub_request(:delete, 'https://example.org'). 53 | to_return(status: 501) 54 | 55 | expect { described_class.delete('https://example.org', {}, nil, nil) }.to raise_error(Net::HTTPError) 56 | end 57 | end 58 | 59 | describe 'self.request' do 60 | context 'when doing a request' do 61 | before do 62 | stub_request(:post, 'example.org') 63 | described_class.request('http://example.org/', Net::HTTP::Post, {}, nil, nil) 64 | end 65 | 66 | it 'uses Accept: application/json' do 67 | expect(a_request(:post, 'example.org'). 68 | with(headers: { 'Accept' => 'application/json' })). 69 | to have_been_made 70 | end 71 | 72 | it 'uses Content: application/json' do 73 | expect(a_request(:post, 'example.org'). 74 | with(headers: { 'Content-Type' => 'application/json' })). 75 | to have_been_made 76 | end 77 | end 78 | 79 | context 'when doing a HTTPS request' do 80 | before do 81 | stub_request(:post, 'https://example.org/') 82 | described_class.request('https://example.org/', Net::HTTP::Post, {}, nil, nil) 83 | end 84 | 85 | it 'uses SSL if url contains https://' do 86 | expect(a_request(:post, 'https://example.org/')).to have_been_made 87 | end 88 | end 89 | end 90 | end 91 | 92 | describe Runner do 93 | describe 'self.register' do 94 | before do 95 | PuppetX::Gitlab::APIClient. 96 | stub(:post). 97 | with('https://gitlab.example.org/api/v4/runners', { token: 'registrationtoken' }, nil, nil). 98 | and_return('id' => 1234, 'token' => '1234567890abcd') 99 | end 100 | 101 | let(:response) { described_class.register('https://gitlab.example.org', { token: 'registrationtoken' }, nil, nil) } 102 | 103 | it 'returns a token' do 104 | expect(response['token']).to eq('1234567890abcd') 105 | end 106 | end 107 | 108 | describe 'self.unregister' do 109 | before do 110 | PuppetX::Gitlab::APIClient. 111 | stub(:delete). 112 | with('https://gitlab.example.org/api/v4/runners', { token: '1234567890abcd' }, nil, nil). 113 | and_return({}) 114 | end 115 | 116 | let(:response) { described_class.unregister('https://gitlab.example.org', { token: '1234567890abcd' }, nil, nil) } 117 | 118 | it 'returns an empty hash' do 119 | expect(response).to eq({}) 120 | end 121 | end 122 | end 123 | end 124 | -------------------------------------------------------------------------------- /tasks/register_runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Registers a runner on a Gitlab instance.", 3 | "files": [ 4 | "ruby_task_helper/files/task_helper.rb", 5 | "gitlab_ci_runner/lib/puppet_x/gitlab/runner.rb" 6 | ], 7 | "input_method": "stdin", 8 | "parameters": { 9 | "url": { 10 | "description": "The url to your Gitlab instance. Please only provide the host part (e.g https://gitlab.com)", 11 | "type": "String[1]" 12 | }, 13 | "token": { 14 | "description": "Registration token.", 15 | "type": "String[1]" 16 | }, 17 | "description": { 18 | "description": "Runners description.", 19 | "type": "Optional[String[1]]" 20 | }, 21 | "info": { 22 | "description": "Runners metadata.", 23 | "type": "Optional[Hash]" 24 | }, 25 | "active": { 26 | "description": "Whether the Runner is active.", 27 | "type": "Optional[Boolean]" 28 | }, 29 | "locked": { 30 | "description": "Whether the Runner should be locked for current project.", 31 | "type": "Optional[Boolean]" 32 | }, 33 | "run_untagged": { 34 | "description": "Whether the Runner should handle untagged jobs.", 35 | "type": "Optional[Boolean]" 36 | }, 37 | "tag_list": { 38 | "description": "List of Runners tags.", 39 | "type": "Optional[Array[String[1]]]" 40 | }, 41 | "access_level": { 42 | "description": "The access_level of the runner.", 43 | "type": "Optional[Enum['not_protected', 'ref_protected']]" 44 | }, 45 | "maximum_timeout": { 46 | "description": "Maximum timeout set when this Runner will handle the job.", 47 | "type": "Optional[Integer[1]]" 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /tasks/register_runner.rb: -------------------------------------------------------------------------------- 1 | #!/opt/puppetlabs/puppet/bin/ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative '../lib/puppet_x/gitlab/runner' 5 | require_relative '../../ruby_task_helper/files/task_helper' 6 | 7 | class RegisterRunnerTask < TaskHelper 8 | def task(**kwargs) 9 | url = kwargs[:url] 10 | options = kwargs.reject { |key, _| %i[_task _installdir url].include?(key) } 11 | 12 | begin 13 | PuppetX::Gitlab::Runner.register(url, options) 14 | rescue Net::HTTPError => e 15 | raise TaskHelper::Error.new("Gitlab runner failed to register: #{e.message}", 'bolt-plugin/gitlab-ci-runner-register-error') 16 | end 17 | end 18 | end 19 | 20 | RegisterRunnerTask.run if $PROGRAM_NAME == __FILE__ 21 | -------------------------------------------------------------------------------- /tasks/unregister_runner.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Unregisters a runner from a Gitlab instance.", 3 | "files": [ 4 | "ruby_task_helper/files/task_helper.rb", 5 | "gitlab_ci_runner/lib/puppet_x/gitlab/runner.rb" 6 | ], 7 | "input_method": "stdin", 8 | "parameters": { 9 | "url": { 10 | "description": "The url to your Gitlab instance. Please provide the host part only! (e.g https://gitlab.com)", 11 | "type": "String[1]" 12 | }, 13 | "token": { 14 | "description": "Runners authentication token.", 15 | "type": "String[1]" 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tasks/unregister_runner.rb: -------------------------------------------------------------------------------- 1 | #!/opt/puppetlabs/puppet/bin/ruby 2 | # frozen_string_literal: true 3 | 4 | require_relative '../lib/puppet_x/gitlab/runner' 5 | require_relative '../../ruby_task_helper/files/task_helper' 6 | 7 | class UnregisterRunnerTask < TaskHelper 8 | def task(**kwargs) 9 | url = kwargs[:url] 10 | options = kwargs.reject { |key, _| %i[_task _installdir url].include?(key) } 11 | 12 | begin 13 | PuppetX::Gitlab::Runner.unregister(url, options) 14 | { status: 'success' } 15 | rescue Net::HTTPError => e 16 | raise TaskHelper::Error.new("Gitlab runner failed to unregister: #{e.message}", 'bolt-plugin/gitlab-ci-runner-unregister-error') 17 | end 18 | end 19 | end 20 | 21 | UnregisterRunnerTask.run if $PROGRAM_NAME == __FILE__ 22 | -------------------------------------------------------------------------------- /types/keyserver.pp: -------------------------------------------------------------------------------- 1 | # Type to match repo_keyserver 2 | # Regex from: https://github.com/puppetlabs/puppetlabs-apt/blob/main/manifests/key.pp 3 | type Gitlab_ci_runner::Keyserver = Pattern[/\A((hkp|hkps|http|https):\/\/)?([a-z\d])([a-z\d-]{0,61}\.)+[a-z\d]+(:\d{2,5})?(\/[a-zA-Z\d\-_.]+)*\/?$/] 4 | 5 | -------------------------------------------------------------------------------- /types/log_format.pp: -------------------------------------------------------------------------------- 1 | # @summary Gitlab Runner log format configuration 2 | type Gitlab_ci_runner::Log_format = Enum['runner', 'text', 'json'] 3 | -------------------------------------------------------------------------------- /types/log_level.pp: -------------------------------------------------------------------------------- 1 | # @summary Gitlab Runner log level configuration 2 | type Gitlab_ci_runner::Log_level = Enum['debug', 'info', 'warn', 'error', 'fatal', 'panic'] 3 | -------------------------------------------------------------------------------- /types/register.pp: -------------------------------------------------------------------------------- 1 | # @summary A struct of all possible additionl options for gitlab_ci_runner::register 2 | type Gitlab_ci_runner::Register = Struct[{ 3 | Optional[description] => String[1], 4 | Optional[info] => Hash[String[1],String[1]], 5 | Optional[active] => Boolean, 6 | Optional[locked] => Boolean, 7 | Optional[run_untagged] => Boolean, 8 | Optional[tag_list] => Array[String[1]], 9 | Optional[access_level] => Enum['not_protected', 'ref_protected'], 10 | Optional[maximum_timeout] => Integer, 11 | }] 12 | -------------------------------------------------------------------------------- /types/register_parameters.pp: -------------------------------------------------------------------------------- 1 | # @summary A enum containing a possible keys used for Gitlab runner registrations 2 | type Gitlab_ci_runner::Register_parameters = Enum['description', 'info', 'active', 'locked', 'run_untagged', 'run-untagged', 'tag_list', 'tag-list', 'access_level', 'access-level', 'maximum_timeout', 'maximum-timeout'] 3 | -------------------------------------------------------------------------------- /types/session_server.pp: -------------------------------------------------------------------------------- 1 | # @summary Gitlab Runner session_server configuration 2 | type Gitlab_ci_runner::Session_server = Struct[ 3 | { 4 | listen_address => String[1], 5 | advertise_address => String[1], 6 | session_timeout => Optional[Integer], 7 | } 8 | ] 9 | --------------------------------------------------------------------------------